[go: nahoru, domu]

Introduce call and emit codegen with new resolver, remove KTX completely

Change-Id: I7c7629593bc890e38d19b65f0e2607018adbf420
diff --git a/compose/compose-compiler-hosted/integration-tests/build.gradle b/compose/compose-compiler-hosted/integration-tests/build.gradle
index 034f8e8..d4afe75 100644
--- a/compose/compose-compiler-hosted/integration-tests/build.gradle
+++ b/compose/compose-compiler-hosted/integration-tests/build.gradle
@@ -37,6 +37,7 @@
 
     testImplementation(KOTLIN_COMPOSE_STDLIB)
     testImplementation(project(":compose:compose-runtime"))
+    testImplementation(project(":ui:ui-framework"))
     testImplementation(project(":ui:ui-android-view-non-ir"))
     testImplementation(project(":compose:compose-compiler-hosted"))
 }
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCompilerTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCompilerTest.kt
index 0942b79..aaa7dcd 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCompilerTest.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCompilerTest.kt
@@ -99,7 +99,7 @@
     }
 
     protected open fun setupEnvironment(environment: KotlinCoreEnvironment) {
-        ComposeComponentRegistrar().registerProjectComponents(
+        ComposeComponentRegistrar.registerProjectExtensions(
             environment.project as MockProject,
             environment.configuration
         )
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractResolvedKtxCallsTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractResolvedKtxCallsTest.kt
deleted file mode 100644
index 8ff7ca4..0000000
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractResolvedKtxCallsTest.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import com.intellij.psi.PsiElement
-import com.intellij.psi.util.PsiTreeUtil
-import junit.framework.TestCase
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import org.jetbrains.kotlin.resolve.BindingContext
-import kotlin.reflect.KClass
-
-abstract class AbstractResolvedKtxCallsTest : AbstractCodegenTest() {
-
-    fun doTest(srcText: String, expected: String) {
-        val (text, carets) = extractCarets(srcText)
-
-        val environment = myEnvironment ?: error("Environment not initialized")
-
-        val ktFile = KtPsiFactory(environment.project).createFile(text)
-        val bindingContext = JvmResolveUtil.analyze(
-            ktFile,
-            environment
-        ).bindingContext
-
-        val resolvedCalls = carets.mapNotNull { caret ->
-            val (element, ktxElementCall) = buildCachedCallAtIndex(bindingContext, ktFile, caret)
-            val elementText = element?.text ?: error("KtxElement expected, but none found")
-            val call = ktxElementCall ?: error("ResolvedKtxElementCall expected, but none found")
-            elementText to call
-        }
-
-        val output = renderOutput(resolvedCalls)
-
-        TestCase.assertEquals(expected.trimIndent(), output.trimIndent())
-    }
-
-    protected open fun renderOutput(
-        resolvedCallsAt: List<Pair<String, ResolvedKtxElementCall>>
-    ): String =
-        resolvedCallsAt.joinToString("\n\n\n") { (_, resolvedCall) ->
-            resolvedCall.print()
-        }
-
-    protected fun extractCarets(text: String): Pair<String, List<Int>> {
-        val parts = text.split("<caret>")
-        if (parts.size < 2) return text to emptyList()
-        // possible to rewrite using 'scan' function to get partial sums of parts lengths
-        val indices = mutableListOf<Int>()
-        val resultText = buildString {
-            parts.dropLast(1).forEach { part ->
-                append(part)
-                indices.add(this.length)
-            }
-            append(parts.last())
-        }
-        return resultText to indices
-    }
-
-    protected open fun buildCachedCallAtIndex(
-        bindingContext: BindingContext,
-        jetFile: KtFile,
-        index: Int
-    ): Pair<PsiElement?, ResolvedKtxElementCall?> {
-        val element = jetFile.findElementAt(index)!!
-        val expression = element.parentOfType<KtxElement>()
-
-        val cachedCall = bindingContext[ComposeWritableSlices.RESOLVED_KTX_CALL, expression]
-        return Pair(element, cachedCall)
-    }
-}
-private inline fun <reified T : PsiElement> PsiElement.parentOfType(): T? = parentOfType(T::class)
-
-private fun <T : PsiElement> PsiElement.parentOfType(vararg classes: KClass<out T>): T? {
-    return PsiTreeUtil.getParentOfType(this, *classes.map { it.java }.toTypedArray())
-}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallLoweringTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallLoweringTests.kt
new file mode 100644
index 0000000..0b6b72d
--- /dev/null
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallLoweringTests.kt
@@ -0,0 +1,1317 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.plugins.kotlin
+
+import android.widget.Button
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.intellij.psi.PsiElement
+import com.intellij.psi.util.PsiTreeUtil
+import org.jetbrains.kotlin.psi.KtCallExpression
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.psi.KtPsiFactory
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import java.net.URLClassLoader
+import kotlin.reflect.KClass
+
+@RunWith(ComposeRobolectricTestRunner::class)
+@Config(
+    manifest = Config.NONE,
+    minSdk = 23,
+    maxSdk = 23
+)
+class ComposeCallLoweringTests : AbstractCodegenTest() {
+
+    @Test
+    fun testInlineNoinline(): Unit = ensureSetup {
+        codegen(
+            """
+        @Composable
+        inline fun PointerInputWrapper(
+            crossinline children: @Composable() () -> Unit
+        ) {
+            LinearLayout {
+                children()
+            }
+        }
+
+        @Composable
+        fun PressReleasedGestureDetector(children: @Composable() () -> Unit) {
+            PointerInputWrapper {
+                children()
+            }
+        }
+            """.trimIndent()
+        )
+    }
+
+    @Test
+    fun testInlinedComposable(): Unit = ensureSetup {
+        codegen(
+            """
+        @Composable 
+        inline fun Foo(crossinline children: @Composable() () -> Unit) {
+                children()
+        }
+
+        @Composable fun test(children: @Composable() () -> Unit) {
+            Foo {
+                println("hello world")
+                children()
+            }
+        }
+            """
+        )
+    }
+
+    @Test
+    fun testGenericEmittables(): Unit = ensureSetup {
+        codegen(
+            """
+        class FooKey<T>(val name: String)
+        class Foo<T>(val key: FooKey<T>, var value: T): Emittable {
+            override fun emitInsertAt(index: Int, instance: Emittable) {
+
+            }
+
+            override fun emitRemoveAt(index: Int, count: Int) {
+
+            }
+
+            override fun emitMove(from: Int, to: Int, count: Int) {
+
+            }
+        }
+
+        val AnyKey = FooKey<Any>("any")
+
+        @Composable fun test(value: Any, children: @Composable() () -> Unit) {
+            Foo(key=AnyKey, value=value) {
+                children()
+            }
+        }
+            """
+        )
+    }
+
+    @Test
+    fun testSetViewContentIssue(): Unit = ensureSetup {
+        codegen(
+            """
+                import android.app.Activity
+                import android.os.Bundle
+                import android.view.Gravity
+                import android.view.ViewGroup
+                import android.widget.*
+                import androidx.compose.*
+                import androidx.ui.androidview.adapters.*
+
+                class RippleActivity : Activity() {
+
+                    override fun onCreate(savedInstanceState: Bundle?) {
+                        super.onCreate(savedInstanceState)
+                        setViewContent {
+                            val layoutParams = LinearLayout.LayoutParams(
+                                ViewGroup.LayoutParams.MATCH_PARENT,
+                                0,
+                                1f
+                            )
+                            val gravity = Gravity.CENTER_HORIZONTAL
+                            LinearLayout(orientation = LinearLayout.VERTICAL) {
+                                TextView(gravity = gravity, text = "Compose card with ripple:")
+                                LinearLayout(layoutParams = layoutParams) {
+                                    // RippleDemo()
+                                }
+                                TextView(gravity = gravity, text = "Platform button with ripple:")
+                                LinearLayout(layoutParams = layoutParams, padding = 50.dp) {
+                                    // Button(background = getDrawable(R.drawable.ripple))
+                                }
+                            }
+                        }
+                    }
+                }
+            """
+        )
+    }
+
+    @Test
+    fun testGenericParameterOrderIssue(): Unit = ensureSetup {
+        codegen(
+            """
+@Composable
+fun A() {
+    val x = ""
+    val y = ""
+
+    B(bar = x, foo = y)
+}
+
+@Composable
+fun <T> B(foo: T, bar: String) { }
+            """
+        )
+    }
+
+    @Test
+    fun testArgumentOrderIssue(): Unit = ensureSetup {
+        codegen(
+            """
+                class A
+
+                @Composable
+                fun B() {
+                    C(bar = 1, foo = 1f)
+                }
+
+                @Composable
+                fun C(
+                    foo: Float,
+                    bar: Int
+                ) {
+
+                }
+            """
+        )
+    }
+
+    @Test
+    fun testObjectName(): Unit = ensureSetup {
+        codegen(
+            """
+
+            @Composable fun SomeThing(children: @Composable() () -> Unit) {}
+
+            @Composable
+            fun Example() {
+                SomeThing {
+                    val id = object {}
+                }
+            }
+            """
+        )
+    }
+
+    @Test
+    fun testWebViewBug(): Unit = ensureSetup {
+        codegen(
+            """
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.compose.Composable
+import androidx.compose.composer
+
+class WebContext {
+    var webView: WebView? = null
+}
+
+private fun WebView.setRef(ref: (WebView) -> Unit) {
+    ref(this)
+}
+
+@Composable
+fun WebComponent(
+    url: String,
+    webViewClient: WebViewClient = WebViewClient(),
+    webContext: WebContext
+) {
+
+    WebView(
+        ref = { webContext.webView = it }
+    )
+}
+            """
+        )
+    }
+
+    @Test
+    fun testStuffThatIWantTo(): Unit = ensureSetup {
+        codegen(
+            """
+
+            fun startCompose(block: @Composable() () -> Unit) {}
+
+            fun nonComposable() {
+                startCompose {
+                    LinearLayout {
+
+                    }
+                }
+            }
+            """
+        )
+    }
+
+    @Test
+    fun testSimpleFunctionResolution(): Unit = ensureSetup {
+        compose(
+            """
+            import androidx.compose.*
+
+            @Composable
+            fun noise(text: String) {}
+
+            @Composable
+            fun bar() {
+                noise(text="Hello World")
+            }
+            """,
+            """
+            """
+        )
+    }
+
+    @Test
+    fun testSimpleClassResolution(): Unit = ensureSetup {
+        compose(
+            """
+            import android.widget.TextView
+            import androidx.compose.*
+
+            @Composable
+            fun bar() {
+                TextView(text="Hello World")
+            }
+            """,
+            """
+            """
+        )
+    }
+
+    @Test
+    fun testSetContent(): Unit = ensureSetup {
+        codegen(
+            """
+                fun fakeCompose(block: @Composable() ()->Unit) { }
+
+                class Test {
+                    fun test() {
+                        fakeCompose {
+                            LinearLayout(orientation = LinearLayout.VERTICAL) {}
+                        }
+                    }
+                }
+            """
+        )
+    }
+
+    @Test
+    @Ignore("b/142488002")
+    fun testReceiverScopeComposer(): Unit = ensureSetup {
+        codegen(
+            """
+            import androidx.compose.Applier
+            import androidx.compose.ApplyAdapter
+            import androidx.compose.Component
+            import androidx.compose.Composable
+            import androidx.compose.Composer
+            import androidx.compose.ComposerUpdater
+            import androidx.compose.CompositionContext
+            import androidx.compose.CompositionReference
+            import androidx.compose.Effect
+            import androidx.compose.Recomposer
+            import androidx.compose.SlotTable
+            import androidx.compose.ViewValidator
+            import androidx.compose.cache
+
+            class TextSpan(
+                val style: String? = null,
+                val text: String? = null,
+                val children: MutableList<TextSpan> = mutableListOf()
+            )
+
+            /**
+             * This adapter is used by [TextSpanComposer] to build the [TextSpan] tree.
+             * @see ApplyAdapter
+             */
+            internal class TextSpanApplyAdapter : ApplyAdapter<TextSpan> {
+                override fun TextSpan.start(instance: TextSpan) {}
+
+                override fun TextSpan.end(instance: TextSpan, parent: TextSpan) {}
+
+                override fun TextSpan.insertAt(index: Int, instance: TextSpan) {
+                    children.add(index, instance)
+                }
+
+                override fun TextSpan.removeAt(index: Int, count: Int) {
+                    repeat(count) {
+                        children.removeAt(index)
+                    }
+                }
+
+                override fun TextSpan.move(from: Int, to: Int, count: Int) {
+                    if (from == to) return
+
+                    if (from > to) {
+                        val moved = mutableListOf<TextSpan>()
+                        repeat(count) {
+                            moved.add(children.removeAt(from))
+                        }
+                        children.addAll(to, moved)
+                    } else {
+                        // Number of elements between to and from is smaller than count, can't move.
+                        if (count > to - from) return
+                        repeat(count) {
+                            val node = children.removeAt(from)
+                            children.add(to - 1, node)
+                        }
+                    }
+                }
+            }
+
+            typealias TextSpanUpdater<T> = ComposerUpdater<TextSpan, T>
+
+            /**
+             * The composer of [TextSpan].
+             */
+            class TextSpanComposer internal constructor(
+                root: TextSpan,
+                recomposer: Recomposer
+            ) : Composer<TextSpan>(SlotTable(), Applier(root, TextSpanApplyAdapter()), recomposer)
+
+            @PublishedApi
+            internal val invocation = Object()
+
+            class TextSpanComposition(val composer: TextSpanComposer) {
+                @Suppress("NOTHING_TO_INLINE")
+                inline operator fun <V> Effect<V>.unaryPlus(): V = resolve(this@TextSpanComposition.composer)
+
+                inline fun emit(
+                    key: Any,
+                    /*crossinline*/
+                    ctor: () -> TextSpan,
+                    update: TextSpanUpdater<TextSpan>.() -> Unit
+                ) = with(composer) {
+                    startNode(key)
+                    @Suppress("UNCHECKED_CAST") val node = if (inserting) ctor().also { emitNode(it) }
+                    else useNode()
+                    TextSpanUpdater(this, node).update()
+                    endNode()
+                }
+
+                inline fun emit(
+                    key: Any,
+                    /*crossinline*/
+                    ctor: () -> TextSpan,
+                    update: TextSpanUpdater<TextSpan>.() -> Unit,
+                    children: () -> Unit
+                ) = with(composer) {
+                    startNode(key)
+                    @Suppress("UNCHECKED_CAST")val node = if (inserting) ctor().also { emitNode(it) }
+                    else useNode()
+                    TextSpanUpdater(this, node).update()
+                    children()
+                    endNode()
+                }
+
+                @Suppress("NOTHING_TO_INLINE")
+                inline fun joinKey(left: Any, right: Any?): Any = composer.joinKey(left, right)
+
+                inline fun call(
+                    key: Any,
+                    /*crossinline*/
+                    invalid: ViewValidator.() -> Boolean,
+                    block: () -> Unit
+                ) = with(composer) {
+                    startGroup(key)
+                    if (ViewValidator(composer).invalid() || inserting) {
+                        startGroup(invocation)
+                        block()
+                        endGroup()
+                    } else {
+                        skipCurrentGroup()
+                    }
+                    endGroup()
+                }
+
+                inline fun <T> call(
+                    key: Any,
+                    /*crossinline*/
+                    ctor: () -> T,
+                    /*crossinline*/
+                    invalid: ViewValidator.(f: T) -> Boolean,
+                    block: (f: T) -> Unit
+                ) = with(composer) {
+                    startGroup(key)
+                    val f = cache(true, ctor)
+                    if (ViewValidator(this).invalid(f) || inserting) {
+                        startGroup(invocation)
+                        block(f)
+                        endGroup()
+                    } else {
+                        skipCurrentGroup()
+                    }
+                    endGroup()
+                }
+            }
+
+            /**
+             * As the name indicates, [Root] object is associated with a [TextSpan] tree root. It contains
+             * necessary information used to compose and recompose [TextSpan] tree. It's created and stored
+             * when the [TextSpan] container is composed for the first time.
+             */
+            private class Root : Component() {
+                fun update() = composer.compose()
+                lateinit var scope: TextSpanScope
+                lateinit var composer: CompositionContext
+                lateinit var composable: @Composable() TextSpanScope.() -> Unit
+                @Suppress("PLUGIN_ERROR")
+                override fun compose() {
+                    with(scope.composer.composer) {
+                        startGroup(0)
+                        scope.composable()
+                        endGroup()
+                    }
+                }
+            }
+
+            /**
+             *  The map used store the [Root] object for [TextSpan] trees.
+             */
+            private val TEXTSPAN_ROOT_COMPONENTS = HashMap<TextSpan, Root>()
+
+            /**
+             * Get the [Root] object of the given [TextSpan] root node.
+             */
+            private fun getRootComponent(node: TextSpan): Root? {
+                return TEXTSPAN_ROOT_COMPONENTS[node]
+            }
+
+            /**
+             * Store the [Root] object of [node].
+             */
+            private fun setRoot(node: TextSpan, component: Root) {
+                TEXTSPAN_ROOT_COMPONENTS[node] = component
+            }
+
+            /**
+             * Compose a [TextSpan] tree.
+             * @param container The root of [TextSpan] tree where the children TextSpans will be attached to.
+             * @param parent The parent composition reference, if applicable. Default is null.
+             * @param composable The composable function to compose the children of [container].
+             * @see CompositionReference
+             */
+            @Suppress("PLUGIN_ERROR")
+            fun compose(
+                container: TextSpan,
+                parent: CompositionReference? = null,
+                composable: @Composable() TextSpanScope.() -> Unit
+            ) {
+                var root = getRootComponent(container)
+                if (root == null) {
+                    lateinit var composer: TextSpanComposer
+                    root = Root()
+                    setRoot(container, root)
+                    root.composer = CompositionContext.prepare(root, parent) {
+                        TextSpanComposer(container, this).also { composer = it }
+                    }
+                    root.scope = TextSpanScope(TextSpanComposition(composer))
+                    root.composable = composable
+
+                    root.update()
+                } else {
+                    root.composable = composable
+
+                    root.update()
+                }
+            }
+
+            /**
+             * Cleanup when the [TextSpan] is no longer used.
+             *
+             * @param container The root of the [TextSpan] to be disposed.
+             * @param parent The [CompositionReference] used together with [container] when [composer] is
+             * called.
+             */
+            fun disposeComposition(
+                container: TextSpan,
+                parent: CompositionReference? = null
+            ) {
+                // temporary easy way to call correct lifecycles on everything
+                compose(container, parent) {}
+                TEXTSPAN_ROOT_COMPONENTS.remove(container)
+            }
+
+            /**
+             * The receiver class of the children of Text and TextSpan. Such that [Span] can only be used
+             * within [Text] and [TextSpan].
+             */
+            class TextSpanScope internal constructor(val composer: TextSpanComposition)
+
+            @Composable
+            fun TextSpanScope.Span(
+                text: String? = null,
+                style: String? = null,
+                child: @Composable TextSpanScope.() -> Unit
+            ) {
+                TextSpan(text = text, style = style) {
+                    child()
+                }
+            }
+
+            @Composable
+            fun TextSpanScope.Span(
+                text: String? = null,
+                style: String? = null
+            ) {
+                TextSpan(text = text, style = style)
+            }
+        """
+        )
+    }
+
+    @Test
+    fun testComposeWithResult(): Unit = ensureSetup {
+        compose(
+            """
+                fun <T> identity(block: @Composable() ()->T): T = block()
+
+                @Composable
+                fun TestCall() {
+                  val value: Any = identity { 12 }
+                  TextView(text = value.toString(), id = 100)
+                }
+            """,
+            "TestCall()"
+        ).then { activity ->
+            val textView = activity.findViewById<TextView>(100)
+            assertEquals("12", textView.text)
+        }
+    }
+
+    @Test
+    fun testObservable(): Unit = ensureSetup {
+        compose(
+            """
+                import android.widget.Button
+                import androidx.compose.*
+                import androidx.ui.androidview.adapters.setOnClick
+
+                @Model
+                class FancyButtonData() {
+                    var x = 0
+                }
+
+                @Composable
+                fun SimpleComposable() {
+                    FancyButton(state=FancyButtonData())
+                }
+
+                @Composable
+                fun FancyButton(state: FancyButtonData) {
+                    Button(text=("Clicked "+state.x+" times"),  id=42)
+                }
+            """,
+            "SimpleComposable()"
+        ).then { activity ->
+            val button = activity.findViewById(42) as Button
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById(42) as Button
+            assertEquals("Clicked 3 times", button.text)
+        }
+    }
+
+    @Test // java.lang.ClassNotFoundException: Z
+    fun testObservableLambda(): Unit = ensureSetup {
+        compose(
+            """
+                @Model
+                class FancyButtonCount() {
+                    var count = 0
+                }
+
+                @Composable
+                fun SimpleComposable(state: FancyButtonCount) {
+                    FancyBox2 {
+                        Button(
+                          text=("Button clicked "+state.count+" times"),
+                          >
+                          id=42
+                        )
+                    }
+                }
+
+                @Composable
+                fun FancyBox2(children: @Composable() ()->Unit) {
+                    children()
+                }
+            """,
+            "SimpleComposable(state=+memo { FancyButtonCount() })"
+        ).then { activity ->
+            val button = activity.findViewById(42) as Button
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById(42) as Button
+            assertEquals("Button clicked 3 times", button.text)
+        }
+    }
+
+    @Test
+    fun testObservableGenericFunction(): Unit = ensureSetup {
+        compose("""
+            @Model
+            class Counter() {
+                var count = 0
+            }
+
+            @Composable
+            fun <T> SimpleComposable(state: Counter, value: T) {
+                Button(
+                  text=("Button clicked "+state.count+" times: " + value),
+                  >
+                  id=42
+                )
+            }
+        """,
+            "SimpleComposable(state=+memo { Counter() }, value=\"Value\")"
+        ).then { activity ->
+            val button = activity.findViewById(42) as Button
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById(42) as Button
+            assertEquals("Button clicked 3 times: Value", button.text)
+        }
+    }
+
+    @Test
+    fun testObservableExtension(): Unit = ensureSetup {
+        compose("""
+            @Model
+            class Counter() {
+                var count = 0
+            }
+
+            @Composable
+            fun Counter.Composable() {
+                Button(
+                    text="Button clicked "+count+" times",
+                    >
+                    id=42
+                )
+            }
+
+            val myCounter = Counter()
+            """,
+            "myCounter.Composable()"
+        ).then { activity ->
+            val button = activity.findViewById<Button>(42)
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById<Button>(42)
+            assertEquals("Button clicked 3 times", button.text)
+        }
+    }
+
+    @Test
+    fun testObserverableExpressionBody(): Unit = ensureSetup {
+        compose("""
+            @Model
+            class Counter() {
+                var count = 0
+            }
+
+            @Composable
+            fun SimpleComposable(counter: Counter) =
+                Button(
+                    text="Button clicked "+counter.count+" times",
+                    >
+                    id=42
+                )
+
+            @Composable
+            fun SimpleWrapper(counter: Counter) = SimpleComposable(counter = counter)
+
+            val myCounter = Counter()
+            """,
+            "SimpleWrapper(counter = myCounter)"
+        ).then { activity ->
+            val button = activity.findViewById<Button>(42)
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById<Button>(42)
+            assertEquals("Button clicked 3 times", button.text)
+        }
+    }
+
+    @Test
+    fun testObservableInlineWrapper(): Unit = ensureSetup {
+        compose("""
+            @Model
+            class Counter() {
+                var count = 0
+            }
+
+            var inWrapper = false
+            val counter = Counter()
+
+            inline fun wrapper(block: () -> Unit) {
+              inWrapper = true
+              try {
+                block()
+              } finally {
+                inWrapper = false
+              }
+            }
+
+            @Composable
+            fun SimpleComposable(state: Counter) {
+                wrapper {
+                    Button(
+                      text=("Button clicked "+state.count+" times"),
+                      >
+                      id=42
+                    )
+                }
+            }
+        """,
+            "SimpleComposable(state=counter)"
+        ).then { activity ->
+            val button = activity.findViewById(42) as Button
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById(42) as Button
+            assertEquals("Button clicked 3 times", button.text)
+        }
+    }
+
+    @Test
+    fun testObservableDefaultParameter(): Unit = ensureSetup {
+        compose("""
+            @Model
+            class Counter() {
+                var count = 0
+            }
+
+            val counter = Counter()
+
+            @Composable
+            fun SimpleComposable(state: Counter, a: Int = 1, b: Int = 2) {
+                Button(
+                  text=("State: ${'$'}{state.count} a = ${'$'}a b = ${'$'}b"),
+                  >
+                  id=42
+                )
+            }
+        """,
+            "SimpleComposable(state=counter, b = 4)"
+        ).then { activity ->
+            val button = activity.findViewById(42) as Button
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById(42) as Button
+            assertEquals("State: 3 a = 1 b = 4", button.text)
+        }
+    }
+
+    @Test
+    fun testObservableEarlyReturn(): Unit = ensureSetup {
+        compose("""
+            @Model
+            class Counter() {
+                var count = 0
+            }
+
+            val counter = Counter()
+
+            @Composable
+            fun SimpleComposable(state: Counter) {
+                Button(
+                  text=("State: ${'$'}{state.count}"),
+                  >
+                  id=42
+                )
+
+                if (state.count > 2) return
+
+                TextView(
+                  text="Included text",
+                  id=43
+                )
+            }
+        """,
+            "SimpleComposable(state=counter)"
+        ).then { activity ->
+            // Check that the text view is in the view
+            assertNotNull(activity.findViewById(43))
+            val button = activity.findViewById(42) as Button
+            button.performClick()
+            button.performClick()
+            button.performClick()
+        }.then { activity ->
+            val button = activity.findViewById<Button>(42)
+            assertEquals("State: 3", button.text)
+
+            // Assert that the text view is no longer in the view
+            assertNull(activity.findViewById<Button>(43))
+        }
+    }
+
+    @Test
+    fun testCGSimpleTextView(): Unit = ensureSetup {
+        compose(
+            """
+
+            """,
+            """
+                TextView(text="Hello, world!", id=42)
+            """
+        ).then { activity ->
+            val textView = activity.findViewById(42) as TextView
+            assertEquals("Hello, world!", textView.text)
+        }
+    }
+
+    @Test
+    fun testCGLocallyScopedFunction(): Unit = ensureSetup {
+        compose(
+            """
+                @Composable
+                fun Foo() {
+                    @Composable fun Bar() {
+                        TextView(text="Hello, world!", id=42)
+                    }
+                    Bar()
+                }
+            """,
+            """
+                Foo()
+            """
+        ).then { activity ->
+            val textView = activity.findViewById(42) as TextView
+            assertEquals("Hello, world!", textView.text)
+        }
+    }
+
+    @Test
+    fun testCGLocallyScopedExtensionFunction(): Unit = ensureSetup {
+        compose(
+            """
+                @Composable
+                fun Foo(x: String) {
+                    @Composable fun String.Bar() {
+                        TextView(text=this, id=42)
+                    }
+                    x.Bar()
+                }
+            """,
+            """
+                Foo(x="Hello, world!")
+            """
+        ).then { activity ->
+            val textView = activity.findViewById(42) as TextView
+            assertEquals("Hello, world!", textView.text)
+        }
+    }
+
+    @Test
+    fun testImplicitReceiverScopeCall(): Unit = ensureSetup {
+        compose(
+            """
+                import androidx.compose.*
+
+                class Bar(val text: String)
+
+                @Composable fun Bar.Foo() {
+                    TextView(text=text,id=42)
+                }
+
+                @Composable
+                fun Bam(bar: Bar) {
+                    with(bar) {
+                        Foo()
+                    }
+                }
+            """,
+            """
+                Bam(bar=Bar("Hello, world!"))
+            """
+        ).then { activity ->
+            val textView = activity.findViewById(42) as TextView
+            assertEquals("Hello, world!", textView.text)
+        }
+    }
+
+    @Test
+    fun testCGLocallyScopedInvokeOperator(): Unit = ensureSetup {
+        compose(
+            """
+                @Composable
+                fun Foo(x: String) {
+                    @Composable
+                    operator fun String.invoke() {
+                        TextView(text=this, id=42)
+                    }
+                    x()
+                }
+            """,
+            """
+                Foo(x="Hello, world!")
+            """
+        ).then { activity ->
+            val textView = activity.findViewById(42) as TextView
+            assertEquals("Hello, world!", textView.text)
+        }
+    }
+
+    @Test
+    fun testTrivialExtensionFunction(): Unit = ensureSetup {
+        compose(
+            """ """,
+            """
+                val x = "Hello"
+                @Composable fun String.foo() {}
+                x.foo()
+            """
+        )
+    }
+
+    @Test
+    fun testTrivialInvokeExtensionFunction(): Unit = ensureSetup {
+        compose(
+            """ """,
+            """
+                val x = "Hello"
+                @Composable operator fun String.invoke() {}
+                x()
+            """
+        )
+    }
+
+    @Test
+    fun testCGNSimpleTextView(): Unit = ensureSetup {
+        compose(
+            """
+
+            """,
+            """
+                TextView(text="Hello, world!", id=42)
+            """
+        ).then { activity ->
+            val textView = activity.findViewById(42) as TextView
+            assertEquals("Hello, world!", textView.text)
+        }
+    }
+
+    @Test // java.lang.ClassNotFoundException: Z
+    fun testInliningTemp(): Unit = ensureSetup {
+        compose(
+            """
+                @Composable
+                fun Foo(x: Double, children: @Composable Double.() -> Unit) {
+                  x.children()
+                }
+            """,
+            """
+                Foo(x=1.0) {
+                    TextView(text=this.toString(), id=123)
+                }
+            """,
+            { mapOf("foo" to "bar") }
+        ).then { activity ->
+            val textView = activity.findViewById(123) as TextView
+            assertEquals("1.0", textView.text)
+        }
+    }
+
+    @Test
+    fun testInliningTemp2(): Unit = ensureSetup {
+        compose(
+            """
+                @Composable
+                fun Foo(onClick: Double.() -> Unit) {
+
+                }
+            """,
+            """
+                Foo(>
+            """,
+            { mapOf("foo" to "bar") }
+        ).then { }
+    }
+
+    @Test
+    fun testInliningTemp3(): Unit = ensureSetup {
+        compose(
+            """
+                @Composable
+                fun Foo(onClick: (Double) -> Unit) {
+
+                }
+            """,
+            """
+                Foo(>
+            """,
+            { mapOf("foo" to "bar") }
+        ).then { }
+    }
+
+    @Test
+    fun testInliningTemp4(): Unit = ensureSetup {
+        compose(
+            """
+                @Composable
+                fun Foo(onClick: (Double) -> Unit) {
+
+                }
+            """,
+            """
+                Foo(>
+            """,
+            { mapOf("foo" to "bar") }
+        ).then {}
+    }
+
+    @Test
+    fun testInline_NonComposable_Identity(): Unit = ensureSetup {
+        compose("""
+            inline fun InlineWrapper(base: Int, children: @Composable() ()->Unit) {
+              children()
+            }
+            """,
+            """
+            InlineWrapper(200) {
+              TextView(text = "Test", id=101)
+            }
+            """).then { activity ->
+            assertEquals("Test", activity.findViewById<TextView>(101).text)
+        }
+    }
+
+    @Test
+    fun testInline_Composable_Identity(): Unit = ensureSetup {
+        compose("""
+            """,
+            """
+              TextView(text="Test", id=101)
+            """).then { activity ->
+            assertEquals("Test", activity.findViewById<TextView>(101).text)
+        }
+    }
+
+    @Test
+    fun testInline_Composable_EmitChildren(): Unit = ensureSetup {
+        compose("""
+            @Composable
+            inline fun InlineWrapper(base: Int, crossinline children: @Composable() ()->Unit) {
+              LinearLayout(id = base + 0) {
+                children()
+              }
+            }
+            """,
+            """
+            InlineWrapper(200) {
+              TextView(text = "Test", id=101)
+            }
+            """).then { activity ->
+            val tv = activity.findViewById<TextView>(101)
+            // Assert the TextView was created with the correct text
+            assertEquals("Test", tv.text)
+            // and it is the first child of the linear layout
+            assertEquals(tv, activity.findViewById<LinearLayout>(200).getChildAt(0))
+        }
+    }
+
+    @Test // java.lang.ClassNotFoundException: Z
+    fun testCGNInlining(): Unit = ensureSetup {
+        compose(
+            """
+
+            """,
+            """
+                LinearLayout(orientation=LinearLayout.VERTICAL) {
+                    TextView(text="Hello, world!", id=42)
+                }
+            """
+        ).then { activity ->
+            val textView = activity.findViewById(42) as TextView
+            assertEquals("Hello, world!", textView.text)
+        }
+    }
+
+    private var isSetup = false
+    override fun setUp() {
+        isSetup = true
+        super.setUp()
+    }
+
+    private fun <T> ensureSetup(block: () -> T): T {
+        if (!isSetup) setUp()
+        return block()
+    }
+
+    fun codegen(text: String, dumpClasses: Boolean = false): Unit = ensureSetup {
+        val className = "Test_${uniqueNumber++}"
+        val fileName = "$className.kt"
+
+        classLoader(
+            """
+           import android.content.Context
+           import android.widget.*
+           import androidx.compose.*
+
+           $text
+
+        """, fileName, dumpClasses
+        )
+    }
+
+    fun assertInterceptions(srcText: String) = ensureSetup {
+        val (text, carets) = extractCarets(srcText)
+
+        val environment = myEnvironment ?: error("Environment not initialized")
+
+        val ktFile = KtPsiFactory(environment.project).createFile(text)
+        val bindingContext = JvmResolveUtil.analyze(
+            ktFile,
+            environment
+        ).bindingContext
+
+        carets.forEachIndexed { index, (offset, calltype) ->
+            val resolvedCall = resolvedCallAtOffset(bindingContext, ktFile, offset)
+                ?: error("No resolved call found at index: $index, offset: $offset. Expected " +
+                        "$calltype.")
+
+            when (calltype) {
+                "<normal>" -> assert(!resolvedCall.isCall() && !resolvedCall.isEmit())
+                "<emit>" -> assert(resolvedCall.isEmit())
+                "<call>" -> assert(resolvedCall.isCall())
+                else -> error("Call type of $calltype not recognized.")
+            }
+        }
+    }
+
+    fun compose(
+        supportingCode: String,
+        composeCode: String,
+        valuesFactory: () -> Map<String, Any> = { emptyMap() },
+        dumpClasses: Boolean = false
+    ): CompositionTest {
+        val className = "TestFCS_${uniqueNumber++}"
+        val fileName = "$className.kt"
+
+        val candidateValues = valuesFactory()
+
+        @Suppress("NO_REFLECTION_IN_CLASS_PATH")
+        val parameterList = candidateValues.map {
+            if (it.key.contains(':')) {
+                it.key
+            } else "${it.key}: ${it.value::class.qualifiedName}"
+        }.joinToString()
+        val parameterTypes = candidateValues.map {
+            it.value::class.javaPrimitiveType ?: it.value::class.javaObjectType
+        }.toTypedArray()
+
+        val compiledClasses = classLoader(
+            """
+       import android.content.Context
+       import android.widget.*
+       import androidx.compose.*
+       import androidx.ui.androidview.adapters.*
+
+       $supportingCode
+
+       class $className {
+
+         @Composable
+         fun test($parameterList) {
+           $composeCode
+         }
+       }
+    """, fileName, dumpClasses
+        )
+
+        val allClassFiles = compiledClasses.allGeneratedFiles.filter {
+            it.relativePath.endsWith(".class")
+        }
+
+        val loader = URLClassLoader(emptyArray(), this.javaClass.classLoader)
+
+        val instanceClass = run {
+            var instanceClass: Class<*>? = null
+            var loadedOne = false
+            for (outFile in allClassFiles) {
+                val bytes = outFile.asByteArray()
+                val loadedClass = loadClass(loader, null, bytes)
+                if (loadedClass.name == className) instanceClass = loadedClass
+                loadedOne = true
+            }
+            if (!loadedOne) error("No classes loaded")
+            instanceClass ?: error("Could not find class $className in loaded classes")
+        }
+
+        val instanceOfClass = instanceClass.newInstance()
+        val testMethod = instanceClass.getMethod("test", *parameterTypes)
+
+        return compose {
+            val values = valuesFactory()
+            val arguments = values.map { it.value }.toTypedArray()
+            testMethod.invoke(instanceOfClass, *arguments)
+        }
+    }
+
+    private fun ResolvedCall<*>.isEmit(): Boolean = candidateDescriptor is ComposableEmitDescriptor
+    private fun ResolvedCall<*>.isCall(): Boolean =
+        candidateDescriptor is ComposableFunctionDescriptor
+
+    private val callPattern = Regex("(<normal>)|(<emit>)|(<call>)")
+    private fun extractCarets(text: String): Pair<String, List<Pair<Int, String>>> {
+        val indices = mutableListOf<Pair<Int, String>>()
+        var offset = 0
+        val src = callPattern.replace(text) {
+            indices.add(it.range.first - offset to it.value)
+            offset += it.range.last - it.range.first + 1
+            ""
+        }
+        return src to indices
+    }
+
+    private fun resolvedCallAtOffset(
+        bindingContext: BindingContext,
+        jetFile: KtFile,
+        index: Int
+    ): ResolvedCall<*>? {
+        val element = jetFile.findElementAt(index)!!
+        val callExpression = element.parentOfType<KtCallExpression>()
+        return callExpression?.getResolvedCall(bindingContext)
+    }
+}
+
+private inline fun <reified T : PsiElement> PsiElement.parentOfType(): T? = parentOfType(T::class)
+
+private fun <T : PsiElement> PsiElement.parentOfType(vararg classes: KClass<out T>): T? {
+    return PsiTreeUtil.getParentOfType(this, *classes.map { it.java }.toTypedArray())
+}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolutionDiagnosticsTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolutionDiagnosticsTests.kt
new file mode 100644
index 0000000..3a03419
--- /dev/null
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolutionDiagnosticsTests.kt
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.plugins.kotlin
+
+class ComposeCallResolutionDiagnosticsTests : AbstractComposeDiagnosticsTest() {
+
+    private var isSetup = false
+    override fun setUp() {
+        isSetup = true
+        super.setUp()
+    }
+
+    private fun <T> ensureSetup(block: () -> T): T {
+        if (!isSetup) setUp()
+        return block()
+    }
+
+    private fun setupAndDoTest(text: String) = ensureSetup { doTest(text) }
+
+    fun testImplicitlyPassedReceiverScope1() = setupAndDoTest(
+        """
+            import androidx.compose.*
+            import android.widget.*
+            import android.os.Bundle
+            import android.app.Activity
+            import android.widget.FrameLayout
+
+            val x: Any? = null
+
+            fun Activity.setViewContent(composable: @Composable() () -> Unit): CompositionContext? {
+                assert(composable != x)
+                return null
+            }
+
+            open class WebComponentActivity : Activity() {
+                override fun onCreate(savedInstanceState: Bundle?) {
+                    super.onCreate(savedInstanceState)
+
+                    setViewContent {
+                        FrameLayout {
+                        }
+                    }
+                }
+            }
+        """
+    )
+
+    fun testSimpleReceiverScope() = setupAndDoTest(
+        """
+            import android.widget.FrameLayout
+            import androidx.compose.Composable
+
+            class SomeScope {
+             val composer get() = androidx.compose.composer
+            }
+
+            @Composable fun SomeScope.foo() {
+                FrameLayout { }
+            }
+
+        """
+    )
+
+    fun testReceiverScopeComposer() = setupAndDoTest(
+        """
+            import androidx.compose.Applier
+            import androidx.compose.ApplyAdapter
+            import androidx.compose.Component
+            import androidx.compose.Composable
+            import androidx.compose.Composer
+            import androidx.compose.ComposerUpdater
+            import androidx.compose.CompositionContext
+            import androidx.compose.CompositionReference
+            import androidx.compose.Effect
+            import androidx.compose.Recomposer
+            import androidx.compose.SlotTable
+            import androidx.compose.ViewValidator
+            import androidx.compose.cache
+
+            class TextSpan(
+                val style: String? = null,
+                val text: String? = null,
+                val children: MutableList<TextSpan> = mutableListOf()
+            )
+
+            /**
+             * This adapter is used by [TextSpanComposer] to build the [TextSpan] tree.
+             * @see ApplyAdapter
+             */
+            internal class TextSpanApplyAdapter : ApplyAdapter<TextSpan> {
+                override fun TextSpan.start(instance: TextSpan) {}
+
+                override fun TextSpan.end(instance: TextSpan, parent: TextSpan) {}
+
+                override fun TextSpan.insertAt(index: Int, instance: TextSpan) {
+                    children.add(index, instance)
+                }
+
+                override fun TextSpan.removeAt(index: Int, count: Int) {
+                    repeat(count) {
+                        children.removeAt(index)
+                    }
+                }
+
+                override fun TextSpan.move(from: Int, to: Int, count: Int) {
+                    if (from == to) return
+
+                    if (from > to) {
+                        val moved = mutableListOf<TextSpan>()
+                        repeat(count) {
+                            moved.add(children.removeAt(from))
+                        }
+                        children.addAll(to, moved)
+                    } else {
+                        // Number of elements between to and from is smaller than count, can't move.
+                        if (count > to - from) return
+                        repeat(count) {
+                            val node = children.removeAt(from)
+                            children.add(to - 1, node)
+                        }
+                    }
+                }
+            }
+
+            typealias TextSpanUpdater<T> = ComposerUpdater<TextSpan, T>
+
+            /**
+             * The composer of [TextSpan].
+             */
+            class TextSpanComposer internal constructor(
+                root: TextSpan,
+                recomposer: Recomposer
+            ) : Composer<TextSpan>(SlotTable(), Applier(root, TextSpanApplyAdapter()), recomposer)
+
+            @PublishedApi
+            internal val invocation = Object()
+
+            class TextSpanComposition(val composer: TextSpanComposer) {
+                @Suppress("NOTHING_TO_INLINE")
+                inline operator fun <V> Effect<V>.unaryPlus(): V = resolve(this@TextSpanComposition.composer)
+
+                inline fun emit(
+                    key: Any,
+                    /*crossinline*/
+                    ctor: () -> TextSpan,
+                    update: TextSpanUpdater<TextSpan>.() -> Unit
+                ) = with(composer) {
+                    startNode(key)
+                    @Suppress("UNCHECKED_CAST") val node = if (inserting) ctor().also { emitNode(it) }
+                    else useNode()
+                    TextSpanUpdater(this, node).update()
+                    endNode()
+                }
+
+                inline fun emit(
+                    key: Any,
+                    /*crossinline*/
+                    ctor: () -> TextSpan,
+                    update: TextSpanUpdater<TextSpan>.() -> Unit,
+                    children: () -> Unit
+                ) = with(composer) {
+                    startNode(key)
+                    @Suppress("UNCHECKED_CAST")val node = if (inserting) ctor().also { emitNode(it) }
+                    else useNode()
+                    TextSpanUpdater(this, node).update()
+                    children()
+                    endNode()
+                }
+
+                @Suppress("NOTHING_TO_INLINE")
+                inline fun joinKey(left: Any, right: Any?): Any = composer.joinKey(left, right)
+
+                inline fun call(
+                    key: Any,
+                    /*crossinline*/
+                    invalid: ViewValidator.() -> Boolean,
+                    block: () -> Unit
+                ) = with(composer) {
+                    startGroup(key)
+                    if (ViewValidator(composer).invalid() || inserting) {
+                        startGroup(invocation)
+                        block()
+                        endGroup()
+                    } else {
+                        skipCurrentGroup()
+                    }
+                    endGroup()
+                }
+
+                inline fun <T> call(
+                    key: Any,
+                    /*crossinline*/
+                    ctor: () -> T,
+                    /*crossinline*/
+                    invalid: ViewValidator.(f: T) -> Boolean,
+                    block: (f: T) -> Unit
+                ) = with(composer) {
+                    startGroup(key)
+                    val f = cache(true, ctor)
+                    if (ViewValidator(this).invalid(f) || inserting) {
+                        startGroup(invocation)
+                        block(f)
+                        endGroup()
+                    } else {
+                        skipCurrentGroup()
+                    }
+                    endGroup()
+                }
+            }
+
+            /**
+             * As the name indicates, [Root] object is associated with a [TextSpan] tree root. It contains
+             * necessary information used to compose and recompose [TextSpan] tree. It's created and stored
+             * when the [TextSpan] container is composed for the first time.
+             */
+            private class Root : Component() {
+                fun update() = composer.compose()
+                lateinit var scope: TextSpanScope
+                lateinit var composer: CompositionContext
+                lateinit var composable: @Composable() TextSpanScope.() -> Unit
+                @Suppress("PLUGIN_ERROR")
+                override fun compose() {
+                    with(scope.composer.composer) {
+                        startGroup(0)
+                        scope.composable()
+                        endGroup()
+                    }
+                }
+            }
+
+            /**
+             *  The map used store the [Root] object for [TextSpan] trees.
+             */
+            private val TEXTSPAN_ROOT_COMPONENTS = HashMap<TextSpan, Root>()
+
+            /**
+             * Get the [Root] object of the given [TextSpan] root node.
+             */
+            private fun getRootComponent(node: TextSpan): Root? {
+                return TEXTSPAN_ROOT_COMPONENTS[node]
+            }
+
+            /**
+             * Store the [Root] object of [node].
+             */
+            private fun setRoot(node: TextSpan, component: Root) {
+                TEXTSPAN_ROOT_COMPONENTS[node] = component
+            }
+
+            /**
+             * Compose a [TextSpan] tree.
+             * @param container The root of [TextSpan] tree where the children TextSpans will be attached to.
+             * @param parent The parent composition reference, if applicable. Default is null.
+             * @param composable The composable function to compose the children of [container].
+             * @see CompositionReference
+             */
+            @Suppress("PLUGIN_ERROR")
+            fun compose(
+                container: TextSpan,
+                parent: CompositionReference? = null,
+                composable: @Composable() TextSpanScope.() -> Unit
+            ) {
+                var root = getRootComponent(container)
+                if (root == null) {
+                    lateinit var composer: TextSpanComposer
+                    root = Root()
+                    setRoot(container, root)
+                    root.composer = CompositionContext.prepare(root, parent) {
+                        TextSpanComposer(container, this).also { composer = it }
+                    }
+                    root.scope = TextSpanScope(TextSpanComposition(composer))
+                    root.composable = composable
+
+                    root.update()
+                } else {
+                    root.composable = composable
+
+                    root.update()
+                }
+            }
+
+            /**
+             * Cleanup when the [TextSpan] is no longer used.
+             *
+             * @param container The root of the [TextSpan] to be disposed.
+             * @param parent The [CompositionReference] used together with [container] when [composer] is
+             * called.
+             */
+            fun disposeComposition(
+                container: TextSpan,
+                parent: CompositionReference? = null
+            ) {
+                // temporary easy way to call correct lifecycles on everything
+                compose(container, parent) {}
+                TEXTSPAN_ROOT_COMPONENTS.remove(container)
+            }
+
+            /**
+             * The receiver class of the children of Text and TextSpan. Such that [Span] can only be used
+             * within [Text] and [TextSpan].
+             */
+            class TextSpanScope internal constructor(val composer: TextSpanComposition)
+
+            @Composable
+            fun TextSpanScope.Span(
+                text: String? = null,
+                style: String? = null,
+                child: @Composable TextSpanScope.() -> Unit
+            ) {
+                TextSpan(text = text, style = style) {
+                    child()
+                }
+            }
+
+            @Composable
+            fun TextSpanScope.Span(
+                text: String? = null,
+                style: String? = null
+            ) {
+                TextSpan(text = text, style = style)
+            }
+        """
+    )
+}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolverTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolverTests.kt
index e5f25cb..7b6f48a 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolverTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolverTests.kt
@@ -34,7 +34,7 @@
             import android.widget.TextView
 
             @Composable fun Foo() {}
-            
+
             fun Bar() {}
 
             @Composable
@@ -79,13 +79,7 @@
     )
 
     private fun <T> setup(block: () -> T): T {
-        val original = ComposeFlags.NEW_CALL_RESOLUTION_INTERCEPTION
-        try {
-            ComposeFlags.NEW_CALL_RESOLUTION_INTERCEPTION = true
-            return block()
-        } finally {
-            ComposeFlags.NEW_CALL_RESOLUTION_INTERCEPTION = original
-        }
+        return block()
     }
 
     fun assertInterceptions(srcText: String) = setup {
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCodegenTestUtils.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCodegenTestUtils.kt
new file mode 100644
index 0000000..382af0c
--- /dev/null
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCodegenTestUtils.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:Suppress("MemberVisibilityCanBePrivate")
+
+package androidx.compose.plugins.kotlin
+
+import android.app.Activity
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.compose.Component
+import androidx.compose.CompositionContext
+import androidx.compose.Compose
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.Robolectric
+import org.robolectric.RuntimeEnvironment
+import org.robolectric.annotation.Config
+import java.net.URLClassLoader
+
+var uniqueNumber = 0
+
+fun loadClass(loader: ClassLoader, name: String?, bytes: ByteArray): Class<*> {
+    val defineClassMethod = ClassLoader::class.javaObjectType.getDeclaredMethod(
+        "defineClass",
+        String::class.javaObjectType,
+        ByteArray::class.javaObjectType,
+        Int::class.javaPrimitiveType,
+        Int::class.javaPrimitiveType
+    )
+    defineClassMethod.isAccessible = true
+    return defineClassMethod.invoke(loader, name, bytes, 0, bytes.size) as Class<*>
+}
+
+const val ROOT_ID = 18284847
+
+private class TestActivity : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(LinearLayout(this).apply { id = ROOT_ID })
+    }
+}
+
+private val Activity.root get() = findViewById(ROOT_ID) as ViewGroup
+
+private class Root(val composable: () -> Unit) : Component() {
+    override fun compose() = composable()
+}
+
+class CompositionTest(val composable: () -> Unit) {
+
+    inner class ActiveTest(val activity: Activity, val cc: CompositionContext) {
+        fun then(block: (activity: Activity) -> Unit): ActiveTest {
+            val scheduler = RuntimeEnvironment.getMasterScheduler()
+            scheduler.advanceToLastPostedRunnable()
+            cc.compose()
+            scheduler.advanceToLastPostedRunnable()
+            block(activity)
+            return this
+        }
+    }
+
+    fun then(block: (activity: Activity) -> Unit): ActiveTest {
+        val scheduler = RuntimeEnvironment.getMasterScheduler()
+        scheduler.pause()
+        val controller = Robolectric.buildActivity(TestActivity::class.java)
+        val activity = controller.create().get()
+        val root = activity.root
+        val component = Root(composable)
+        val cc = Compose.createCompositionContext(root.context, root, component, null)
+        return ActiveTest(activity, cc).then(block)
+    }
+}
+
+fun compose(composable: () -> Unit) = CompositionTest(composable)
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeRobolectricTestRunner.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeRobolectricTestRunner.kt
index 3314aa1..8c2b058 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeRobolectricTestRunner.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeRobolectricTestRunner.kt
@@ -24,6 +24,7 @@
     override fun createClassLoaderConfig(method: FrameworkMethod?): InstrumentationConfiguration {
         val builder = InstrumentationConfiguration.Builder(super.createClassLoaderConfig(method))
         builder.doNotInstrumentPackage("androidx.compose")
+        builder.doNotInstrumentPackage("androidx.ui")
         return builder.build()
     }
 }
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt
index eb763b8..64ec08e 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt
@@ -39,6 +39,25 @@
 class FcsCodegenTests : AbstractCodegenTest() {
 
     @Test
+    fun testForDevelopment(): Unit = ensureSetup {
+        codegen(
+            """
+            import androidx.compose.*
+
+            @Composable
+            fun bar() {
+
+            }
+
+            @Composable
+            fun foo() {
+                TextView(text="Hello World")
+            }
+            """
+        )
+    }
+
+    @Test
     fun testSimpleFunctionResolution(): Unit = ensureSetup {
         compose(
             """
@@ -180,7 +199,7 @@
                 }
 
                 @Composable
-                fun FancyBox2(@Children children: @Composable() ()->Unit) {
+                fun FancyBox2(children: @Composable() ()->Unit) {
                     children()
                 }
             """,
@@ -564,7 +583,7 @@
         compose(
             """
                 @Composable
-                fun Foo(x: Double, @Children children: Double.() -> Unit) {
+                fun Foo(x: Double, children: @Composable Double.() -> Unit) {
                   x.children()
                 }
             """,
@@ -1304,40 +1323,6 @@
         }
     }
 
-    // @Test
-    fun testCGNSimpleCall3(): Unit = ensureSetup {
-        val tvId = 258
-        var text = "Hello, world!"
-        var someInt = 456
-
-        compose(
-            """
-                @Stateful
-                class SomeClassoawid(var x: String) {
-                    @Composable
-                    operator fun invoke(y: Int) {
-                        TextView(text="${"$"}x ${"$"}y", id=$tvId)
-                    }
-                }
-            """,
-            { mapOf("text" to text, "someInt" to someInt) },
-            """
-                SomeClassoawid(x=text, y=someInt)
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals("Hello, world! 456", textView.text)
-
-            text = "Other value"
-            someInt = 123
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals("Other value 123", textView.text)
-        }
-    }
-
     @Test
     fun testCGNCallWithChildren(): Unit = ensureSetup {
         val tvId = 258
@@ -1346,7 +1331,7 @@
         compose(
             """
                 @Composable
-                fun Block(@Children children: () -> Unit) {
+                fun Block(children: @Composable() () -> Unit) {
                     children()
                 }
             """,
@@ -1733,7 +1718,7 @@
             """
             var called = 0
 
-            class TestContainer(@Children var children: @Composable() ()->Unit): Component() {
+            class TestContainer(var children: @Composable() ()->Unit): Component() {
               override fun compose() {
                 LinearLayout {
                   children()
@@ -1768,7 +1753,7 @@
 
         compose(
             """
-            class ClassComponent(@Children private val callback: () -> Unit) : Component() {
+            class ClassComponent(private val callback: @Composable() () -> Unit) : Component() {
                 override fun compose() {
                     callback()
                 }
@@ -1907,7 +1892,7 @@
         compose(
             """
                 @Composable
-                fun Foo(a: Int = 42, b: String, @Children c: () -> Unit) {
+                fun Foo(a: Int = 42, b: String, c: @Composable() () -> Unit) {
                     c()
                     TextView(text=b, id=a)
                 }
@@ -1960,14 +1945,12 @@
                 override fun toString(): String = ""
             }
 
-
             class Canvas2() {
                 fun drawPath(path: Path3) {
                     System.out.println(""+path)
                 }
             }
 
-
             class Path3(private val internalPath: android.graphics.Path = android.graphics.Path()) {
             }
         """
@@ -2075,7 +2058,7 @@
                 }
 
                 @Composable
-                fun Box(@Children children: ()->Unit) {
+                fun Box(children: @Composable() ()->Unit) {
                     LinearLayout(orientation=LinearLayout.VERTICAL) {
                         children()
                     }
@@ -2175,7 +2158,7 @@
                 @Composable
                 fun DefineAction(
                     onAction: Action = Action(param = 1) {},
-                    @Children children: ()->Unit
+                    children: @Composable() ()->Unit
                  ) { }
             """
         )
@@ -2244,7 +2227,7 @@
             }
 
             @Composable
-            fun Main(v: ValueHolder) {
+            fun Main(v: ValueHolder, n: NotStable) {
               TestSkipping(a=1, b=1f, c=2.0, d=NotStable(), e=v)
             }
         """, {
@@ -2254,7 +2237,7 @@
         }, """
             output = outerOutput
             val v = ValueHolder(0)
-            Main(v)
+            Main(v, NotStable())
         """).then {
             // Expect that all the methods are called in order
             assertEquals(
@@ -2296,7 +2279,7 @@
             fun log(msg: String) { output.add(msg) }
 
             @Composable
-            fun Container(@Children children: () -> Unit) {
+            fun Container(children: @Composable() () -> Unit) {
               log("Container")
               children()
             }
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsModelCodeGenTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsModelCodeGenTests.kt
index de276aa..987fc6e 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsModelCodeGenTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsModelCodeGenTests.kt
@@ -116,7 +116,6 @@
               }
             }
 
-
             """, { mapOf("name" to name, "age" to age) }, """
                fcs_president.name = name
                fcs_president.age = age
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsTypeResolutionTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsTypeResolutionTests.kt
new file mode 100644
index 0000000..e982d99
--- /dev/null
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsTypeResolutionTests.kt
@@ -0,0 +1,512 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.plugins.kotlin
+
+class FcsTypeResolutionTests : AbstractComposeDiagnosticsTest() {
+
+    fun testImplicitlyPassedReceiverScope1() = doTest(
+        """
+            import androidx.compose.*
+
+            @Composable
+            fun Int.Foo(children: @Composable Int.() -> Unit) {
+                children()
+            }
+        """
+    )
+
+    fun testImplicitlyPassedReceiverScope2() = doTest(
+        """
+            import androidx.compose.*
+
+            @Composable
+            fun Int.Foo(children: @Composable Int.(foo: String) -> Unit) {
+                children(<!NO_VALUE_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>)<!>
+            }
+
+            @Composable
+            fun Bar(children: @Composable Int.() -> Unit) {
+                children(<!NO_VALUE_FOR_PARAMETER!>)<!>
+            }
+        """
+    )
+
+    fun testSmartCastsAndPunning() = doTest(
+        """
+            import androidx.compose.*
+
+            @Composable
+            fun Foo(bar: String) { print(bar) }
+
+            @Composable
+            fun test(bar: String?) {
+                Foo(<!TYPE_MISMATCH!>bar<!>)
+                if (bar != null) {
+                    Foo(bar)
+                    Foo(bar=bar)
+                }
+            }
+        """
+    )
+
+    fun testExtensionInvoke() = doTest(
+        """
+            import androidx.compose.*
+
+            class Foo {}
+            @Composable operator fun Foo.invoke() {}
+
+            @Composable fun test() {
+                Foo()
+            }
+        """
+    )
+
+    fun testResolutionInsideWhenExpression() = doTest(
+        """
+            import androidx.compose.*
+            import android.widget.TextView
+
+            @Composable fun doSomething(foo: Boolean) {
+                when (foo) {
+                    true -> TextView(text="Started...")
+                    false -> TextView(text="Continue...")
+                }
+            }
+        """
+    )
+
+    fun testUsedParameters() = doTest(
+        """
+            import androidx.compose.*
+            import android.widget.LinearLayout
+
+            @Composable fun Foo(x: Int, composeItem: @Composable() () -> Unit = {}) {
+                println(x)
+                print(composeItem == {})
+            }
+
+            @Composable fun test(
+                children: @Composable() () -> Unit,
+                value: Int,
+                x: Int,
+                children2: @Composable() () -> Unit,
+                value2: Int
+            ) {
+                LinearLayout {
+                    // named argument
+                    Foo(x=value)
+
+                    // indexed argument
+                    Foo(x)
+
+                    // tag
+                    children()
+                }
+                Foo(x=123, composeItem={
+                    val abc = 123
+
+                    // attribute value
+                    Foo(x=abc)
+
+                    // attribute value
+                    Foo(x=value2)
+
+                    // tag
+                    children2()
+                })
+            }
+        """
+    )
+
+    fun testDispatchInvoke() = doTest(
+        """
+            import androidx.compose.*
+
+            class Bam {
+                @Composable fun Foo() {}
+            }
+
+            @Composable fun test() {
+                with(Bam()) {
+                    Foo()
+                }
+            }
+        """
+    )
+
+    fun testDispatchAndExtensionReceiver() = doTest(
+        """
+            import androidx.compose.*
+
+            class Bam {
+                inner class Foo {}
+            }
+
+            @Composable operator fun Bam.Foo.invoke() {}
+
+            @Composable fun test() {
+                with(Bam()) {
+                    Foo()
+                }
+            }
+        """
+    )
+
+    fun testDispatchAndExtensionReceiverLocal() = doTest(
+        """
+            import androidx.compose.*
+
+            class Foo {}
+
+            class Bam {
+                @Composable operator fun Foo.invoke() {}
+                @Composable operator fun invoke() {
+                    Foo()
+                }
+            }
+
+        """
+    )
+
+    fun testMissingAttributes() = doTest(
+        """
+            import androidx.compose.*
+
+            data class Foo(val value: Int)
+
+            @Composable fun A(x: Foo) { println(x) }
+
+            // NOTE: It's important that the diagnostic be only over the call target, and not the
+            // entire element so that a single error doesn't end up making a huge part of an 
+            // otherwise correct file "red".
+            @Composable fun Test(F: @Composable() (x: Foo) -> Unit) {
+                // NOTE: constructor attributes and fn params get a "missing parameter" diagnostic
+                A(<!NO_VALUE_FOR_PARAMETER!>)<!>
+
+                // local
+                F(<!NO_VALUE_FOR_PARAMETER!>)<!>
+
+                val x = Foo(123)
+
+                A(x)
+                F(x)
+                A(x=x)
+                F(x=x)
+            }
+
+        """.trimIndent()
+    )
+
+    fun testDuplicateAttributes() = doTest(
+        """
+            import androidx.compose.*
+
+            data class Foo(val value: Int)
+
+            @Composable fun A(x: Foo) { println(x) }
+
+            @Composable fun Test() {
+                val x = Foo(123)
+
+                // NOTE: It's important that the diagnostic be only over the attribute key, so that
+                // we don't make a large part of the elements red when the type is otherwise correct
+                A(x=x, <!ARGUMENT_PASSED_TWICE!>x<!>=x)
+            }
+
+        """.trimIndent()
+    )
+
+    fun testChildrenNamedAndBodyDuplicate() = doTest(
+        """
+            import androidx.compose.*
+
+            @Composable fun A(children: @Composable() () -> Unit) { children() }
+
+            @Composable fun Test() {
+                A(children={}) <!TOO_MANY_ARGUMENTS!>{ }<!>
+            }
+
+        """.trimIndent()
+    )
+
+    fun testAbstractClassTags() = doTest(
+        """
+            import androidx.compose.*
+            import android.content.Context
+            import android.widget.LinearLayout
+
+            abstract class Foo {}
+
+            abstract class Bar(context: Context) : LinearLayout(context) {}
+
+            @Composable fun Test() {
+                <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>Foo()<!>
+                <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>Bar(<!NO_VALUE_FOR_PARAMETER!>)<!><!>
+            }
+
+        """.trimIndent()
+    )
+
+    fun testGenerics() = doTest(
+        """
+            import androidx.compose.*
+
+            class A { fun a() {} }
+            class B { fun b() {} }
+
+            @Composable fun <T> Bar(x: Int, value: T, f: (T) -> Unit) { println(value); println(f); println(x) }
+
+            @Composable fun Test() {
+
+                val fa: (A) -> Unit = { it.a() }
+                val fb: (B) -> Unit = { it.b() }
+
+                Bar(x=1, value=A(), f={ it.a() })
+                Bar(x=1, value=B(), f={ it.b() })
+                Bar(x=1, value=A(), f=fa)
+                Bar(x=1, value=B(), f=fb)
+                Bar(x=1, value=B(), f={ it.<!UNRESOLVED_REFERENCE!>a<!>() })
+                Bar(x=1, value=A(), f={ it.<!UNRESOLVED_REFERENCE!>b<!>() })
+                <!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>Bar<!>(
+                  x=1, 
+                  value=A(), 
+                  f=fb
+                )
+                <!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>Bar<!>(
+                  x=1,
+                  value=B(), 
+                  f=fa
+                )
+            }
+
+        """.trimIndent()
+    )
+
+    fun testUnresolvedAttributeValueResolvedTarget() = doTest(
+        """
+            import androidx.compose.*
+
+            @Composable fun Fam(bar: Int, x: Int) {
+                print(bar)
+                print(x)
+            }
+
+            @Composable fun Test() {
+                Fam(
+                  bar=<!UNRESOLVED_REFERENCE!>undefined<!>,
+                  x=1
+                )
+                Fam(
+                  bar=1,
+                  x=<!UNRESOLVED_REFERENCE!>undefined<!>
+                )
+                Fam(
+                  <!UNRESOLVED_REFERENCE!>bar<!>,
+                  <!UNRESOLVED_REFERENCE!>x<!>
+                )
+
+                Fam(
+                  bar=<!TYPE_MISMATCH!>""<!>,
+                  x=<!TYPE_MISMATCH!>""<!>
+                )
+            }
+
+        """.trimIndent()
+    )
+
+    // TODO(lmr): this triggers an exception!
+    fun testEmptyAttributeValue() = doTest(
+        """
+            import androidx.compose.*
+
+            @Composable fun Foo(abc: Int, xyz: Int) {
+                print(abc)
+                print(xyz)
+            }
+
+            @Composable fun Test() {
+                Foo(abc=<!NO_VALUE_FOR_PARAMETER!>)<!>
+
+                // NOTE(lmr): even though there is NO diagnostic here, there *is* a parse
+                // error. This is intentional and done to mimic how kotlin handles function
+                // calls with no value expression in a call parameter list (ie, `Foo(123,)`)
+                Foo(abc=123, xyz=)
+            }
+
+        """.trimIndent()
+    )
+
+    fun testMismatchedAttributes() = doTest(
+        """
+            import androidx.compose.*
+
+            open class A {}
+            class B : A() {}
+
+            @Composable fun Foo(x: A = A(), y: A = B(), z: B = B()) {
+                print(x)
+                print(y)
+                print(z)
+            }
+
+            @Composable fun Test() {
+                Foo(
+                    x=A(),
+                    y=A(),
+                    z=<!TYPE_MISMATCH!>A()<!>
+                )
+                Foo(
+                    x=B(),
+                    y=B(),
+                    z=B()
+                )
+                Foo(
+                    x=<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>,
+                    y=<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>,
+                    z=<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>
+                )
+            }
+
+        """.trimIndent()
+    )
+
+    fun testErrorAttributeValue() = doTest(
+        """
+            import androidx.compose.*
+
+            @Composable fun Foo(x: Int = 1) { print(x) }
+
+            @Composable fun Test() {
+                Foo(
+                    x=<!UNRESOLVED_REFERENCE!>someUnresolvedValue<!>,
+                    <!NAMED_PARAMETER_NOT_FOUND!>y<!>=<!UNRESOLVED_REFERENCE!>someUnresolvedValue<!>
+                )
+            }
+
+        """.trimIndent()
+    )
+
+    fun testUnresolvedQualifiedTag() = doTest(
+        """
+            import androidx.compose.*
+
+            object MyNamespace {
+                @Composable fun Bar(children: @Composable() () -> Unit = {}) { 
+                    children() 
+                }
+
+                var Baz = @Composable { }
+
+                var someString = ""
+                class NonComponent {}
+            }
+
+            class Boo {
+                @Composable fun Wat() { }
+            }
+
+            @Composable fun Test() {
+
+                MyNamespace.Bar()
+                MyNamespace.Baz()
+                MyNamespace.<!UNRESOLVED_REFERENCE!>Qoo<!>()
+                MyNamespace.<!FUNCTION_EXPECTED!>someString<!>()
+                MyNamespace.NonComponent()
+                MyNamespace.Bar {}
+                MyNamespace.Baz <!TOO_MANY_ARGUMENTS!>{}<!>
+
+                val obj = Boo()
+                Boo.<!UNRESOLVED_REFERENCE!>Wat<!>()
+                obj.Wat()
+
+                MyNamespace.<!UNRESOLVED_REFERENCE!>Bam<!>()
+                <!UNRESOLVED_REFERENCE!>SomethingThatDoesntExist<!>.Foo()
+
+                obj.Wat <!TOO_MANY_ARGUMENTS!>{
+                }<!>
+
+                MyNamespace.<!UNRESOLVED_REFERENCE!>Qoo<!> {
+                }
+
+                MyNamespace.<!FUNCTION_EXPECTED!>someString<!> {
+                }
+
+                <!UNRESOLVED_REFERENCE!>SomethingThatDoesntExist<!>.Foo {
+                }
+
+                MyNamespace.NonComponent <!TOO_MANY_ARGUMENTS!>{}<!>
+
+                MyNamespace.<!UNRESOLVED_REFERENCE!>Bam<!> {}
+
+            }
+
+        """.trimIndent()
+    )
+
+    // TODO(lmr): overloads creates resolution exception
+    fun testChildren() = doTest(
+        """
+            import androidx.compose.*
+            import android.widget.Button
+            import android.widget.LinearLayout
+
+            @Composable fun ChildrenRequired2(children: @Composable() () -> Unit) { children() }
+
+            @Composable fun ChildrenOptional3(children: @Composable() () -> Unit = {}){ children() }
+
+            @Composable fun NoChildren2() {}
+
+            @Composable 
+            fun MultiChildren(c: @Composable() (x: Int) -> Unit = {}) { c(1) }
+
+            @Composable 
+            fun MultiChildren(c: @Composable() (x: Int, y: Int) -> Unit = { x, y ->println(x + y) }) { c(1,1) }
+
+            @Composable fun Test() {
+                ChildrenRequired2 {}
+                ChildrenRequired2(<!NO_VALUE_FOR_PARAMETER!>)<!>
+
+                ChildrenOptional3 {}
+                ChildrenOptional3()
+
+                NoChildren2 <!TOO_MANY_ARGUMENTS!>{}<!>
+                NoChildren2()
+
+                <!OVERLOAD_RESOLUTION_AMBIGUITY!>MultiChildren<!> {}
+                MultiChildren { x ->
+                    println(x)
+                }
+                MultiChildren { x, y ->
+                    println(x + y)
+                }
+                <!NONE_APPLICABLE!>MultiChildren<!> { <!CANNOT_INFER_PARAMETER_TYPE!>x<!>, 
+                <!CANNOT_INFER_PARAMETER_TYPE!>y<!>, <!CANNOT_INFER_PARAMETER_TYPE!>z<!> ->
+                    println(x + y + z)
+                }
+
+                Button()
+                LinearLayout()
+
+                LinearLayout {}
+
+                Button <!TOO_MANY_ARGUMENTS!>{}<!>
+            }
+
+        """.trimIndent()
+    )
+}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/GenerateWrapperViewTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/GenerateWrapperViewTest.kt
deleted file mode 100644
index bead928..0000000
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/GenerateWrapperViewTest.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import junit.framework.TestCase
-
-class GenerateWrapperViewTest : AbstractCodegenTest() {
-
-    fun testPlaceholder() {
-        // do nothing, in order to prevent warning
-    }
-
-    fun xtestWrapperViewGeneration() {
-
-        val klass = loadClass("MainComponent", """
-            import android.app.Activity
-            import android.os.Bundle
-            import androidx.compose.Component
-            import androidx.compose.CompositionContext
-
-            class MainActivity : Activity() {
-                override fun onCreate(savedInstanceState: Bundle?) {
-                    super.onCreate(savedInstanceState)
-                    val inst = MainComponent.createInstance(this)
-                    inst.setFoo("string")
-                    setContentView(inst)
-                }
-            }
-
-            class MainComponent : Component() {
-                lateinit var foo: String
-                override fun compose() {}
-            }
-        """)
-
-        val wrapperClass = klass.declaredClasses.find {
-            it.name == "MainComponent\$MainComponentWrapperView"
-        }
-        TestCase.assertNotNull("wrapper view gets generated", wrapperClass)
-        if (wrapperClass == null) return
-        TestCase.assertEquals(
-            "Wrapper view subclasses LinearLayout", "android.widget.LinearLayout",
-            wrapperClass.superclass?.name
-        )
-        val setFoo = wrapperClass.declaredMethods.find { it.name == "setFoo" }
-        TestCase.assertNotNull("has a setter method for properties", setFoo)
-
-        val companionClass =
-            klass.declaredClasses.find { it.name == "MainComponent\$R4HStaticRenderCompanion" }
-        TestCase.assertNotNull("companion class gets generated", companionClass)
-        if (companionClass == null) return
-        val createInstanceFn = companionClass.declaredMethods.find { it.name == "createInstance" }
-        TestCase.assertNotNull("createInstance function gets generated", createInstanceFn)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCallResolutionTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCallResolutionTests.kt
deleted file mode 100644
index 422f7b6..0000000
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCallResolutionTests.kt
+++ /dev/null
@@ -1,1191 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-class KtxCallResolutionTests : AbstractResolvedKtxCallsTest() {
-
-    fun testReceiverScopeCall() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composble fun Foo(onClick: Double.() -> Unit) {}
-
-            @Composable
-            fun test() {
-                <caret><Foo  />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Double.() -> Unit): Boolean
-                        assignment = <null>
-                        attribute = onClick
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun Foo(Double.() -> Unit)
-                  params = onClick
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = onClick
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testImplicitReceiverScopeCall() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bar {}
-
-            @Composable fun Bar.Foo() {}
-
-            @Composable
-            fun test(bar: Bar) {
-                with(bar) {
-                    <caret><Foo />
-                }
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations = <empty>
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun Bar.Foo()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = <empty>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testSomethingQualifiedTag() = doTest(
-        """
-            import androidx.compose.*
-
-            object Foo {
-                class Bar {
-                    @Composable
-                    operator fun invoke() {}
-                }
-            }
-
-            @Composable
-            fun test() {
-                <caret><Foo.Bar />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations = <empty>
-                call = NonMemoizedCallNode:
-                  resolvedCall = Bar()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = NonMemoizedCallNode:
-                    resolvedCall = fun invoke()
-                    params = <empty>
-                    postAssignments = <empty>
-                    nextCall = <null>
-              usedAttributes = <empty>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testReceiverScopeTag() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo {}
-
-            @Composable
-            fun test(children: Foo.() -> Unit) {
-                val foo = Foo()
-                <caret><foo.children />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations = <empty>
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun Foo.invoke()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = <empty>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testSomething() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bar(var y: Int = 0) {
-                @Composable
-                operator fun invoke(z: Int) {
-
-                }
-            }
-
-            @Composable
-            fun test() {
-                <caret><Bar y=2 z=3>
-                </Bar>
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = var y: Int
-                        attribute = y
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = z
-                call = NonMemoizedCallNode:
-                  resolvedCall = Bar(Int)
-                  params = y
-                  postAssignments = <empty>
-                  nextCall = NonMemoizedCallNode:
-                    resolvedCall = fun invoke(Int)
-                    params = z
-                    postAssignments = <empty>
-                    nextCall = <null>
-              usedAttributes = y, z
-              unusedAttributes = <children>
-        """
-    )
-
-    fun testNestedCalls() = doTest(
-        """
-            import androidx.compose.*
-
-            @Stateful
-            class Bar(var y: Int = 0) {
-                @Composable
-                operator fun invoke(z: Int) {
-
-                }
-            }
-
-            @Stateful
-            @Composable
-            fun Foo(a: Int): @Composable() (y: Int) -> Bar = { y: Int -> Bar(y) }
-
-            @Composable
-            fun test() {
-                <caret><Foo a=1 y=2 z=3 />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> (Int) -> Bar, ViewValidator.((Int) -> Bar) -> Boolean, ((Int) -> Bar) -> Unit)
-                  pivotals = a
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = fun Foo(Int): (Int) -> Bar
-                  ctorParams = a
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = y
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = z
-                call = MemoizedCallNode:
-                  memoize = ComposerCallInfo:
-                    composerCall = fun call(Any, () -> Bar, ViewValidator.(Bar) -> Boolean, (Bar) -> Unit)
-                    pivotals = <empty>
-                    joinKeyCall = fun joinKey(Any, Any?): Any
-                    ctorCall = fun invoke(Int): Bar
-                    ctorParams = y
-                    validations =
-                      - ValidatedAssignment(UPDATE):
-                          validationCall = fun update(Int, (Int) -> Unit): Boolean
-                          assignment = var y: Int
-                          attribute = y
-                      - ValidatedAssignment(CHANGED):
-                          validationCall = fun changed(Int): Boolean
-                          assignment = <null>
-                          attribute = z
-                  call = NonMemoizedCallNode:
-                    resolvedCall = fun invoke(Int)
-                    params = z
-                    postAssignments = <empty>
-                    nextCall = <null>
-              usedAttributes = z, y, a
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testTopLevelFunction() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable
-            fun Foo(a: Int, z: Int) {
-
-            }
-
-            @Composable
-            fun test() {
-                <caret><Foo a=1 z=3 />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = a
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = z
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun Foo(Int, Int)
-                  params = a, z
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = a, z
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testParameterNamesForInstantiatedClassObjects() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bar {
-                @Composable
-                operator fun invoke(z: Int) {
-
-                }
-            }
-
-            @Composable
-            fun test() {
-                val x = Bar()
-                <caret><x z=3 />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Bar): Boolean
-                        assignment = <null>
-                        attribute = <tag>
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = z
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke(Int)
-                  params = z
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = z, <tag>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testParameterNamesForLambdas() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable
-            fun test() {
-                val x: (z: Int) -> Unit = { z: Int -> }
-                <caret><x z=3 />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed((Int) -> Unit): Boolean
-                        assignment = <null>
-                        attribute = <tag>
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = z
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke(Int)
-                  params = z
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = z, <tag>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testSomethingWithChildren() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bar(var y: Int = 0) {
-                @Children var children: @Composable() () -> Unit = {}
-                @Composable
-                operator fun invoke(z: Int) {
-
-                }
-            }
-
-            @Composable
-            fun test() {
-                <caret><Bar y=2 z=3>
-                </Bar>
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = var y: Int
-                        attribute = y
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(() -> Unit): Boolean
-                        assignment = <null>
-                        attribute = <children>
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = z
-                call = NonMemoizedCallNode:
-                  resolvedCall = Bar(Int)
-                  params = y
-                  postAssignments =
-                    - ValidatedAssignment(SET):
-                        validationCall = fun set(() -> Unit, (() -> Unit) -> Unit): Boolean
-                        assignment = var children: () -> Unit
-                        attribute = <children>
-                  nextCall = NonMemoizedCallNode:
-                    resolvedCall = fun invoke(Int)
-                    params = z
-                    postAssignments = <empty>
-                    nextCall = <null>
-              usedAttributes = y, <children>, z
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testViewResolution() = doTest(
-        """
-            import androidx.compose.*
-            import android.widget.Button
-
-            @Composable
-            fun test() {
-                <caret><Button text="some text" enabled=false />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = EmitCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun emit(Any, (Context) -> Button, ViewUpdater<Button>.() -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = constructor Button(Context!)
-                  ctorParams = (implicit)context
-                  validations =
-                    - ValidatedAssignment(SET):
-                        validationCall = fun set(CharSequence!, Button.(CharSequence!) -> Unit)
-                        assignment = fun setText(CharSequence!)
-                        attribute = text
-                    - ValidatedAssignment(SET):
-                        validationCall = fun set(Boolean, Button.(Boolean) -> Unit)
-                        assignment = fun setEnabled(Boolean)
-                        attribute = enabled
-              usedAttributes = text, enabled
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testNonMemoizableClassComponent() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bar(var a: Int) {
-                @Composable
-                operator fun invoke(b: Int) {}
-            }
-
-            @Composable
-            fun test() {
-                <caret><Bar a=1 b=2 />
-            }
-            /*
-                call(k, { changed(a) + changed(b) }) {
-                    Bar(a)(b)
-                }
-            */
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = var a: Int
-                        attribute = a
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = b
-                call = NonMemoizedCallNode:
-                  resolvedCall = Bar(Int)
-                  params = a
-                  postAssignments = <empty>
-                  nextCall = NonMemoizedCallNode:
-                    resolvedCall = fun invoke(Int)
-                    params = b
-                    postAssignments = <empty>
-                    nextCall = <null>
-              usedAttributes = a, b
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testChildrenLambdaSetterWithMultipleParams() = doTest(
-        """
-            import androidx.compose.*
-
-            class Example {
-                @Children
-                fun setChildren(fn: (x: Int, y: String) -> Unit) {}
-                @Composable
-                operator fun invoke() {}
-            }
-
-            @Composable
-            fun helper(x: Int = 4, y: Int) {
-            }
-
-            fun run(text: String) {
-
-//                <helper y=123 />
-
-//                val lambda = { x, y -> ... }
-//                composer.call(
-//                    123,
-//                    { changed(lambda) },
-//                    { Example().apply { setChildren(lambda) }() }
-//                )
-
-                <caret><Example> x, y ->
-                    println("hello ${"$"}x ${"$"}y")
-                </Example>
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed((Int, String) -> Unit): Boolean
-                        assignment = <null>
-                        attribute = <children>
-                call = NonMemoizedCallNode:
-                  resolvedCall = Example()
-                  params = <empty>
-                  postAssignments =
-                    - ValidatedAssignment(SET):
-                        validationCall = fun set((Int, String) -> Unit, ((Int, String) -> Unit) -> Unit): Boolean
-                        assignment = fun setChildren((Int, String) -> Unit)
-                        attribute = <children>
-                  nextCall = NonMemoizedCallNode:
-                    resolvedCall = fun invoke()
-                    params = <empty>
-                    postAssignments = <empty>
-                    nextCall = <null>
-              usedAttributes = <children>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testMemoizableClassComponent() = doTest(
-        """
-            import androidx.compose.*
-
-            @Stateful
-            class Bar(var a: Int) {
-                @Composable
-                operator fun invoke(b: Int) {}
-            }
-
-            @Composable
-            fun test() {
-                <caret><Bar a=1 b=2 />
-            }
-            /*
-                call(k, { Bar(a) }, { update(a) { a = it } + changed(b) }) { bar ->
-                    bar(b)
-                }
-            */
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> Bar, ViewValidator.(Bar) -> Boolean, (Bar) -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = Bar(Int)
-                  ctorParams = a
-                  validations =
-                    - ValidatedAssignment(UPDATE):
-                        validationCall = fun update(Int, (Int) -> Unit): Boolean
-                        assignment = var a: Int
-                        attribute = a
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = b
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke(Int)
-                  params = b
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = b, a
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testMemoizableClassComponentComponent() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bar(var a: Int): Component() {
-                override fun compose() {}
-            }
-
-            @Composable
-            fun test() {
-                <caret><Bar a=1 />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> Bar, ViewValidator.(Bar) -> Boolean, (Bar) -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = Bar(Int)
-                  ctorParams = a
-                  validations =
-                    - ValidatedAssignment(UPDATE):
-                        validationCall = fun update(Int, (Int) -> Unit): Boolean
-                        assignment = var a: Int
-                        attribute = a
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = a
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testMemoizableClassComponentComponent2() = doTest(
-        """
-            import androidx.compose.*
-
-            class TestContainer(@Children var children: @Composable() (x: Double)->Unit): Component() {
-              override fun compose() {}
-            }
-
-            @Composable
-            fun test() {
-                <caret><TestContainer> x->
-
-                </TestContainer>
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> TestContainer, ViewValidator.(TestContainer) -> Boolean, (TestContainer) -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = TestContainer((Double) -> Unit)
-                  ctorParams = <children>
-                  validations =
-                    - ValidatedAssignment(UPDATE):
-                        validationCall = fun update((Double) -> Unit, ((Double) -> Unit) -> Unit): Boolean
-                        assignment = var children: (Double) -> Unit
-                        attribute = <children>
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = <children>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testDynamicTagsMemoizableClassComponent() = doTest(
-        """
-            import androidx.compose.*
-
-            @Stateful
-            class Bar(var a: Int) {
-                @Composable
-                operator fun invoke(b: Int) {}
-            }
-
-            @Composable
-            fun test() {
-                val bar = Bar()
-                <caret><bar b=2 />
-            }
-            /*
-                call(k, { changed(bar) + changed(b) }) {
-                    bar(b)
-                }
-            */
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Bar): Boolean
-                        assignment = <null>
-                        attribute = <tag>
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = b
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke(Int)
-                  params = b
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = b, <tag>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testDynamicTagsInnerClassMemoizableClassComponent() = doTest(
-        """
-            import androidx.compose.*
-
-
-            class Bar(var a: Int) {
-                @Stateful
-                inner class Foo {
-                    @Composable
-                    operator fun invoke(b: Int) {}
-                }
-            }
-
-            @Composable
-            fun test() {
-                val bar = Bar()
-                <caret><bar.Foo b=2 />
-            }
-            /*
-                call(k, { changed(bar) + changed(b) }) {
-                    bar.Foo(b)
-                }
-            */
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> Bar.Foo, ViewValidator.(Bar.Foo) -> Boolean, (Bar.Foo) -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = Foo()
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Bar): Boolean
-                        assignment = <null>
-                        attribute = <tag>
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = b
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke(Int)
-                  params = b
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = b, <tag>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testDeepNestedCalls() = doTest(
-        """
-            import androidx.compose.*
-
-
-            class A { operator fun invoke(a: Int): B { return B() } }
-            class B { operator fun invoke(b: Int): C { return C() } }
-            class C { operator fun invoke(c: Int): D { return D() } }
-            class D { operator fun invoke(d: Int): E { return E() } }
-            class E { operator fun invoke(e: Int) {} }
-
-            @Composable
-            fun test() {
-                <caret><A a=1 b=2 c=3 d=4 e=5 />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = a
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = b
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = c
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = d
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = e
-                call = NonMemoizedCallNode:
-                  resolvedCall = A()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = NonMemoizedCallNode:
-                    resolvedCall = fun invoke(Int): B
-                    params = a
-                    postAssignments = <empty>
-                    nextCall = NonMemoizedCallNode:
-                      resolvedCall = fun invoke(Int): C
-                      params = b
-                      postAssignments = <empty>
-                      nextCall = NonMemoizedCallNode:
-                        resolvedCall = fun invoke(Int): D
-                        params = c
-                        postAssignments = <empty>
-                        nextCall = NonMemoizedCallNode:
-                          resolvedCall = fun invoke(Int): E
-                          params = d
-                          postAssignments = <empty>
-                          nextCall = NonMemoizedCallNode:
-                            resolvedCall = fun invoke(Int)
-                            params = e
-                            postAssignments = <empty>
-                            nextCall = <null>
-              usedAttributes = a, b, c, d, e
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testRecursionLimitNoParams() = doTest(
-        """
-            import androidx.compose.*
-
-
-            class A { operator fun invoke(): B { return B() } }
-            class B { operator fun invoke(): C { return C() } }
-            class C { operator fun invoke(): D { return D() } }
-            class D { operator fun invoke(): E { return E() } }
-            class E { operator fun invoke() {} }
-
-            @Composable
-            fun test() {
-                <caret><A />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations = <empty>
-                call = NonMemoizedCallNode:
-                  resolvedCall = A()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <ERROR:RecursionLimitError>
-              usedAttributes = <empty>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testPivotalsAreNotValidated() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable
-            fun A(@Pivotal x: Int, y: Int) {
-                println(x)
-                println(y)
-            }
-
-            @Composable
-            fun test(x: Int, y: Int) {
-                <caret><A x y />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = x
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = x
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(Int): Boolean
-                        assignment = <null>
-                        attribute = y
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun A(Int, Int)
-                  params = x, y
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = x, y
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testConstructorParamsArePivotal() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo(a: Int, private val b: Int, var c: Int, d: Int) : Component() {
-              var d: Int = d
-              override fun compose() {}
-            }
-
-            @Composable
-            fun test(a: Int, b: Int, c: Int, d: Int) {
-                <caret><Foo a b c d />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> Foo, ViewValidator.(Foo) -> Boolean, (Foo) -> Unit)
-                  pivotals = a, b
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = Foo(Int, Int, Int, Int)
-                  ctorParams = a, b, c, d
-                  validations =
-                    - ValidatedAssignment(UPDATE):
-                        validationCall = fun update(Int, (Int) -> Unit): Boolean
-                        assignment = var c: Int
-                        attribute = c
-                    - ValidatedAssignment(UPDATE):
-                        validationCall = fun update(Int, (Int) -> Unit): Boolean
-                        assignment = var d: Int
-                        attribute = d
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = a, b, c, d
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testValChildren() = doTest(
-        """
-            import androidx.compose.*
-
-            class A(@Children val children: () -> Unit) : Component() {
-                override fun compose() {}
-            }
-
-            @Composable
-            fun test() {
-                <caret><A></A>
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> A, ViewValidator.(A) -> Boolean, (A) -> Unit)
-                  pivotals = <children>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = A(() -> Unit)
-                  ctorParams = <children>
-                  validations = <empty>
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = <children>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testPrivateValChildren() = doTest(
-        """
-            import androidx.compose.*
-
-            class A(@Children private val children: () -> Unit) : Component() {
-                override fun compose() {}
-            }
-
-            @Composable
-            fun test() {
-                <caret><A></A>
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, () -> A, ViewValidator.(A) -> Boolean, (A) -> Unit)
-                  pivotals = <children>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = A(() -> Unit)
-                  ctorParams = <children>
-                  validations = <empty>
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun invoke()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = <children>
-              unusedAttributes = <empty>
-        """
-    )
-
-    fun testIsStaticNature() = doTest(
-        """
-            import androidx.compose.*
-
-//            class Bar {
-//                @Composable
-//                operator fun invoke() {}
-//            }
-
-            val Bar get() = @Composable { }
-
-            // All of these should be "static"
-            // ===============================
-
-            // class A { operator fun invoke() }
-            // <A />
-
-            // class A { companion object { class B { operator fun invoke() {} } } }
-            // <A.B />
-
-            // class A { companion object { fun B() {} } }
-            // <A.B />
-
-            // class A { class B { operator fun invoke() {} } } }
-            // <A.B />
-
-            // object A { fun B() {} }
-            // <A.B />
-
-            // object A { object B { fun C() {} } }
-            // <A.B.C />
-
-            // object A { class B { operator fun invoke() {} } }
-            // <A.B />
-
-            // fun A() {}
-            // <A />
-
-            // val A = @Composable {}
-            // <A />
-
-            // class A { inner class B { operator fun invoke() {} } }
-            // val a = A()
-            // <a.B />
-
-
-            // All of these should be "dynamic"
-            // ===============================
-
-            // var A = @Composable {}
-            // <A />
-
-            // val A get() = @Composable {}
-            // <A />
-
-            // object A { inner class B { operator fun invoke() {} } }
-            // <A.B />
-
-            // class A { inner class B { operator fun invoke() {} } }
-            // A().let { <it.B /> }
-
-
-            class UI {
-                @Composable
-                fun Foo() {}
-            }
-            val ui = UI()
-
-            @Composable
-            fun test() {
-                <caret><ui.Foo />
-            }
-        """,
-        """
-            ResolvedKtxElementCall:
-              emitOrCall = MemoizedCallNode:
-                memoize = ComposerCallInfo:
-                  composerCall = fun call(Any, ViewValidator.() -> Boolean, () -> Unit)
-                  pivotals = <empty>
-                  joinKeyCall = fun joinKey(Any, Any?): Any
-                  ctorCall = <null>
-                  ctorParams = <empty>
-                  validations =
-                    - ValidatedAssignment(CHANGED):
-                        validationCall = fun changed(UI): Boolean
-                        assignment = <null>
-                        attribute = <tag>
-                call = NonMemoizedCallNode:
-                  resolvedCall = fun Foo()
-                  params = <empty>
-                  postAssignments = <empty>
-                  nextCall = <null>
-              usedAttributes = <tag>
-              unusedAttributes = <empty>
-        """
-    )
-}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCodegenTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCodegenTests.kt
deleted file mode 100644
index 5418a2d..0000000
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCodegenTests.kt
+++ /dev/null
@@ -1,1885 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:Suppress("MemberVisibilityCanBePrivate")
-
-package androidx.compose.plugins.kotlin
-
-import android.app.Activity
-import android.os.Bundle
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.compose.Component
-import androidx.compose.CompositionContext
-import androidx.compose.Compose
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.robolectric.Robolectric
-import org.robolectric.RuntimeEnvironment
-import org.robolectric.annotation.Config
-import java.net.URLClassLoader
-
-@RunWith(ComposeRobolectricTestRunner::class)
-@Config(
-    manifest = Config.NONE,
-    minSdk = 23,
-    maxSdk = 23
-)
-class KtxCodegenTests : AbstractCodegenTest() {
-
-    @Test
-    fun testModelOne(): Unit = ensureSetup {
-        codegen(
-            """
-@Model
-class ModelClass() {
-    var x = 0
-}
-            """
-        )
-    }
-
-    @Test
-    fun testObservable(): Unit = ensureSetup {
-        compose(
-            """
-                import android.widget.Button
-                import androidx.compose.*
-                import androidx.ui.androidview.adapters.setOnClick
-
-                @Model
-                class FancyButtonData() {
-                    var x = 0
-                }
-
-                @Composable
-                fun SimpleComposable() {
-                    <FancyButton state=FancyButtonData() />
-                }
-
-                @Composable
-                fun FancyButton(state: FancyButtonData) {
-                    <Button text=("Clicked "+state.x+" times")  id=42 />
-                }
-            """,
-            { mapOf<String, String>() },
-            "<SimpleComposable />"
-        ).then { activity ->
-            val button = activity.findViewById(42) as Button
-            button.performClick()
-            button.performClick()
-            button.performClick()
-        }.then { activity ->
-            val button = activity.findViewById(42) as Button
-            assertEquals("Clicked 3 times", button.text)
-        }
-    }
-
-    @Test
-    fun testObservableLambda(): Unit = ensureSetup {
-        compose(
-            """
-                import android.widget.*
-                import androidx.compose.*
-                import androidx.ui.androidview.adapters.setOnClick
-
-                @Model
-                class FancyButtonCount() {
-                    var count = 0
-                }
-
-                @Composable
-                fun SimpleComposable(state: FancyButtonCount) {
-                    <FancyBox2>
-                        <Button
-                          text=("Button clicked "+state.count+" times")
-                           id=42 />
-                    </FancyBox2>
-                }
-
-                @Composable
-                fun FancyBox2(@Children children: ()->Unit) {
-                    <children />
-                }
-            """,
-            { mapOf<String, String>() },
-            "<SimpleComposable state=+memo { FancyButtonCount() } />"
-        ).then { activity ->
-            val button = activity.findViewById(42) as Button
-            button.performClick()
-            button.performClick()
-            button.performClick()
-        }.then { activity ->
-            val button = activity.findViewById(42) as Button
-            assertEquals("Button clicked 3 times", button.text)
-        }
-    }
-
-    @Test
-    fun testCGSimpleTextView(): Unit = ensureSetup {
-        compose(
-            """
-                <TextView text="Hello, world!" id=42 />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGLocallyScopedFunction(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo() {
-                    @Composable fun Bar() {
-                        <TextView text="Hello, world!" id=42 />
-                    }
-                    <Bar />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Foo />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGLocallyScopedExtensionFunction(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(x: String) {
-                    @Composable fun String.Bar() {
-                        <TextView text=this id=42 />
-                    }
-                    <x.Bar />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Foo x="Hello, world!" />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testImplicitReceiverScopeCall(): Unit = ensureSetup {
-        compose(
-            """
-                import androidx.compose.*
-
-                class Bar(val text: String)
-
-                @Composable fun Bar.Foo() {
-                    <TextView text=text id=42 />
-                }
-
-                @Composable
-                fun Bam(bar: Bar) {
-                    with(bar) {
-                        <Foo />
-                    }
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Bam bar=Bar("Hello, world!") />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGLocallyScopedInvokeOperator(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(x: String) {
-                    @Composable operator fun String.invoke() {
-                        <TextView text=this id=42 />
-                    }
-                    <x />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Foo x="Hello, world!" />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNSimpleTextView(): Unit = ensureSetup {
-        compose(
-            """
-                <TextView text="Hello, world!" id=42 />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testInliningTemp(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(x: Double, @Children children: Double.() -> Unit) {
-                  <x.children />
-                }
-            """,
-            { mapOf("foo" to "bar") },
-            """
-                <Foo x=1.0>
-                    <TextView text=this.toString() id=123 />
-                </Foo>
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(123) as TextView
-            assertEquals("1.0", textView.text)
-        }
-    }
-
-    @Test
-    fun testInliningTemp2(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(onClick: Double.() -> Unit) {
-
-                }
-            """,
-            { mapOf("foo" to "bar") },
-            """
-                <Foo  />
-            """
-        ).then {
-        }
-    }
-
-    @Test
-    fun testInliningTemp3(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(onClick: (Double) -> Unit) {
-
-                }
-            """,
-            { mapOf("foo" to "bar") },
-            """
-                <Foo  />
-            """
-        ).then {
-        }
-    }
-
-    @Test
-    fun testInliningTemp4(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(onClick: (Double) -> Unit) {
-
-                }
-            """,
-            { mapOf("foo" to "bar") },
-            """
-                <Foo  />
-            """
-        ).then {
-        }
-    }
-
-    @Test
-    fun testCGNInlining(): Unit = ensureSetup {
-        compose(
-            """
-                <LinearLayout orientation=LinearLayout.VERTICAL>
-                    <TextView text="Hello, world!" id=42 />
-                </LinearLayout>
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGUpdatedComposition(): Unit = ensureSetup {
-        var value = "Hello, world!"
-
-        compose(
-            { mapOf("value" to value) }, """
-           <TextView text=value id=42 />
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-
-            value = "Other value"
-        }.then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Other value", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNUpdatedComposition(): Unit = ensureSetup {
-        var value = "Hello, world!"
-
-        compose(
-            { mapOf("value" to value) }, """
-           <TextView text=value id=42 />
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-
-            value = "Other value"
-        }.then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Other value", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGViewGroup(): Unit = ensureSetup {
-        val tvId = 258
-        val llId = 260
-        var text = "Hello, world!"
-        var orientation = LinearLayout.HORIZONTAL
-
-        compose(
-            { mapOf("text" to text, "orientation" to orientation) }, """
-            <LinearLayout orientation id=$llId>
-              <TextView text id=$tvId />
-            </LinearLayout>
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val linearLayout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(text, textView.text)
-            assertEquals(orientation, linearLayout.orientation)
-
-            text = "Other value"
-            orientation = LinearLayout.VERTICAL
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val linearLayout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(text, textView.text)
-            assertEquals(orientation, linearLayout.orientation)
-        }
-    }
-
-    @Test
-    fun testCGNAmbient(): Unit = ensureSetup {
-        val tvId = 258
-        var text = "Hello, world!"
-
-        compose(
-            """
-
-            val StringAmbient = Ambient.of<String> { "default" }
-
-            @Composable fun Foo() {
-                val value = +ambient(StringAmbient)
-                <TextView id=$tvId text=value />
-            }
-
-        """,
-            { mapOf("text" to text) },
-            """
-            <StringAmbient.Provider value=text>
-                <Foo />
-            </StringAmbient.Provider>
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-            text = "wat"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testAmbientNesting(): Unit = ensureSetup {
-        val tvId1 = 345
-        val tvId2 = 456
-
-        compose(
-            """
-            val A1 = Ambient.of("one") { 0 }
-            val A2 = Ambient.of("two") { 0 }
-            var changing = 0
-
-            @Composable
-            fun Foo() {
-                <A1.Provider value=2>
-                    <ConsumeBoth id=$tvId1 />
-                </A1.Provider>
-            }
-
-            @Composable
-            fun Bar() {
-                <ConsumeBoth id=$tvId2 />
-            }
-
-            @Composable
-            fun ConsumeBoth(id: Int) {
-                val notUsed = +ambient(A2)
-                val value = +ambient(A1)
-                <TextView id=id text=("" + value) />
-            }
-
-            """,
-            { mapOf("text" to "") },
-            """
-            <A1.Provider value=1>
-                <A2.Provider value=changing++>
-                    <Foo />
-                    <Bar />
-                </A2.Provider>
-            </A1.Provider>
-            """
-        ).then { activity ->
-            val tv1 = activity.findViewById(tvId1) as TextView
-            val tv2 = activity.findViewById(tvId2) as TextView
-
-            assertEquals("2", tv1.text)
-            assertEquals("1", tv2.text)
-        }.then { activity ->
-            val tv1 = activity.findViewById(tvId1) as TextView
-            val tv2 = activity.findViewById(tvId2) as TextView
-
-            assertEquals("2", tv1.text)
-            assertEquals("1", tv2.text)
-        }
-    }
-
-    @Test
-    fun testAmbientPortal1(): Unit = ensureSetup {
-        val llId = 123
-        val tvId = 345
-        var text = "Hello, world!"
-
-        compose(
-            """
-            val StringAmbient = Ambient.of<String> { "default" }
-
-            @Composable fun App(value: String) {
-                <StringAmbient.Provider value>
-                    <Parent />
-                </StringAmbient.Provider>
-            }
-
-            @Composable fun Parent() {
-                val compositionRef = +compositionReference()
-                val viewRef = +memo { Ref<LinearLayout>() }
-
-                <LinearLayout id=$llId ref=viewRef />
-
-                +onPreCommit {
-                    Compose.composeInto(
-                        container = viewRef.value ?: error("No View Ref!"),
-                        parent = compositionRef
-                    ) {
-                        <Child />
-                    }
-                }
-            }
-
-            @Composable fun Child() {
-                val value = +ambient(StringAmbient)
-                <TextView id=$tvId text=value />
-            }
-
-            """,
-            { mapOf("text" to text) },
-            """
-            <App value=text />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val layout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(1, layout.childCount)
-            assertEquals(text, textView.text)
-            text = "wat"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val layout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(1, layout.childCount)
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testAmbientPortal2(): Unit = ensureSetup {
-        val llId = 123
-        val tvId = 345
-        var text = "Hello, world!"
-
-        compose(
-            """
-            val StringAmbient = Ambient.of<String> { "default" }
-
-            @Composable fun App(value: String) {
-                <StringAmbient.Provider value>
-                    <Parent />
-                </StringAmbient.Provider>
-            }
-
-            @Composable fun Parent() {
-                val compositionRef = +compositionReference()
-                val viewRef = +memo { Ref<LinearLayout>() }
-
-                <LinearLayout id=$llId ref=viewRef />
-
-                +onPreCommit {
-                    Compose.composeInto(
-                        container = viewRef.value ?: error("No View Ref!"),
-                        parent = compositionRef
-                    ) {
-                        <Child />
-                    }
-                }
-            }
-
-            @Composable fun Child() {
-                val value = +ambient(StringAmbient)
-                <TextView id=$tvId text=value />
-            }
-
-            """,
-            { mapOf("text" to text) },
-            """
-            <App value=text />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val layout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(1, layout.childCount)
-            assertEquals(text, textView.text)
-            text = "wat"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val layout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(1, layout.childCount)
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNClassComponent(): Unit = ensureSetup {
-        var text = "Hello, world!"
-        val tvId = 123
-
-        compose(
-            """
-            class Foo {
-                var text = ""
-                @Composable
-                operator fun invoke(bar: Int) {
-                    <TextView id=$tvId text=text />
-                }
-            }
-
-        """,
-            { mapOf("text" to text) },
-            """
-             <Foo text bar=123 />
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-            text = "wat"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNFunctionComponent(): Unit = ensureSetup {
-        var text = "Hello, world!"
-        val tvId = 123
-
-        compose(
-            """
-            @Composable
-            fun Foo(text: String) {
-                <TextView id=$tvId text=text />
-            }
-
-        """,
-            { mapOf("text" to text) },
-            """
-             <Foo text />
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-            text = "wat"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testAmbientReference(): Unit = ensureSetup {
-        val outerId = 123
-        val innerId = 345
-        val buttonId = 456
-
-        compose(
-            """
-                fun <T> refFor() = memo { Ref<T>() }
-
-                val textAmbient = Ambient.of { "default" }
-
-                @Composable fun DisplayTest(id: Int) {
-                    val text = +ambient(textAmbient)
-                    <TextView id text />
-                }
-
-                @Composable fun PortalTest() {
-                    val portal = +compositionReference()
-                    val ref = +refFor<LinearLayout>()
-                    <DisplayTest id=$outerId />
-
-                    <LinearLayout ref />
-
-                    val root = ref.value ?: error("Expected a linear")
-
-                    Compose.composeInto(root, portal) {
-                        <DisplayTest id=$innerId />
-                    }
-                }
-
-                @Composable
-                fun TestApp() {
-                    val inc = +state { 1 }
-
-                    <Button id=$buttonId text="Click Me"  inc.value += 1 } />
-
-                    <textAmbient.Provider value="value: ${"$"}{inc.value}">
-                        <PortalTest />
-                    </textAmbient.Provider>
-                }
-            """,
-            { mapOf("text" to "") },
-            """
-                <TestApp />
-            """
-        ).then { activity ->
-            val inner = activity.findViewById(innerId) as TextView
-            val outer = activity.findViewById(outerId) as TextView
-            val button = activity.findViewById(buttonId) as Button
-
-            assertEquals("inner", "value: 1", inner.text)
-            assertEquals("outer", "value: 1", outer.text)
-
-            button.performClick()
-        }.then { activity ->
-            val inner = activity.findViewById(innerId) as TextView
-            val outer = activity.findViewById(outerId) as TextView
-            val button = activity.findViewById(buttonId) as Button
-
-            assertEquals("inner", "value: 2", inner.text)
-            assertEquals("outer", "value: 2", outer.text)
-
-            button.performClick()
-        }.then { activity ->
-            val inner = activity.findViewById(innerId) as TextView
-            val outer = activity.findViewById(outerId) as TextView
-
-            assertEquals("inner", "value: 3", inner.text)
-            assertEquals("outer", "value: 3", outer.text)
-        }
-    }
-
-    @Test
-    fun testCGNViewGroup(): Unit = ensureSetup {
-        val tvId = 258
-        val llId = 260
-        var text = "Hello, world!"
-        var orientation = LinearLayout.HORIZONTAL
-
-        compose(
-            { mapOf("text" to text, "orientation" to orientation) }, """
-             <LinearLayout orientation id=$llId>
-               <TextView text id=$tvId />
-             </LinearLayout>
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val linearLayout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(text, textView.text)
-            assertEquals(orientation, linearLayout.orientation)
-
-            text = "Other value"
-            orientation = LinearLayout.VERTICAL
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val linearLayout = activity.findViewById(llId) as LinearLayout
-
-            assertEquals(text, textView.text)
-            assertEquals(orientation, linearLayout.orientation)
-        }
-    }
-
-    @Test
-    fun testMemoization(): Unit = ensureSetup {
-        val tvId = 258
-        val tagId = (3 shl 24) or "composed_set".hashCode()
-
-        @Suppress("UNCHECKED_CAST")
-        fun View.getComposedSet(): Set<String>? = getTag(tagId) as? Set<String>
-
-        compose(
-            """
-                import android.view.View
-
-                var composedSet = mutableSetOf<String>()
-                var inc = 1
-
-                fun View.setComposed(composed: Set<String>) = setTag($tagId, composed)
-
-                @Composable fun ComposePrimitive(value: Int) {
-                    composedSet.add("ComposePrimitive(" + value + ")")
-                }
-
-                class MutableThing(var value: String)
-
-                val constantMutableThing = MutableThing("const")
-
-                @Composable fun ComposeMutable(value: MutableThing) {
-                    composedSet.add("ComposeMutable(" + value.value + ")")
-                }
-            """,
-            { mapOf("text" to "") },
-            """
-                composedSet.clear()
-
-                <ComposePrimitive value=123 />
-                <ComposePrimitive value=inc />
-                <ComposeMutable value=constantMutableThing />
-                <ComposeMutable value=MutableThing("new") />
-
-                <TextView id=$tvId composed=composedSet />
-
-                inc++
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val composedSet = textView.getComposedSet() ?: error("expected a compose set to exist")
-
-            fun assertContains(contains: Boolean, key: String) {
-                assertEquals("composedSet contains key '$key'", contains, composedSet.contains(key))
-            }
-
-            assertContains(true, "ComposePrimitive(123)")
-            assertContains(true, "ComposePrimitive(1)")
-            assertContains(true, "ComposeMutable(const)")
-            assertContains(true, "ComposeMutable(new)")
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            val composedSet = textView.getComposedSet() ?: error("expected a compose set to exist")
-
-            fun assertContains(contains: Boolean, key: String) {
-                assertEquals("composedSet contains key '$key'", contains, composedSet.contains(key))
-            }
-
-            // the primitive component skips based on equality
-            assertContains(false, "ComposePrimitive(123)")
-
-            // since the primitive changed, this one recomposes again
-            assertContains(true, "ComposePrimitive(2)")
-
-            // since this is a potentially mutable object, we don't skip based on it
-            assertContains(true, "ComposeMutable(const)")
-
-            // since its a new one every time, we definitely don't skip
-            assertContains(true, "ComposeMutable(new)")
-        }
-    }
-
-    @Test
-    fun testCGNSimpleCall(): Unit = ensureSetup {
-        val tvId = 258
-        var text = "Hello, world!"
-
-        compose(
-            """
-                @Composable fun SomeFun(x: String) {
-                    <TextView text=x id=$tvId />
-                }
-            """,
-            { mapOf("text" to text) },
-            """
-                <SomeFun x=text />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-
-            text = "Other value"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNSimpleCall2(): Unit = ensureSetup {
-        val tvId = 258
-        var text = "Hello, world!"
-        var someInt = 456
-
-        compose(
-            """
-                class SomeClass(var x: String) {
-                    @Composable
-                    operator fun invoke(y: Int) {
-                        <TextView text="${"$"}x ${"$"}y" id=$tvId />
-                    }
-                }
-            """,
-            { mapOf("text" to text, "someInt" to someInt) },
-            """
-                <SomeClass x=text y=someInt />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals("Hello, world! 456", textView.text)
-
-            text = "Other value"
-            someInt = 123
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals("Other value 123", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNSimpleCall3(): Unit = ensureSetup {
-        val tvId = 258
-        var text = "Hello, world!"
-        var someInt = 456
-
-        compose(
-            """
-                @Stateful
-                class SomeClassoawid(var x: String) {
-                    @Composable
-                    operator fun invoke(y: Int) {
-                        <TextView text="${"$"}x ${"$"}y" id=$tvId />
-                    }
-                }
-            """,
-            { mapOf("text" to text, "someInt" to someInt) },
-            """
-                <SomeClassoawid x=text y=someInt />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals("Hello, world! 456", textView.text)
-
-            text = "Other value"
-            someInt = 123
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals("Other value 123", textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNCallWithChildren(): Unit = ensureSetup {
-        val tvId = 258
-        var text = "Hello, world!"
-
-        compose(
-            """
-                @Composable
-                fun Block(@Children children: () -> Unit) {
-                    <children />
-                }
-            """,
-            { mapOf("text" to text) },
-            """
-                <Block>
-                    <Block>
-                        <TextView text id=$tvId />
-                    </Block>
-                </Block>
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-
-            text = "Other value"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testCGNStuff(): Unit = ensureSetup {
-        val tvId = 258
-        var num = 123
-
-        compose(
-            """
-                class OneArg {
-                    var foo = 0
-                    @Composable
-                    operator fun invoke() {
-                        <TextView text="${"$"}foo" id=$tvId />
-                    }
-                }
-                fun OneArg.setBar(bar: Int) { foo = bar }
-            """,
-            { mapOf("num" to num) },
-            """
-            <OneArg bar=num />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            assertEquals("$num", textView.text)
-
-            num = 456
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            assertEquals("$num", textView.text)
-        }
-    }
-
-    @Test
-    fun testTagBasedMemoization(): Unit = ensureSetup {
-        val tvId = 258
-        var text = "Hello World"
-
-        compose(
-            """
-                class A {
-                    var foo = ""
-                    inner class B {
-                        @Composable
-                        operator fun invoke() {
-                            <TextView text=foo id=$tvId />
-                        }
-                    }
-                }
-            """,
-            { mapOf("text" to text) },
-            """
-                val a = A()
-                a.foo = text
-                <a.B />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            assertEquals(text, textView.text)
-
-            text = "new value"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            assertEquals(text, textView.text)
-        }
-    }
-
-    @Test
-    fun testCGComposableFunctionInvocationOneParameter(): Unit = ensureSetup {
-        val tvId = 91
-        var phone = "(123) 456-7890"
-        compose(
-            """
-           fun Phone(value: String) {
-             <TextView text=value id=$tvId />
-           }
-        """, { mapOf("phone" to phone) }, """
-           <Phone value=phone />
-        """
-        ).then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            assertEquals(phone, textView.text)
-
-            phone = "(123) 456-7899"
-        }.then { activity ->
-            val textView = activity.findViewById(tvId) as TextView
-            assertEquals(phone, textView.text)
-        }
-    }
-
-    @Test
-    fun testCGComposableFunctionInvocationTwoParameters(): Unit = ensureSetup {
-        val tvId = 111
-        val rsId = 112
-        var left = 0
-        var right = 0
-        compose(
-            """
-           var addCalled = 0
-
-           fun AddView(left: Int, right: Int) {
-             addCalled++
-             <TextView text="${'$'}left + ${'$'}right = ${'$'}{left + right}" id=$tvId />
-             <TextView text="${'$'}addCalled" id=$rsId />
-           }
-        """, { mapOf("left" to left, "right" to right) }, """
-           <AddView left right />
-        """
-        ).then { activity ->
-            // Should be called on the first compose
-            assertEquals("1", (activity.findViewById(rsId) as TextView).text)
-            assertEquals(
-                "$left + $right = ${left + right}",
-                (activity.findViewById(tvId) as TextView).text
-            )
-        }.then { activity ->
-            // Should be skipped on the second compose
-            assertEquals("1", (activity.findViewById(rsId) as TextView).text)
-            assertEquals(
-                "$left + $right = ${left + right}",
-                (activity.findViewById(tvId) as TextView).text
-            )
-
-            left = 1
-        }.then { activity ->
-            // Should be called again because left changed.
-            assertEquals("2", (activity.findViewById(rsId) as TextView).text)
-            assertEquals(
-                "$left + $right = ${left + right}",
-                (activity.findViewById(tvId) as TextView).text
-            )
-
-            right = 41
-        }.then { activity ->
-            // Should be called again because right changed
-            assertEquals("3", (activity.findViewById(rsId) as TextView).text)
-            assertEquals(
-                "$left + $right = ${left + right}",
-                (activity.findViewById(tvId) as TextView).text
-            )
-        }.then { activity ->
-            // Should be skipped because nothing changed
-            assertEquals("3", (activity.findViewById(rsId) as TextView).text)
-        }
-    }
-
-    @Test
-    fun testImplicitReceiverPassing1(): Unit = ensureSetup {
-        compose(
-            """
-                fun Int.Foo(x: @Composable() Int.() -> Unit) {
-                    <x />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                val id = 42
-
-                <id.Foo x={
-                    <TextView text="Hello, world!" id=this />
-                } />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testImplicitReceiverPassing2(): Unit = ensureSetup {
-        compose(
-            """
-                fun Int.Foo(x: @Composable() Int.(text: String) -> Unit, text: String) {
-                    <x text />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                val id = 42
-
-                <id.Foo text="Hello, world!" x={ text ->
-                    <TextView text id=this />
-                } />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testEffects1(): Unit = ensureSetup {
-        compose(
-            """
-                import androidx.ui.androidview.adapters.*
-
-                @Composable
-                fun Counter() {
-                    <Observe>
-                        var count = +state { 0 }
-                        <TextView
-                            text=("Count: " + count.value)
-                            >
-                                count.value += 1
-                            }
-                            id=42
-                        />
-                    </Observe>
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Counter />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Count: 0", textView.text)
-            textView.performClick()
-        }.then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Count: 1", textView.text)
-        }
-    }
-
-    @Test
-    fun testEffects2(): Unit = ensureSetup {
-        compose(
-            """
-                import androidx.ui.androidview.adapters.*
-
-                @Model class MyState<T>(var value: T)
-
-                @Composable
-                fun Counter() {
-                    <Observe>
-                        var count = +memo { MyState(0) }
-                        <TextView
-                            text=("Count: " + count.value)
-                            >
-                                count.value += 1
-                            }
-                            id=42
-                        />
-                    </Observe>
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Counter />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Count: 0", textView.text)
-            textView.performClick()
-        }.then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Count: 1", textView.text)
-        }
-    }
-
-    @Test
-    fun testEffects3(): Unit = ensureSetup {
-        val log = StringBuilder()
-        compose(
-            """
-                import androidx.ui.androidview.adapters.*
-
-                @Composable
-                fun Counter(log: StringBuilder) {
-                    <Observe>
-                        var count = +state { 0 }
-                        +onPreCommit {
-                            log.append("a")
-                        }
-                        +onActive {
-                            log.append("b")
-                        }
-                        <TextView
-                            text=("Count: " + count.value)
-                            >
-                                count.value += 1
-                            }
-                            id=42
-                        />
-                    </Observe>
-                }
-            """,
-            { mapOf("log" to log) },
-            """
-                <Counter log />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Count: 0", textView.text)
-            assertEquals("ab", log.toString())
-
-            execute {
-                textView.performClick()
-            }
-
-            assertEquals("Count: 1", textView.text)
-            assertEquals("aba", log.toString())
-        }
-    }
-
-    @Test
-    fun testEffects4(): Unit = ensureSetup {
-        val log = StringBuilder()
-        compose(
-            """
-                import androidx.ui.androidview.adapters.*
-
-                fun printer(log: StringBuilder, str: String) = effectOf<Unit> {
-                    +onPreCommit {
-                        log.append(str)
-                    }
-                }
-
-                @Composable
-                fun Counter(log: StringBuilder) {
-                    <Observe>
-                        var count = +state { 0 }
-                        +printer(log, "" + count.value)
-                        <TextView
-                            text=("Count: " + count.value)
-                            >
-                                count.value += 1
-                            }
-                            id=42
-                        />
-                    </Observe>
-                }
-            """,
-            { mapOf("log" to log) },
-            """
-                <Counter log />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Count: 0", textView.text)
-            assertEquals("0", log.toString())
-
-            execute {
-                textView.performClick()
-            }
-
-            assertEquals("Count: 1", textView.text)
-            assertEquals("01", log.toString())
-        }
-    }
-
-    // b/118610495
-    @Test
-    fun testCGChildCompose(): Unit = ensureSetup {
-        val tvId = 153
-
-        var text = "Test 1"
-
-        compose(
-            """
-            var called = 0
-
-            class TestContainer(@Children var children: @Composable() ()->Unit): Component() {
-              override fun compose() {
-                <LinearLayout>
-                  <children />
-                </LinearLayout>
-              }
-            }
-
-            class TestClass(var text: String): Component() {
-              override fun compose() {
-                <TestContainer>
-                  <TextView text id=$tvId />
-                </TestContainer>
-              }
-            }
-        """, { mapOf("text" to text) }, """
-            <TestClass text />
-        """
-        ).then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals(text, tv.text)
-
-            text = "Test 2"
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals(text, tv.text)
-        }
-    }
-
-    @Test
-    fun testPrivatePivotalProperties(): Unit = ensureSetup {
-        val tvId = 153
-
-        compose(
-            """
-            class ClassComponent(@Children private val callback: () -> Unit) : Component() {
-                override fun compose() {
-                    <callback />
-                }
-            }
-        """, { mapOf("text" to "") }, """
-            <ClassComponent>
-                <TextView id=$tvId text="Hello world!" />
-            </ClassComponent>
-        """
-        ).then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Hello world!", tv.text)
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("Hello world!", tv.text)
-        }
-    }
-
-    @Test
-    fun testVariableCalls1(): Unit = ensureSetup {
-        compose(
-            """
-                val component = @Composable {
-                    <TextView text="Hello, world!" id=42 />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <component />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testVariableCalls2(): Unit = ensureSetup {
-        compose(
-            """
-                val component = @Composable {
-                    <TextView text="Hello, world!" id=42 />
-                }
-                class HolderA(val composable: @Composable() () -> Unit)
-
-                val holder = HolderA(component)
-
-            """,
-            { mapOf<String, String>() },
-            """
-                <holder.composable />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testVariableCalls3(): Unit = ensureSetup {
-        compose(
-            """
-                val component = @Composable {
-                    <TextView text="Hello, world!" id=42 />
-                }
-                class HolderB(val composable: @Composable() () -> Unit) {
-                    @Composable
-                    fun Foo() {
-                        <composable />
-                    }
-                }
-
-                val holder = HolderB(component)
-
-            """,
-            { mapOf<String, String>() },
-            """
-                <holder.Foo />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testVariableCalls4(): Unit = ensureSetup {
-        compose(
-            """
-                val component = @Composable {
-                    <TextView text="Hello, world!" id=42 />
-                }
-                class HolderC(val composable: @Composable() () -> Unit) {
-                    inner class Foo(): Component() {
-                        override fun compose() {
-                            <composable />
-                        }
-                    }
-                }
-
-                val holder = HolderC(component)
-
-            """,
-            { mapOf<String, String>() },
-            """
-                <holder.Foo />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    // b/123721921
-    @Test
-    fun testDefaultParameters1(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(a: Int = 42, b: String) {
-                    <TextView text=b id=a />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Foo b="Hello, world!" />
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testDefaultParameters2(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun Foo(a: Int = 42, b: String, @Children c: () -> Unit) {
-                    <c />
-                    <TextView text=b id=a />
-                }
-            """,
-            { mapOf<String, String>() },
-            """
-                <Foo b="Hello, world!">
-                </Foo>
-            """
-        ).then { activity ->
-            val textView = activity.findViewById(42) as TextView
-            assertEquals("Hello, world!", textView.text)
-        }
-    }
-
-    @Test
-    fun testPropertiesAndCtorParamsOnEmittables(): Unit = codegen(
-        """
-            class SimpleEmittable(label: String? = null) : Emittable {
-                var label: String? = null
-                override fun emitInsertAt(index: Int, instance: Emittable) {}
-                override fun emitMove(from: Int, to: Int, count: Int) {}
-                override fun emitRemoveAt(index: Int, count: Int) {}
-            }
-
-            @Composable
-            fun foo() {
-                <SimpleEmittable label="Foo" />
-            }
-        """
-    )
-
-    @Test
-    fun testMovement(): Unit = ensureSetup {
-        val tvId = 50
-        val btnIdAdd = 100
-        val btnIdUp = 200
-        val btnIdDown = 300
-
-        // Duplicate the steps to reproduce an issue discovered in the Reorder example
-        compose(
-            """
-            fun <T> List<T>.move(from: Int, to: Int): List<T> {
-                if (to < from) return move(to, from)
-                val item = get(from)
-                val currentItem = get(to)
-                val left = if (from > 0) subList(0, from) else emptyList()
-                val right = if (to < size) subList(to + 1, size) else emptyList()
-                val middle = if (to - from > 1) subList(from + 1, to) else emptyList()
-                return left + listOf(currentItem) + middle + listOf(item) + right
-            }
-
-            @Composable
-            fun Reordering() {
-                <Observe>
-                    val items = +state { listOf(1, 2, 3, 4, 5) }
-
-                    <LinearLayout orientation=LinearLayout.VERTICAL>
-                        items.value.forEachIndexed { index, id ->
-                            <Item
-                                id
-                                 amount ->
-                                    val next = index + amount
-                                    if (next >= 0 && next < items.value.size) {
-                                        items.value = items.value.move(index, index + amount)
-                                    }
-                                }
-                            />
-                        }
-                    </LinearLayout>
-                </Observe>
-            }
-
-            @Composable
-            private fun Item(@Pivotal id: Int, onMove: (Int) -> Unit) {
-                <Observe>
-                    val count = +state { 0 }
-                    <LinearLayout orientation=LinearLayout.HORIZONTAL>
-                        <TextView id=(id+$tvId) text="id: ${'$'}id amt: ${'$'}{count.value}" />
-                        <Button id=(id+$btnIdAdd) text="+"  count.value++ } />
-                        <Button id=(id+$btnIdUp) text="Up"  onMove(1) } />
-                        <Button id=(id+$btnIdDown) text="Down"  onMove(-1) } />
-                    </LinearLayout>
-                </Observe>
-            }
-            """, { emptyMap<String, String>() },
-            """
-               <Reordering />
-            """
-        ).then { activity ->
-            // Click 5 add
-            val button = activity.findViewById(btnIdAdd + 5) as Button
-            button.performClick()
-        }.then { activity ->
-            // Click 5 down
-            val button = activity.findViewById(btnIdDown + 5) as Button
-            button.performClick()
-        }.then { activity ->
-            // Click 5 down
-            val button = activity.findViewById(btnIdDown + 5) as Button
-            button.performClick()
-        }.then { activity ->
-            // Click 5 up
-            val button = activity.findViewById(btnIdUp + 5) as Button
-            button.performClick()
-        }.then { activity ->
-            // Click 5 up
-            val button = activity.findViewById(btnIdUp + 5) as Button
-            button.performClick()
-        }.then { activity ->
-            // Click 5 add
-            val button = activity.findViewById(btnIdAdd + 5) as Button
-            button.performClick()
-        }.then { activity ->
-            val textView = activity.findViewById(tvId + 5) as TextView
-            assertEquals("id: 5 amt: 2", textView.text)
-        }
-    }
-
-    @Test
-    fun testObserveKtxWithInline(): Unit = ensureSetup {
-        compose(
-            """
-                @Composable
-                fun SimpleComposable() {
-                    val count = +state { 1 }
-                    <Box>
-                        repeat(count.value) {
-                            <Button text="Increment"  count.value += 1 } id=(41+it) />
-                        }
-                    </Box>
-                }
-
-                @Composable
-                fun Box(@Children children: ()->Unit) {
-                    <LinearLayout orientation=LinearLayout.VERTICAL>
-                        <children />
-                    </LinearLayout>
-                }
-            """, { emptyMap<String, String>() },
-            """
-               <SimpleComposable />
-            """
-        ).then { activity ->
-            val button = activity.findViewById(41) as Button
-            button.performClick()
-            button.performClick()
-            button.performClick()
-            button.performClick()
-            button.performClick()
-        }.then { activity ->
-            assertNotNull(activity.findViewById(46))
-        }
-    }
-
-    @Test
-    fun testKeyTag(): Unit = ensureSetup {
-        compose(
-            """
-            val list = mutableListOf(0,1,2,3)
-
-            @Composable
-            fun Reordering() {
-                <LinearLayout>
-                    <Recompose> recompose ->
-                        <Button id=50 text="Recompose!" >
-                          list.add(list.removeAt(0)); recompose();
-                         } />
-                        <LinearLayout id=100>
-                            for(id in list) {
-                                <Key key=id>
-                                    <StatefulButton />
-                                </Key>
-                            }
-                        </LinearLayout>
-                    </Recompose>
-                </LinearLayout>
-            }
-
-            @Composable
-            private fun StatefulButton() {
-                val count = +state { 0 }
-                <Button text="Clicked ${'$'}{count.value} times!"  count.value++ } />
-            }
-            """, { emptyMap<String, String>() },
-            """
-               <Reordering />
-            """
-        ).then { activity ->
-            val layout = activity.findViewById(100) as LinearLayout
-            layout.getChildAt(0).performClick()
-        }.then { activity ->
-            val recomposeButton = activity.findViewById(50) as Button
-            recomposeButton.performClick()
-        }.then { activity ->
-            val layout = activity.findViewById(100) as LinearLayout
-            assertEquals("Clicked 0 times!", (layout.getChildAt(0) as Button).text)
-            assertEquals("Clicked 0 times!", (layout.getChildAt(1) as Button).text)
-            assertEquals("Clicked 0 times!", (layout.getChildAt(2) as Button).text)
-            assertEquals("Clicked 1 times!", (layout.getChildAt(3) as Button).text)
-        }
-    }
-
-    override fun setUp() {
-        isSetup = true
-        super.setUp()
-    }
-
-    private var isSetup = false
-    private inline fun <T> ensureSetup(block: () -> T): T {
-        if (!isSetup) setUp()
-        return block()
-    }
-
-    fun codegen(text: String, dumpClasses: Boolean = false): Unit = ensureSetup {
-        val className = "Test_${uniqueNumber++}"
-        val fileName = "$className.kt"
-
-        classLoader(
-            """
-           import android.content.Context
-           import android.widget.*
-           import androidx.compose.*
-
-           $text
-
-        """, fileName, dumpClasses
-        )
-    }
-
-    fun compose(text: String, dumpClasses: Boolean = false): CompositionTest =
-        compose({ mapOf<String, Any>() }, text, dumpClasses)
-
-    fun <T : Any> compose(
-        valuesFactory: () -> Map<String, T>,
-        text: String,
-        dumpClasses: Boolean = false
-    ) = compose("", valuesFactory, text, dumpClasses)
-
-    private fun execute(block: () -> Unit) {
-        val scheduler = RuntimeEnvironment.getMasterScheduler()
-        scheduler.pause()
-        block()
-        scheduler.advanceToLastPostedRunnable()
-    }
-
-    fun <T : Any> compose(
-        prefix: String,
-        valuesFactory: () -> Map<String, T>,
-        text: String,
-        dumpClasses: Boolean = false
-    ): CompositionTest {
-        val className = "Test_${uniqueNumber++}"
-        val fileName = "$className.kt"
-
-        val candidateValues = valuesFactory()
-
-        @Suppress("NO_REFLECTION_IN_CLASS_PATH")
-        val parameterList = candidateValues.map {
-            "${it.key}: ${it.value::class.qualifiedName}"
-        }.joinToString()
-        val parameterTypes = candidateValues.map {
-            it.value::class.javaPrimitiveType
-                ?: it.value::class.javaObjectType
-        }.toTypedArray()
-
-        val compiledClasses = classLoader(
-            """
-           import android.content.Context
-           import android.widget.*
-           import androidx.compose.*
-           import androidx.compose.adapters.*
-           import androidx.ui.androidview.adapters.*
-
-           $prefix
-
-           class $className {
-
-             fun test($parameterList) {
-               $text
-             }
-           }
-        """, fileName, dumpClasses
-        )
-
-        val allClassFiles =
-            compiledClasses.allGeneratedFiles.filter { it.relativePath.endsWith(".class") }
-
-        val loader = URLClassLoader(emptyArray(), this.javaClass.classLoader)
-
-        val instanceClass = run {
-            var instanceClass: Class<*>? = null
-            var loadedOne = false
-            for (outFile in allClassFiles) {
-                val bytes = outFile.asByteArray()
-                val loadedClass = loadClass(loader, null, bytes)
-                if (loadedClass.name == className) instanceClass = loadedClass
-                loadedOne = true
-            }
-            if (!loadedOne) error("No classes loaded")
-            instanceClass ?: error("Could not find class $className in loaded classes")
-        }
-
-        val instanceOfClass = instanceClass.newInstance()
-        val testMethod = instanceClass.getMethod("test", *parameterTypes)
-
-        return compose {
-            val values = valuesFactory()
-            val arguments = values.map { it.value as Any }.toTypedArray()
-            testMethod.invoke(instanceOfClass, *arguments)
-        }
-    }
-}
-
-var uniqueNumber = 0
-
-fun loadClass(loader: ClassLoader, name: String?, bytes: ByteArray): Class<*> {
-    val defineClassMethod = ClassLoader::class.javaObjectType.getDeclaredMethod(
-        "defineClass",
-        String::class.javaObjectType,
-        ByteArray::class.javaObjectType,
-        Int::class.javaPrimitiveType,
-        Int::class.javaPrimitiveType
-    )
-    defineClassMethod.isAccessible = true
-    return defineClassMethod.invoke(loader, name, bytes, 0, bytes.size) as Class<*>
-}
-
-const val ROOT_ID = 18284847
-
-private class TestActivity : Activity() {
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        setContentView(LinearLayout(this).apply { id = ROOT_ID })
-    }
-}
-
-private val Activity.root get() = findViewById(ROOT_ID) as ViewGroup
-
-private class Root(val composable: () -> Unit) : Component() {
-    override fun compose() = composable()
-}
-
-class CompositionTest(val composable: () -> Unit) {
-
-    inner class ActiveTest(val activity: Activity, val cc: CompositionContext) {
-        fun then(block: (activity: Activity) -> Unit): ActiveTest {
-            val scheduler = RuntimeEnvironment.getMasterScheduler()
-            scheduler.advanceToLastPostedRunnable()
-            cc.compose()
-            scheduler.advanceToLastPostedRunnable()
-            block(activity)
-            return this
-        }
-    }
-
-    fun then(block: (activity: Activity) -> Unit): ActiveTest {
-        val scheduler = RuntimeEnvironment.getMasterScheduler()
-        scheduler.pause()
-        val controller = Robolectric.buildActivity(TestActivity::class.java)
-        val activity = controller.create().get()
-        val root = activity.root
-        val component = Root(composable)
-        val cc = Compose.createCompositionContext(root.context, root, component, null)
-        return ActiveTest(activity, cc).then(block)
-    }
-}
-
-fun compose(composable: () -> Unit) = CompositionTest(composable)
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCrossModuleTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCrossModuleTests.kt
index c35a9ad..2aec6de 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCrossModuleTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxCrossModuleTests.kt
@@ -47,6 +47,120 @@
 class KtxCrossModuleTests : AbstractCodegenTest() {
 
     @Test
+    fun testCrossModule_SimpleCompositionxxx(): Unit = ensureSetup {
+        val tvId = 29
+
+        compose(
+            "TestF", mapOf(
+                "library module" to mapOf(
+                    "my/test/lib/InternalComp.kt" to """
+                    package my.test.lib
+
+                import androidx.compose.Composable
+                import androidx.compose.composer
+                import androidx.compose.Emittable
+                import androidx.ui.core.DataNode
+                import androidx.ui.core.ParentData
+                import androidx.ui.core.ParentDataKey
+
+                class Bar
+
+                class XDataNodeKey<T>(val name: String)
+
+                class XDataNode<T>(var key: XDataNodeKey<T>, var value: T) : Emittable {
+                    override fun emitInsertAt(index: Int, instance: Emittable) {
+
+                    }
+
+                    override fun emitRemoveAt(index: Int, count: Int) {
+
+                    }
+
+                    override fun emitMove(from: Int, to: Int, count: Int) {
+
+                    }
+                }
+
+                val Key1 = XDataNodeKey<String>("foo")
+                val Key2 = XDataNodeKey<Bar>("bar")
+
+        class ViewEmitWrapper(context: android.content.Context) : android.view.View(context) {
+            var emittable: Emittable? = null
+        }
+
+        class EmitViewWrapper : Emittable {
+            var view: android.view.View? = null
+            override fun emitInsertAt(index: Int, instance: Emittable) {
+
+            }
+
+            override fun emitRemoveAt(index: Int, count: Int) {
+
+            }
+
+            override fun emitMove(from: Int, to: Int, count: Int) {
+
+            }
+        }
+
+                 """
+                ),
+                "Main" to mapOf(
+                    "my/test/app/Main.kt" to """
+                   package my.test.app
+
+                   import android.widget.*
+                   import androidx.compose.*
+                   import my.test.lib.*
+
+                   var doRecompose: () -> Unit = {}
+
+                   class TestF {
+                       @Composable
+                       fun compose() {
+
+                       composer.registerAdapter { parent, child ->
+                            when (parent) {
+                                is android.view.ViewGroup -> when (child) {
+                                    is android.view.View -> child
+                                    is Emittable -> ViewEmitWrapper(composer.composer.context).apply { 
+                                    emittable = child }
+                                    else -> null
+                                }
+                                is Emittable -> when (child) {
+                                    is android.view.View -> EmitViewWrapper().apply { view = child }
+                                    is Emittable -> child
+                                    else -> null
+                                }
+                                else -> null
+                            }
+                        }
+
+                         Recompose { recompose ->
+                           Foo()
+                         }
+                       }
+
+                       fun advance() {
+                         doRecompose()
+                       }
+                   }
+
+                   @Composable
+                   fun Foo() {
+                    val s = ""
+                    val b = Bar()
+                    XDataNode(key = Key2, value = b)
+                   }
+                """
+                )
+            )
+        ).then { activity ->
+            assert(true)
+        }
+    }
+
+    @Test
     fun testCrossModule_SimpleComposition(): Unit = ensureSetup {
         val tvId = 29
 
@@ -58,11 +172,8 @@
 
                     import androidx.compose.*
 
-                    class InternalComp(@Children var block: () -> Unit) : Component() {
-
-                      override fun compose() {
-                        <block />
-                      }
+                    @Composable fun InternalComp(block: @Composable() () -> Unit) {
+                        block()
                     }
                  """
                 ),
@@ -80,10 +191,10 @@
                    class TestF {
                        @Composable
                        fun compose() {
-                         <Recompose> recompose ->
+                         Recompose { recompose ->
                            doRecompose = recompose
-                           <Foo bar />
-                         </Recompose>
+                           Foo(bar)
+                         }
                        }
 
                        fun advance() {
@@ -94,9 +205,9 @@
 
                    @Composable
                    fun Foo(bar: Int) {
-                     <InternalComp>
-                       <TextView text="${'$'}bar" id=$tvId />
-                     </InternalComp>
+                     InternalComp {
+                       TextView(text="${'$'}bar", id=$tvId)
+                     }
                    }
                 """
                 )
@@ -126,10 +237,10 @@
 
                        @Composable
                        fun ComponentFunction(name: String, age: Int) {
-                         <LinearLayout>
-                           <TextView text=name id=$tvName />
-                           <TextView text="${'$'}age" id=$tvAge />
-                         </LinearLayout>
+                         LinearLayout {
+                           TextView(text=name, id=$tvName)
+                           TextView(text="${'$'}age", id=$tvAge)
+                         }
                        }
                  """
                 ),
@@ -148,10 +259,10 @@
                        class TestF {
                            @Composable
                            fun compose() {
-                             <Recompose> recompose ->
+                             Recompose { recompose ->
                                doRecompose = recompose
-                               <Foo name age />
-                             </Recompose>
+                               Foo(name=name, age=age)
+                             }
                            }
 
                            fun advance() {
@@ -163,7 +274,7 @@
 
                        @Composable
                        fun Foo(name: String, age: Int) {
-                         <ComponentFunction name age />
+                         ComponentFunction(name, age)
                        }
                     """
                 )
@@ -198,10 +309,10 @@
                        object Container {
                            @Composable
                            fun ComponentFunction(name: String, age: Int) {
-                             <LinearLayout>
-                               <TextView text=name id=$tvName />
-                               <TextView text="${'$'}age" id=$tvAge />
-                             </LinearLayout>
+                             LinearLayout {
+                               TextView(text=name, id=$tvName)
+                               TextView(text="${'$'}age", id=$tvAge)
+                             }
                            }
                        }
                  """
@@ -221,10 +332,10 @@
                        class TestF {
                            @Composable
                            fun compose() {
-                             <Recompose> recompose ->
+                             Recompose { recompose ->
                                doRecompose = recompose
-                               <Foo name age />
-                             </Recompose>
+                               Foo(name, age)
+                             }
                            }
 
                            fun advance() {
@@ -236,7 +347,7 @@
 
                        @Composable
                        fun Foo(name: String, age: Int) {
-                         <Container.ComponentFunction name age />
+                         Container.ComponentFunction(name, age)
                        }
                     """
                 )
@@ -254,157 +365,6 @@
         }
     }
 
-    @Test
-    fun testCrossModule_ConstructorProperties(): Unit = ensureSetup {
-        val tvId = 29
-
-        compose(
-            "TestF", mapOf(
-                "library module" to mapOf(
-                    "my/test/lib/MyComponent.kt" to """
-                    package my.test.lib
-
-                    import androidx.compose.*
-
-                    class MyComponent(
-                        var a: Int,
-                        var b: String,
-                        @Children var children: (a: Int, b: String)->Unit
-                    ) : Component() {
-
-                      override fun compose() {
-                        <children a b />
-                      }
-                    }
-                 """
-                ),
-                "Main" to mapOf(
-                    "my/test/app/Main.kt" to """
-                   package my.test.app
-
-                   import android.widget.*
-                   import androidx.compose.*
-                   import my.test.lib.*
-
-                   var bar = 0
-                   var doRecompose: () -> Unit = {}
-
-                   class TestF {
-                       @Composable
-                       fun compose() {
-                         <Recompose> recompose ->
-                           doRecompose = recompose
-                           <Foo bar />
-                         </Recompose>
-                       }
-
-                       fun advance() {
-                         bar++
-                         doRecompose()
-                       }
-                   }
-
-                   @Composable
-                   fun Foo(bar: Int) {
-                     <MyComponent b="SomeValue" a=bar> c, d ->
-                       <TextView text="${'$'}d: ${'$'}c" id=$tvId />
-                     </MyComponent>
-                   }
-                """
-                )
-            )
-        ).then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("SomeValue: 0", tv.text)
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("SomeValue: 1", tv.text)
-        }
-    }
-
-    @Test
-    fun testCrossModule_ConstructorParameters(): Unit = ensureSetup {
-        val tvId = 29
-
-        compose(
-            "TestF", mapOf(
-                "library module" to mapOf(
-                    "my/test/lib/MyComponent.kt" to """
-                    package my.test.lib
-
-                    import androidx.compose.*
-
-                    class MyComponent(
-                      a: Int,
-                      b: String,
-                      @Children var children: (a: Int, b: String)->Unit
-                    ) : Component() {
-                      val aValue = a
-                      val bValue = b
-
-                      override fun compose() {
-                        <children a=aValue b=bValue />
-                      }
-                    }
-                 """
-                ),
-                "Main" to mapOf(
-                    "my/test/app/Main.kt" to """
-                   package my.test.app
-
-                   import android.widget.*
-                   import androidx.compose.*
-                   import my.test.lib.*
-
-                   var bar = 0
-                   var doRecompose: () -> Unit = {}
-
-                    class MyComponent(
-                      a: Int,
-                      b: String,
-                      @Children var children: (a: Int, b: String)->Unit
-                    ) : Component() {
-                      val aValue = a
-                      val bValue = b
-
-                      override fun compose() {
-                        <children a=aValue b=bValue />
-                      }
-                    }
-
-                   class TestF {
-                       @Composable
-                       fun compose() {
-                         <Recompose> recompose ->
-                           doRecompose = recompose
-                           <Foo bar />
-                         </Recompose>
-                       }
-
-                       fun advance() {
-                         bar++
-                         doRecompose()
-                       }
-                   }
-
-                   @Composable
-                   fun Foo(bar: Int) {
-                     <MyComponent b="SomeValue" a=bar> c, d ->
-                       <TextView text="${'$'}d: ${'$'}c" id=$tvId />
-                     </MyComponent>
-                   }
-                """
-                )
-            )
-        ).then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("SomeValue: 0", tv.text)
-        }.then { activity ->
-            val tv = activity.findViewById(tvId) as TextView
-            assertEquals("SomeValue: 1", tv.text)
-        }
-    }
-
     fun compose(
         mainClassName: String,
         modules: Map<String, Map<String, String>>,
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxModelCodeGenTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxModelCodeGenTests.kt
index f5aca24..b031da3 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxModelCodeGenTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxModelCodeGenTests.kt
@@ -79,10 +79,10 @@
 
             @Composable
             fun PersonView4(person: Person4) {
-              <Observe>
-                <TextView text=person.name id=$tvNameId />
-                <TextView text=person.age.toString() id=$tvAgeId />
-              </Observe>
+              Observe {
+                TextView(text=person.name, id=$tvNameId)
+                TextView(text=person.age.toString(), id=$tvAgeId)
+              }
             }
 
             val president = Person4("$PRESIDENT_NAME_1", $PRESIDENT_AGE_1)
@@ -90,7 +90,7 @@
                president.name = name
                president.age = age
             """, """
-                <PersonView4 person=president />
+                PersonView4(person=president)
             """).then { activity ->
             val tvName = activity.findViewById(tvNameId) as TextView
             val tvAge = activity.findViewById(tvAgeId) as TextView
@@ -124,18 +124,17 @@
 
             @Composable
             fun PresidentView() {
-              <Observe>
-                <TextView text=president.name id=$tvNameId />
-                <TextView text=president.age.toString() id=$tvAgeId />
-              </Observe>
+              Observe {
+                TextView(text=president.name, id=$tvNameId)
+                TextView(text=president.age.toString(), id=$tvAgeId)
+              }
             }
 
-
             """, { mapOf("name" to name, "age" to age) }, """
                president.name = name
                president.age = age
             """, """
-                <PresidentView />
+                PresidentView()
             """).then { activity ->
             val tvName = activity.findViewById(tvNameId) as TextView
             val tvAge = activity.findViewById(tvAgeId) as TextView
@@ -166,10 +165,10 @@
 
             @Composable
             fun PersonViewB(person: PersonB) {
-              <Observe>
-                <TextView text=person.name id=$tvNameId />
-                <TextView text=person.age.toString() id=$tvAgeId />
-              </Observe>
+              Observe {
+                TextView(text=person.name, id=$tvNameId)
+                TextView(text=person.age.toString(), id=$tvAgeId)
+              }
             }
 
             val president = PersonB("$PRESIDENT_NAME_1", $PRESIDENT_AGE_1)
@@ -177,7 +176,7 @@
                president.name = name
                president.age = age
             """, """
-                <PersonViewB person=president />
+                PersonViewB(person=president)
             """).then { activity ->
             val tvName = activity.findViewById(tvNameId) as TextView
             val tvAge = activity.findViewById(tvAgeId) as TextView
@@ -208,10 +207,10 @@
 
             @Composable
             fun PersonViewC(person: PersonC) {
-              <Observe>
-                <TextView text=person.name id=$tvNameId />
-                <TextView text=person.age.toString() id=$tvAgeId />
-              </Observe>
+              Observe {
+                TextView(text=person.name, id=$tvNameId)
+                TextView(text=person.age.toString(), id=$tvAgeId)
+              }
             }
 
             val president = FrameManager.unframed { PersonC("$PRESIDENT_NAME_1", $PRESIDENT_AGE_1) }
@@ -219,7 +218,7 @@
                president.name = name
                president.age = age
             """, """
-                <PersonViewC person=president />
+                PersonViewC(person=president)
             """).then { activity ->
             val tvName = activity.findViewById(tvNameId) as TextView
             val tvAge = activity.findViewById(tvAgeId) as TextView
@@ -250,10 +249,10 @@
 
             @Composable
             fun PersonViewD(person: PersonD) {
-              <Observe>
-                <TextView text=person.name id=$tvNameId />
-                <TextView text=person.age.toString() id=$tvAgeId />
-              </Observe>
+              Observe {
+                TextView(text=person.name, id=$tvNameId)
+                TextView(text=person.age.toString(), id=$tvAgeId)
+              }
             }
 
             val president = FrameManager.framed { PersonD("$PRESIDENT_NAME_1", $PRESIDENT_AGE_1).apply { age = $PRESIDENT_AGE_1 } }
@@ -261,7 +260,7 @@
                president.name = name
                president.age = age
             """, """
-                <PersonViewD person=president />
+                PersonViewD(person=president)
             """).then { activity ->
             val tvName = activity.findViewById(tvNameId) as TextView
             val tvAge = activity.findViewById(tvAgeId) as TextView
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt
index e918f5e..f4a2054 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt
@@ -31,12 +31,12 @@
 
             @Composable
             fun SimpleComposable() {
-                <FancyButton state=FancyButtonData() />
+                FancyButton(state=FancyButtonData())
             }
 
             @Composable
             fun FancyButton(state: FancyButtonData) {
-               <Button text=("Clicked "+state.x+" times")  id=42 />
+               Button(text=("Clicked "+state.x+" times"),  id=42)
             }
         """
     )
@@ -60,7 +60,7 @@
         class Foo {
             @Composable
             operator fun invoke() {
-                <TextView />
+                TextView()
             }
         }
         """
@@ -74,9 +74,9 @@
         class Foo {
             @Composable
             operator fun invoke() {
-                <TextView />
-                <TextView />
-                <TextView />
+                TextView()
+                TextView()
+                TextView()
             }
         }
         """
@@ -90,13 +90,13 @@
         class Foo {
             @Composable
             operator fun invoke() {
-                <LinearLayout>
-                    <TextView />
-                    <LinearLayout>
-                        <TextView />
-                        <TextView />
-                    </LinearLayout>
-                </LinearLayout>
+                LinearLayout {
+                    TextView()
+                    LinearLayout {
+                        TextView()
+                        TextView()
+                    }
+                }
             }
         }
         """
@@ -106,15 +106,13 @@
         """
          import androidx.compose.*
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
 
         class Foo {
             @Composable
             operator fun invoke() {
-                <Bar />
+                Bar()
             }
         }
         """
@@ -124,17 +122,15 @@
         """
          import androidx.compose.*
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
 
         class Foo {
             @Composable
             operator fun invoke() {
-                <Bar />
-                <Bar />
-                <Bar />
+                Bar()
+                Bar()
+                Bar()
             }
         }
         """
@@ -145,58 +141,15 @@
         import androidx.compose.*
         import android.widget.*
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
 
         class Foo {
             @Composable
             operator fun invoke() {
-                <LinearLayout>
-                    <Bar />
-                </LinearLayout>
-            }
-        }
-        """
-    )
-
-    fun testAttributes() = testCompile(
-        """
-         import androidx.compose.*
-        import android.widget.*
-
-        class Bar {
-            var num: Int = 0
-            var a: String = ""
-            var b: String = ""
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Foo {
-            @Composable
-            operator fun invoke() {
-                val s = "foo" + "bar"
-                <LinearLayout orientation=LinearLayout.VERTICAL>
-                    <Bar num=123 a=s b="const" />
-                </LinearLayout>
-            }
-        }
-        """
-    )
-
-    // NOTE: test the key attribute separately as it receives different handling.
-    // TODO(lmr): add test in compose-runtime around behavior of this attribute
-    fun testKeyAttributes() = testCompile(
-        """
-         import androidx.compose.*
-
-        class Foo {
-            var key: Int = 0
-            @Composable
-            operator fun invoke() {
-                <Foo key=123 />
+                LinearLayout {
+                    Bar()
+                }
             }
         }
         """
@@ -206,16 +159,14 @@
         """
          import androidx.compose.*
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
 
         class Foo {
             @Composable
             operator fun invoke() {
                 listOf(1, 2, 3).forEach {
-                    <Bar />
+                    Bar()
                 }
             }
         }
@@ -226,16 +177,14 @@
         """
          import androidx.compose.*
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
 
         class Foo {
             @Composable
             operator fun invoke() {
                 for (i in listOf(1, 2, 3)) {
-                    <Bar />
+                    Bar()
                 }
             }
         }
@@ -246,10 +195,8 @@
         """
          import androidx.compose.*
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
 
         class Foo {
             var visible: Boolean = false
@@ -257,7 +204,7 @@
             operator fun invoke() {
                 if (!visible) return
                 else "" // TODO: Remove this line when fixed upstream
-                <Bar />
+                Bar()
             }
         }
         """
@@ -266,26 +213,21 @@
     fun testConditionalRendering() = testCompile(
         """
          import androidx.compose.*
-        import java.util.Random
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
 
-        class Bam {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bam() {}
 
         class Foo {
             var visible: Boolean = false
             @Composable
             operator fun invoke() {
                 if (!visible) {
-                    <Bar />
+                    Bar()
                 } else {
-                    <Bam />
+                    Bam()
                 }
             }
         }
@@ -296,94 +238,18 @@
         """
         import androidx.compose.*
 
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Bar() {}
+
         class Foo {
             @Composable
             operator fun invoke() {
                 val foo = object: Function0<Unit> {
                     override fun invoke() {
-                        <Bar />
+                        Bar()
                     }
                 }
-                <foo />
-            }
-        }
-        """
-    )
-
-    fun testFunctionInstanceMultipleArgs() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
-        class Foo {
-            @Composable
-            operator fun invoke() {
-                val foo = object: Function2<@kotlin.ParameterName("x") String,
-                  @kotlin.ParameterName("y")Int, Unit> {
-                    override fun invoke(x: String, y: Int) {
-                        <Bar />
-                    }
-                }
-                <foo x="foo" y=123 />
-            }
-        }
-        """
-    )
-
-    fun testComposeAttribute() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
-        class Foo {
-            lateinit var children: () -> Unit
-            @Composable
-            operator fun invoke() {
-                val children = children
-                <children />
-            }
-        }
-        """
-    )
-
-    fun testComposeWithParamsAttribute() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Bar {
-            @Composable
-            operator fun invoke() {}
-        }
-        class Foo {
-            lateinit var children: (x: Int) -> Unit
-            @Composable
-            operator fun invoke() {
-                val children = children
-                <children x=123 />
-            }
-        }
-        """
-    )
-
-    fun testComposeAttributeFunctionType() = testCompile(
-        """
-        import androidx.compose.*
-
-        class X {
-            lateinit var composeItem: Function1<@kotlin.ParameterName("arg0") Int, Unit>
-            fun fn() {
-                val composeItem = composeItem
-                <composeItem arg0=123 />
+                foo()
             }
         }
         """
@@ -400,36 +266,7 @@
         class X {
             @Composable
             operator fun invoke() {
-                <LinearLayout someExtension=123 />
-            }
-        }
-        """
-    )
-
-    fun testChildrenOfComponent() = testCompile(
-        """
-        import android.widget.*
-        import androidx.compose.*
-
-        class HelperComponent {
-            private lateinit var children: () -> Unit
-
-            @Children
-            fun setChildren2(x: () -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                <children />
-            }
-        }
-
-        class MainComponent {
-            var name = "World"
-            @Composable
-            operator fun invoke() {
-                <HelperComponent>
-                    <TextView text="some child content2!" />
-                    <TextView text="some child content!3" />
-                </HelperComponent>
+                LinearLayout(someExtension=123)
             }
         }
         """
@@ -440,56 +277,21 @@
         import android.widget.*
         import androidx.compose.*
 
-        class HelperComponent {
-            private lateinit var children: (title: String, rating: Int) -> Unit
-            @Children fun setChildren2(x: (title: String, rating: Int) -> Unit) { children = x }
-
-            @Composable
-            operator fun invoke() {
-                val children = this.children
-                <children title="Hello World!" rating=5 />
-                <children title="Kompose is awesome!" rating=5 />
-                <children title="Bitcoin!" rating=4 />
-            }
+        @Composable fun HelperComponent(
+            children: @Composable() (title: String, rating: Int) -> Unit
+        ) {
+            children("Hello World!", 5)
+            children("Kompose is awesome!", 5)
+            children("Bitcoin!", 4)
         }
 
         class MainComponent {
             var name = "World"
             @Composable
             operator fun invoke() {
-                <HelperComponent> title: String, rating: Int ->
-                    <TextView text=(title+" ("+rating+" stars)") />
-                </HelperComponent>
-            }
-        }
-        """
-    )
-
-    fun testChildrenWithUntypedParameters() = testCompile(
-        """
-        import android.widget.*
-        import androidx.compose.*
-
-        class HelperComponent {
-            private lateinit var children: (title: String, rating: Int) -> Unit
-
-            @Children
-            fun setChildren2(x: (title: String, rating: Int) -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                <children title="Hello World!" rating=5 />
-                <children title="Kompose is awesome!" rating=5 />
-                <children title="Bitcoin!" rating=4 />
-            }
-        }
-
-        class MainComponent {
-            var name = "World"
-            @Composable
-            operator fun invoke() {
-                <HelperComponent> title, rating ->
-                    <TextView text=(title+" ("+rating+" stars)") />
-                </HelperComponent>
+                HelperComponent { title: String, rating: Int ->
+                    TextView(text=(title+" ("+rating+" stars)"))
+                }
             }
         }
         """
@@ -500,14 +302,7 @@
         import android.widget.*
         import androidx.compose.*
 
-        class HelperComponent {
-            lateinit private var children: () -> Unit
-            @Children
-            fun setChildren2(x: () -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                val children = this.children
-            }
+        @Composable fun HelperComponent(children: @Composable() () -> Unit) {
         }
 
         class MainComponent {
@@ -515,9 +310,9 @@
             @Composable
             operator fun invoke() {
                 val childText = "Hello World!"
-                <HelperComponent>
-                    <TextView text=childText />
-                </HelperComponent>
+                HelperComponent {
+                    TextView(text=childText + name)
+                }
             }
         }
         """
@@ -528,24 +323,12 @@
         import android.widget.*
         import androidx.compose.*
 
-        class A {
-            lateinit private var children: () -> Unit
-            @Children
-            fun setChildren2(x: () -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                val children = this.children
-            }
+        @Composable fun A(children: @Composable() () -> Unit) {
+            children()
         }
 
-        class B {
-            lateinit private var children: () -> Unit
-            @Children
-            fun setChildren2(x: () -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                val children = this.children
-            }
+        @Composable fun B(children: @Composable() () -> Unit) {
+            children()
         }
 
         class MainComponent {
@@ -553,11 +336,11 @@
             @Composable
             operator fun invoke() {
                 val childText = "Hello World!"
-                <A>
-                    <B>
-                        println(childText)
-                    </B>
-                </A>
+                A {
+                    B {
+                        println(childText + name)
+                    }
+                }
             }
         }
         """
@@ -568,24 +351,12 @@
         import android.widget.*
         import androidx.compose.*
 
-        class A {
-            lateinit private var children: (String) -> Unit
-            @Children
-            fun setChildren2(x: (String) -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                val children = this.children
-            }
+        @Composable fun A(children: @Composable() (x: String) -> Unit) {
+            children("")
         }
 
-        class B {
-            lateinit private var children: (String) -> Unit
-            @Children
-            fun setChildren2(x: (String) -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                val children = this.children
-            }
+        @Composable fun B(children: @Composable() (y: String) -> Unit) {
+            children("")
         }
 
         class MainComponent {
@@ -593,11 +364,11 @@
             @Composable
             operator fun invoke() {
                 val childText = "Hello World!"
-                <A> x ->
-                    <B> y ->
-                        println(childText + x + y)
-                    </B>
-                </A>
+                A { x ->
+                    B { y ->
+                        println(childText + name + x + y)
+                    }
+                }
             }
         }
         """
@@ -611,10 +382,10 @@
         class MainComponent {
             @Composable
             operator fun invoke() {
-                <LinearLayout>
-                    <TextView text="some child content2!" />
-                    <TextView text="some child content!3" />
-                </LinearLayout>
+                LinearLayout {
+                    TextView(text="some child content2!")
+                    TextView(text="some child content!3")
+                }
             }
         }
         """
@@ -625,54 +396,29 @@
         import android.widget.*
         import androidx.compose.*
 
-        class HelperComponent {
-            private lateinit var children: () -> Unit
-            @Children
-            fun setChildren2(x: () -> Unit) { children = x }
-            @Composable
-            operator fun invoke() {
-                val children = this.children
-            }
-        }
+        @Composable fun HelperComponent(children: @Composable() () -> Unit) {}
 
         class MainComponent {
             @Composable
             operator fun invoke() {
                 val x = "Hello"
                 val y = "World"
-                <HelperComponent>
+                HelperComponent {
                     for(i in 1..100) {
-                        <TextView text=(x+y+i) />
+                        TextView(text=x+y+i)
                     }
-                    Unit // NOTE(lmr): this Unit is needed here but it's a general compiler bug,
-                         // not our bug. Remove when fixed.
-                </HelperComponent>
+                }
             }
         }
         """
     )
 
-    fun testForLoopIrBug() = testCompile(
-        """
-        var z = {
-            for (i in 1..100) {
-                print("wat")
-            }
-            Unit // NOTE(lmr): this Unit is needed here but it's a general compiler bug,
-                 // not our bug. Remove when fixed.
-        }
-        """
-    )
-
     fun testGenericsInnerClass() = testCompile(
         """
         import androidx.compose.*
 
         class A<T>(val value: T) {
-            inner class Getter {
-                var x: T? = null
-                @Composable
-                operator fun invoke() {}
+            @Composable fun Getter(x: T? = null) {
             }
         }
 
@@ -680,26 +426,7 @@
             val a = A(123)
 
             // a.Getter() here has a bound type argument through A
-            <a.Getter x=456 />
-        }
-        """
-    )
-
-    fun testXGenericInnerClassConstructor() = testCompile(
-        """
-        import androidx.compose.*
-
-        class A<T>(val value: T) {
-            inner class C {
-                @Composable
-                operator fun invoke() {}
-            }
-        }
-
-        fun doStuff() {
-            val B = A(123)
-
-            <B.C />
+            a.Getter(x=456)
         }
         """
     )
@@ -708,27 +435,25 @@
         """
         import androidx.compose.*
 
-        class A<T>(
-            val value: T
+        @Composable fun <T> A(
+            value: T,
+            list: List<T>? = null
         ) {
-            var list2: List<T>? = null
-            fun setList(list: List<T>) {}
-            @Composable
-            operator fun invoke() {}
+
         }
 
+        @Composable
         fun doStuff() {
             val x = 123
 
             // we can create element with just value, no list
-            <A value=x />
+            A(value=x)
 
             // if we add a list, it can infer the type
-            <A
-                value=x
+            A(
+                value=x,
                 list=listOf(234, x)
-                list2=listOf(234, x)
-            />
+            )
         }
         """
     )
@@ -737,172 +462,12 @@
         """
         import androidx.compose.*
 
-        class Simple {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Simple() {}
 
+        @Composable
         fun run() {
-            <Simple />
-        }
-        """
-    )
-
-    fun testSimpleVarInConstructor() = testCompile(
-        """
-        import androidx.compose.*
-
-        class SimpleConstructorArg(var foo: String) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run() {
-            <SimpleConstructorArg foo="string" />
-        }
-        """
-    )
-
-    fun testLateInitProp() = testCompile(
-        """
-        import androidx.compose.*
-
-        class SimpleLateInitArg {
-            lateinit var foo: String
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run() {
-            <SimpleLateInitArg foo="string" />
-        }
-        """
-    )
-
-    fun testGenericCtorArg() = testCompile(
-        """
-        import androidx.compose.*
-
-        class GenericCtorArg<T>(var foo: T) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run() {
-            <GenericCtorArg foo="string" />
-            <GenericCtorArg foo=123 />
-        }
-        """
-    )
-
-    fun testPropsAndSettersAndExtensionSetters() = testCompile(
-        """
-        import androidx.compose.*
-
-        class OneArg {
-            var bar: String? = null
-            var baz: String? = null
-            fun setBam(bam: String) {
-                bar = bam
-            }
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun OneArg.setJazz(x: String) {}
-
-        fun OneArg.setJazz(y: Int) {}
-
-        fun run() {
-            <OneArg bar="string" />
-            val bar = "string"
-            val num = 123
-            <OneArg
-                bar
-                baz=bar
-                bam=bar
-                jazz=num
-            />
-        }
-        """
-    )
-
-    fun testGenericAttribute() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Simple {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Ref<T> {
-            var value: T? = null
-        }
-
-        fun <T: Any> T.setRef(ref: Ref<T>) {
-
-        }
-
-        fun run() {
-            val ref = Ref<Simple>()
-            <Simple ref=ref />
-        }
-        """
-    )
-
-    fun testSimpleFunctionComponent() = testCompile(
-        """
-        import androidx.compose.*
-
-        fun OneArg(foo: String) {}
-
-        fun run() {
-            <OneArg foo="string" />
-        }
-        """
-    )
-
-    fun testOverloadedFunctions() = testCompile(
-        """
-        import androidx.compose.*
-
-        fun OneArg(foo: String) {}
-        fun OneArg(foo: Int) {}
-
-        fun run() {
-            <OneArg foo=("string") />
-            <OneArg foo=123 />
-        }
-        """
-    )
-
-    fun testConstructorVal() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Foo(val x: Int) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run() {
-            <Foo x=123 />
-        }
-        """
-    )
-
-    fun testConstructorNonPropertyParam() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Foo(x: Int) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run() {
-            <Foo x=123 />
+            Simple()
         }
         """
     )
@@ -912,14 +477,13 @@
         import androidx.compose.*
 
         object Obj {
-            class B {
-                @Composable
-                operator fun invoke() {}
-            }
+            @Composable
+            fun B() {}
         }
 
+        @Composable
         fun run() {
-            <Obj.B />
+            Obj.B()
         }
         """
     )
@@ -928,65 +492,9 @@
         """
         import androidx.compose.*
 
+        @Composable
         fun run() {
-            <android.widget.TextView text="bar" />
-        }
-        """
-    )
-
-    fun testDotQualifiedClassToClass() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Y {
-            class Z {
-                class F {
-                    @Composable
-                    operator fun invoke() {}
-                }
-            }
-        }
-
-        fun run() {
-            <Y.Z.F />
-        }
-        """
-    )
-
-    fun testInnerClass() = testCompile(
-        """
-        import androidx.compose.*
-
-        class A(var foo: String) {
-            inner class B(var bar: String) {
-                @Composable
-                operator fun invoke() {}
-            }
-        }
-
-        fun run() {
-            val X = A("string")
-            <X.B bar="string" />
-        }
-        """
-    )
-
-    fun testGenericInnerClass() = testCompile(
-        """
-        import androidx.compose.*
-
-        class A<T>(var foo: T) {
-            inner class B(var bar: T) {
-                @Composable
-                operator fun invoke() {}
-            }
-        }
-
-        fun run() {
-            val X = A("string")
-            val Y = A(123)
-            <X.B bar="string" />
-            <Y.B bar=123 />
+            android.widget.TextView(text="bar")
         }
         """
     )
@@ -995,14 +503,12 @@
         """
         import androidx.compose.*
 
-        class Simple {
-            @Composable
-            operator fun invoke() {}
-        }
+        @Composable
+        fun Simple() {}
 
         fun run() {
-            val foo = { <Simple /> }
-            <foo />
+            val foo = @Composable { Simple() }
+            foo()
         }
         """
     )
@@ -1011,10 +517,10 @@
         """
         import androidx.compose.*
 
-        class Test(var children: () -> Unit) {
+        class Test(var children: @Composable () () -> Unit) {
             @Composable
             operator fun invoke() {
-                <children />
+                children()
             }
         }
         """
@@ -1024,10 +530,10 @@
         """
         import androidx.compose.*
 
-        class Test(var children: (x: Int) -> Unit) {
+        class Test(var children: @Composable() (x: Int) -> Unit) {
             @Composable
             operator fun invoke() {
-                <children x=123 />
+                children(x=123)
             }
         }
         """
@@ -1038,275 +544,46 @@
         import androidx.compose.*
 
         class Test {
+            @Composable
             fun doStuff() {}
             @Composable
             operator fun invoke() {
-                <doStuff />
+                doStuff()
             }
         }
         """
     )
 
-    fun testPunningProperty() = testCompile(
+    fun testSimpleLambdaChildren() = testCompile(
         """
         import androidx.compose.*
+        import android.widget.*
+        import android.content.*
 
-        class Simple(var foo: String) {
-            fun setBar(bar: String) {}
-            @Composable
-            operator fun invoke() {}
+        @Composable fun Example(children: @Composable() () -> Unit) {
+
         }
 
-        class Test(var foo: String, var bar: String) {
-            @Composable
-            operator fun invoke() {
-                <Simple foo bar />
+        fun run(text: String) {
+            Example {
+                println("hello ${"$"}text")
             }
         }
         """
     )
 
-    fun testPunningLocalVar() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Simple() {
-            var bar: String? = null
-            fun setFoo(foo: String) {}
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Test {
-            @Composable
-            operator fun invoke() {
-                val foo = "string"
-                val bar = "other"
-                <Simple foo bar />
-            }
-        }
-        """
-    )
-
-    fun testSimpleLambdaChildrenSetter() = testCompile(
-        """
-        import androidx.compose.*
-        import android.widget.*
-        import android.content.*
-
-        class Example {
-            @Children
-            fun setChildren(fn: () -> Unit) {}
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example>
-                println("hello ${"$"}text")
-            </Example>
-        }
-        """
-    )
-
-    // disabled: b/133441299
-    fun xtestSimpleLambdaChildrenProperty() = testCompile(
-        """
-        import androidx.compose.*
-        import android.widget.*
-        import android.content.*
-
-        class Example {
-            @Children
-            var children: (() -> Unit)? = null
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example>
-                println("hello ${"$"}text")
-            </Example>
-        }
-        """
-    )
-
-    fun testSimpleLambdaChildrenPropertyInCtor() = testCompile(
-        """
-        import androidx.compose.*
-        import android.widget.*
-        import android.content.*
-
-        class Example(
-            @Children var children: () -> Unit
-        ) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example>
-                println("hello ${"$"}text")
-            </Example>
-        }
-        """
-    )
-
-    fun testBlockChildrenForViews() = testCompile(
-        """
-        import androidx.compose.*
-        import android.widget.*
-
-        fun run(text: String) {
-            <LinearLayout>
-                println("hello ${"$"}text")
-            </LinearLayout>
-        }
-        """
-    )
-
-    fun testChildrenLambdaSetterWithSingleParam() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Example {
-            @Children
-            fun setChildren(fn: (x: Int) -> Unit) {}
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example> x ->
-                println("hello ${"$"}x")
-            </Example>
-        }
-        """
-    )
-
-    // disabled: b/133441299
-    fun xtestChildrenLambdaPropertyWithSingleParam() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Example {
-            @Children
-            var children: ((x: Int) -> Unit)? = null
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example> x ->
-                println("hello ${"$"}x")
-            </Example>
-        }
-        """
-    )
-
-    fun testChildrenLambdaSetterWithMultipleParams() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Example {
-            @Children
-            fun setChildren(fn: (x: Int, y: String) -> Unit) {}
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-
-//                val lambda = { x, y -> ... }
-//                composer.call(
-//                    123,
-//                    { changed(lambda) },
-//                    { Example().also { setChildren(lambda) }() }
-//                )
-
-
-            <Example> x, y ->
-                println("hello ${"$"}x ${"$"}y")
-            </Example>
-        }
-        """
-    )
-
-    // disabled: b/133441299
-    fun xtestChildrenLambdaPropertyWithMultipleParams() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Example {
-            @Children
-            var children: ((x: Int, y: String) -> Unit)? = null
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example> x, y ->
-                println("hello ${"$"}x ${"$"}y")
-            </Example>
-        }
-        """
-    )
-
-    fun testGenericChildrenArgSetter() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Example<T>(var value: T) {
-            @Children
-            fun setChildren(fn: (x: T) -> Unit) {}
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example value="string"> x ->
-                println("hello ${"$"}x")
-            </Example>
-            <Example value=123> x ->
-                println("hello ${"$"}{x + 1}")
-            </Example>
-        }
-        """
-    )
-
-    // disabled b/133441299
-    fun xtestGenericChildrenArgProperty() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Example<T>(var value: T) {
-            @Children
-            var children: ((x: T) -> Unit)? = null
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun run(text: String) {
-            <Example value="string"> x ->
-                println("hello ${"$"}x")
-            </Example>
-            <Example value=123> x ->
-                println("hello ${"$"}{x + 1}")
-            </Example>
-        }
-        """
-    )
-
     fun testFunctionComponentsWithChildrenSimple() = testCompile(
         """
         import androidx.compose.*
 
-        fun Example(@Children children: () -> Unit) {}
+        @Composable
+        fun Example(children: @Composable() () -> Unit) {}
 
+        @Composable
         fun run(text: String) {
-            <Example>
+            Example {
                 println("hello ${"$"}text")
-            </Example>
+            }
         }
         """
     )
@@ -1315,30 +592,14 @@
         """
         import androidx.compose.*
 
-        fun Example(@Children children: (String) -> Unit) {}
+        @Composable
+        fun Example(children: @Composable() (String) -> Unit) {}
 
+        @Composable
         fun run(text: String) {
-            <Example> x ->
+            Example { x ->
                 println("hello ${"$"}x")
-            </Example>
-        }
-        """
-    )
-
-    // disabled: b/133441299
-    fun xtestFunctionComponentWithGenericChildren() = testCompile(
-        """
-        import androidx.compose.*
-
-        fun <T> Example(foo: T, @Children children: (T) -> Unit) {}
-
-        fun run(text: String) {
-            <Example foo="string"> x ->
-                println("hello ${"$"}x")
-            </Example>
-            <Example foo=123> x ->
-                println("hello ${"$"}{x + 1}")
-            </Example>
+            }
         }
         """
     )
@@ -1351,8 +612,8 @@
         fun foo() {
             val lambda = @Composable {  }
             for(x in 1..5) {
-                <lambda />
-                <lambda />
+                lambda()
+                lambda()
             }
         }
         """
@@ -1363,91 +624,44 @@
         import androidx.compose.*
         import android.widget.TextView
 
+        @Composable
         fun foo(x: Boolean) {
-            val lambda = @Composable { <TextView text="Hello World" /> }
+            val lambda = @Composable { TextView(text="Hello World") }
             if(true) {
-                <lambda />
-                <lambda />
-                <lambda />
+                lambda()
+                lambda()
+                lambda()
             } else {
-                <lambda />
+                lambda()
             }
         }
         """
     )
 
-    fun testLateUsingObjectLiteral() = testCompile(
-        """
-        import androidx.compose.*
-
-         class Example {
-             lateinit var callback: (Int) -> Unit
-             var index = 0
-             @Composable
-            operator fun invoke() {
-               <Example callback=(object : Function1<Int, Unit> {
-                    override fun invoke(p1: Int) {
-                        index = p1
-                    }
-                }) />
-             }
-         }
-        """
-    )
-
     fun testMultiplePivotalAttributesOdd() = testCompile(
         """
         import androidx.compose.*
 
-        class Foo(
-            val a: Int,
-            val b: Int,
-            val c: Int,
-            val d: Int,
-            val e: Int
+        @Composable fun Foo(
+            @Pivotal a: Int,
+            @Pivotal b: Int,
+            @Pivotal c: Int,
+            @Pivotal d: Int,
+            @Pivotal e: Int
         ) {
-            @Composable
-            operator fun invoke() {}
+
         }
 
         class Bar {
             @Composable
             operator fun invoke() {
-                <Foo
-                    a=1
-                    b=2
-                    c=3
-                    d=4
+                Foo(
+                    a=1,
+                    b=2,
+                    c=3,
+                    d=4,
                     e=5
-                />
-            }
-        }
-        """
-    )
-
-    fun testMultiplePivotalAttributesEven() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Foo(
-            val a: Int,
-            val b: Int,
-            val c: Int,
-            val d: Int
-        ) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar {
-            @Composable
-            operator fun invoke() {
-                <Foo
-                    a=1
-                    b=2
-                    c=3
-                    d=4
-                />
+                )
             }
         }
         """
@@ -1457,154 +671,18 @@
         """
         import androidx.compose.*
 
-        class Foo(
-            val a: Int
+        @Composable fun Foo(
+            @Pivotal a: Int
         ) {
-            @Composable
-            operator fun invoke() {}
+
         }
 
         class Bar {
             @Composable
             operator fun invoke() {
-                <Foo
+                Foo(
                     a=1
-                />
-            }
-        }
-        """
-    )
-
-    fun testKeyAttributeWithPivotal() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        class Foo(
-            val a: Int,
-            var b: Int
-        ) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        fun Foo.setKey(@Pivotal key: Any?) {}
-
-        class Bar {
-            @Composable
-            operator fun invoke() {
-                <Foo
-                    a=1
-                    b=2
-                    key=3
-                />
-            }
-        }
-        """
-    )
-
-    fun testKeyAttributeWithoutPivotal() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        @Pivotal
-        fun Foo.setKey(x: Any?) {}
-
-        class Foo(
-            var a: Int,
-            var b: Int
-        ) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar {
-            @Composable
-            operator fun invoke() {
-                <Foo
-                    a=1
-                    b=2
-                    key=3
-                />
-            }
-        }
-        """
-    )
-
-    fun testNamedChildrenAttributeProperty() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        class Foo {
-            @Children var children: (() -> Unit)? = null
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar {
-            @Composable
-            operator fun invoke() {
-                <Foo
-                    children={ }
-                />
-            }
-        }
-        """
-    )
-
-    fun testNamedChildrenAttributeSetter() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        class Foo {
-            @Children fun setChildren(children: () -> Unit) {}
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar {
-            @Composable
-            operator fun invoke() {
-                <Foo
-                    children={ }
-                />
-            }
-        }
-        """
-    )
-
-    // disabled: b/133441299
-    fun xtestOverloadedChildren() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        class Foo {
-            @Children var children: ((x: Int, y: Int) -> Unit)? = null
-            @Children fun setChildren(children: (x: Int) -> Unit) {}
-            @Children fun setChildren(children: () -> Unit) {}
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar {
-            @Composable
-            operator fun invoke() {
-                <Foo children={ -> } />
-                <Foo children={ x -> println(x) } />
-                <Foo children={ x, y -> println(x + y) } />
-                <Foo>
-                    println("")
-                </Foo>
-                <Foo> x ->
-                    println(x)
-                </Foo>
-                <Foo> x, y ->
-                    println(x + y)
-                </Foo>
+                )
             }
         }
         """
@@ -1615,134 +693,27 @@
         import androidx.compose.*
         import androidx.ui.androidview.adapters.*
 
-        class Foo(@Children var children: (sub: () -> Unit) -> Unit) {
-            @Composable
-            operator fun invoke() {}
+        @Composable fun Foo(children: @Composable() (sub: @Composable() () -> Unit) -> Unit) {
+
         }
 
-        class Boo(@Children var children: () -> Unit) {
-            @Composable
-            operator fun invoke() {}
+        @Composable fun Boo(children: @Composable() () -> Unit) {
+
         }
 
         class Bar {
             @Composable
             operator fun invoke() {
-                <Foo> sub ->
-                    <Boo>
-                        <sub />
-                    </Boo>
-                </Foo>
+                Foo { sub ->
+                    Boo {
+                        sub()
+                    }
+                }
             }
         }
         """
     )
 
-    // disabled: b/133441299
-    fun xtestPassChildrenLambdaVarWithCorrectType() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        class Boo(@Children var children: () -> Unit) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar(var data: List<Int>) {
-            @Composable
-            operator fun invoke() {
-                val children = { Unit; }
-                <Boo children />
-            }
-        }
-        """
-    )
-
-    fun testPassChildrenLambdaLiteralWithCorrectType() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        class Boo {
-            @Children lateinit var children: () -> Unit
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar(var data: List<Int>) {
-            @Composable
-            operator fun invoke() {
-                <Boo
-                    children={ Unit; }
-                />
-            }
-        }
-        """
-    )
-
-    // disabled: b/133441299
-    fun xtestChildrenLiteral() = testCompile(
-        """
-        import androidx.compose.*
-        import androidx.ui.androidview.adapters.*
-
-        class Boo(@Children var children: () -> Unit) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar(var data: List<Int>) {
-            @Composable
-            operator fun invoke() {
-                <Boo
-                    children={ Unit; }
-                />
-            }
-        }
-        """
-    )
-
-    fun testKtxLambdaCapturedVariableInAssignment() = testCompile(
-        """
-        import androidx.compose.*
-
-        class Tabs(@Children var children: () -> Unit) {
-            @Composable
-            operator fun invoke() {}
-        }
-
-        class Bar {
-            @Composable
-            operator fun invoke() {
-                val bam = "x"
-                <Tabs>
-                    val qoo = bam
-                </Tabs>
-            }
-        }
-        """
-    )
-
-    fun testKtxParameterlessFunction() = testCompile(
-        """
-        import androidx.compose.*
-        import android.widget.*
-
-        @Composable
-        fun Paramless() {
-          <TextView text="Hello!" />
-        }
-
-        class Bar {
-          @Composable
-            operator fun invoke() {
-            <Paramless />
-          }
-        }
-        """
-    )
-
     fun testKtxEmittable() = testCompile(
         """
         import androidx.compose.*
@@ -1760,7 +731,7 @@
         class Comp {
           @Composable
             operator fun invoke() {
-            <MyEmittable a=2 />
+            MyEmittable(a=2)
           }
         }
         """
@@ -1783,12 +754,12 @@
         class Comp {
           @Composable
             operator fun invoke() {
-            <MyEmittable a=1>
-              <MyEmittable a=2 />
-              <MyEmittable a=3 />
-              <MyEmittable a=4 />
-              <MyEmittable a=5 />
-            </MyEmittable>
+            MyEmittable(a=1) {
+              MyEmittable(a=2)
+              MyEmittable(a=3)
+              MyEmittable(a=4)
+              MyEmittable(a=5)
+            }
           }
         }
         """
@@ -1805,7 +776,7 @@
         @Composable
         fun test() {
             val foo = Foo()
-            <foo />
+            foo()
         }
         """
     )
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTypeResolutionTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTypeResolutionTests.kt
deleted file mode 100644
index e4bb666..0000000
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTypeResolutionTests.kt
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-class KtxTypeResolutionTests : AbstractComposeDiagnosticsTest() {
-
-    fun testImplicitlyPassedReceiverScope1() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable
-            fun Int.Foo(@Children children: Int.() -> Unit) {
-                <children />
-            }
-        """
-    )
-
-    fun testImplicitlyPassedReceiverScope2() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable
-            fun Int.Foo(@Children children: Int.(foo: String) -> Unit) {
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_ATTRIBUTES!>children<!> />
-            }
-
-            @Composable
-            fun Bar(@Children children: Int.() -> Unit) {
-                <<!NO_VALUE_FOR_PARAMETER!>children<!> />
-            }
-        """
-    )
-
-    fun testThatUnresolvedTagDiagnosticIsOnlyOnTagName() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo {
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun test() {
-                <<!UNRESOLVED_TAG!>SomeNameThatWillNotResolve<!> <!UNRESOLVED_ATTRIBUTE_KEY!>foo<!>=123>
-                    <Foo />
-                </<!INVALID_TAG_DESCRIPTOR!>SomeNameThatWillNotResolve<!>>
-            }
-        """
-    )
-
-    fun testAmbiguousKtxTags() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo {
-                var foo: Int = 0
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable
-            fun Foo(foo: Int) { print(foo) }
-
-            @Composable fun test() {
-                <<!AMBIGUOUS_KTX_CALL!>Foo<!> foo=0 />
-            }
-        """
-    )
-
-    fun testSmartCastsAndPunning() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable
-            fun Foo(bar: String) { print(bar) }
-
-            @Composable
-            fun test(bar: String?) {
-                <Foo <!TYPE_MISMATCH!>bar<!> />
-                if (bar != null) {
-                    <Foo bar />
-                    <Foo bar=bar />
-                }
-            }
-        """
-    )
-
-    fun testExtensionInvoke() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo {}
-            @Composable operator fun Foo.invoke() {}
-
-            @Composable fun test() {
-                <Foo />
-            }
-        """
-    )
-
-    fun testResolutionInsideWhenExpression() = doTest(
-        """
-            import androidx.compose.*
-            import android.widget.TextView
-
-            @Composable fun doSomething(foo: Boolean) {
-                when (foo) {
-                    true -> <TextView text="Started..." />
-                    false -> <TextView text="Continue..." />
-                }
-            }
-        """
-    )
-
-    fun testComposerExtensions() = doTest(
-        """
-            import androidx.compose.*
-
-            open class Foo {}
-            class Bar : Foo() {}
-
-            class Bam {}
-
-            fun <T : Foo> ViewComposition.emit(key: Any, ctor: () -> T, update: ViewUpdater<T>.() -> Unit) {
-                print(key)
-                print(ctor)
-                print(update)
-            }
-
-            @Composable fun test() {
-                <Bar />
-                <<!INVALID_TAG_TYPE!>Bam<!> />
-            }
-        """
-    )
-
-    fun testUsedParameters() = doTest(
-        """
-            import androidx.compose.*
-            import android.widget.LinearLayout
-
-            class Foo {
-                var composeItem: @Composable() () -> Unit = {}
-                @Composable operator fun invoke(x: Int) {
-                    println(x)
-                }
-            }
-
-
-            @Composable fun test(
-                children: @Composable() () -> Unit,
-                value: Int,
-                x: Int,
-                children2: @Composable() () -> Unit,
-                value2: Int
-            ) {
-                <LinearLayout>
-                    // attribute value
-                    <Foo x=value />
-
-                    // punned attribute
-                    <Foo x />
-
-                    // tag
-                    <children />
-                </LinearLayout>
-                <Foo x=123 composeItem={
-                    val abc = 123
-
-                    // attribute value
-                    <Foo x=abc />
-
-                    // attribute value
-                    <Foo x=value2 />
-
-                    // tag
-                    <children2 />
-                } />
-            }
-        """
-    )
-
-    fun testDispatchInvoke() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bam {
-                @Composable fun Foo() {}
-            }
-
-            @Composable fun test() {
-                with(Bam()) {
-                    <Foo />
-                }
-            }
-        """
-    )
-
-    fun testDispatchAndExtensionReceiver() = doTest(
-        """
-            import androidx.compose.*
-
-            class Bam {
-                inner class Foo {}
-            }
-
-            @Composable operator fun Bam.Foo.invoke() {}
-
-            @Composable fun test() {
-                with(Bam()) {
-                    <Foo />
-                }
-            }
-        """
-    )
-
-    fun testDispatchAndExtensionReceiverLocal() = doTest(
-        """
-            import androidx.compose.*
-
-
-            class Foo {}
-
-            class Bam {
-                @Composable operator fun Foo.invoke() {}
-                @Composable operator fun invoke() {
-                    <Foo />
-                }
-            }
-
-        """
-    )
-
-    fun testMissingAttributes() = doTest(
-        """
-            import androidx.compose.*
-
-            data class Foo(val value: Int)
-
-            @Composable fun A(x: Foo) { println(x) }
-            class B(var x: Foo) { @Composable operator fun invoke() { println(x) } }
-            class C(x: Foo) { init { println(x) } @Composable operator fun invoke() { } }
-            class D(val x: Foo) { @Composable operator fun invoke() { println(x) } }
-            class E {
-                lateinit var x: Foo
-                @Composable operator fun invoke() { println(x) }
-            }
-
-            // NOTE: It's important that the diagnostic be only over the tag target, and not the entire element
-            // so that a single error doesn't end up making a huge part of an otherwise correct file "red".
-            @Composable fun Test(F: @Composable() (x: Foo) -> Unit) {
-                // NOTE: constructor attributes and fn params get a "missing parameter" diagnostic
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_ATTRIBUTES!>A<!> />
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_ATTRIBUTES!>B<!> />
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_ATTRIBUTES!>C<!> />
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_ATTRIBUTES!>D<!> />
-
-                // NOTE: lateinit attributes get only the "missing required attribute" diagnostic
-                <<!MISSING_REQUIRED_ATTRIBUTES!>E<!> />
-
-                // local
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_ATTRIBUTES!>F<!> />
-
-                val x = Foo(123)
-
-                <A x />
-                <B x />
-                <C x />
-                <D x />
-                <E x />
-                <F x />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testDuplicateAttributes() = doTest(
-        """
-            import androidx.compose.*
-
-            data class Foo(val value: Int)
-
-            @Composable fun A(x: Foo) { println(x) }
-            class B(var x: Foo) { @Composable operator fun invoke() { println(x) } }
-            class C(x: Foo) { init { println(x) } @Composable operator fun invoke() { } }
-            class D(val x: Foo) { @Composable operator fun invoke() { println(x) } }
-            class E {
-                lateinit var x: Foo
-                @Composable operator fun invoke() { println(x) }
-            }
-
-            @Composable fun Test() {
-                val x = Foo(123)
-
-                // NOTE: It's important that the diagnostic be only over the attribute key, so that
-                // we don't make a large part of the elements red when the type is otherwise correct
-                <A x=x <!DUPLICATE_ATTRIBUTE!>x<!>=x />
-                <B x=x <!DUPLICATE_ATTRIBUTE!>x<!>=x />
-                <C x=x <!DUPLICATE_ATTRIBUTE!>x<!>=x />
-                <D x=x <!DUPLICATE_ATTRIBUTE!>x<!>=x />
-                <E x=x <!DUPLICATE_ATTRIBUTE!>x<!>=x />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testChildrenNamedAndBodyDuplicate() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable fun A(@Children children: @Composable() () -> Unit) { <children /> }
-            class B(@Children var children: @Composable() () -> Unit) { @Composable operator fun invoke() { <children /> } }
-            class C {
-                @Children var children: @Composable() () -> Unit = {}
-                @Composable operator fun invoke() { <children /> }
-            }
-            class D {
-                @Children lateinit var children: @Composable() () -> Unit
-                @Composable operator fun invoke() { <children /> }
-            }
-
-            @Composable fun Test() {
-                <A <!CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE!>children<!>={}></A>
-                <B <!CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE!>children<!>={}></B>
-                <C <!CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE!>children<!>={}></C>
-                <D <!CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE!>children<!>={}></D>
-            }
-
-        """.trimIndent()
-    )
-
-    fun testAbstractClassTags() = doTest(
-        """
-            import androidx.compose.*
-            import android.content.Context
-            import android.widget.LinearLayout
-
-            abstract class Foo {}
-
-            abstract class Bar(context: Context) : LinearLayout(context) {}
-
-            @Composable fun Test() {
-                <<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, INVALID_TAG_TYPE!>Foo<!> />
-                <<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>Bar<!> />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testAmbiguousTags() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable fun Foo() {}
-            @Composable fun Foo(x: Int) { println(x) }
-
-
-            class Wat {
-                operator fun invoke(): Xam {
-                    return Xam()
-                }
-            }
-
-            class Xam {
-                @Composable
-                operator fun invoke(x: Int) { println(x) }
-            }
-
-            @Composable fun Test() {
-//                <Foo x=123 />
-//                <Foo />
-                <Wat x=123 />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testOverloadedTargets() = doTest(
-        """
-            import androidx.compose.*
-
-            data class FooModel(val x: Int, val y: Double)
-
-            class Foo(model: FooModel) {
-                init { println(model) }
-                constructor(x: Int, y: Double) : this(FooModel(x, y))
-
-                @Composable operator fun invoke() {}
-            }
-
-
-            @Composable fun Bar(x: Int, y: Double) { <Bar model=FooModel(x, y) /> }
-            @Composable fun Bar(model: FooModel) { println(model) }
-
-            @Composable fun Test() {
-                val x = 1
-                val y = 1.0
-                val model = FooModel(x, y)
-
-                <Foo x y />
-                <Foo model />
-                <Foo x y <!UNRESOLVED_ATTRIBUTE_KEY!>model<!> />
-
-                <Bar x y />
-                <Bar model />
-                <Bar x y <!UNRESOLVED_ATTRIBUTE_KEY!>model<!> />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testGenerics() = doTest(
-        """
-            import androidx.compose.*
-
-            class A { fun a() {} }
-            class B { fun b() {} }
-
-            class Foo<T>(var value: T, var f: (T) -> Unit) {
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun <T> Bar(x: Int, value: T, f: (T) -> Unit) { println(value); println(f); println(x) }
-
-            @Composable fun Test() {
-
-                val fa: (A) -> Unit = { it.a() }
-                val fb: (B) -> Unit = { it.b() }
-
-                <Foo value=A() f={ it.a() } />
-                <Foo value=B() f={ it.b() } />
-                <Foo value=A() f=fa />
-                <Foo value=B() f=fb />
-                <Foo value=B() f={ it.<!UNRESOLVED_REFERENCE!>a<!>() } />
-                <Foo value=A() f={ it.<!UNRESOLVED_REFERENCE!>b<!>() } />
-                <<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>Foo<!> <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>value<!>=A() <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>f<!>=fb />
-                <<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>Foo<!> <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>value<!>=B() <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>f<!>=fa />
-
-
-                <Bar x=1 value=A() f={ it.a() } />
-                <Bar x=1 value=B() f={ it.b() } />
-                <Bar x=1 value=A() f=fa />
-                <Bar x=1 value=B() f=fb />
-                <Bar x=1 value=B() f={ it.<!UNRESOLVED_REFERENCE!>a<!>() } />
-                <Bar x=1 value=A() f={ it.<!UNRESOLVED_REFERENCE!>b<!>() } />
-                <<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>Bar<!> x=1 <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>value<!>=A() <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>f<!>=fb />
-                <<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>Bar<!> x=1 <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>value<!>=B() <!MISMATCHED_INFERRED_ATTRIBUTE_TYPE!>f<!>=fa />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testUnresolvedAttributeValueResolvedTarget() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo {
-                var bar: Int = 0
-                @Composable operator fun invoke(x: Int) {
-                    print(x)
-                }
-            }
-
-            @Composable fun Fam(bar: Int, x: Int) {
-                print(bar)
-                print(x)
-            }
-
-            @Composable fun Test() {
-                <Foo <!MISMATCHED_ATTRIBUTE_TYPE!>bar<!>=<!UNRESOLVED_REFERENCE!>undefined<!> x=1 />
-                <Foo bar=1 x=<!UNRESOLVED_REFERENCE!>undefined<!> />
-                <Foo <!UNRESOLVED_REFERENCE, MISMATCHED_ATTRIBUTE_TYPE!>bar<!> <!UNRESOLVED_REFERENCE!>x<!> />
-                <Fam bar=<!UNRESOLVED_REFERENCE!>undefined<!> x=1 />
-                <Fam bar=1 x=<!UNRESOLVED_REFERENCE!>undefined<!> />
-                <Fam <!UNRESOLVED_REFERENCE!>bar<!> <!UNRESOLVED_REFERENCE!>x<!> />
-
-                <Fam <!MISMATCHED_ATTRIBUTE_TYPE!>bar<!>=<!TYPE_MISMATCH!>""<!> <!MISMATCHED_ATTRIBUTE_TYPE!>x<!>=<!TYPE_MISMATCH!>""<!> />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testEmptyAttributeValue() = doTest(
-        """
-            import androidx.compose.*
-
-            @Composable fun Foo(abc: Int, xyz: Int) {
-                print(abc)
-                print(xyz)
-            }
-
-            @Composable fun Test() {
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_ATTRIBUTES!>Foo<!> abc= />
-
-                // NOTE(lmr): even though there is NO diagnostic here, there *is* a parse
-                // error. This is intentional and done to mimic how kotlin handles function
-                // calls with no value expression in a call parameter list (ie, `Foo(123,)`)
-                <Foo abc=123 xyz= />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testMissingComposer() = doTest(
-        """
-            import androidx.compose.Composable
-
-            @Composable fun A() {}
-            @Composable fun B(a: Int, b: Int) { print(a + b) }
-            fun C(a: Int): @Composable() (b: Int) -> Unit = { b: Int -> print(a + b) }
-            class D(var a: Int) {
-                var b: Int = 0
-                @Composable operator fun invoke(c: Int) { print(c) }
-            }
-
-            class E(var a: Int) {
-                var b: Int = 0
-            }
-
-            @Composable fun Test() {
-                <<!NO_COMPOSER_FOUND!>A<!> />
-
-                <<!NO_COMPOSER_FOUND, NO_VALUE_FOR_PARAMETER!>B<!> />
-                <<!NO_COMPOSER_FOUND, NO_VALUE_FOR_PARAMETER!>B<!> a=1 />
-                <<!NO_COMPOSER_FOUND!>B<!> a=1 b=1 />
-                <<!NO_COMPOSER_FOUND!>B<!> a=1 <!MISMATCHED_ATTRIBUTE_TYPE!>b<!>=<!TYPE_MISMATCH!>""<!> />
-
-                <<!NO_COMPOSER_FOUND, NO_VALUE_FOR_PARAMETER!>C<!> />
-                <<!NO_COMPOSER_FOUND!>C<!> a=1 />
-                <<!NO_COMPOSER_FOUND!>C<!> a=1 b=1 />
-                <<!NO_COMPOSER_FOUND!>C<!> a=1 <!MISMATCHED_ATTRIBUTE_TYPE!>b<!>=<!TYPE_MISMATCH!>""<!> />
-
-                <<!NO_COMPOSER_FOUND, NO_VALUE_FOR_PARAMETER!>D<!> />
-                <<!NO_COMPOSER_FOUND!>D<!> a=1 />
-                <<!NO_COMPOSER_FOUND!>D<!> a=1 b=1 />
-                <<!NO_COMPOSER_FOUND!>D<!> a=1 b=1 c=1 />
-                <<!NO_COMPOSER_FOUND!>D<!> a=1 b=1 <!MISMATCHED_ATTRIBUTE_TYPE!>c<!>=<!TYPE_MISMATCH!>""<!> />
-
-                <<!NO_COMPOSER_FOUND, NO_VALUE_FOR_PARAMETER!>E<!> />
-                <<!NO_COMPOSER_FOUND!>E<!> a=1 />
-                <<!NO_COMPOSER_FOUND!>E<!> a=1 b=1 />
-                <<!NO_COMPOSER_FOUND!>E<!> a=1 <!MISMATCHED_ATTRIBUTE_TYPE!>b<!>="" />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testValidInvalidAttributes() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo(val a: Int, var b: Int, c: Int, d: Int = 1) {
-                init { println(c); println(d); }
-                var e = 1
-                var f: Int? = null
-                var g: Int
-                    get() = 1
-                    set(_: Int) {}
-                val h: Int get() = 1
-                val i = 1
-
-                fun setJ(j: Int) { println(j) }
-
-                val k by lazy { 123 }
-                private var l = 1
-                private var m: Int
-                    get() = 1
-                    set(v: Int) { println(v) }
-                private val n = 1
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun Test() {
-                <Foo
-                    a=1
-                    b=1
-                    c=1
-                    d=1
-                    e=1
-                    f=null
-                    g=1
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>h<!>=1
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>i<!>=1
-                    j=1
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>k<!>=1
-                    <!UNRESOLVED_ATTRIBUTE_KEY!>z<!>=1
-                    <!INVISIBLE_MEMBER!>l<!>=1
-                    <!INVISIBLE_MEMBER!>m<!>=1
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>n<!>=1
-                />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testMismatchedAttributes() = doTest(
-        """
-            import androidx.compose.*
-
-            open class A {}
-            class B : A() {}
-
-            class Foo() {
-                var x: A = A()
-                var y: A = B()
-                var z: B = B()
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun Test() {
-                <Foo
-                    x=A()
-                    y=A()
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>z<!>=A()
-                />
-                <Foo
-                    x=B()
-                    y=B()
-                    z=B()
-                />
-                <Foo
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>x<!>=1
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>y<!>=1
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>z<!>=1
-                />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testErrorAttributeValue() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo() {
-                var x: Int = 1
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun Test() {
-                <Foo
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>x<!>=<!UNRESOLVED_REFERENCE!>someUnresolvedValue<!>
-                    <!UNRESOLVED_ATTRIBUTE_KEY_UNKNOWN_TYPE!>y<!>=<!UNRESOLVED_REFERENCE!>someUnresolvedValue<!>
-                />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testUnresolvedQualifiedTag() = doTest(
-        """
-            import androidx.compose.*
-
-            object MyNamespace {
-                class Foo() {
-                    @Children var children: @Composable() () -> Unit = {}
-                    @Composable operator fun invoke() { <children /> }
-                }
-                @Composable fun Bar(@Children children: @Composable() () -> Unit = {}) { <children /> }
-
-                var Baz = @Composable { }
-
-                var someString = ""
-                class NonComponent {}
-            }
-
-            class Boo {
-                class Wat {
-                    @Children var children: @Composable() () -> Unit = {}
-                    @Composable operator fun invoke() { <children /> }
-                }
-                inner class Qoo {
-                    @Children var children: @Composable() () -> Unit = {}
-                    @Composable operator fun invoke() { <children /> }
-                }
-            }
-
-            @Composable fun Test() {
-
-                <MyNamespace.Foo />
-                <MyNamespace.Bar />
-                <MyNamespace.Baz />
-                <<!INVALID_TAG_DESCRIPTOR!>MyNamespace.<!UNRESOLVED_REFERENCE!>Qoo<!><!> />
-                <<!INVALID_TAG_TYPE!>MyNamespace.<!UNRESOLVED_REFERENCE!>someString<!><!> />
-                <<!INVALID_TAG_TYPE!>MyNamespace.NonComponent<!> />
-                <MyNamespace.Foo></MyNamespace.Foo>
-                <MyNamespace.Bar></MyNamespace.Bar>
-                <<!CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED!>MyNamespace.Baz<!>></MyNamespace.Baz>
-
-
-                val obj = Boo()
-                <obj.Qoo />
-                <Boo.Wat />
-                <obj.Qoo></obj.Qoo>
-                <Boo.Wat></Boo.Wat>
-                <<!INVALID_TAG_DESCRIPTOR!>obj.<!UNRESOLVED_REFERENCE!>Wat<!><!> />
-
-                <<!INVALID_TAG_DESCRIPTOR!>MyNamespace.<!UNRESOLVED_REFERENCE!>Bam<!><!> />
-                <<!UNRESOLVED_REFERENCE!>SomethingThatDoesntExist<!>.Foo />
-
-                <<!INVALID_TAG_DESCRIPTOR!>obj.<!UNRESOLVED_REFERENCE!>Wat<!><!>>
-                </<!INVALID_TAG_DESCRIPTOR!>obj.Wat<!>>
-
-                <<!INVALID_TAG_DESCRIPTOR!>MyNamespace.<!UNRESOLVED_REFERENCE!>Qoo<!><!>>
-                </<!INVALID_TAG_DESCRIPTOR!>MyNamespace.Qoo<!>>
-
-                <<!INVALID_TAG_TYPE!>MyNamespace.<!UNRESOLVED_REFERENCE!>someString<!><!>>
-                </<!INVALID_TAG_TYPE!>MyNamespace.someString<!>>
-
-                <<!CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED!><!UNRESOLVED_REFERENCE!>SomethingThatDoesntExist<!>.Foo<!>>
-                </SomethingThatDoesntExist.Foo>
-
-                <<!INVALID_TAG_TYPE!>MyNamespace.NonComponent<!>>
-                </<!INVALID_TAG_TYPE!>MyNamespace.NonComponent<!>>
-
-                <<!INVALID_TAG_DESCRIPTOR!>MyNamespace.<!UNRESOLVED_REFERENCE!>Bam<!><!>>
-                </<!INVALID_TAG_DESCRIPTOR!>MyNamespace.Bam<!>>
-
-            }
-
-        """.trimIndent()
-    )
-
-    fun testExtensionAttributes() = doTest(
-        """
-            import androidx.compose.*
-
-            class Foo() {
-                var x: Int = 1
-                @Composable operator fun invoke() {}
-            }
-
-            fun Foo.setBar(x: Int) { println(x) }
-
-            fun Foo.setX(s: String) { println(s) }
-
-            @Composable fun Test() {
-                <Foo
-                    x=1
-                />
-
-                <Foo
-                    x="a"
-                />
-
-                <Foo
-                    bar=123
-                />
-
-                <Foo
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>bar<!>=123.0
-                    <!MISMATCHED_ATTRIBUTE_TYPE!>x<!>=123.0
-                />
-            }
-
-        """.trimIndent()
-    )
-
-    fun testChildren() = doTest(
-        """
-            import androidx.compose.*
-            import android.widget.Button
-            import android.widget.LinearLayout
-
-            class ChildrenRequired1(@Children var children: @Composable() () -> Unit) {
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun ChildrenRequired2(@Children children: @Composable() () -> Unit) { <children /> }
-
-            class ChildrenOptional1(@Children var children: @Composable() () -> Unit = {}) {
-                @Composable operator fun invoke() {}
-            }
-            class ChildrenOptional2() {
-                @Children var children: @Composable() () -> Unit = {}
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun ChildrenOptional3(@Children children: @Composable() () -> Unit = {}) { <children /> }
-
-            class NoChildren1() {
-                @Composable operator fun invoke() {}
-            }
-            @Composable fun NoChildren2() {}
-
-
-            class MultiChildren() {
-                @Children var c1: @Composable() () -> Unit = {}
-                @Children var c2: @Composable() (x: Int) -> Unit = {}
-                @Children var c3: @Composable() (x: Int, y: Int) -> Unit = { x, y -> println(x + y) }
-
-                @Composable operator fun invoke() {}
-            }
-
-            @Composable fun Test() {
-                <ChildrenRequired1></ChildrenRequired1>
-                <ChildrenRequired2></ChildrenRequired2>
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_CHILDREN!>ChildrenRequired1<!> />
-                <<!NO_VALUE_FOR_PARAMETER, MISSING_REQUIRED_CHILDREN!>ChildrenRequired2<!> />
-
-                <ChildrenOptional1></ChildrenOptional1>
-                <ChildrenOptional2></ChildrenOptional2>
-                <ChildrenOptional3></ChildrenOptional3>
-                <ChildrenOptional1 />
-                <ChildrenOptional2 />
-                <ChildrenOptional3 />
-
-
-                <<!CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED!>NoChildren1<!>></NoChildren1>
-                <<!CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED!>NoChildren2<!>></NoChildren2>
-                <NoChildren1 />
-                <NoChildren2 />
-
-                <MultiChildren></MultiChildren>
-                <MultiChildren> x ->
-                    println(x)
-                </MultiChildren>
-                <MultiChildren> x, y ->
-                    println(x + y)
-                </MultiChildren>
-                <<!UNRESOLVED_CHILDREN!>MultiChildren<!>> <!TYPE_MISMATCH!><!EXPECTED_PARAMETERS_NUMBER_MISMATCH!><!CANNOT_INFER_PARAMETER_TYPE!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>, <!CANNOT_INFER_PARAMETER_TYPE!>z<!><!> ->
-                    println(x + y + z)<!>
-                </MultiChildren>
-
-                <Button />
-                <LinearLayout />
-
-                <LinearLayout>
-                </LinearLayout>
-
-                <<!CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED!>Button<!>></Button>
-            }
-
-        """.trimIndent()
-    )
-}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ChildrenAnnotationTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ChildrenAnnotationTest.kt
deleted file mode 100644
index dedcd26..0000000
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ChildrenAnnotationTest.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin.analysis
-
-import androidx.compose.plugins.kotlin.AbstractComposeDiagnosticsTest
-
-class ChildrenAnnotationTest : AbstractComposeDiagnosticsTest() {
-
-    fun testReportChildrenOnWrongParameter() {
-        doTest("""
-            import androidx.compose.*;
-
-            @Composable fun MyWidget(<!CHILDREN_MUST_BE_LAST!>@Children children: ()->Unit<!>, value: Int) {
-                System.out.println(""+children+value)
-            }
-        """)
-    }
-}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
index 9bc8f04..2612abb 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
@@ -9,13 +9,6 @@
 
 class ComposableCheckerTests : AbstractComposeDiagnosticsTest() {
 
-    companion object {
-        val MODE_KTX_CHECKED = 1
-        val MODE_KTX_STRICT = 2
-        val MODE_KTX_PEDANTIC = 4
-        val MODE_FCS = 8
-    }
-
     override fun setUp() {
         // intentionally don't call super.setUp() here since we are recreating an environment
         // every test
@@ -66,11 +59,11 @@
             import android.widget.TextView;
 
             fun myStatelessFunctionalComponent() {
-                <TextView text="Hello World!" />
+                TextView(text="Hello World!")
             }
 
             fun foo() {
-                <myStatelessFunctionalComponent />
+                myStatelessFunctionalComponent()
             }
         """)
         check("""
@@ -79,12 +72,12 @@
 
             @Composable
             fun myStatelessFunctionalComponent() {
-                <TextView text="Hello World!" />
+                TextView(text="Hello World!")
             }
 
             @Composable
             fun foo() {
-                <myStatelessFunctionalComponent />
+                myStatelessFunctionalComponent()
             }
         """)
     }
@@ -94,15 +87,15 @@
             import androidx.compose.*;
             import android.widget.TextView;
 
-            val myLambda1 = { <TextView text="Hello World!" /> }
-            val myLambda2: ()->Unit = { <TextView text="Hello World!" /> }
+            val myLambda1 = { TextView(text="Hello World!") }
+            val myLambda2: () -> Unit = { TextView(text="Hello World!") }
         """)
         check("""
             import androidx.compose.*;
             import android.widget.TextView;
 
-            val myLambda1 = @Composable() { <TextView text="Hello World!" /> }
-            val myLambda2: @Composable() ()->Unit = { <TextView text="Hello World!" /> }
+            val myLambda1 = @Composable() { TextView(text="Hello World!") }
+            val myLambda2: @Composable() ()->Unit = { TextView(text="Hello World!") }
         """)
     }
 
@@ -111,8 +104,8 @@
             import androidx.compose.*;
             import android.widget.TextView;
 
-            fun <!KTX_IN_NON_COMPOSABLE!>myRandomFunction<!>() {
-                <TextView text="Hello World!" />
+            fun myRandomFunction() {
+                <!NONE_APPLICABLE!>TextView<!>(text="Hello World!")
             }
         """)
     }
@@ -124,25 +117,12 @@
 
             @Composable
             fun foo() {
-                val myRandomLambda = <!KTX_IN_NON_COMPOSABLE!>{ <TextView text="Hello World!" /> }<!>
+                val myRandomLambda = { <!NONE_APPLICABLE!>TextView<!>(text="Hello World!") }
                 System.out.println(myRandomLambda)
             }
         """)
     }
 
-    fun testComposableReporting005() {
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyComponent : Component() {
-                override fun compose() {
-                    <TextView text="Hello World!" />
-                }
-            }
-        """)
-    }
-
     fun testComposableReporting006() {
         checkFail("""
             import androidx.compose.*;
@@ -150,9 +130,9 @@
 
             fun foo() {
                 val bar = {
-                    <TextView />
+                    TextView()
                 }
-                <bar />
+                bar()
                 System.out.println(bar)
             }
         """)
@@ -163,9 +143,9 @@
             @Composable
             fun foo() {
                 val bar = @Composable {
-                    <TextView />
+                    TextView()
                 }
-                <bar />
+                bar()
                 System.out.println(bar)
             }
         """)
@@ -189,7 +169,7 @@
 
             fun foo() {
                 val bar: @Composable() ()->Unit = @Composable {
-                    <TextView />
+                    TextView()
                 }
                 <!SVC_INVOCATION!>bar<!>()
                 System.out.println(bar)
@@ -203,7 +183,7 @@
             import android.widget.TextView;
 
             fun myStatelessFunctionalComponent() {
-                <TextView text="Hello World!" />
+                TextView(text="Hello World!")
             }
 
             fun noise() {
@@ -216,7 +196,7 @@
 
             @Composable
             fun myStatelessFunctionalComponent() {
-                <TextView text="Hello World!" />
+                TextView(text="Hello World!")
             }
 
             fun noise() {
@@ -225,123 +205,6 @@
         """)
     }
 
-    fun testComposableReporting010() {
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyComponent : Component() {
-                @Children lateinit var children: @Composable() ()->Unit
-                override fun compose() {
-                    val children = this.children
-                    <children />
-                    System.out.println(children)
-                }
-            }
-        """)
-    }
-
-    fun testComposableReporting011() {
-        checkFail("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyComponent : Component() {
-                @Children lateinit var children: @Composable() ()->Unit
-                override fun compose() {
-                    <!SVC_INVOCATION!>children<!>()
-                }
-            }
-        """)
-    }
-
-    fun testComposableReporting012() {
-        checkFail("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyComponent : Component() {
-                @Children lateinit var children: ()->Unit
-                override fun compose() {
-                    <!SVC_INVOCATION!>children<!>()
-                }
-            }
-        """)
-    }
-
-    fun testComposableReporting013() {
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyComponent : Component() {
-                @Children(composable=false) lateinit var children: (value: Int)->Unit
-                override fun compose() {
-                    children(5)
-                }
-            }
-        """)
-    }
-
-    fun testComposableReporting014() {
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyReceiver {}
-
-            class MyComponent : Component() {
-                @Children(composable=false) lateinit var children: MyReceiver.()->Unit
-                override fun compose() {
-                    MyReceiver().children()
-                }
-            }
-        """)
-    }
-
-    fun testComposableReporting015() {
-        checkFail("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyComponent : Component() {
-                override fun compose() {
-                    <helper1 />
-                    <helper2 />
-                }
-
-                fun helper1() {
-                    <TextView text="Hello Helper" />
-                }
-
-                @Composable
-                fun helper2() {
-                    <TextView text="Hello Helper" />
-                }
-            }
-        """)
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            class MyComponent : Component() {
-                override fun compose() {
-                    <helper1 />
-                    <helper2 />
-                }
-
-                fun <!KTX_IN_NON_COMPOSABLE!>helper1<!>() {
-                    <TextView text="Hello Helper" />
-                }
-
-                @Composable
-                fun helper2() {
-                    <TextView text="Hello Helper" />
-                }
-            }
-        """)
-    }
-
     fun testComposableReporting016() {
         check("""
             import androidx.compose.*;
@@ -378,13 +241,13 @@
             import android.widget.TextView;
 
             @Composable
-            fun Foo(@Children(composable=false) children: ()->Unit) {
+            fun Foo(children: ()->Unit) {
                 children()
             }
 
             @Composable
             fun main() {
-                <Foo><TextView text="Hello" /></Foo>
+                Foo { TextView(text="Hello") }
             }
         """)
         check("""
@@ -393,13 +256,13 @@
             import android.widget.TextView;
 
             @Composable
-            fun Foo(@Children(composable=false) children: ()->Unit) {
+            fun Foo(children: ()->Unit) {
                 children()
             }
 
             @Composable
             fun main() {
-                <Foo><!KTX_IN_NON_COMPOSABLE!><TextView text="Hello" /><!></Foo>
+                Foo { <!NONE_APPLICABLE!>TextView<!>(text="Hello") }
             }
         """)
     }
@@ -410,7 +273,7 @@
             import android.widget.TextView;
 
             fun foo() {
-                val myVariable: ()->Unit = @Composable { <TextView text="Hello World!" /> }
+                val myVariable: ()->Unit = @Composable { TextView(text="Hello World!") }
                 System.out.println(myVariable)
             }
         """)
@@ -419,51 +282,13 @@
             import android.widget.TextView;
 
             fun foo() {
-                val myVariable: ()->Unit = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>@Composable { <TextView text="Hello World!" /> }<!>
+                val myVariable: ()->Unit = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>@Composable {
+                 TextView(text="Hello World!") }<!>
                 System.out.println(myVariable)
             }
         """)
     }
 
-    fun testComposableReporting019() {
-        checkFail("""
-           import androidx.compose.*;
-           import android.widget.TextView;
-
-           @Composable
-           fun foo() {
-               val myVariable: ()->Unit = { }
-               <<!NON_COMPOSABLE_INVOCATION!>myVariable<!> />
-               System.out.println(myVariable)
-           }
-        """)
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            @Composable
-            fun foo() {
-                val nonComposableLambda: ()->Unit = { }
-                <<!NON_COMPOSABLE_INVOCATION!>nonComposableLambda<!> />
-                System.out.println(nonComposableLambda)
-            }
-        """)
-    }
-
-    fun testComposableReporting020() {
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            fun nonComposableFunction() {}
-
-            @Composable
-            fun foo() {
-                <<!NON_COMPOSABLE_INVOCATION!>nonComposableFunction<!> />
-            }
-        """)
-    }
-
     fun testComposableReporting021() {
         check("""
             import androidx.compose.*;
@@ -472,7 +297,10 @@
             @Composable
             fun foo() {
                 val myList = listOf(1,2,3,4,5)
-                myList.forEach @Composable { value: Int -> <TextView text=value.toString() />; System.out.println(value); }
+                myList.forEach @Composable { value: Int -> 
+                    TextView(text=value.toString())
+                    System.out.println(value)
+                }
             }
         """)
     }
@@ -484,34 +312,26 @@
 
             fun foo() {
                 val myList = listOf(1,2,3,4,5)
-                myList.forEach { value: Int -> <TextView text=value.toString() />; System.out.println(value); }
+                myList.forEach { value: Int -> 
+                    TextView(text=value.toString()) 
+                    System.out.println(value)
+                }
             }
         """)
         check("""
             import androidx.compose.*;
             import android.widget.TextView;
 
-            fun <!KTX_IN_NON_COMPOSABLE!>foo<!>() {
+            fun foo() {
                 val myList = listOf(1,2,3,4,5)
-                myList.forEach @Composable { value: Int -> <TextView text=value.toString() />; System.out.println(value); }
+                myList.forEach @Composable { value: Int -> 
+                    <!NONE_APPLICABLE!>TextView<!>(text=value.toString())
+                    System.out.println(value) 
+                }
             }
         """)
     }
 
-    fun testComposableReporting023() {
-        check("""
-               import androidx.compose.*;
-               import android.widget.TextView;
-
-               fun foo() {}
-
-               @Composable
-               fun bar() {
-                    <<!NON_COMPOSABLE_INVOCATION!>foo<!> />
-               }
-           """)
-    }
-
     fun testComposableReporting024() {
         check("""
             import androidx.compose.*;
@@ -519,7 +339,7 @@
             import android.widget.LinearLayout;
 
             fun foo(ll: LinearLayout) {
-                ll.setViewContent({ <TextView text="Hello World!" /> })
+                ll.setViewContent({ TextView(text="Hello World!") })
             }
         """)
     }
@@ -531,7 +351,7 @@
 
             @Composable
             fun foo() {
-                listOf(1,2,3,4,5).forEach { <TextView text="Hello World!" /> }
+                listOf(1,2,3,4,5).forEach { TextView(text="Hello World!") }
             }
         """)
     }
@@ -544,9 +364,9 @@
 
             @Composable
             fun foo() {
-                <LinearLayout>
-                    <TextView text="Hello Jim!" />
-                </LinearLayout>
+                LinearLayout {
+                    TextView(text="Hello Jim!")
+                }
             }
         """)
     }
@@ -559,11 +379,11 @@
 
             @Composable
             fun foo() {
-                <LinearLayout>
+                LinearLayout {
                     listOf(1,2,3).forEach {
-                        <TextView text="Hello Jim!" />
+                        TextView(text="Hello Jim!")
                     }
-                </LinearLayout>
+                }
             }
         """)
     }
@@ -589,29 +409,6 @@
         """)
     }
 
-    fun testComposableReporting029() {
-        checkFail("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            @Composable
-            fun foo(v: ()->Unit) {
-                val myVariable: @Composable() ()->Unit = v;
-                <myVariable />
-            }
-        """)
-        check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
-
-            @Composable
-            fun foo(v: ()->Unit) {
-                val myVariable: @Composable() ()->Unit = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>v<!>;
-                <myVariable />
-            }
-        """)
-    }
-
     fun testComposableReporting030() {
         check("""
             import androidx.compose.*;
@@ -620,7 +417,7 @@
             @Composable
             fun foo() {
                 val myVariable: @Composable() ()->Unit = {};
-                <myVariable />
+                myVariable()
             }
         """)
     }
@@ -631,7 +428,7 @@
             import android.widget.TextView;
 
             fun foo() {
-                val myVariable: ()->Unit = <!KTX_IN_NON_COMPOSABLE!>{ <TextView text="Hello" /> }<!>;
+                val myVariable: ()->Unit = { <!NONE_APPLICABLE!>TextView<!>(text="Hello") };
                 myVariable();
             }
         """)
@@ -640,15 +437,14 @@
     fun testComposableReporting032() {
         check("""
             import androidx.compose.*;
-            import androidx.compose.Children;
             import android.widget.TextView;
 
             @Composable
-            fun MyComposable(@Children children: ()->Unit) { <children /> }
+            fun MyComposable(children: @Composable() ()->Unit) { children() }
 
             @Composable
             fun foo() {
-                <MyComposable><TextView text="Hello" /></MyComposable>
+                MyComposable { TextView(text="Hello") }
             }
         """)
     }
@@ -656,15 +452,14 @@
     fun testComposableReporting033() {
         check("""
             import androidx.compose.*;
-            import androidx.compose.Children;
             import android.widget.TextView;
 
             @Composable
-            fun MyComposable(@Children children: ()->Unit) { <children /> }
+            fun MyComposable(children: @Composable() ()->Unit) { children() }
 
             @Composable
             fun foo() {
-                <MyComposable children={<TextView text="Hello" />} />
+                MyComposable(children={ TextView(text="Hello")})
             }
         """)
     }
@@ -679,7 +474,7 @@
             @Composable
             fun test(f: @Composable() ()->Unit) {
                 val f2: @Composable() ()->Unit = identity(f);
-                <f2 />
+                f2()
             }
         """)
         check("""
@@ -691,7 +486,7 @@
             @Composable
             fun test(f: @Composable() ()->Unit) {
                 val f2: @Composable() ()->Unit = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>identity(<!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>f<!>)<!>;
-                <f2 />
+                f2()
             }
         """)
     }
@@ -703,7 +498,7 @@
             @Composable
             fun Foo(x: String) {
                 @Composable operator fun String.invoke() {}
-                <x />
+                x()
             }
         """)
     }
@@ -715,7 +510,7 @@
 
             fun Foo() {
                 repeat(5) {
-                    <TextView text="Hello World" />
+                    TextView(text="Hello World")
                 }
             }
 
@@ -729,7 +524,7 @@
 
             fun Foo() {
                 repeat(5) {
-                    <TextView text="Hello World" />
+                    TextView(text="Hello World")
                 }
             }
 
@@ -746,7 +541,7 @@
 
             fun Foo() {
                 fun Noise() {
-                    <TextView text="Hello World" />
+                    TextView(text="Hello World")
                 }
             }
 
@@ -765,9 +560,9 @@
             fun repeat(x: Int, l: ()->Unit) { for(i in 1..x) l() }
 
             fun Foo() {
-                repeat(5) <!KTX_IN_NON_COMPOSABLE!>{
-                    <TextView text="Hello World" />
-                }<!>
+                repeat(5) {
+                    <!NONE_APPLICABLE!>TextView<!>(text="Hello World")
+                }
             }
         """)
     }
@@ -781,7 +576,7 @@
 
             fun Foo() {
                 composeInto {
-                    <TextView text="Hello World" />
+                    TextView(text="Hello World")
                 }
             }
 
@@ -797,7 +592,7 @@
 
             fun Foo() {
                 noise {
-                    <TextView text="Hello World" />
+                    TextView(text="Hello World")
                 }
             }
 
@@ -807,24 +602,6 @@
         """)
     }
 
-    fun testComposableReporting040() {
-        check("""
-            import androidx.compose.*
-            import android.widget.TextView;
-
-            @Composable
-            fun ComposeWrapperComposable(children: @Composable() () -> Unit) {
-                <MyComposeWrapper>
-                    <children />
-                </MyComposeWrapper>
-            }
-
-            class MyComposeWrapper(var children: @Composable() () -> Unit) : Component() {
-                override fun compose() { }
-            }
-        """)
-    }
-
     fun testComposableReporting041() {
         check("""
             import androidx.compose.*
@@ -834,50 +611,13 @@
 
             @Composable
             fun ComposeWrapperComposable(children: COMPOSABLE_UNIT_LAMBDA) {
-                <MyComposeWrapper>
-                    <children />
-                </MyComposeWrapper>
-            }
-
-            class MyComposeWrapper(var children: COMPOSABLE_UNIT_LAMBDA) : Component() {
-                override fun compose() { }
-            }
-        """)
-    }
-
-    fun testComposableReporting042() {
-        check("""
-            import androidx.compose.*
-            import android.widget.TextView;
-
-            fun composeInto(l: @Composable() ()->Unit) { System.out.println(l) }
-
-            @Composable
-            fun FancyButton() {}
-
-            fun Foo() {
-                composeInto {
-                    FancyButton()
+                MyComposeWrapper {
+                    children()
                 }
             }
 
-            fun Bar() {
-                Foo()
-            }
-        """)
-        check("""
-            import androidx.compose.*
-            import android.widget.TextView;
-
-            inline fun noise(l: ()->Unit) { l() }
-
-            @Composable
-            fun FancyButton() {}
-
-            fun <!COMPOSABLE_INVOCATION_IN_NON_COMPOSABLE!>Foo<!>() {
-                noise {
-                    <!COMPOSABLE_INVOCATION_IN_NON_COMPOSABLE!>FancyButton<!>()
-                }
+            @Composable fun MyComposeWrapper(children: COMPOSABLE_UNIT_LAMBDA) {
+                print(children.hashCode())
             }
         """)
     }
@@ -928,17 +668,18 @@
         """)
     }
 
-    fun testComposableReporting046() {
+    fun testComposableReporting047() {
         check("""
-            import androidx.compose.*;
-            import android.widget.TextView;
+            import androidx.compose.*
+            import android.widget.LinearLayout;
 
-            class MyComponent : Component() {
-                @Children lateinit var children: @Composable() ()->Unit
-                override fun compose() {
-                    val children = this.children
-                    children()
-                    System.out.println(children)
+            @Composable
+            fun FancyButton() {}
+
+            @Composable
+            fun Foo() {
+                LinearLayout {
+                    FancyButton()
                 }
             }
         """)
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/UnionCheckerTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/UnionCheckerTests.kt
index f16144c..4a03459 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/UnionCheckerTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/UnionCheckerTests.kt
@@ -31,9 +31,9 @@
 
             @Composable
             fun bar() {
-                <foo value=1 />
-                <foo value="1" />
-                <foo value=<!ILLEGAL_ASSIGN_TO_UNIONTYPE!>1f<!> />
+                foo(value=1)
+                foo(value="1")
+                foo(value=<!ILLEGAL_ASSIGN_TO_UNIONTYPE!>1f<!>)
             }
         """)
     }
@@ -49,7 +49,7 @@
 
             @Composable
             fun bar(value: @UnionType(Int::class, String::class) Any) {
-                <foo value />
+                foo(value)
             }
         """)
     }
@@ -65,7 +65,7 @@
 
             @Composable
             fun bar(value: @UnionType(Int::class, String::class) Any) {
-                <foo value />
+                foo(value)
             }
         """)
     }
@@ -81,7 +81,7 @@
 
             @Composable
             fun bar(value: @UnionType(Int::class, String::class, Float::class) Any) {
-                <foo <!ILLEGAL_ASSIGN_TO_UNIONTYPE!>value<!> />
+                foo(<!ILLEGAL_ASSIGN_TO_UNIONTYPE!>value<!>)
             }
         """)
     }
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/ComposeClassAnalysisHandlerExtensionTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/ComposeClassAnalysisHandlerExtensionTests.kt
deleted file mode 100644
index e4637a5..0000000
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/ComposeClassAnalysisHandlerExtensionTests.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package androidx.compose.plugins.kotlin.frames
-
-import androidx.compose.plugins.kotlin.AbstractComposeDiagnosticsTest
-
-class ComposeClassAnalysisHandlerExtensionTests : AbstractComposeDiagnosticsTest() {
-
-    fun testReportOpen() {
-        doTest("""
-            import androidx.compose.Component;
-
-            open class <!OPEN_COMPONENT!>MyComponent<!> : Component() {
-               override fun compose() { }
-            }
-        """)
-    }
-
-    fun testAllowClosed() {
-        doTest("""
-            import androidx.compose.Component;
-
-            class MyComponent: Component() {
-               override fun compose() { }
-            }
-        """)
-    }
-
-    fun testReportAbstract() {
-        doTest("""
-            import androidx.compose.Component;
-
-            abstract class <!OPEN_COMPONENT!>MyComponent<!>: Component() {
-               override fun compose() { }
-            }
-        """)
-    }
-}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameTransformExtensionTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameTransformExtensionTests.kt
index f9aab45..1ef4269 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameTransformExtensionTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameTransformExtensionTests.kt
@@ -226,7 +226,6 @@
           var strVal get() = myStrVal; set(value) { myStrVal = value }
         }
 
-
         class Test {
           fun test() {
             val instance = frame { MyModel() }
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ChildAnnotationChecker.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ChildAnnotationChecker.kt
deleted file mode 100644
index 2616c8f..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ChildAnnotationChecker.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
-import org.jetbrains.kotlin.psi.KtDeclaration
-import org.jetbrains.kotlin.psi.KtElement
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
-import org.jetbrains.kotlin.container.StorageComponentContainer
-import org.jetbrains.kotlin.container.useInstance
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor
-import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
-import org.jetbrains.kotlin.platform.TargetPlatform
-import org.jetbrains.kotlin.platform.jvm.isJvm
-import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
-import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
-
-open class ChildAnnotationChecker() : DeclarationChecker, StorageComponentContainerContributor {
-    override fun check(
-        declaration: KtDeclaration,
-        descriptor: DeclarationDescriptor,
-        context: DeclarationCheckerContext
-    ) {
-        if (descriptor is FunctionDescriptor) {
-            descriptor.valueParameters.forEachIndexed { index, param ->
-                if (param.hasChildrenAnnotation() &&
-                    index != descriptor.valueParameters.lastIndex) {
-                    context.trace.report(
-                        ComposeErrors.CHILDREN_MUST_BE_LAST.on(param.findPsi() as KtElement)
-                    )
-                }
-            }
-        }
-    }
-
-    override fun registerModuleComponents(
-        container: StorageComponentContainer,
-        platform: TargetPlatform,
-        moduleDescriptor: ModuleDescriptor
-    ) {
-        if (!platform.isJvm()) return
-        container.useInstance(this)
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComponentsClosedDeclarationChecker.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComponentsClosedDeclarationChecker.kt
deleted file mode 100644
index 11a987f..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComponentsClosedDeclarationChecker.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.container.StorageComponentContainer
-import org.jetbrains.kotlin.container.useInstance
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor
-import org.jetbrains.kotlin.diagnostics.reportFromPlugin
-import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtClass
-import org.jetbrains.kotlin.psi.KtDeclaration
-import androidx.compose.plugins.kotlin.analysis.ComponentMetadata
-import androidx.compose.plugins.kotlin.analysis.ComposeDefaultErrorMessages
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
-import org.jetbrains.kotlin.platform.TargetPlatform
-import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
-import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
-import org.jetbrains.kotlin.platform.jvm.isJvm
-
-class ComponentsClosedDeclarationChecker :
-    DeclarationChecker,
-    StorageComponentContainerContributor {
-
-    override fun registerModuleComponents(
-        container: StorageComponentContainer,
-        platform: TargetPlatform,
-        moduleDescriptor: ModuleDescriptor
-    ) {
-        if (!platform.isJvm()) return
-        container.useInstance(ComponentsClosedDeclarationChecker())
-    }
-
-    override fun check(
-        declaration: KtDeclaration,
-        descriptor: DeclarationDescriptor,
-        context: DeclarationCheckerContext
-    ) {
-        if (descriptor !is ClassDescriptor || declaration !is KtClass) return
-        if (descriptor.kind != ClassKind.CLASS) return
-        if (!ComponentMetadata.isComposeComponent(descriptor)) return
-
-        if (declaration.hasModifier(KtTokens.OPEN_KEYWORD) ||
-            declaration.hasModifier(KtTokens.ABSTRACT_KEYWORD)) {
-            val element = declaration.nameIdentifier ?: declaration
-            context.trace.reportFromPlugin(
-                ComposeErrors.OPEN_COMPONENT.on(element),
-                ComposeDefaultErrorMessages
-            )
-        }
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableAnnotationChecker.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableAnnotationChecker.kt
index aa1d342..3582970 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableAnnotationChecker.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableAnnotationChecker.kt
@@ -51,18 +51,20 @@
 import org.jetbrains.kotlin.psi.KtParameter
 import org.jetbrains.kotlin.psi.KtProperty
 import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.kotlin.analysis.ComponentMetadata
 import androidx.compose.plugins.kotlin.analysis.ComposeDefaultErrorMessages
 import androidx.compose.plugins.kotlin.analysis.ComposeErrors
 import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices.COMPOSABLE_ANALYSIS
 import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices.FCS_RESOLVEDCALL_COMPOSABLE
 import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices.INFERRED_COMPOSABLE_DESCRIPTOR
+import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
 import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
 import org.jetbrains.kotlin.resolve.BindingContext
 import org.jetbrains.kotlin.resolve.BindingTrace
 import org.jetbrains.kotlin.platform.TargetPlatform
 import org.jetbrains.kotlin.platform.jvm.isJvm
+import org.jetbrains.kotlin.psi.KtFunctionLiteral
+import org.jetbrains.kotlin.psi.KtLambdaArgument
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
 import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
 import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
 import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
@@ -80,21 +82,11 @@
 import org.jetbrains.kotlin.types.typeUtil.builtIns
 import org.jetbrains.kotlin.types.upperIfFlexible
 import org.jetbrains.kotlin.util.OperatorNameConventions
+import org.jetbrains.kotlin.utils.addToStdlib.cast
 
 open class ComposableAnnotationChecker : CallChecker, DeclarationChecker,
     AdditionalTypeChecker, AdditionalAnnotationChecker, StorageComponentContainerContributor {
 
-    enum class Mode {
-        /** @Composable annotations are enforced when inferred/specified **/
-        KTX_CHECKED,
-        /** @Composable annotations are explicitly required on all composables **/
-        KTX_STRICT,
-        /** @Composable annotations are explicitly required and are not subtypes of their unannotated types **/
-        KTX_PEDANTIC,
-        /** @Composable annotations are explicitly required and are not subtypes, but use FCS **/
-        FCS
-    }
-
     companion object {
         fun get(project: Project): ComposableAnnotationChecker {
             return StorageComponentContainerContributor.getInstances(project).single {
@@ -109,8 +101,6 @@
         if (resolvedCall is VariableAsFunctionResolvedCall) {
             if (resolvedCall.variableCall.candidateDescriptor.type.hasComposableAnnotation())
                 return true
-            if (resolvedCall.variableCall.candidateDescriptor.isComposableFromChildrenAnnotation())
-                return true
             if (resolvedCall.functionCall.resultingDescriptor.hasComposableAnnotation()) return true
             return false
         }
@@ -131,30 +121,27 @@
             }
         }
         if (candidateDescriptor is ValueParameterDescriptor) {
-            if (candidateDescriptor.isComposableFromChildrenAnnotation()) return true
             return candidateDescriptor.type.hasComposableAnnotation()
         }
         if (candidateDescriptor is LocalVariableDescriptor) {
             return candidateDescriptor.type.hasComposableAnnotation()
         }
         if (candidateDescriptor is PropertyDescriptor) {
-            if (candidateDescriptor.isComposableFromChildrenAnnotation()) return true
             return candidateDescriptor.type.hasComposableAnnotation()
         }
         return candidateDescriptor.hasComposableAnnotation()
     }
 
     fun analyze(trace: BindingTrace, descriptor: FunctionDescriptor): Composability {
-        val unwrappedDescriptor =
-            if (descriptor is
-                        ComposeCallResolutionInterceptorExtension.ComposableInvocationDescriptor)
-                descriptor.original
-            else descriptor
+        val unwrappedDescriptor = when (descriptor) {
+            is ComposableFunctionDescriptor -> descriptor.underlyingDescriptor
+            else -> descriptor
+        }
         val psi = unwrappedDescriptor.findPsi() as? KtElement
         psi?.let { trace.bindingContext.get(COMPOSABLE_ANALYSIS, it)?.let { return it } }
         if (unwrappedDescriptor.name == Name.identifier("compose") &&
             unwrappedDescriptor.containingDeclaration is ClassDescriptor &&
-            ComponentMetadata.isComposeComponent(unwrappedDescriptor.containingDeclaration)
+            ComposeUtils.isComposeComponent(unwrappedDescriptor.containingDeclaration)
         ) return Composability.MARKED
         var composability = Composability.NOT_COMPOSABLE
         if (trace.bindingContext.get(
@@ -176,6 +163,13 @@
                 is JavaMethodDescriptor ->
                     if (unwrappedDescriptor.hasComposableAnnotation()) composability =
                         Composability.MARKED
+                is AnonymousFunctionDescriptor -> {
+                    if (unwrappedDescriptor.hasComposableAnnotation()) composability =
+                        Composability.MARKED
+                    if (psi is KtFunctionLiteral && psi.isEmitInline(trace.bindingContext)) {
+                        composability = Composability.MARKED
+                    }
+                }
                 else -> if (unwrappedDescriptor.hasComposableAnnotation()) composability =
                     Composability.MARKED
             }
@@ -193,14 +187,9 @@
         signatureComposability: Composability
     ): Composability {
         var composability = signatureComposability
-        var localKtx = false
         var localFcs = false
         var isInlineLambda = false
         element.accept(object : KtTreeVisitorVoid() {
-            override fun visitKtxElement(element: KtxElement) {
-                localKtx = true
-            }
-
             override fun visitDeclaration(dcl: KtDeclaration) {
                 if (dcl == element) {
                     super.visitDeclaration(dcl)
@@ -219,6 +208,22 @@
             }
 
             override fun visitCallExpression(expression: KtCallExpression) {
+                val resolvedCall = expression.getResolvedCall(trace.bindingContext)
+                when (resolvedCall?.candidateDescriptor) {
+                    is ComposableEmitDescriptor,
+                    is ComposableFunctionDescriptor -> {
+                        localFcs = true
+                        if (!isInlineLambda && composability != Composability.MARKED) {
+                            // Report error on composable element to make it obvious which invocation is offensive
+                            val reportElement = expression.calleeExpression ?: expression
+                            trace.reportFromPlugin(
+                                ComposeErrors.COMPOSABLE_INVOCATION_IN_NON_COMPOSABLE
+                                    .on(reportElement),
+                                ComposeDefaultErrorMessages
+                            )
+                        }
+                    }
+                }
                 // Can be null in cases where the call isn't resolvable (eg. due to a bug/typo in the user's code)
                 val isCallComposable = trace.get(FCS_RESOLVEDCALL_COMPOSABLE, expression)
                 if (isCallComposable == true) {
@@ -237,7 +242,7 @@
             }
         }, null)
         if (
-            (localKtx || localFcs) &&
+            localFcs &&
             !isInlineLambda && composability != Composability.MARKED
         ) {
             val reportElement = when (element) {
@@ -250,14 +255,8 @@
                     ComposeDefaultErrorMessages
                 )
             }
-            if (localKtx) {
-                trace.reportFromPlugin(
-                    ComposeErrors.KTX_IN_NON_COMPOSABLE.on(reportElement),
-                    ComposeDefaultErrorMessages
-                )
-            }
         }
-        if (localKtx && composability == Composability.NOT_COMPOSABLE)
+        if (localFcs && composability == Composability.NOT_COMPOSABLE)
             composability =
                 Composability.INFERRED
         return composability
@@ -267,7 +266,7 @@
      * Analyze a KtElement
      *  - Determine if it is @Compoasble (eg. the element or inferred type has an @Composable annotation)
      *  - Update the binding context to cache analysis results
-     *  - Report errors (eg. KTX tags occur in a non-composable, invocations of an @Composable, etc)
+     *  - Report errors (eg. invocations of an @Composable, etc)
      *  - Return true if element is @Composable, else false
      */
     fun analyze(trace: BindingTrace, element: KtElement, type: KotlinType?): Composability {
@@ -283,7 +282,7 @@
                 trace.bindingContext.get(BindingContext.ANNOTATION, it)?.isComposableAnnotation
                     ?: false
             }
-            if (annotationEntry != null && !ComponentMetadata.isComposeComponent(descriptor)) {
+            if (annotationEntry != null && !ComposeUtils.isComposeComponent(descriptor)) {
                 trace.report(
                     Errors.WRONG_ANNOTATION_TARGET.on(
                         annotationEntry,
@@ -291,19 +290,11 @@
                     )
                 )
             }
-            if (ComponentMetadata.isComposeComponent(descriptor)) {
+            if (ComposeUtils.isComposeComponent(descriptor)) {
                 composability += Composability.MARKED
             }
         }
         if (element is KtParameter) {
-            val childrenAnnotation = element.annotationEntries
-                .mapNotNull { trace.bindingContext.get(BindingContext.ANNOTATION, it) }
-                .singleOrNull { it.isComposableChildrenAnnotation }
-
-            if (childrenAnnotation != null) {
-                composability += Composability.MARKED
-            }
-
             val composableAnnotation = element
                 .typeReference
                 ?.annotationEntries
@@ -315,14 +306,6 @@
             }
         }
         if (element is KtParameter) {
-            val childrenAnnotation = element.annotationEntries
-                .mapNotNull { trace.bindingContext.get(BindingContext.ANNOTATION, it) }
-                .singleOrNull { it.isComposableChildrenAnnotation }
-
-            if (childrenAnnotation != null) {
-                composability += Composability.MARKED
-            }
-
             val composableAnnotation = element
                 .typeReference
                 ?.annotationEntries
@@ -356,12 +339,18 @@
             if (descriptor.isComposableAnnotation) {
                 composability += Composability.MARKED
             }
-            if (descriptor.isComposableChildrenAnnotation) {
-                composability += Composability.MARKED
-            }
         }
 
         if (element is KtLambdaExpression || element is KtFunction) {
+            val associatedCall = parent?.parent as? KtCallExpression
+
+            if (associatedCall != null && parent is KtLambdaArgument) {
+                val resolvedCall = associatedCall.getResolvedCall(trace.bindingContext)
+                if (resolvedCall?.candidateDescriptor is ComposableEmitDescriptor) {
+                    composability += Composability.MARKED
+                }
+            }
+
             composability = analyzeFunctionContents(trace, element, composability)
         }
 
@@ -400,7 +389,7 @@
                         )?.isComposableAnnotation ?: false
                     }
                     if (composableAnnotationEntry != null &&
-                        !ComponentMetadata.isComposeComponent(classDescriptor)) {
+                        !ComposeUtils.isComposeComponent(classDescriptor)) {
                         trace.report(
                             Errors.WRONG_ANNOTATION_TARGET.on(
                                 composableAnnotationEntry,
@@ -453,6 +442,19 @@
                     )
                 if (isInlineable) return
 
+                if (expression.parent is KtLambdaArgument) {
+                    val callDescriptor = expression
+                        .parent
+                        ?.parent
+                        ?.cast<KtCallExpression>()
+                        ?.getResolvedCall(c.trace.bindingContext)
+                        ?.candidateDescriptor
+
+                    if (callDescriptor is ComposableEmitDescriptor) {
+                        return
+                    }
+                }
+
                 val reportOn =
                     if (expression.parent is KtAnnotatedExpression)
                         expression.parent as KtExpression
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableEmitDescriptor.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableEmitDescriptor.kt
index 02ae09b..f9301e9 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableEmitDescriptor.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableEmitDescriptor.kt
@@ -17,6 +17,7 @@
 package androidx.compose.plugins.kotlin
 
 import org.jetbrains.kotlin.builtins.DefaultBuiltIns
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
 import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
 import org.jetbrains.kotlin.descriptors.Modality
@@ -28,12 +29,20 @@
 import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
 import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
 import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
+import org.jetbrains.kotlin.resolve.BindingTrace
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+import org.jetbrains.kotlin.types.KotlinType
 import org.jetbrains.kotlin.types.replace
 import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
 
 class ComposableEmitDescriptor(
-    val ktxCall: ResolvedKtxElementCall,
+    val composer: ResolvedCall<*>,
+    val emitCall: ResolvedCall<*>,
+    val hasChildren: Boolean,
+    val pivotals: List<String>,
+    val ctorCall: ResolvedCall<*>,
+    val ctorParams: List<String>,
+    val validations: List<ValidatedAssignment>,
     containingDeclaration: DeclarationDescriptor,
     original: SimpleFunctionDescriptor?,
     annotations: Annotations,
@@ -50,25 +59,32 @@
 ) {
 
     companion object {
-        fun fromKtxCall(
-            ktxCall: ResolvedKtxElementCall,
-            scopeTower: ImplicitScopeTower,
+        fun build(
+            hasChildren: Boolean,
+            emitCall: ResolvedCall<*>,
+            pivotals: List<String>,
+            ctorCall: ResolvedCall<*>,
+            ctorParams: List<String>,
+            validations: List<ValidatedAssignment>,
+            composerCall: ResolvedCall<*>,
             name: Name
-        ): ComposableEmitDescriptor? {
+        ): ComposableEmitDescriptor {
 
             val builtIns = DefaultBuiltIns.Instance
-            val emitOrCall = ktxCall.emitOrCall
-            if (emitOrCall !is EmitCallNode) {
-                return null
-            }
 
-            val resolvedCall = emitOrCall.primaryCall ?: return null
+            val resolvedCall = ctorCall
 
-            val original = resolvedCall.candidateDescriptor
-                            as? SimpleFunctionDescriptor
+            val original = resolvedCall.resultingDescriptor as? SimpleFunctionDescriptor
+
             val descriptor = ComposableEmitDescriptor(
-                ktxCall,
-                ktxCall.infixOrCall!!.candidateDescriptor.containingDeclaration,
+                composerCall,
+                emitCall,
+                hasChildren,
+                pivotals,
+                ctorCall,
+                ctorParams,
+                validations,
+                emitCall.candidateDescriptor.containingDeclaration,
                 original,
                 Annotations.EMPTY,
                 name,
@@ -77,18 +93,21 @@
             )
 
             val valueArgs = mutableListOf<ValueParameterDescriptor>()
+            val paramSet = mutableSetOf<String>()
 
-            ktxCall.usedAttributes.forEachIndexed { index, attributeInfo ->
+            for (paramName in ctorParams) {
+                if (paramSet.contains(paramName)) continue
+                val param = resolvedCall.resultingDescriptor.valueParameters.find {
+                    it.name.identifier == paramName
+                } ?: continue
+
+                paramSet.add(paramName)
                 valueArgs.add(
                     ValueParameterDescriptorImpl(
-                        descriptor, null, index,
+                        descriptor, null, valueArgs.size,
                         Annotations.EMPTY,
-                        Name.identifier(
-                            if (attributeInfo.name == CHILDREN_KEY)
-                                attributeInfo.descriptor.name.identifier
-                            else attributeInfo.name
-                        ),
-                        attributeInfo.type, false,
+                        param.name,
+                        param.type, false,
                         false,
                         false, null,
                         SourceElement.NO_SOURCE
@@ -96,14 +115,40 @@
                 )
             }
 
+            for (validation in validations) {
+                if (paramSet.contains(validation.name)) continue
+                paramSet.add(validation.name)
+                valueArgs.add(
+                    ValueParameterDescriptorImpl(
+                        descriptor,
+                        null,
+                        valueArgs.size,
+                        Annotations.EMPTY,
+                        Name.identifier(validation.name),
+                        validation.type,
+                        false,
+                        false,
+                        false,
+                        null,
+                        SourceElement.NO_SOURCE
+                    )
+                )
+            }
+
             val unitLambdaType = builtIns.getFunction(
                 0
             ).defaultType.replace(
                 listOf(builtIns.unitType.asTypeProjection())
-            ).makeComposable(scopeTower.module)
-            (emitOrCall as? EmitCallNode)?.inlineChildren?.let {
+            )
+            // NOTE(lmr): it's actually kind of important that this is *not* a composable lambda,
+            // so that the observe patcher doesn't insert an observe scope.
+            // In the future, we should reconsider how this is done since semantically a composable
+            // lambda is more correct here. I tried, but had trouble passing enough information to
+            // the observe patcher so it knew not to do this.
+            /*.makeComposable(scopeTower.module)*/
+            if (hasChildren) {
                 valueArgs.add(
-                    ValueParameterDescriptorImpl(
+                    EmitChildrenValueParameterDescriptor(
                         descriptor, null, valueArgs.size,
                         Annotations.EMPTY,
                         Name.identifier("\$CHILDREN"),
@@ -128,4 +173,30 @@
             return descriptor
         }
     }
-}
\ No newline at end of file
+}
+
+class EmitChildrenValueParameterDescriptor(
+    containingDeclaration: CallableDescriptor,
+    original: ValueParameterDescriptor?,
+    index: Int,
+    annotations: Annotations,
+    name: Name,
+    outType: KotlinType,
+    declaresDefaultValue: Boolean,
+    isCrossinline: Boolean,
+    isNoinline: Boolean,
+    varargElementType: KotlinType?,
+    source: SourceElement
+) : ValueParameterDescriptorImpl(
+    containingDeclaration,
+    original,
+    index,
+    annotations,
+    name,
+    outType,
+    declaresDefaultValue,
+    isCrossinline,
+    isNoinline,
+    varargElementType,
+    source
+)
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableFunctionDescriptor.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableFunctionDescriptor.kt
index c02b0dd..fd88da2 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableFunctionDescriptor.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposableFunctionDescriptor.kt
@@ -17,6 +17,22 @@
 package androidx.compose.plugins.kotlin
 
 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
+import org.jetbrains.kotlin.descriptors.VariableDescriptor
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+import org.jetbrains.kotlin.types.TypeSubstitutor
 
-class ComposableFunctionDescriptor(val underlyingDescriptor: FunctionDescriptor) :
-    FunctionDescriptor by underlyingDescriptor
\ No newline at end of file
+class ComposableFunctionDescriptor(
+    val underlyingDescriptor: FunctionDescriptor,
+    val composerCall: ResolvedCall<*>,
+    val composerMetadata: ComposerMetadata
+) : FunctionDescriptor by underlyingDescriptor {
+    override fun substitute(substitutor: TypeSubstitutor): FunctionDescriptor? {
+        return underlyingDescriptor.substitute(substitutor)?.let {
+            ComposableFunctionDescriptor(
+                underlyingDescriptor = it,
+                composerCall = composerCall,
+                composerMetadata = composerMetadata
+            )
+        }
+    }
+}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt
index 8246059..ac4e1a9 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt
@@ -17,39 +17,35 @@
 package androidx.compose.plugins.kotlin
 
 import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION
 import com.intellij.psi.PsiElement
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
 import org.jetbrains.kotlin.descriptors.Modality
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
-import org.jetbrains.kotlin.descriptors.SourceElement
-import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.descriptors.Visibilities
-import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
+import org.jetbrains.kotlin.descriptors.VariableDescriptor
 import org.jetbrains.kotlin.extensions.CallResolutionInterceptorExtension
 import org.jetbrains.kotlin.incremental.components.LookupLocation
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.psi.KtExpression
 import org.jetbrains.kotlin.psi.KtFunction
-import org.jetbrains.kotlin.psi.KtLambdaArgument
 import org.jetbrains.kotlin.psi.KtPsiFactory
 import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.calls.CallResolver
 import org.jetbrains.kotlin.resolve.calls.CandidateResolver
 import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
 import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
+import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
 import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
 import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
 import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference
-import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinedArgument
+import org.jetbrains.kotlin.resolve.inline.InlineUtil
 import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
+import org.jetbrains.kotlin.types.KotlinType
 import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
-import org.jetbrains.kotlin.types.replace
-import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
-import org.jetbrains.kotlin.util.OperatorNameConventions
 
 class ComposeCallResolutionInterceptorExtension : CallResolutionInterceptorExtension {
     override fun interceptCandidates(
@@ -71,62 +67,59 @@
         name: Name,
         location: LookupLocation
     ): Collection<FunctionDescriptor> {
-        if (ComposeFlags.NEW_CALL_RESOLUTION_INTERCEPTION) {
-            val callResolver =
-                (scopeTower as NewResolutionOldInference.ImplicitScopeTowerImpl).callResolver
-            val element = resolutionContext.call.callElement as KtExpression
-            val project = element.project
-            val psiFactory = KtPsiFactory(project, markGenerated = false)
+        val callResolver =
+            (scopeTower as NewResolutionOldInference.ImplicitScopeTowerImpl).callResolver
+        val element = resolutionContext.call.callElement as KtExpression
+        val project = element.project
 
-            return ComposeCallResolver(
-                callResolver,
-                project,
-                psiFactory
-            ).interceptCandidates(
-                candidates,
-                scopeTower,
-                resolutionContext,
-                resolutionScope,
-                name,
-                location
-            )
-        }
         if (candidates.isEmpty()) return candidates
         val bindingContext = resolutionContext.trace.bindingContext
         val call = resolutionContext.call
-        val shouldIgnore = bindingContext[IGNORE_COMPOSABLE_INTERCEPTION, call] ?: false
+        val shouldIgnore = bindingContext[
+                ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION,
+                call
+        ] ?: false
+
         if (shouldIgnore) return candidates
 
-        for (arg in resolutionContext.call.valueArguments) {
-            if (arg is KtLambdaArgument) continue
-            if (arg.getArgumentName() != null) continue
-            return candidates
+        val composables = mutableListOf<FunctionDescriptor>()
+        val nonComposablesNonConstructors = mutableListOf<FunctionDescriptor>()
+        val constructors = mutableListOf<ConstructorDescriptor>()
+
+        var needToLookupComposer = false
+
+        for (candidate in candidates) {
+            when {
+                candidate.hasComposableAnnotation() -> {
+                    needToLookupComposer = true
+                    composables.add(candidate)
+                }
+                candidate is ConstructorDescriptor -> {
+                    needToLookupComposer = true
+                    constructors.add(candidate)
+                }
+                else -> nonComposablesNonConstructors.add(candidate)
+            }
         }
 
-        val element = resolutionContext.call.callElement as KtExpression
-        val composableAnnotationChecker =
-            ComposableAnnotationChecker.get(element.project)
-
-        val context = ExpressionTypingContext.newContext(
-            resolutionContext.trace,
-            resolutionContext.scope,
-            resolutionContext.dataFlowInfo,
-            resolutionContext.expectedType,
-            resolutionContext.languageVersionSettings,
-            resolutionContext.dataFlowValueFactory
-        )
+        // If none of the candidates are composable or constructors, then it's unnecessary for us
+        // to do any work at all, since it will never be anything we intercept
+        if (!needToLookupComposer) return candidates
 
         val temporaryTraceForKtxCall =
-                TemporaryTraceAndCache.create(
-                        context,
-                        "trace to resolve ktx call", element
-                )
-        val temporaryForKtxCall = context.replaceTraceAndCache(temporaryTraceForKtxCall)
+            TemporaryTraceAndCache.create(
+                resolutionContext,
+                "trace to resolve ktx call", element
+            )
+
+        val composableAnnotationChecker =
+            ComposableAnnotationChecker.get(call.callElement.project)
 
         // Ensure we are in a composable context
-        var walker: PsiElement? = element
+        // TODO(lmr): there ought to be a better way to do this
+        var walker: PsiElement? = call.callElement
         var isComposableContext = false
-        var composableDescriptor: SimpleFunctionDescriptor? = null
+//        var composableDescriptor: SimpleFunctionDescriptor? = null
         while (walker != null) {
             val descriptor = try {
                 resolutionContext.trace[BindingContext.FUNCTION, walker]
@@ -139,189 +132,198 @@
                     descriptor
                 )
                 isComposableContext =
-                        composability != ComposableAnnotationChecker.Composability.NOT_COMPOSABLE
-                if (isComposableContext) composableDescriptor = descriptor
+                    composability != ComposableAnnotationChecker.Composability.NOT_COMPOSABLE
+//                if (isComposableContext) composableDescriptor = descriptor
 
                 // If the descriptor is for an inlined lambda, infer composability from the
                 // outer scope
                 if (!(walker is KtFunction) ||
-                        !isInlinedArgument(
-                                walker,
-                                context.trace.bindingContext,
-                                true))
+                    !InlineUtil.isInlinedArgument(
+                        walker,
+                        resolutionContext.trace.bindingContext,
+                        true
+                    )
+                )
                     break
             }
             walker = try { walker.parent } catch (e: Throwable) { null }
         }
         if (!isComposableContext) return candidates
 
-        val callResolver =
-            (scopeTower as NewResolutionOldInference.ImplicitScopeTowerImpl).callResolver
-        val ktxCallResolver = KtxCallResolver(
+        // use the call resolver to find any variable that would resolve with "composer" in scope.
+        val composerCall = callResolver.resolveComposer(resolutionContext)
+        val composer = composerCall?.resultingDescriptor as? VariableDescriptor
+
+        // If there is no composer in scope, then we cannot intercept. This means that we need to
+        // remove any @Composable from the candidates
+        if (composer == null) {
+            return nonComposablesNonConstructors + constructors
+        }
+
+        val psiFactory = KtPsiFactory(project, markGenerated = false)
+
+        // If we made it this far, we need to check and see if the constructors qualify as emit
+        // calls instead of constructor calls.  First, we need to look at the composer to see
+        // what kinds of "emittables" it accepts.
+        // We cache the metadata into a writeable slice based on the descriptor
+        val composerMetadata = ComposerMetadata.getOrBuild(
+            composer,
             callResolver,
-            null,
-            element.project,
-            composableAnnotationChecker
+            psiFactory,
+            resolutionContext
         )
 
-        val resolvedKtxElementCall = try {
+        // TODO(lmr):
+        // We might decide there are some composers that are not "valid", ie, I shouldn't be able
+        // to call a composable if I just have `val composer = Unit` in scope... Right now we are
+        // just seeing if there are call descriptors. In the future, more validation might be
+        // warranted
+        val isValidComposer = composerMetadata.callDescriptors.isNotEmpty()
 
-            ktxCallResolver.initializeFromCall(call, temporaryForKtxCall)
-
-            ktxCallResolver.resolveFromCall(
-                call,
-                temporaryForKtxCall
-            )
-        } catch (e: Throwable) {
-            e.printStackTrace()
-            throw e
+        if (!isValidComposer) {
+            return nonComposablesNonConstructors + constructors
         }
 
-        // Doesn't appear to be resolvable to a composable; return normal resolution candidates
-        val resolvedCall = when (resolvedKtxElementCall.emitOrCall) {
-            is MemoizedCallNode -> resolvedKtxElementCall.emitOrCall.call.resolvedCalls().first()
-            is EmitCallNode -> resolvedKtxElementCall.emitOrCall.resolvedCalls().first()
-            is ErrorNode -> return candidates
-            else ->
-                throw Error("Unexpectd type: " + resolvedKtxElementCall.emitOrCall.javaClass)
-        }
-
-        if (resolvedKtxElementCall.emitOrCall is MemoizedCallNode &&
-                !ComposableAnnotationChecker.get(element.project).shouldInvokeAsTag(
-                    temporaryForKtxCall.trace,
-                    resolvedCall
-                ))
-            return candidates
-        val candidateDescriptor = resolvedCall.candidateDescriptor
-        if (candidateDescriptor is FunctionDescriptor && candidateDescriptor.isOperator &&
-                candidateDescriptor.name == OperatorNameConventions.INVOKE)
-            return candidates
-
-        // If control flow gets here, we are intercepting this call.
-
-        val original = when (resolvedKtxElementCall.emitOrCall) {
-            is MemoizedCallNode -> {
-                resolvedKtxElementCall.emitOrCall.call.resolvedCalls().first().candidateDescriptor
-                        as? SimpleFunctionDescriptor
+        // If there are no constructors, then all of the candidates are either composables or
+        // non-composable functions, and we follow normal resolution rules.
+        if (constructors.isEmpty()) {
+            // we wrap the composable descriptors into a ComposableFunctionDescriptor so we know
+            // to intercept it in the backend.
+            return nonComposablesNonConstructors + composables.map {
+                ComposableFunctionDescriptor(it, composerCall, composerMetadata)
             }
-            else -> null
         }
 
-        val descriptor =
-            ComposableInvocationDescriptor(
-                element,
-                resolvedKtxElementCall,
-                resolvedKtxElementCall.infixOrCall!!.candidateDescriptor.containingDeclaration,
-                original,
-                Annotations.EMPTY,
-                name,
-                CallableMemberDescriptor.Kind.SYNTHESIZED,
-                SourceElement.NO_SOURCE
-            )
+        val emittables = constructors.filter {
+            composerMetadata.isEmittable(it.returnType) && !it.returnType.isAbstract()
+        }
+        val hasEmittableCandidate = emittables.isNotEmpty()
 
-        val valueArgs = mutableListOf<ValueParameterDescriptor>()
-
-        resolvedKtxElementCall.usedAttributes.forEachIndexed { index, attributeInfo ->
-            valueArgs.add(
-                ValueParameterDescriptorImpl(
-                    descriptor, null, index,
-                    Annotations.EMPTY,
-                    Name.identifier(
-                            if (attributeInfo.name == CHILDREN_KEY)
-                                attributeInfo.descriptor.name.identifier
-                            else attributeInfo.name
-                    ),
-                    attributeInfo.type, false,
-                    false,
-                    false, null,
-                    SourceElement.NO_SOURCE
-                )
-            )
+        // if none of the constructors are emittables, then all of the candidates are valid
+        if (!hasEmittableCandidate) {
+            return nonComposablesNonConstructors + constructors + composables.map {
+                ComposableFunctionDescriptor(it, composerCall, composerMetadata)
+            }
         }
 
-        val unitLambdaType = scopeTower.module.builtIns.getFunction(
-                0
-        ).defaultType.replace(
-                listOf(scopeTower.module.builtIns.unitType.asTypeProjection())
-        ).makeComposable(scopeTower.module)
-        (resolvedKtxElementCall.emitOrCall as? EmitCallNode)?.inlineChildren?.let {
-            valueArgs.add(
-                ValueParameterDescriptorImpl(
-                    descriptor, null, valueArgs.size,
-                    Annotations.EMPTY,
-                    Name.identifier("\$CHILDREN"),
-                    unitLambdaType, false,
-                    false,
-                    false, null,
-                    SourceElement.NO_SOURCE
-                )
-            )
-        }
+        // since some of the constructors are emittables, we fall back to resolving using the
+        // emit resolver.
+        val emitResolver = ComposeEmitResolver(
+            callResolver,
+            project,
+            composerMetadata
+        )
 
+        val context = ExpressionTypingContext.newContext(
+            resolutionContext.trace,
+            resolutionContext.scope,
+            resolutionContext.dataFlowInfo,
+            resolutionContext.expectedType,
+            resolutionContext.languageVersionSettings,
+            resolutionContext.dataFlowValueFactory
+        )
+
+        val temporaryForKtxCall = context.replaceTraceAndCache(temporaryTraceForKtxCall)
+
+        val emitCandidates = emitResolver.resolveCandidates(
+            call,
+            emittables,
+            composerCall,
+            name,
+            temporaryForKtxCall
+        )
+
+        // TODO(lmr): deal with the RESTART_CALLS_NEEDED stuff for restartGroups
         // Once we know we have a valid binding to a composable function call see if the scope need
         // the startRestartGroup and endRestartGroup information
-        val trace = temporaryTraceForKtxCall.trace
-        if (trace.get(
-                ComposeWritableSlices.RESTART_CALLS_NEEDED,
-                composableDescriptor!!
-            ) != false) {
-            val recordingContext = TemporaryTraceAndCache.create(
-                context,
-                "trace to resolve ktx call", element
-            )
-            val recordingTrace = recordingContext.trace
-            recordingTrace.record(
-                ComposeWritableSlices.RESTART_CALLS_NEEDED,
-                composableDescriptor,
-                false
-            )
+//        val trace = temporaryTraceForKtxCall.trace
+//        if (trace.get(
+//                ComposeWritableSlices.RESTART_CALLS_NEEDED,
+//                composableDescriptor!!
+//            ) != false) {
+//            val recordingContext = TemporaryTraceAndCache.create(
+//                context,
+//                "trace to resolve ktx call", element
+//            )
+//            val recordingTrace = recordingContext.trace
+//            recordingTrace.record(
+//                ComposeWritableSlices.RESTART_CALLS_NEEDED,
+//                composableDescriptor,
+//                false
+//            )
+//
+//            val startRestartGroup = ktxCallResolver.resolveStartRestartGroup(
+//                call,
+//                temporaryForKtxCall
+//            )
+//            val endRestartGroup = ktxCallResolver.resolveEndRestartGroup(call, temporaryForKtxCall)
+//            val composerCall = ktxCallResolver.resolveComposerCall()
+//            if (startRestartGroup != null && endRestartGroup != null && composerCall != null) {
+//                recordingTrace.record(
+//                    ComposeWritableSlices.RESTART_CALLS, composableDescriptor,
+//                    ResolvedRestartCalls(
+//                        startRestartGroup = startRestartGroup,
+//                        endRestartGroup = endRestartGroup,
+//                        composer = composerCall
+//                    )
+//                )
+//            }
+//            recordingTrace.commit()
+//        }
 
-            val startRestartGroup = ktxCallResolver.resolveStartRestartGroup(
-                call,
-                temporaryForKtxCall
-            )
-            val endRestartGroup = ktxCallResolver.resolveEndRestartGroup(call, temporaryForKtxCall)
-            val composerCall = ktxCallResolver.resolveComposerCall()
-            if (startRestartGroup != null && endRestartGroup != null && composerCall != null) {
-                recordingTrace.record(
-                    ComposeWritableSlices.RESTART_CALLS, composableDescriptor,
-                    ResolvedRestartCalls(
-                        startRestartGroup = startRestartGroup,
-                        endRestartGroup = endRestartGroup,
-                        composer = composerCall
-                    )
-                )
-            }
-            recordingTrace.commit()
-        }
-
-        descriptor.initialize(
-            null,
-            null,
-            mutableListOf(),
-            valueArgs,
-            scopeTower.module.builtIns.unitType,
-            Modality.FINAL,
-            Visibilities.DEFAULT_VISIBILITY
-        )
-
-        return listOf(descriptor)
+        return nonComposablesNonConstructors +
+                composables.map {
+                    ComposableFunctionDescriptor(it, composerCall, composerMetadata)
+                } +
+                constructors.filter { !composerMetadata.isEmittable(it.returnType) } +
+                emitCandidates
     }
 
-    class ComposableInvocationDescriptor(
-        val element: KtExpression,
-        val ktxCall: ResolvedKtxElementCall,
-        containingDeclaration: DeclarationDescriptor,
-        original: SimpleFunctionDescriptor?,
-        annotations: Annotations,
+    private fun CallResolver.resolveVar(
         name: Name,
-        kind: CallableMemberDescriptor.Kind,
-        source: SourceElement
-    ) : SimpleFunctionDescriptorImpl(
-        containingDeclaration,
-        original,
-        annotations,
-        name,
-        kind,
-        source)
+        context: BasicCallResolutionContext
+    ): OverloadResolutionResults<CallableDescriptor> {
+        val temporaryForVariable = TemporaryTraceAndCache.create(
+            context,
+            "trace to resolve variable",
+            context.call.callElement as KtExpression
+        )
+        val call = makeCall(context.call.callElement)
+        val contextForVariable = BasicCallResolutionContext.create(
+            context.replaceTraceAndCache(temporaryForVariable),
+            call,
+            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
+            DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
+
+        )
+        contextForVariable.trace.record(
+            ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION,
+            call,
+            true
+        )
+        return computeTasksAndResolveCall<CallableDescriptor>(
+            contextForVariable,
+            name,
+            TracingStrategy.EMPTY,
+            NewResolutionOldInference.ResolutionKind.Variable
+        )
+    }
+
+    private fun CallResolver.resolveComposer(context: BasicCallResolutionContext):
+            ResolvedCall<CallableDescriptor>? {
+
+        // The composer is currently resolved as whatever is currently in scope with the name "composer".
+        val resolvedComposer = resolveVar(KtxNameConventions.COMPOSER, context)
+
+        if (!resolvedComposer.isSuccess) {
+            return null
+        }
+
+        return resolvedComposer.resultingCall
+    }
+
+    private fun KotlinType.isAbstract(): Boolean {
+        val modality = (constructor.declarationDescriptor as? ClassDescriptor)?.modality
+        return modality == Modality.ABSTRACT || modality == Modality.SEALED
+    }
 }
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolver.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolver.kt
deleted file mode 100644
index d745bbb..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolver.kt
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION
-import com.intellij.openapi.project.Project
-import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.VariableDescriptor
-import org.jetbrains.kotlin.extensions.CallResolutionInterceptorExtension
-import org.jetbrains.kotlin.incremental.components.LookupLocation
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.resolve.calls.CallResolver
-import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
-import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
-import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
-import org.jetbrains.kotlin.resolve.scopes.LexicalScope
-import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
-import org.jetbrains.kotlin.resolve.scopes.utils.collectVariables
-import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
-
-class ComposeCallResolver(
-    private val callResolver: CallResolver,
-    private val project: Project,
-    private val psiFactory: KtPsiFactory
-) {
-
-    @Suppress("UNUSED_PARAMETER")
-    fun interceptCandidates(
-        candidates: Collection<FunctionDescriptor>,
-        scopeTower: ImplicitScopeTower,
-        resolutionContext: BasicCallResolutionContext,
-        resolutionScope: ResolutionScope,
-        name: Name,
-        location: LookupLocation
-    ): Collection<FunctionDescriptor> {
-        if (candidates.isEmpty()) return candidates
-        val bindingContext = resolutionContext.trace.bindingContext
-        val call = resolutionContext.call
-        val shouldIgnore = bindingContext[IGNORE_COMPOSABLE_INTERCEPTION, call] ?: false
-
-        if (shouldIgnore) return candidates
-
-        val composables = mutableListOf<FunctionDescriptor>()
-        val nonComposables = mutableListOf<FunctionDescriptor>()
-        val constructors = mutableListOf<ConstructorDescriptor>()
-
-        var needToLookupComposer = false
-
-        for (candidate in candidates) {
-            if (candidate.hasComposableAnnotation()) {
-                needToLookupComposer = true
-                composables.add(candidate)
-            } else {
-                nonComposables.add(candidate)
-            }
-            if (candidate is ConstructorDescriptor) {
-                needToLookupComposer = true
-                constructors.add(candidate)
-            }
-        }
-
-        // If none of the candidates are composable or constructors, then it's unnecessary for us
-        // to do any work at all, since it will never be anything we intercept
-        if (!needToLookupComposer) return candidates
-
-        // use the scope tower to find any variable that would resolve with "composer" in scope.
-        val composer = scopeTower
-            .lexicalScope
-            .collectVariables(KtxNameConventions.COMPOSER, location)
-            .firstOrNull()
-
-        // If there is no composer in scope, then we cannot intercept. This means that we need to
-        // remove any @Composable from the candidates
-        if (composer == null) {
-            return nonComposables
-        }
-
-        // TODO(lmr): figure out if we need to do something here
-        // We might decide there are some composers that are not "valid", ie, I shouldn't be able
-        // to call a composable if I just have `val composer = Unit` in scope... but with this
-        // logic, you'd be able to. This will get refined as we pass a composer as a variable.
-        val isValidComposer = true
-
-        // If there are no constructors, then all of the candidates are either composables or
-        // non-composable functions, and we follow normal resolution rules.
-        if (isValidComposer && constructors.isEmpty()) {
-            // we wrap the composable descriptors into a ComposableFunctionDescriptor so we know
-            // to intercept it in the backend.
-            return nonComposables + composables.map { ComposableFunctionDescriptor(it) }
-        }
-
-        // If we made it this far, we need to check and see if the constructors qualify as emit
-        // calls instead of constructor calls.  First, we need to look at the composer to see
-        // what kinds of "emittables" it accepts.
-        // We cache the metadata into a writeable slice based on the descriptor
-        val emitMetadata = ComposerEmitMetadata.getOrBuild(
-            composer,
-            callResolver,
-            psiFactory,
-            resolutionContext
-        )
-
-        val hasEmittableCandidate = constructors.any { emitMetadata.isEmittable(it.returnType) }
-
-        // if none of the constructors are emittables, then all of the candidates are valid
-        if (!hasEmittableCandidate) {
-            return nonComposables + composables.map { ComposableFunctionDescriptor(it) }
-        }
-
-        // since some of the constructors are emittables, we fall back to resolving using the
-        // ktx call resolver. This needs to be refactored to be simpler, but this should work as
-        // a starting point.
-        //
-        // TODO(lmr): refactor this to remove KtxCallResolver
-        val ktxCallResolver = KtxCallResolver(
-            callResolver,
-            null,
-            project,
-            ComposableAnnotationChecker.get(project)
-        )
-
-        val context = ExpressionTypingContext.newContext(
-            resolutionContext.trace,
-            resolutionContext.scope,
-            resolutionContext.dataFlowInfo,
-            resolutionContext.expectedType,
-            resolutionContext.languageVersionSettings,
-            resolutionContext.dataFlowValueFactory
-        )
-
-        val element = call.callElement as KtExpression
-
-        val temporaryTraceForKtxCall =
-            TemporaryTraceAndCache.create(
-                context,
-                "trace to resolve ktx call", element
-            )
-
-        val temporaryForKtxCall = context.replaceTraceAndCache(temporaryTraceForKtxCall)
-
-        ktxCallResolver.initializeFromCall(call, temporaryForKtxCall)
-
-        val resolvedKtxElementCall = ktxCallResolver.resolveFromCall(
-            call,
-            temporaryForKtxCall
-        )
-
-        val result = ComposableEmitDescriptor.fromKtxCall(
-            resolvedKtxElementCall,
-            scopeTower,
-            name
-        )
-
-        if (result == null) {
-            return nonComposables +
-                    composables.map { ComposableFunctionDescriptor(it) } +
-                    constructors.filter { !emitMetadata.isEmittable(it.returnType) }
-        }
-
-        // TODO(lmr): deal with this RESTART_CALLS_NEEDED stuff
-        // Once we know we have a valid binding to a composable function call see if the scope need
-        // the startRestartGroup and endRestartGroup information
-
-        return listOf(result)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeEmitResolver.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeEmitResolver.kt
new file mode 100644
index 0000000..8739253
--- /dev/null
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeEmitResolver.kt
@@ -0,0 +1,1584 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.plugins.kotlin
+
+import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
+import com.intellij.lang.ASTNode
+import com.intellij.openapi.project.Project
+import com.intellij.psi.impl.source.tree.LeafPsiElement
+import com.intellij.util.SmartList
+import org.jetbrains.kotlin.builtins.DefaultBuiltIns
+import org.jetbrains.kotlin.builtins.createFunctionType
+import org.jetbrains.kotlin.builtins.extractParameterNameFromFunctionTypeArgument
+import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
+import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
+import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
+import org.jetbrains.kotlin.builtins.isExtensionFunctionType
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.ClassKind
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.descriptors.FunctionDescriptor
+import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
+import org.jetbrains.kotlin.descriptors.PropertyDescriptor
+import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
+import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
+import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
+import org.jetbrains.kotlin.descriptors.VariableDescriptor
+import org.jetbrains.kotlin.descriptors.Visibilities
+import org.jetbrains.kotlin.descriptors.annotations.Annotations
+import org.jetbrains.kotlin.diagnostics.Severity
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.psi.Call
+import org.jetbrains.kotlin.psi.KtElement
+import org.jetbrains.kotlin.psi.KtExpression
+import org.jetbrains.kotlin.psi.KtLambdaArgument
+import org.jetbrains.kotlin.psi.KtPsiFactory
+import org.jetbrains.kotlin.psi.KtQualifiedExpression
+import org.jetbrains.kotlin.psi.KtReferenceExpression
+import org.jetbrains.kotlin.psi.KtSimpleNameExpression
+import org.jetbrains.kotlin.psi.ValueArgument
+import org.jetbrains.kotlin.psi.ValueArgumentName
+import org.jetbrains.kotlin.builtins.isFunctionType
+import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.descriptors.SourceElement
+import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
+import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
+import org.jetbrains.kotlin.psi.KtTypeArgumentList
+import org.jetbrains.kotlin.psi.KtTypeProjection
+import org.jetbrains.kotlin.psi.KtValueArgumentList
+import org.jetbrains.kotlin.psi.LambdaArgument
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.BindingTrace
+import org.jetbrains.kotlin.resolve.DescriptorFactory
+import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
+import org.jetbrains.kotlin.resolve.calls.CallResolver
+import org.jetbrains.kotlin.resolve.calls.checkers.UnderscoreUsageChecker
+import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
+import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
+import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
+import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
+import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
+import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatchStatus
+import org.jetbrains.kotlin.resolve.calls.model.ArgumentUnmapped
+import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl
+import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
+import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
+import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
+import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil
+import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
+import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
+import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
+import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl
+import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference
+import org.jetbrains.kotlin.resolve.calls.util.CallMaker
+import org.jetbrains.kotlin.resolve.descriptorUtil.module
+import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
+import org.jetbrains.kotlin.resolve.scopes.MemberScope
+import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
+import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
+import org.jetbrains.kotlin.resolve.scopes.receivers.PackageQualifier
+import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
+import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
+import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
+import org.jetbrains.kotlin.resolve.scopes.receivers.TypeAliasQualifier
+import org.jetbrains.kotlin.resolve.scopes.receivers.TypeParameterQualifier
+import org.jetbrains.kotlin.resolve.scopes.receivers.expression
+import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
+import org.jetbrains.kotlin.resolve.scopes.utils.findFirstFromMeAndParent
+import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
+import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
+import org.jetbrains.kotlin.synthetic.isVisibleOutside
+import org.jetbrains.kotlin.types.ErrorUtils
+import org.jetbrains.kotlin.types.KotlinType
+import org.jetbrains.kotlin.types.TypeConstructor
+import org.jetbrains.kotlin.types.TypeSubstitutor
+import org.jetbrains.kotlin.types.TypeUtils
+import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
+import org.jetbrains.kotlin.types.checker.KotlinTypeCheckerImpl
+import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
+import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
+import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
+import org.jetbrains.kotlin.types.typeUtil.equalTypesOrNulls
+import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
+import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
+import org.jetbrains.kotlin.types.typeUtil.isUnit
+import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
+import java.util.Locale
+
+/**
+ * This class is used to resolve a KTX Element to the corresponding set of calls on the composer, and the individual calls for
+ * each attribute, etc.
+ */
+class ComposeEmitResolver(
+    callResolver: CallResolver,
+    project: Project,
+    private val composer: ComposerMetadata
+) {
+
+    private val callResolver = NoInterceptionCallResolver(callResolver)
+
+    private class TempParameterInfo(
+        val attribute: AttributeInfo,
+        val descriptor: DeclarationDescriptor
+    )
+
+    // NOTE(lmr): I am unsure of the performance consequences of using KtPsiFactory. it appears to create a file for every
+    // call, which seems like something we definitely do not want, but it's also used in resolving for(..) loops, so
+    // maybe it's not terrible.
+    private val psiFactory = KtPsiFactory(project, markGenerated = false)
+
+    private fun KotlinType.isEmittable() = composer.isEmittable(this)
+
+    private fun KotlinType.isCompoundEmittable() = composer.isCompoundEmittable(this)
+
+    private fun isImplicitConstructorParam(
+        param: ValueParameterDescriptor,
+        fn: CallableDescriptor
+    ) = composer.isImplicitConstructorParam(param, fn)
+
+    fun resolveCandidates(
+        call: Call,
+        candidates: Collection<FunctionDescriptor>,
+        getComposerCall: ResolvedCall<*>,
+        name: Name,
+        context: ExpressionTypingContext
+    ): List<ComposableEmitDescriptor> {
+        val openTagExpr = call.calleeExpression ?: error("Expected calleeExpression")
+
+        val tmpTraceAndCache = TemporaryTraceAndCache.create(
+            context,
+            "trace for ktx tag",
+            openTagExpr
+        )
+
+        val contextToUse = context.replaceTraceAndCache(tmpTraceAndCache)
+
+        val attrInfos = mutableMapOf<String, AttributeInfo>()
+
+        for (arg in call.valueArguments) {
+            if (arg is KtLambdaArgument) continue
+
+            // NOTE: emits *must* use all named parameters. If they don't, we will not resolve them.
+            val argName = arg.getArgumentName() ?: return emptyList()
+
+            val key = argName.referenceExpression
+            val value = arg.getArgumentExpression()
+            val identifier = argName.asName.asString()
+
+            // NOTE: We don't have to check for duplicate argument names, that will be done elsewhere.
+
+            // NOTE: We don't have to deal with punning. punning isn't supported in FCS.
+
+            attrInfos[identifier] = AttributeInfo(
+                value = value ?: error("expected a value expression"),
+                key = key,
+                name = identifier
+            )
+        }
+
+        for (arg in call.functionLiteralArguments) {
+            if (attrInfos.containsKey(CHILDREN_KEY))
+                error("Only one children argument supported at a time")
+            attrInfos[CHILDREN_KEY] =
+                AttributeInfo(
+                    value = arg.getLambdaExpression() ?: error("expected a value expression"),
+                    key = null,
+                    name = CHILDREN_KEY
+                )
+        }
+
+        val receiver = resolveReceiver(openTagExpr, contextToUse)
+
+        attrInfos[TAG_KEY] =
+            AttributeInfo(
+                value = when (receiver) {
+                    is ExpressionReceiver -> receiver.expression
+                    else -> openTagExpr
+                },
+                key = null,
+                name = TAG_KEY
+            )
+
+        val result = resolveChild(
+            openTagExpr,
+            candidates,
+            getComposerCall,
+            name,
+            makeCall(
+                callElement = call.callElement,
+                calleeExpression = call.calleeExpression,
+                receiver = call.explicitReceiver,
+                dispatchReceiver = call.dispatchReceiver
+            ),
+            attrInfos,
+            context
+        )
+
+        tmpTraceAndCache.commit()
+        return result
+    }
+
+    private fun resolveChild(
+        expression: KtExpression,
+        candidates: Collection<FunctionDescriptor>,
+        getComposerCall: ResolvedCall<*>,
+        name: Name,
+        call: Call,
+        attributes: Map<String, AttributeInfo>,
+        context: ExpressionTypingContext
+    ): List<ComposableEmitDescriptor> {
+        return candidates
+            .mapNotNull { result ->
+            val tmpForCandidate = TemporaryTraceAndCache.create(
+                context, "trace to resolve ktx element", expression
+            )
+
+            val trace: BindingTrace = tmpForCandidate.trace
+
+            val candidateContext = context
+                .replaceTraceAndCache(tmpForCandidate)
+                .replaceBindingTrace(trace)
+
+            val attrsUsedInCall = mutableSetOf<String>()
+
+            val attrsUsedInSets = mutableSetOf<String>()
+
+            val subMissingRequiredAttributes = mutableListOf<DeclarationDescriptor>()
+
+            val usedAttributeInfos = mutableListOf<TempParameterInfo>()
+
+            val candidateResults = resolveCandidate(
+                result,
+                call,
+                attributes,
+                attrsUsedInCall,
+                usedAttributeInfos,
+                subMissingRequiredAttributes,
+                candidateContext
+            )
+
+            if (candidateResults.isNothing)
+                return@mapNotNull null
+
+            val resolvedCall = candidateResults.resultingCalls.first()
+
+            if (!candidateResults.isSuccess) {
+                when (candidateResults.resultCode) {
+                    OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH -> {
+                        resolvedCall.call.valueArguments.map {
+                            resolvedCall.getArgumentMapping(it)
+                        }.forEach {
+                            when (it) {
+                                is ArgumentMatch -> {
+                                    when (it.status) {
+                                        ArgumentMatchStatus.TYPE_MISMATCH -> {
+                                            return@forEach
+                                        }
+                                        ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES -> {
+                                            return@forEach
+                                        }
+                                        ArgumentMatchStatus.UNKNOWN -> {
+                                            // NOTE(lmr): This can happen with the implicit constructor params. ignore it
+                                        }
+                                        ArgumentMatchStatus.SUCCESS -> {
+                                            // do nothing
+                                        }
+                                        ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE -> {
+                                            // NOTE(lmr): This can happen when the attribute has no value expression, since
+                                            // we pass in a fake psi node for the value in that case.
+                                        }
+                                    }
+                                }
+                                is ArgumentUnmapped -> {
+                                    return@mapNotNull null
+                                }
+                            }
+                        }
+                    }
+                    OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE,
+                    OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES,
+                    OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER -> {
+                        return@mapNotNull null
+                    }
+                    else -> {
+                        error("new kind of resolution problem. figure out why this happened...")
+                    }
+                }
+            }
+
+            if (
+                !descriptorsEqualWithSubstitution(
+                    resolvedCall.semanticCall.candidateDescriptor.original,
+                    result.original
+                )
+            ) {
+                // if this happens, we've likely resolved the candidate to one of the other candidates, and we don't want that.
+                // we fail in this case, since it will succeed once we actually process the candidate that this resolved to.
+                return@mapNotNull null
+            }
+
+            val returnType = resolvedCall.resultingDescriptor.returnType ?: builtIns.unitType
+
+            if (!returnType.isEmittable()) return@mapNotNull null
+
+            var hasChildren = false
+
+            val emitCall = resolveComposerEmit(
+                constructedType = returnType,
+                hasBody = attributes.contains(CHILDREN_KEY),
+                implicitCtorTypes = resolvedCall.call.valueArguments.mapNotNull {
+                    (it as? ImplicitCtorValueArgument)?.type
+                },
+                expressionToReportErrorsOn = expression,
+                context = candidateContext
+            ) ?: return@mapNotNull null
+
+            if (attributes.contains(CHILDREN_KEY) && returnType.isCompoundEmittable()) {
+                attrsUsedInSets.add(CHILDREN_KEY)
+                hasChildren = true
+            }
+
+            val updateReceiverScope = emitCall
+                .resultingDescriptor
+                .valueParameters
+                .first { it.name == KtxNameConventions.EMIT_UPDATER_PARAMETER }
+                .type
+                .getReceiverTypeFromFunctionType() ?: error("Expected receiver type")
+
+            val setterValidations = resolveAllSetAttributes(
+                expressionToReportErrorsOn = expression,
+                receiverScope = updateReceiverScope,
+                type = returnType,
+                attributes = attributes,
+                attributesUsedInCall = attrsUsedInCall,
+                consumedAttributes = attrsUsedInSets,
+                missingRequiredAttributes = subMissingRequiredAttributes,
+                context = candidateContext
+            )
+
+            val pivotals = resolvePivotalAttributes(
+                attributes,
+                attrsUsedInCall,
+                usedAttributeInfos,
+                setterValidations,
+                returnType
+            )
+
+            return@mapNotNull ComposableEmitDescriptor.build(
+                hasChildren = hasChildren,
+                ctorCall = resolvedCall,
+                validations = setterValidations,
+                pivotals = pivotals,
+                ctorParams = resolvedCall.buildParamsFromAttributes(attributes),
+                composerCall = getComposerCall,
+                emitCall = emitCall,
+                name = name
+            )
+        }
+    }
+
+    private fun resolvePivotalAttributes(
+        attributes: Map<String, AttributeInfo>,
+        attrsUsedInCall: Set<String>,
+        callParamInfos: List<TempParameterInfo>,
+        validations: List<ValidatedAssignment>,
+        returnType: KotlinType?
+    ): List<String> {
+        val result = mutableListOf<String>()
+
+        if (returnType == null || returnType.isUnit()) {
+            return callParamInfos
+                .filter { it.descriptor.hasPivotalAnnotation() }
+                .map {
+                    it.attribute.name
+                }
+        }
+
+        val validationSet = validations.map { it.name }.toSet()
+
+        // if you were in the ctor call but not in the sets, you *have* to be pivotal
+        for (info in callParamInfos) {
+            if (validationSet.contains(info.attribute.name)) continue
+            attributes[info.attribute.name] ?: continue
+            result.add(info.attribute.name)
+        }
+
+        // There are additional cases where attributes can be pivotal:
+        //   1. It is annotated as @Pivotal
+        //   2. It is a `val` ctor parameter
+        for (assignment in validations) {
+            val name = assignment.name
+            val descriptor = assignment.descriptor
+
+            if (descriptor.hasPivotalAnnotation()) {
+                result.add(name)
+                continue
+            }
+            if (descriptor is PropertyDescriptor &&
+                attrsUsedInCall.contains(name) && !descriptor.isVar) {
+                result.add(name)
+                continue
+            }
+        }
+
+        return result
+    }
+
+    private fun ResolvedCall<*>.buildParamsFromAttributes(
+        attributes: Map<String, AttributeInfo>
+    ): List<String> {
+        val possbileChildrenParam = valueArguments.keys.possibleChildrenParameter
+        return valueArguments.mapNotNull { (param, value) ->
+            val name = param.name.asString()
+//            var type = param.type
+            var attr = attributes[name]
+
+            if (param == possbileChildrenParam && attr == null) {
+                val childrenAttr = attributes[CHILDREN_KEY]
+                if (childrenAttr != null) {
+                    attr = childrenAttr
+                }
+//                if (param.isComposableFromChildrenAnnotation()) {
+//                    type = type.makeComposable(module)
+//                }
+            }
+
+            if (value is DefaultValueArgument) {
+                return@mapNotNull null
+            }
+
+            if (attr == null && isImplicitConstructorParam(param, resultingDescriptor)) {
+                return@mapNotNull null
+//                ImplicitCtorValueNode(
+//                    name = name,
+//                    descriptor = param,
+//                    type = type
+//                )
+            }
+
+            if (attr == null) {
+                error("Couldn't find attribute but expected to. param=$param name=$name")
+            }
+
+            attr.name
+        }
+    }
+
+    private fun resolveAllSetAttributes(
+        expressionToReportErrorsOn: KtExpression,
+        receiverScope: KotlinType,
+        type: KotlinType?,
+        attributes: Map<String, AttributeInfo>,
+        attributesUsedInCall: Set<String>,
+        consumedAttributes: MutableSet<String>,
+        missingRequiredAttributes: MutableList<DeclarationDescriptor>,
+        context: ExpressionTypingContext
+    ): List<ValidatedAssignment> {
+        if (type == null) return emptyList()
+        val results = mutableListOf<ValidatedAssignment>()
+
+        val tempForAttributes = TemporaryTraceAndCache.create(
+            context, "temp for attributes", expressionToReportErrorsOn
+        )
+
+        val tempForValidations = TemporaryTraceAndCache.create(
+            context, "temp for validations", expressionToReportErrorsOn
+        )
+
+        for ((name, attribute) in attributes) {
+            if (name == TAG_KEY) continue
+            if (name == CHILDREN_KEY) {
+                continue
+            }
+            val keyExpr = attribute.key ?: error("key expected")
+
+            val expectedTypes = mutableListOf<KotlinType>()
+
+            var resolvedCall: ResolvedCall<*>? = null
+
+            // NOTE(lmr): A ktx element that has access (like it's a recursive call or a nested class) to the private property
+            // of the tag will be able to set it as an attribute...  I'm not sure if that'a s good thing or not, but unless we
+            // do something extra, that is indeed possible. Perhaps it's something we should look into.
+
+            if (resolvedCall == null) {
+                resolvedCall = resolveAttributeAsSetter(
+                    type,
+                    attribute.name,
+                    keyExpr,
+                    attribute.value,
+                    expectedTypes,
+                    context.replaceTraceAndCache(tempForAttributes)
+                )
+            }
+
+            if (resolvedCall == null) {
+                resolvedCall = resolveAttributeAsProperty(
+                    type,
+                    keyExpr,
+                    attribute.value,
+                    expectedTypes,
+                    context.replaceTraceAndCache(tempForAttributes)
+                )
+            }
+
+            if (resolvedCall != null) {
+
+                val validationType = when {
+                    attributesUsedInCall.contains(name) -> ValidationType.UPDATE
+                    else -> ValidationType.SET
+                }
+
+                val attrType = when (val descriptor = resolvedCall.resultingDescriptor) {
+                    is FunctionDescriptor -> descriptor.valueParameters.firstOrNull()?.type
+                    is PropertyDescriptor -> descriptor.type
+                    else -> null
+                } ?: continue
+
+                val (validationCall, uncheckedValidationCall, lambdaDescriptor) =
+                    resolveValidationCall(
+                        expressionToReportErrorsOn = expressionToReportErrorsOn,
+                        receiverScope = receiverScope,
+                        assignmentReceiverScope = type,
+                        validationType = validationType,
+                        attrType = attrType,
+                        context = context.replaceTraceAndCache(tempForValidations)
+                    )
+
+                results.add(
+                    ValidatedAssignment(
+                        validationType = validationType,
+                        assignment = resolvedCall,
+                        assignmentLambda = lambdaDescriptor,
+                        name = name,
+                        validationCall = validationCall,
+                        uncheckedValidationCall = uncheckedValidationCall,
+                        descriptor = resolvedCall.resultingDescriptor,
+                        type = attrType
+                    )
+                )
+                consumedAttributes.add(name)
+            }
+        }
+
+        if (!type.isUnit()) {
+            val cls = type.constructor.declarationDescriptor as? ClassDescriptor
+                ?: error("unexpected classifier descriptor")
+            val requiredAttributes = cls.unsubstitutedMemberScope
+                .getContributedDescriptors()
+                .mapNotNull { it as? PropertyDescriptor }
+                // NOTE(lmr): I think we should consider not marking lateinit properties as required. It would maybe align
+                // ourselves more with the language semantic of `lateinit`
+                .filter {
+                    it.isLateInit && it.visibility.isVisibleOutside() &&
+                            !Visibilities.isPrivate(it.visibility)
+                }
+                .filter { !it.hasHiddenAttributeAnnotation() }
+
+            requiredAttributes
+                .filter { !consumedAttributes.contains(it.name.asString()) }
+                .ifNotEmpty { missingRequiredAttributes.addAll(this) }
+        }
+
+        tempForAttributes.commit()
+        tempForValidations.commit()
+        return results
+    }
+
+    private fun resolveAttributeAsSetter(
+        instanceType: KotlinType,
+        name: String,
+        keyExpr: KtReferenceExpression,
+        valueExpr: KtExpression,
+        expectedTypes: MutableCollection<KotlinType>,
+        context: ExpressionTypingContext
+    ): ResolvedCall<*>? {
+        val setterName = Name.identifier(
+            ComposeUtils.setterMethodFromPropertyName(
+                name
+            )
+        )
+        val receiver = TransientReceiver(instanceType)
+
+        val call = makeCall(
+            keyExpr,
+            calleeExpression = keyExpr,
+            valueArguments = listOf(CallMaker.makeValueArgument(valueExpr)),
+            receiver = receiver
+        )
+
+        val temporaryForFunction = TemporaryTraceAndCache.create(
+            context, "trace to resolve as function call", keyExpr
+        )
+
+        val results = callResolver.computeTasksAndResolveCall<FunctionDescriptor>(
+            BasicCallResolutionContext.create(
+                context.replaceTraceAndCache(temporaryForFunction),
+                call,
+                CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
+                DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
+            ),
+            setterName,
+            keyExpr,
+            NewResolutionOldInference.ResolutionKind.Function
+        )
+
+        if (results.isNothing) {
+            return null
+        }
+
+        if (results.isAmbiguity || temporaryForFunction.trace.hasTypeMismatchErrorsOn(valueExpr)) {
+            expectedTypes.addAll(
+                results.resultingCalls.mapNotNull {
+                    it.resultingDescriptor.valueParameters.firstOrNull()
+                }.map { it.type }
+            )
+            return null
+        }
+
+        val resolvedCall = OverloadResolutionResultsUtil.getResultingCall(results, context)
+            ?: return null
+
+        temporaryForFunction.commit()
+
+        return resolvedCall
+    }
+
+    private fun resolveAttributeAsProperty(
+        instanceType: KotlinType,
+        keyExpr: KtSimpleNameExpression,
+        valueExpr: KtExpression,
+        expectedTypes: MutableCollection<KotlinType>,
+        context: ExpressionTypingContext
+    ): ResolvedCall<*>? {
+
+        // NOTE(lmr): I'm not sure what the consequences are of using the tagExpr as the receiver...
+        val receiver = TransientReceiver(instanceType)
+
+        val temporaryForVariable = TemporaryTraceAndCache.create(
+            context, "trace to resolve as local variable or property", keyExpr
+        )
+
+        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
+
+        val call = CallMaker.makePropertyCall(receiver, null, keyExpr)
+
+        val contextForVariable = BasicCallResolutionContext.create(
+            contextToUse,
+            call,
+            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS
+        )
+
+        val results = callResolver.resolveSimpleProperty(contextForVariable)
+
+        if (results.isNothing) {
+            return null
+        }
+
+        val resolvedCall = OverloadResolutionResultsUtil.getResultingCall(results, contextToUse)
+            ?: return null
+
+        val descriptor = resolvedCall.resultingDescriptor as PropertyDescriptor
+        val expectedType = descriptor.type
+
+        if (temporaryForVariable.trace.hasTypeMismatchErrorsOn(valueExpr)) {
+            expectedTypes.add(expectedType)
+            return null
+        }
+
+        if (descriptor.setter == null) {
+            // NOTE(lmr): we probably shouldn't do this. if this ends up being a cross-module compile, then the
+            // setter will be gone. I'm not sure the right way to figure out whether or not a property is
+            // settable or not...
+            return null
+        }
+
+        temporaryForVariable.commit()
+
+        return resolvedCall
+    }
+
+    private fun resolveCandidate(
+        candidate: FunctionDescriptor,
+        original: Call,
+        attributes: Map<String, AttributeInfo>,
+        usedAttributes: MutableSet<String>,
+        usedAttributeInfos: MutableList<TempParameterInfo>,
+        missingRequiredAttributes: MutableList<DeclarationDescriptor>,
+        context: ExpressionTypingContext
+    ): OverloadResolutionResults<FunctionDescriptor> {
+        val valueArguments = mutableListOf<ValueArgument>()
+
+        val dispatchReceiver = original.dispatchReceiver
+
+        val stableParamNames = candidate.hasStableParameterNames()
+
+        val possibleChildrenParameter =
+            candidate.valueParameters.possibleChildrenParameter
+
+        for (param in candidate.valueParameters) {
+            val name = param.name.asString()
+            val attr = attributes[name]
+            var arg: ValueArgument? = null
+
+            if (arg == null && param == possibleChildrenParameter) {
+                val childrenAttr = attributes[CHILDREN_KEY]
+                if (childrenAttr != null) {
+                    usedAttributes.add(CHILDREN_KEY)
+
+                    usedAttributeInfos.add(
+                        TempParameterInfo(
+                            attribute = childrenAttr,
+                            descriptor = param
+                        )
+                    )
+
+                    arg = childrenAttr.toValueArgument(name, stableParamNames)
+                }
+            }
+
+            if (arg == null && attr != null) {
+                usedAttributes.add(name)
+                usedAttributeInfos.add(
+                    TempParameterInfo(
+                        attribute = attr,
+                        descriptor = param
+                    )
+                )
+                context.trace.record(BindingContext.REFERENCE_TARGET, attr.key, param)
+                arg = attr.toValueArgument(attr.name, stableParamNames)
+            }
+
+            if (arg == null && isImplicitConstructorParam(param, candidate)) {
+                arg = ImplicitCtorValueArgument(param.type)
+            }
+
+            if (arg != null) {
+                valueArguments.add(arg)
+            } else if (!param.declaresDefaultValue()) {
+                // missing required parameter!
+                if (
+                    dispatchReceiver?.type?.isExtensionFunctionType != true ||
+                    param != candidate.valueParameters[0]
+                ) {
+                    // if this isn't the case, the missing parameter is an extension parameter...
+                    // and it will be provided implicitly. We don't want to diagnose this as a
+                    // missing attribute. If it is missing, the call resolver will add a
+                    // diagnostic anyway.
+                    missingRequiredAttributes.add(param)
+                }
+            }
+        }
+
+        val call = makeCall(
+            original.callElement,
+            valueArguments = valueArguments,
+            calleeExpression = original.calleeExpression,
+            receiver = original.explicitReceiver,
+            dispatchReceiver = dispatchReceiver
+        )
+
+        val contextForVariable = BasicCallResolutionContext.create(
+            context,
+            call,
+            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
+            DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
+        )
+
+        return callResolver.resolveFunctionCall(contextForVariable)
+    }
+
+    private fun resolveReceiver(
+        expression: KtExpression,
+        context: ExpressionTypingContext
+    ): Receiver? {
+        if (expression !is KtQualifiedExpression) return null
+        val currentContext = context
+            .replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)
+            .replaceContextDependency(ContextDependency.INDEPENDENT)
+
+        expression.elementChain(currentContext)
+
+        val receiverExpr = expression.receiverExpression
+
+        return context.trace.get(BindingContext.QUALIFIER, receiverExpr)
+            ?: ExpressionReceiver.create(
+                receiverExpr,
+                ErrorUtils.createErrorType("Type for " + receiverExpr.text),
+                context.trace.bindingContext
+            )
+    }
+
+    private fun makeValueArgument(
+        type: KotlinType,
+        context: ExpressionTypingContext,
+        forceType: Boolean = false
+    ): ValueArgument {
+        val fakeExpr = psiFactory.createSimpleName("tmpVar")
+
+        context.trace.record(
+            BindingContext.EXPRESSION_TYPE_INFO, fakeExpr, KotlinTypeInfo(
+                type = type,
+                dataFlowInfo = DataFlowInfo.EMPTY,
+                jumpOutPossible = false,
+                jumpFlowInfo = DataFlowInfo.EMPTY
+            )
+        )
+
+        if (forceType) {
+            context.trace.record(BindingContext.PROCESSED, fakeExpr, true)
+        }
+
+        return CallMaker.makeValueArgument(fakeExpr)
+    }
+
+    private fun resolveComposerEmit(
+        implicitCtorTypes: List<KotlinType>,
+        constructedType: KotlinType,
+        hasBody: Boolean,
+        expressionToReportErrorsOn: KtExpression,
+        context: ExpressionTypingContext
+    ): ResolvedCall<*>? {
+        return resolveSubstitutableComposerMethod(
+            KtxNameConventions.EMIT,
+            listOfNotNull(
+                builtIns.anyType,
+                functionType(
+                    parameterTypes = implicitCtorTypes,
+                    returnType = constructedType
+                ),
+                functionType(),
+                if (hasBody) functionType() else null
+            ),
+            constructedType,
+            expressionToReportErrorsOn,
+            context
+        )
+    }
+
+    private fun resolveSingleValidationCall(
+        expressionToReportErrorsOn: KtExpression,
+        receiverScope: KotlinType,
+        validationType: ValidationType,
+        checked: Boolean,
+        attrType: KotlinType,
+        lambdaArg: ValueArgument?,
+        context: ExpressionTypingContext
+    ): ResolvedCall<*>? {
+        val temporaryForVariable = TemporaryTraceAndCache.create(
+            context, "trace to resolve variable", expressionToReportErrorsOn
+        )
+        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
+        val name = validationType.name.toLowerCase(Locale.ROOT).let {
+            if (!checked) (it + "Unchecked") else it
+        }
+        val calleeExpression = psiFactory.createSimpleName(name)
+        val call = makeCall(
+            callElement = calleeExpression,
+            calleeExpression = calleeExpression,
+            valueArguments = listOfNotNull(
+                makeValueArgument(attrType, contextToUse, forceType = true),
+                lambdaArg
+            ),
+            receiver = TransientReceiver(receiverScope)
+        )
+        val results = callResolver.resolveCallWithGivenName(
+            BasicCallResolutionContext.create(
+                contextToUse,
+                call,
+                CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
+                DataFlowInfoForArgumentsImpl(contextToUse.dataFlowInfo, call)
+            ),
+            call,
+            calleeExpression,
+            Name.identifier(name)
+        )
+
+        if (results.isSuccess) return results.resultingCall
+
+        if (results.resultCode == OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
+
+            // NOTE(lmr): We know the type of the attribute at this point, but it's possible for the validation call to require
+            // some help in order to do the type inference for the call. We are just guessing here that the type is going to be
+            // the attribute type, and not something more complicated. It is kind of a bummer that we need this and I wonder if
+            // there isn't a cleaner way to do this.
+
+            for (candidate in results.resultingCalls) {
+
+                val typeParam = candidate.typeArguments.keys.singleOrNull() ?: continue
+
+                if (!attrType.satisfiesConstraintsOf(typeParam)) continue
+
+                val nextTempTrace = TemporaryTraceAndCache.create(
+                    context, "trace to resolve variable", expressionToReportErrorsOn
+                )
+
+                val nextContext = context
+                    .replaceTraceAndCache(nextTempTrace)
+                    .replaceCollectAllCandidates(false)
+
+                val substitutor = TypeSubstitutor.create(
+                    mapOf(
+                        typeParam.typeConstructor to attrType.asTypeProjection()
+                    )
+                )
+
+                val nextCall = makeCall(
+                    callElement = expressionToReportErrorsOn,
+                    calleeExpression = calleeExpression,
+                    receiver = TransientReceiver(composer.type),
+                    valueArguments = candidate.candidateDescriptor.valueParameters.map {
+                        makeValueArgument(it.type, nextContext)
+                    }
+                )
+
+                val nextResults = callResolver.resolveCallWithKnownCandidate(
+                    nextCall,
+                    TracingStrategyImpl.create(calleeExpression, nextCall),
+                    BasicCallResolutionContext.create(
+                        nextContext,
+                        nextCall,
+                        CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
+                        DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
+                    ),
+                    ResolutionCandidate.create(
+                        nextCall,
+                        candidate.candidateDescriptor,
+                        candidate.dispatchReceiver,
+                        candidate.explicitReceiverKind,
+                        substitutor
+                    ),
+                    DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
+                )
+
+                if (nextResults.isSuccess) {
+                    nextTempTrace.commit()
+                    return nextResults.resultingCall
+                }
+            }
+        }
+
+        return null
+    }
+
+    private fun resolveValidationCall(
+        expressionToReportErrorsOn: KtExpression,
+        receiverScope: KotlinType,
+        assignmentReceiverScope: KotlinType?,
+        validationType: ValidationType,
+        attrType: KotlinType,
+        context: ExpressionTypingContext
+    ): Triple<ResolvedCall<*>?, ResolvedCall<*>?, FunctionDescriptor?> {
+        val temporaryForVariable = TemporaryTraceAndCache.create(
+            context, "trace to resolve variable", expressionToReportErrorsOn
+        )
+        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
+
+        val includeLambda = validationType != ValidationType.CHANGED
+
+        // for call:
+        // ValidatorType.set(AttrType, (AttrType) -> Unit): Boolean
+        // ValidatorType.update(AttrType, (AttrType) -> Unit): Boolean
+        // ValidatorType.changed(AttrType): Boolean
+
+        // for emit:
+        // ValidatorType.set(AttrType, ElementType.(AttrType) -> Unit): Unit
+        // ValidatorType.update(AttrType, ElementType.(AttrType) -> Unit): Unit
+        // ValidatorType.changed(AttrType): Unit
+
+        val lambdaType = when {
+            includeLambda -> functionType(
+                parameterTypes = listOf(attrType),
+                receiverType = assignmentReceiverScope
+            )
+            else -> null
+        }
+        val lambdaArg = lambdaType?.let { makeValueArgument(it, contextToUse) }
+        val lambdaDescriptor = lambdaType?.let {
+            createFunctionDescriptor(
+                it,
+                contextToUse
+            )
+        }
+
+        val validationCall = resolveSingleValidationCall(
+            expressionToReportErrorsOn = expressionToReportErrorsOn,
+            receiverScope = receiverScope,
+            validationType = validationType,
+            checked = true,
+            attrType = attrType,
+            lambdaArg = lambdaArg,
+            context = context
+        )
+
+        val uncheckedValidationCall = resolveSingleValidationCall(
+            expressionToReportErrorsOn = expressionToReportErrorsOn,
+            receiverScope = receiverScope,
+            validationType = validationType,
+            checked = false,
+            attrType = attrType,
+            lambdaArg = lambdaArg,
+            context = context
+        )
+
+        return Triple(validationCall, uncheckedValidationCall, lambdaDescriptor)
+    }
+
+    private fun resolveSubstitutableComposerMethod(
+        methodName: Name,
+        argumentTypes: List<KotlinType>,
+        typeToSubstitute: KotlinType?,
+        expressionToReportErrorsOn: KtExpression,
+        context: ExpressionTypingContext
+    ): ResolvedCall<*>? {
+        val temporaryForVariable = TemporaryTraceAndCache.create(
+            context, "trace to resolve variable", expressionToReportErrorsOn
+        )
+        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
+
+        val composerExpr = psiFactory.createSimpleName(methodName.asString())
+
+        val call = makeCall(
+            callElement = expressionToReportErrorsOn,
+            calleeExpression = composerExpr,
+            receiver = TransientReceiver(composer.type),
+            valueArguments = argumentTypes.map { makeValueArgument(it, contextToUse) }
+        )
+
+        val results = callResolver.resolveCallWithGivenName(
+            BasicCallResolutionContext.create(
+                contextToUse,
+                call,
+                CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
+                DataFlowInfoForArgumentsImpl(contextToUse.dataFlowInfo, call)
+            ),
+            call,
+            composerExpr,
+            methodName
+        )
+
+        if (results.isSuccess) return results.resultingCall
+
+        if (typeToSubstitute == null) return null
+
+        val candidates = if (context.collectAllCandidates)
+            results.allCandidates ?: emptyList()
+        else results.resultingCalls
+
+        for (candidate in candidates) {
+
+            val typeParam = candidate.candidateDescriptor.typeParameters.singleOrNull() ?: continue
+
+            if (!typeToSubstitute.satisfiesConstraintsOf(typeParam)) continue
+
+            val nextTempTrace = TemporaryTraceAndCache.create(
+                context, "trace to resolve variable", expressionToReportErrorsOn
+            )
+
+            val nextContext = context
+                .replaceTraceAndCache(nextTempTrace)
+                .replaceCollectAllCandidates(false)
+
+            val substitutor = TypeSubstitutor.create(
+                mapOf(
+                    typeParam.typeConstructor to typeToSubstitute.asTypeProjection()
+                )
+            )
+
+            val nextCall = makeCall(
+                callElement = expressionToReportErrorsOn,
+                calleeExpression = composerExpr,
+                receiver = TransientReceiver(composer.type),
+                valueArguments = candidate.candidateDescriptor.valueParameters.map {
+                    makeValueArgument(it.type, nextContext)
+                }
+            )
+
+            val nextResults = callResolver.resolveCallWithKnownCandidate(
+                nextCall,
+                TracingStrategyImpl.create(composerExpr, nextCall),
+                BasicCallResolutionContext.create(
+                    nextContext,
+                    nextCall,
+                    CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
+                    DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
+                ),
+                ResolutionCandidate.create(
+                    nextCall,
+                    candidate.candidateDescriptor,
+                    candidate.dispatchReceiver,
+                    candidate.explicitReceiverKind,
+                    substitutor
+                ),
+                DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
+            )
+
+            if (nextResults.isSuccess) {
+                nextTempTrace.commit()
+                return nextResults.resultingCall
+            }
+        }
+
+        return if (context.collectAllCandidates) null
+        else resolveSubstitutableComposerMethod(
+            methodName,
+            argumentTypes,
+            typeToSubstitute,
+            expressionToReportErrorsOn,
+            context.replaceCollectAllCandidates(true)
+        )
+    }
+
+    private fun KtQualifiedExpression.elementChain(context: ExpressionTypingContext) {
+        val moduleDescriptor = context.scope.ownerDescriptor.module
+        val trace = context.trace
+        val scopeForFirstPart = context.scope
+
+        val path = asQualifierPartList()
+        val firstPart = path.first()
+        var currentDescriptor: DeclarationDescriptor? = scopeForFirstPart.findDescriptor(firstPart)
+        currentDescriptor =
+            currentDescriptor ?: moduleDescriptor.getPackage(FqName.topLevel(firstPart.name)).let {
+                if (it.isEmpty()) null else it
+            }
+
+        if (currentDescriptor == null) return
+        else storeSimpleNameExpression(firstPart.expression!!, currentDescriptor, trace)
+
+        // TODO(lmr): we need to add visibility checks into this function...
+        for (qualifierPartIndex in 1 until path.size) {
+            val qualifierPart = path[qualifierPartIndex]
+
+            val nextPackageOrClassDescriptor =
+                when (currentDescriptor) {
+                    // TODO(lmr): i wonder if we could allow this for Ktx. Seems like a nice to have
+                    // TODO type aliases as qualifiers? (would break some assumptions in TypeResolver)
+                    is TypeAliasDescriptor -> null
+                    is ClassDescriptor -> {
+                        var next: DeclarationDescriptor? = null
+                        next = next
+                            ?: currentDescriptor.unsubstitutedInnerClassesScope.findDescriptor(
+                                qualifierPart
+                            )
+                        if (currentDescriptor.kind == ClassKind.OBJECT) {
+                            next = next
+                                ?: currentDescriptor.unsubstitutedMemberScope.findDescriptor(
+                                    qualifierPart
+                                )
+                        }
+                        val cod = currentDescriptor.companionObjectDescriptor
+                        if (cod != null) {
+                            next = next
+                                ?: cod.unsubstitutedMemberScope.findDescriptor(qualifierPart)
+                        }
+                        next = next ?: currentDescriptor.staticScope.findDescriptor(qualifierPart)
+                        next
+                    }
+                    is PackageViewDescriptor -> {
+                        val packageView =
+                            if (qualifierPart.typeArguments == null) {
+                                moduleDescriptor.getPackage(
+                                    currentDescriptor.fqName.child(qualifierPart.name)
+                                )
+                            } else null
+                        if (packageView != null && !packageView.isEmpty()) {
+                            packageView
+                        } else {
+                            currentDescriptor.memberScope.findDescriptor(qualifierPart)
+                        }
+                    }
+                    is VariableDescriptor -> {
+                        currentDescriptor.type.memberScope.findDescriptor(qualifierPart)
+                    }
+                    else -> null
+                }
+
+            if (nextPackageOrClassDescriptor == null) return
+            else storeSimpleNameExpression(
+                qualifierPart.expression!!,
+                nextPackageOrClassDescriptor,
+                trace
+            )
+
+            currentDescriptor = nextPackageOrClassDescriptor
+        }
+    }
+
+    private fun storeSimpleNameExpression(
+        expression: KtSimpleNameExpression,
+        descriptor: DeclarationDescriptor,
+        trace: BindingTrace
+    ) {
+        trace.record(BindingContext.REFERENCE_TARGET, expression, descriptor)
+        UnderscoreUsageChecker.checkSimpleNameUsage(descriptor, expression, trace)
+
+        val qualifier = when (descriptor) {
+            is PackageViewDescriptor -> PackageQualifier(expression, descriptor)
+            is ClassDescriptor -> ClassQualifier(expression, descriptor)
+            is TypeParameterDescriptor -> TypeParameterQualifier(expression, descriptor)
+            is TypeAliasDescriptor -> descriptor.classDescriptor?.let {
+                TypeAliasQualifier(expression, descriptor, it)
+            }
+            else -> null
+        }
+
+        if (qualifier != null) {
+            trace.record(BindingContext.QUALIFIER, qualifier.expression, qualifier)
+        }
+    }
+}
+
+// general utils
+// ==============================
+
+private val builtIns = DefaultBuiltIns.Instance
+
+private fun functionType(
+    parameterTypes: List<KotlinType> = emptyList(),
+    annotations: Annotations = Annotations.EMPTY,
+    returnType: KotlinType = builtIns.unitType,
+    receiverType: KotlinType? = null
+): KotlinType = createFunctionType(
+    builtIns = builtIns,
+    annotations = annotations,
+    parameterNames = null,
+    parameterTypes = parameterTypes,
+    receiverType = receiverType,
+    returnType = returnType
+)
+
+private fun KotlinType.satisfiesConstraintsOf(T: TypeParameterDescriptor): Boolean {
+    return T.upperBounds.all { isSubtypeOf(it) }
+}
+
+// We want to return null in cases where types mismatch, so we use this heuristic to find out. I think there might be a more robust
+// way to find this out, but I'm not sure what it would be
+private fun BindingTrace.hasTypeMismatchErrorsOn(element: KtElement): Boolean =
+    bindingContext.diagnostics.forElement(element).any { it.severity == Severity.ERROR }
+
+private fun KtExpression.asQualifierPartList(): List<QualifiedExpressionResolver.QualifierPart> {
+    val result = SmartList<QualifiedExpressionResolver.QualifierPart>()
+
+    fun addQualifierPart(expression: KtExpression?): Boolean {
+        if (expression is KtSimpleNameExpression) {
+            result.add(
+                QualifiedExpressionResolver.ExpressionQualifierPart(
+                    expression.getReferencedNameAsName(),
+                    expression
+                )
+            )
+            return true
+        }
+        return false
+    }
+
+    var expression: KtExpression? = this
+    while (true) {
+        if (addQualifierPart(expression)) break
+        if (expression !is KtQualifiedExpression) break
+
+        addQualifierPart(expression.selectorExpression)
+
+        expression = expression.receiverExpression
+    }
+
+    return result.asReversed()
+}
+
+private fun HierarchicalScope.findDescriptor(
+    part: QualifiedExpressionResolver.QualifierPart
+): DeclarationDescriptor? {
+    return findFirstFromMeAndParent {
+        it.findVariable(part.name, part.location)
+            ?: it.findFunction(part.name, part.location)
+            ?: it.findClassifier(part.name, part.location)
+    }
+}
+
+private fun MemberScope.findDescriptor(
+    part: QualifiedExpressionResolver.QualifierPart
+): DeclarationDescriptor? {
+    return this.getContributedClassifier(part.name, part.location)
+        ?: getContributedFunctions(part.name, part.location).singleOrNull()
+        ?: getContributedVariables(part.name, part.location).singleOrNull()
+}
+
+private fun AttributeInfo.toValueArgument(name: String, named: Boolean): ValueArgument {
+    val argumentName = if (named) object : ValueArgumentName {
+        override val asName: Name
+            get() = Name.identifier(name)
+        override val referenceExpression: KtSimpleNameExpression?
+            get() = key
+    } else null
+    return object : ValueArgument {
+        override fun getArgumentExpression() = value
+        override fun getArgumentName() = argumentName
+        override fun isNamed() = named
+        override fun asElement(): KtElement = value
+        override fun getSpreadElement(): LeafPsiElement? = null
+        override fun isExternal() = true
+    }
+}
+
+/**
+ * This function was copied verbatim from descriptorUtils.kt from ide-common.  For some reason, importing this method into our module
+ * would not work and would cause a NoClassDefFound exception.
+ */
+private fun descriptorsEqualWithSubstitution(
+    descriptor1: DeclarationDescriptor?,
+    descriptor2: DeclarationDescriptor?
+): Boolean {
+    if (descriptor1 == descriptor2) return true
+    if (descriptor1 == null || descriptor2 == null) return false
+    if (descriptor1 !is CallableDescriptor) return true
+    descriptor2 as CallableDescriptor
+
+    val typeChecker = KotlinTypeCheckerImpl.withAxioms(
+        object : KotlinTypeChecker.TypeConstructorEquality {
+            override fun equals(a: TypeConstructor, b: TypeConstructor): Boolean {
+                val typeParam1 = a.declarationDescriptor as? TypeParameterDescriptor
+                val typeParam2 = b.declarationDescriptor as? TypeParameterDescriptor
+                if (typeParam1 != null && typeParam2 != null &&
+                    typeParam1.containingDeclaration == descriptor1 &&
+                    typeParam2.containingDeclaration == descriptor2
+                ) {
+                    return typeParam1.index == typeParam2.index
+                }
+
+                return a == b
+            }
+        }
+    )
+
+    if (!typeChecker.equalTypesOrNulls(descriptor1.returnType, descriptor2.returnType)) return false
+
+    val parameters1 = descriptor1.valueParameters
+    val parameters2 = descriptor2.valueParameters
+    if (parameters1.size != parameters2.size) return false
+    for ((param1, param2) in parameters1.zip(parameters2)) {
+        if (!typeChecker.equalTypes(param1.type, param2.type)) return false
+    }
+    // NOTE(lmr): edit
+    // this check was added
+    if (descriptor1.javaClass !== descriptor2.javaClass) return false
+    // NOTE(lmr): /end
+    return true
+}
+
+private val ResolvedCall<*>.semanticCall: ResolvedCall<*>
+    get() = when (this) {
+        is VariableAsFunctionResolvedCall -> variableCall
+        else -> this
+    }
+
+private val Collection<ValueParameterDescriptor>.possibleChildrenParameter:
+        ValueParameterDescriptor?
+    get() = maxBy { it.index }?.let { if (it.type.isFunctionType) it else null }
+
+// move these to naming conventions???
+const val CHILDREN_KEY = "<children>"
+const val TAG_KEY = "<tag>"
+
+fun makeCall(
+    callElement: KtElement,
+    calleeExpression: KtExpression? = null,
+    valueArguments: List<ValueArgument> = emptyList(),
+    receiver: Receiver? = null,
+    dispatchReceiver: ReceiverValue? = null
+): Call {
+    return object : Call {
+        override fun getDispatchReceiver(): ReceiverValue? = dispatchReceiver
+        override fun getValueArgumentList(): KtValueArgumentList? = null
+        override fun getTypeArgumentList(): KtTypeArgumentList? = null
+        override fun getExplicitReceiver(): Receiver? = receiver
+        override fun getCalleeExpression(): KtExpression? = calleeExpression
+        override fun getValueArguments(): List<ValueArgument> = valueArguments
+        override fun getCallElement(): KtElement = callElement
+        override fun getFunctionLiteralArguments(): List<LambdaArgument> = emptyList()
+        override fun getTypeArguments(): List<KtTypeProjection> = emptyList()
+        override fun getCallType(): Call.CallType = Call.CallType.DEFAULT
+        override fun getCallOperationNode(): ASTNode? = null
+    }
+}
+
+fun createFunctionDescriptor(
+    type: KotlinType,
+    context: ExpressionTypingContext
+): FunctionDescriptor {
+    return AnonymousFunctionDescriptor(
+        context.scope.ownerDescriptor,
+        Annotations.EMPTY,
+        CallableMemberDescriptor.Kind.SYNTHESIZED,
+        SourceElement.NO_SOURCE,
+        false
+    ).apply {
+        initialize(
+            type.getReceiverTypeFromFunctionType()?.let {
+                DescriptorFactory.createExtensionReceiverParameterForCallable(
+                    this,
+                    it,
+                    Annotations.EMPTY)
+            },
+            null,
+            emptyList(),
+            type.getValueParameterTypesFromFunctionType().mapIndexed { i, t ->
+                ValueParameterDescriptorImpl(
+                    containingDeclaration = this,
+                    original = null,
+                    index = i,
+                    annotations = Annotations.EMPTY,
+                    name = t.type.extractParameterNameFromFunctionTypeArgument()
+                        ?: Name.identifier("p$i"),
+                    outType = t.type,
+                    declaresDefaultValue = false,
+                    isCrossinline = false,
+                    isNoinline = false,
+                    varargElementType = null,
+                    source = SourceElement.NO_SOURCE
+                )
+            },
+            type.getReturnTypeFromFunctionType(),
+            Modality.FINAL,
+            Visibilities.LOCAL,
+            null
+        )
+        isOperator = false
+        isInfix = false
+        isExternal = false
+        isInline = false
+        isTailrec = false
+        isSuspend = false
+        isExpect = false
+        isActual = false
+    }
+}
+
+fun KotlinType.satisfiesConstraintsOf(bounds: List<KotlinType>): Boolean {
+    return bounds.all { isSubtypeOf(it) }
+}
+
+fun KotlinType.upperBounds(): List<KotlinType> {
+    return if (isTypeParameter()) {
+        TypeUtils.getTypeParameterDescriptorOrNull(this)?.upperBounds ?: emptyList()
+    } else {
+        listOf(this)
+    }
+}
+
+// util classes
+// ========================
+class ImplicitCtorValueArgument(val type: KotlinType) : ValueArgument {
+    override fun getArgumentExpression(): KtExpression? = null
+    override fun getArgumentName(): ValueArgumentName? = null
+    override fun isNamed(): Boolean = false
+    override fun asElement(): KtElement = error("tried to get element")
+    override fun getSpreadElement(): LeafPsiElement? = null
+    override fun isExternal(): Boolean = true
+}
+
+class AttributeInfo(
+    val value: KtExpression,
+    val key: KtSimpleNameExpression?,
+    val name: String
+)
+
+class NoInterceptionCallResolver(private val callResolver: CallResolver) {
+    fun resolveCallWithGivenName(
+        context: ResolutionContext<*>,
+        call: Call,
+        functionReference: KtReferenceExpression,
+        name: Name
+    ): OverloadResolutionResults<FunctionDescriptor> {
+        context.trace.record(
+            ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION,
+            call,
+            true
+        )
+        return callResolver.resolveCallWithGivenName(
+            context,
+            call,
+            functionReference,
+            name
+        )
+    }
+
+    fun resolveCallWithKnownCandidate(
+        call: Call,
+        tracing: TracingStrategy,
+        context: ResolutionContext<*>,
+        candidate: ResolutionCandidate<FunctionDescriptor>,
+        dataFlowInfoForArguments: MutableDataFlowInfoForArguments?
+    ): OverloadResolutionResults<FunctionDescriptor> {
+        context.trace.record(
+            ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION,
+            call,
+            true
+        )
+        return callResolver.resolveCallWithKnownCandidate(
+            call,
+            tracing,
+            context,
+            candidate,
+            dataFlowInfoForArguments
+        )
+    }
+
+    fun resolveSimpleProperty(
+        context: BasicCallResolutionContext
+    ): OverloadResolutionResults<VariableDescriptor> {
+        return callResolver.resolveSimpleProperty(
+            context
+        )
+    }
+
+    fun resolveFunctionCall(
+        context: BasicCallResolutionContext
+    ): OverloadResolutionResults<FunctionDescriptor> {
+        context.trace.record(
+            ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION,
+            context.call,
+            true
+        )
+        return callResolver.resolveFunctionCall(
+            context
+        )
+    }
+
+    fun <T : CallableDescriptor> computeTasksAndResolveCall(
+        context: BasicCallResolutionContext,
+        name: Name,
+        referenceExpression: KtReferenceExpression,
+        kind: NewResolutionOldInference.ResolutionKind
+    ): OverloadResolutionResults<T> {
+        context.trace.record(
+            ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION,
+            context.call,
+            true
+        )
+        return callResolver.computeTasksAndResolveCall(
+            context,
+            name,
+            referenceExpression,
+            kind
+        )
+    }
+}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFlags.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFlags.kt
index 986ff92..ac6a98f 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFlags.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFlags.kt
@@ -19,5 +19,4 @@
 object ComposeFlags {
     var FRAMED_COMPONENTS = false
     var FRAMED_MODEL_CLASSES = true
-    var NEW_CALL_RESOLUTION_INTERCEPTION = false
 }
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt
index e00a888..e34cafc 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt
@@ -24,7 +24,6 @@
 import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
 import org.jetbrains.kotlin.name.ClassId
 import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.resolve.annotations.argumentValue
 import org.jetbrains.kotlin.resolve.constants.ConstantValue
 import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
 import org.jetbrains.kotlin.types.KotlinType
@@ -35,10 +34,7 @@
 object ComposeFqNames {
     val Composable = ComposeUtils.composeFqName("Composable")
     val Pivotal = ComposeUtils.composeFqName("Pivotal")
-    val Children = ComposeUtils.composeFqName("Children")
-    val Stateful = ComposeUtils.composeFqName("Stateful")
     val StableMarker = ComposeUtils.composeFqName("StableMarker")
-    val Emittable = ComposeUtils.composeFqName("Emittable")
     val HiddenAttribute = ComposeUtils.composeFqName("HiddenAttribute")
 
     fun makeComposableAnnotation(module: ModuleDescriptor): AnnotationDescriptor =
@@ -69,31 +65,13 @@
     annotations.findAnnotation(ComposeFqNames.Composable) != null
 fun Annotated.hasPivotalAnnotation(): Boolean =
     annotations.findAnnotation(ComposeFqNames.Pivotal) != null
-fun Annotated.hasChildrenAnnotation(): Boolean =
-    annotations.findAnnotation(ComposeFqNames.Children) != null
-fun Annotated.hasStatefulAnnotation(): Boolean =
-    annotations.findAnnotation(ComposeFqNames.Stateful) != null
-fun Annotated.hasEmittableAnnotation(): Boolean =
-    annotations.findAnnotation(ComposeFqNames.Emittable) != null
 fun Annotated.hasHiddenAttributeAnnotation(): Boolean =
     annotations.findAnnotation(ComposeFqNames.HiddenAttribute) != null
 
-fun Annotated.isComposableFromChildrenAnnotation(): Boolean {
-    val childrenAnnotation = annotations.findAnnotation(ComposeFqNames.Children) ?: return false
-    return childrenAnnotation.isComposableChildrenAnnotation
-}
-
 internal val KotlinType.isSpecialType: Boolean get() =
     this === NO_EXPECTED_TYPE || this === UNIT_EXPECTED_TYPE
 
 val AnnotationDescriptor.isComposableAnnotation: Boolean get() = fqName == ComposeFqNames.Composable
-val AnnotationDescriptor.isChildrenAnnotation: Boolean get() = fqName == ComposeFqNames.Children
-val AnnotationDescriptor.isComposableChildrenAnnotation: Boolean
-    get() {
-        if (fqName != ComposeFqNames.Children) return false
-        val composableValueArgument = argumentValue("composable")?.value
-        return composableValueArgument == null || composableValueArgument == true
-    }
 
 fun Annotations.hasStableMarker(): Boolean = any(AnnotationDescriptor::isStableMarker)
 
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeIrLoweringExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeIrLoweringExtension.kt
index 20e3a29..c766875 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeIrLoweringExtension.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeIrLoweringExtension.kt
@@ -20,7 +20,7 @@
 import org.jetbrains.kotlin.backend.common.phaser.then
 import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
 import org.jetbrains.kotlin.backend.jvm.extensions.IrLoweringExtension
-import androidx.compose.plugins.kotlin.compiler.lower.ComposeFcsPatcher
+import androidx.compose.plugins.kotlin.compiler.lower.ComposableCallTransformer
 import androidx.compose.plugins.kotlin.compiler.lower.ComposeObservePatcher
 import androidx.compose.plugins.kotlin.frames.FrameIrTransformer
 import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
@@ -38,8 +38,8 @@
     description = "Transform @Model classes into framed classes"
 )
 
-val ComposeFcsPhase = makeIrModulePhase(
-    ::ComposeFcsPatcher,
+val ComposeCallPhase = makeIrModulePhase(
+    ::ComposableCallTransformer,
     name = "ComposeFcsPhase",
     description = "Rewrite FCS descriptors to IR bytecode"
 )
@@ -48,6 +48,9 @@
     override fun interceptLoweringPhases(
         phases: CompilerPhase<JvmBackendContext, IrModuleFragment, IrModuleFragment>
     ): CompilerPhase<JvmBackendContext, IrModuleFragment, IrModuleFragment> {
-        return FrameClassGenPhase then ComposeObservePhase then ComposeFcsPhase then phases
+        return FrameClassGenPhase then
+                ComposeCallPhase then
+                ComposeObservePhase then
+                phases
     }
 }
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxControlFlowExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxControlFlowExtension.kt
deleted file mode 100644
index 9c4156d..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxControlFlowExtension.kt
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import com.intellij.util.SmartFMap
-import org.jetbrains.kotlin.builtins.KotlinBuiltIns
-import org.jetbrains.kotlin.cfg.ControlFlowBuilder
-import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
-import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.AccessTarget
-import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.InstructionWithValue
-import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.descriptors.VariableDescriptor
-import org.jetbrains.kotlin.extensions.KtxControlFlowExtension
-import org.jetbrains.kotlin.psi.KtCallExpression
-import org.jetbrains.kotlin.psi.KtDeclaration
-import org.jetbrains.kotlin.psi.KtElement
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtIfExpression
-import org.jetbrains.kotlin.psi.KtPsiUtil
-import org.jetbrains.kotlin.psi.KtStatementExpression
-import org.jetbrains.kotlin.psi.KtTryExpression
-import org.jetbrains.kotlin.psi.KtVisitorVoid
-import org.jetbrains.kotlin.psi.KtWhenExpression
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.ValueArgument
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import org.jetbrains.kotlin.resolve.BindingTrace
-import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
-import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
-import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
-import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
-import org.jetbrains.kotlin.resolve.calls.tower.getFakeDescriptorForObject
-import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
-import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
-import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
-import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
-import java.util.ArrayList
-
-class ComposeKtxControlFlowExtension : KtxControlFlowExtension {
-
-    private class ControlFlowVisitor(
-        val builder: ControlFlowBuilder,
-        val visitor: KtVisitorVoid,
-        val trace: BindingTrace
-    ) {
-
-        private fun mark(element: KtElement) = builder.mark(element)
-
-        private fun createSyntheticValue(
-            instructionElement: KtElement,
-            kind: MagicKind,
-            vararg from: KtElement
-        ): PseudoValue =
-            builder.magic(
-                instructionElement,
-                null,
-                elementsToValues(from.asList()), kind
-            ).outputValue
-
-        private fun createNonSyntheticValue(
-            to: KtElement,
-            from: List<KtElement?>,
-            kind: MagicKind
-        ): PseudoValue =
-            builder.magic(to, to, elementsToValues(from), kind).outputValue
-
-        private fun getBoundOrUnreachableValue(element: KtElement?): PseudoValue? {
-            if (element == null) return null
-
-            val value = builder.getBoundValue(element)
-            return if (value != null || element is KtDeclaration) value
-            else builder.newValue(element)
-        }
-
-        private fun elementsToValues(from: List<KtElement?>): List<PseudoValue> =
-            from.mapNotNull { element -> getBoundOrUnreachableValue(element) }
-
-        private fun instructionsToValues(from: List<InstructionWithValue>): List<PseudoValue> =
-            from.mapNotNull { instruction -> instruction.outputValue }
-
-        private fun generateInstructions(element: KtElement?) {
-            if (element == null) return
-            element.accept(visitor)
-            checkNothingType(element)
-        }
-
-        private fun checkNothingType(element: KtElement) {
-            if (element !is KtExpression) return
-
-            val expression = KtPsiUtil.deparenthesize(element) ?: return
-
-            if (expression is KtStatementExpression || expression is KtTryExpression ||
-                expression is KtIfExpression || expression is KtWhenExpression
-            ) {
-                return
-            }
-
-            val type = trace.bindingContext.getType(expression)
-            if (type != null && KotlinBuiltIns.isNothing(type)) {
-                builder.jumpToError(expression)
-            }
-        }
-
-        private fun checkAndGenerateCall(resolvedCall: ResolvedCall<*>?): Boolean {
-            if (resolvedCall == null) return false
-            generateCall(resolvedCall)
-            return true
-        }
-
-        private fun generateCall(resolvedCall: ResolvedCall<*>): InstructionWithValue {
-            val callElement = resolvedCall.call.callElement
-
-            val receivers = getReceiverValues(resolvedCall)
-
-            var parameterValues = SmartFMap.emptyMap<PseudoValue, ValueParameterDescriptor>()
-            for (argument in resolvedCall.call.valueArguments) {
-                val argumentMapping = resolvedCall.getArgumentMapping(argument)
-                val argumentExpression = argument.getArgumentExpression()
-                if (argumentMapping is ArgumentMatch) {
-                    parameterValues = generateValueArgument(
-                        argument, argumentMapping.valueParameter,
-                        parameterValues
-                    )
-                } else if (argumentExpression != null) {
-                    generateInstructions(argumentExpression)
-                    createSyntheticValue(
-                        argumentExpression,
-                        MagicKind.VALUE_CONSUMER,
-                        argumentExpression
-                    )
-                }
-            }
-
-            if (resolvedCall.resultingDescriptor is VariableDescriptor) {
-                // If a callee of the call is just a variable (without 'invoke'), 'read variable' is generated.
-                // todo : process arguments for such a case (KT-5387)
-                val callExpression = callElement as? KtExpression
-                    ?: error("Variable-based call without callee expression: " + callElement.text)
-                assert(parameterValues.isEmpty()) {
-                    "Variable-based call with non-empty argument list: " + callElement.text
-                }
-                return builder.readVariable(callExpression, resolvedCall, receivers)
-            }
-
-            mark(resolvedCall.call.callElement)
-            return builder.call(callElement, resolvedCall, receivers, parameterValues)
-        }
-
-        private fun getReceiverValues(
-            resolvedCall: ResolvedCall<*>
-        ): Map<PseudoValue, ReceiverValue> {
-            var varCallResult: PseudoValue? = null
-            var explicitReceiver: ReceiverValue? = null
-            if (resolvedCall is VariableAsFunctionResolvedCall) {
-                varCallResult = generateCall(resolvedCall.variableCall).outputValue
-
-                val kind = resolvedCall.explicitReceiverKind
-                //noinspection EnumSwitchStatementWhichMissesCases
-                when (kind) {
-                    ExplicitReceiverKind.DISPATCH_RECEIVER ->
-                        explicitReceiver = resolvedCall.dispatchReceiver
-                    ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS ->
-                        explicitReceiver = resolvedCall.extensionReceiver
-                    ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> Unit
-                }
-            }
-
-            var receiverValues = SmartFMap.emptyMap<PseudoValue, ReceiverValue>()
-            if (explicitReceiver != null && varCallResult != null) {
-                receiverValues = receiverValues.plus(varCallResult, explicitReceiver)
-            }
-            val callElement = resolvedCall.call.callElement
-            receiverValues = getReceiverValues(
-                callElement,
-                resolvedCall.dispatchReceiver,
-                receiverValues
-            )
-            receiverValues = getReceiverValues(
-                callElement,
-                resolvedCall.extensionReceiver,
-                receiverValues
-            )
-            return receiverValues
-        }
-
-        private fun getReceiverValues(
-            callElement: KtElement,
-            receiver: ReceiverValue?,
-            receiverValuesArg: SmartFMap<PseudoValue, ReceiverValue>
-        ): SmartFMap<PseudoValue, ReceiverValue> {
-            var receiverValues = receiverValuesArg
-            if (receiver == null || receiverValues.containsValue(receiver)) return receiverValues
-
-            when (receiver) {
-                is ImplicitReceiver -> {
-                    if (callElement is KtCallExpression) {
-                        val declaration = receiver.declarationDescriptor
-                        if (declaration is ClassDescriptor) {
-                            val fakeDescriptor = getFakeDescriptorForObject(declaration)
-                            val calleeExpression = callElement.calleeExpression
-                            if (fakeDescriptor != null && calleeExpression != null) {
-                                builder.read(
-                                    calleeExpression,
-                                    AccessTarget.Declaration(fakeDescriptor),
-                                    emptyMap()
-                                )
-                            }
-                        }
-                    }
-                    receiverValues = receiverValues.plus(
-                        createSyntheticValue(callElement, MagicKind.IMPLICIT_RECEIVER),
-                        receiver
-                    )
-                }
-                is ExpressionReceiver -> {
-                    val expression = receiver.expression
-                    if (builder.getBoundValue(expression) == null) {
-                        generateInstructions(expression)
-                    }
-
-                    val receiverPseudoValue = getBoundOrUnreachableValue(expression)
-                    if (receiverPseudoValue != null) {
-                        receiverValues = receiverValues.plus(receiverPseudoValue, receiver)
-                    }
-                }
-                is TransientReceiver -> {
-                    // Do nothing
-                }
-                else -> {
-                    throw IllegalArgumentException("Unknown receiver kind: $receiver")
-                }
-            }
-
-            return receiverValues
-        }
-
-        private fun generateValueArgument(
-            valueArgument: ValueArgument,
-            parameterDescriptor: ValueParameterDescriptor,
-            parameterValuesArg: SmartFMap<PseudoValue, ValueParameterDescriptor>
-        ): SmartFMap<PseudoValue, ValueParameterDescriptor> {
-            var parameterValues = parameterValuesArg
-            val expression = valueArgument.getArgumentExpression()
-            if (expression != null) {
-                if (!valueArgument.isExternal()) {
-                    generateInstructions(expression)
-                }
-
-                val argValue = getBoundOrUnreachableValue(expression)
-                if (argValue != null) {
-                    parameterValues = parameterValues.plus(argValue, parameterDescriptor)
-                }
-            }
-            return parameterValues
-        }
-
-        private fun copyValue(from: KtElement?, to: KtElement) {
-            getBoundOrUnreachableValue(from)?.let { builder.bindValue(it, to) }
-        }
-
-        fun visitComposerCallInfo(
-            memoize: ComposerCallInfo,
-            inputInstructions: MutableList<InstructionWithValue>
-        ) {
-            memoize.ctorCall?.let { inputInstructions.add(generateCall(it)) }
-            memoize.composerCall?.let { inputInstructions.add(generateCall(it)) }
-            memoize.validations.forEach { validation ->
-                validation.validationCall?.let { inputInstructions.add(generateCall(it)) }
-                validation.assignment?.let { inputInstructions.add(generateCall(it)) }
-            }
-        }
-
-        fun visitKtxElement(element: KtxElement) {
-            val inputExpressions = ArrayList<KtElement>()
-            val inputInstructions = ArrayList<InstructionWithValue>()
-            val tagExpr = element.simpleTagName ?: element.qualifiedTagName ?: return
-
-            inputExpressions.add(tagExpr)
-
-            for (attribute in element.attributes) {
-                val valueExpr = attribute.value ?: attribute.key ?: break
-                generateInstructions(valueExpr)
-                mark(valueExpr)
-                inputExpressions.add(valueExpr)
-            }
-
-            element.bodyLambdaExpression?.let {
-                generateInstructions(it)
-                inputExpressions.add(it)
-            }
-
-            val elementCall = trace.get(ComposeWritableSlices.RESOLVED_KTX_CALL, element) ?: return
-            var node: EmitOrCallNode? = elementCall.emitOrCall
-
-            elementCall.getComposerCall?.let { inputInstructions.add(generateCall(it)) }
-
-            while (node != null) {
-                when (node) {
-                    is MemoizedCallNode -> {
-                        visitComposerCallInfo(node.memoize, inputInstructions)
-                        node = node.call
-                    }
-                    is NonMemoizedCallNode -> {
-                        inputInstructions.add(generateCall(node.resolvedCall))
-                        node = node.nextCall
-                    }
-                    is EmitCallNode -> {
-                        visitComposerCallInfo(node.memoize, inputInstructions)
-                        node = null
-                    }
-                    is ErrorNode -> {
-                        node = null
-                    }
-                }
-            }
-
-            builder.magic(
-                instructionElement = element,
-                valueElement = null,
-                inputValues = elementsToValues(inputExpressions) +
-                        instructionsToValues(inputInstructions),
-                kind = MagicKind.VALUE_CONSUMER
-            )
-        }
-    }
-
-    override fun visitKtxElement(
-        element: KtxElement,
-        builder: ControlFlowBuilder,
-        visitor: KtVisitorVoid,
-        trace: BindingTrace
-    ) {
-        ControlFlowVisitor(
-            builder,
-            visitor,
-            trace
-        ).visitKtxElement(element)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxParsingExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxParsingExtension.kt
deleted file mode 100644
index 0a1e5aa..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxParsingExtension.kt
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import com.intellij.lang.PsiBuilder
-import com.intellij.psi.tree.TokenSet
-import org.jetbrains.kotlin.KtNodeTypes.BLOCK
-import org.jetbrains.kotlin.KtNodeTypes.DOT_QUALIFIED_EXPRESSION
-import org.jetbrains.kotlin.KtNodeTypes.FUNCTION_LITERAL
-import org.jetbrains.kotlin.KtNodeTypes.KTX_ATTRIBUTE
-import org.jetbrains.kotlin.KtNodeTypes.KTX_BODY_LAMBDA
-import org.jetbrains.kotlin.KtNodeTypes.KTX_ELEMENT
-import org.jetbrains.kotlin.KtNodeTypes.REFERENCE_EXPRESSION
-import org.jetbrains.kotlin.KtNodeTypes.VALUE_PARAMETER_LIST
-import org.jetbrains.kotlin.lexer.KtTokens.ARROW
-import org.jetbrains.kotlin.lexer.KtTokens.COLON
-import org.jetbrains.kotlin.lexer.KtTokens.COMMA
-import org.jetbrains.kotlin.lexer.KtTokens.DIV
-import org.jetbrains.kotlin.lexer.KtTokens.DOT
-import org.jetbrains.kotlin.lexer.KtTokens.EQ
-import org.jetbrains.kotlin.lexer.KtTokens.GT
-import org.jetbrains.kotlin.lexer.KtTokens.IDENTIFIER
-import org.jetbrains.kotlin.lexer.KtTokens.LBRACE
-import org.jetbrains.kotlin.lexer.KtTokens.LPAR
-import org.jetbrains.kotlin.lexer.KtTokens.LT
-import org.jetbrains.kotlin.lexer.KtTokens.RBRACE
-import org.jetbrains.kotlin.lexer.KtTokens.SEMICOLON
-import org.jetbrains.kotlin.parsing.KotlinExpressionParsing
-import org.jetbrains.kotlin.parsing.KtxParsingExtension
-import org.jetbrains.kotlin.parsing.KtxStatementsParser
-import java.util.ArrayList
-
-private val EXPRESSION_FOLLOW_KTX =
-    TokenSet.orSet(KotlinExpressionParsing.EXPRESSION_FOLLOW, TokenSet.create(DIV, GT))
-private val ATTRIBUTE_FOLLOW = TokenSet.create(DIV, GT, IDENTIFIER, EQ, LBRACE, RBRACE, SEMICOLON)
-
-class ComposeKtxParsingExtension : KtxParsingExtension {
-
-    override fun atKtxStart(parser: KotlinExpressionParsing) = parser.at(LT)
-
-    override fun parseKtxTag(parser: KotlinExpressionParsing) = parser.parseKtxTag()
-
-    override fun parseKtxExpressionFollow() = EXPRESSION_FOLLOW_KTX
-
-    override fun createStatementsParser(
-        parser: KotlinExpressionParsing,
-        closeTagToken: String?
-    ): KtxStatementsParser {
-        return object : KtxStatementsParser {
-            val tags = ArrayList<KtxMarkerStart>()
-            var shouldBreak = false
-            var shouldContinue = false
-
-            override fun handleTag() {
-                if (parser.shouldExitKtxBodyBlock(tags, closeTagToken)) {
-                    shouldBreak = true
-                    shouldContinue = false
-                } else {
-                    parser.handleKtx(tags)
-                    shouldBreak = false
-                    shouldContinue = true
-                }
-            }
-
-            override fun shouldBreak() = shouldBreak
-            override fun shouldContinue() = shouldContinue
-
-            override fun finish() {
-                // Close all open KTX tags
-                for (i in tags.size - 1 downTo 0) {
-                    val marker = tags.removeAt(i)
-                    marker.bodyMarker!!.done(BLOCK)
-                    marker.functionLiteralMarker!!.done(FUNCTION_LITERAL)
-                    marker.lambdaExpressionMarker!!.done(KTX_BODY_LAMBDA)
-                    marker.close()
-                    parser.errorWithRecovery("Close tag expected",
-                        EXPRESSION_FOLLOW_KTX
-                    )
-                }
-            }
-        }
-    }
-}
-
-private fun KotlinExpressionParsing.shouldExitKtxBodyBlock(
-    tags: List<KtxMarkerStart>,
-    closeTagToken: String?
-): Boolean {
-    val marker = mark()
-    try {
-        if (closeTagToken == null) return false
-        if (!at(LT)) return false
-        advance()
-        if (!at(DIV)) return false
-        advance()
-        val tagName = parseKtxTagName()
-        for (tag in tags)
-            if (closeTagToken == tag.tagName)
-                return false
-        @Suppress("SENSELESS_COMPARISON")
-        return tagName == null || closeTagToken == tagName
-    } finally {
-        marker.rollbackTo()
-    }
-}
-
-private fun KotlinExpressionParsing.atCloseKtxTag(): Boolean {
-    return lookahead(0) === LT && lookahead(1) === DIV
-}
-
-private fun KotlinExpressionParsing.handleKtx(markers: MutableList<KtxMarkerStart>) {
-    // Determine if this is a open or close tag
-    if (atCloseKtxTag()) {
-        val startOfTag = mark()
-        // Find the best match in terms of tags to close
-        val tagName = parseKtxCloseTag()
-        if (markers.size == 0) {
-            startOfTag.drop()
-            return
-        }
-        var index = markers.size - 1
-        val tagsToClose = ArrayList<KtxMarkerStart>()
-        if (tagName == null) {
-            // We don't know what type of close tag it is, so just close something and try to recover as gracefully as possible.
-            tagsToClose.add(markers.removeAt(index))
-        } else {
-            while (index >= 0) {
-                if (tagName == markers[index].tagName) break
-                index--
-            }
-            if (index >= 0 && !markers.isEmpty() && tagName == markers[index].tagName) {
-                for (i in markers.size - 1 downTo index) {
-                    tagsToClose.add(markers.removeAt(i))
-                }
-            }
-        }
-        if (tagsToClose.size > 0) {
-            startOfTag.rollbackTo()
-            for (i in 0 until tagsToClose.size - 1) {
-                val tag = tagsToClose[i]
-                tag.bodyMarker!!.done(BLOCK)
-                tag.functionLiteralMarker!!.done(FUNCTION_LITERAL)
-                tag.lambdaExpressionMarker!!.done(KTX_BODY_LAMBDA)
-                tag.close()
-            }
-            val tag = tagsToClose[tagsToClose.size - 1]
-            tag.bodyMarker!!.done(BLOCK)
-            tag.functionLiteralMarker!!.done(FUNCTION_LITERAL)
-            tag.lambdaExpressionMarker!!.done(KTX_BODY_LAMBDA)
-            parseKtxCloseTag()
-            tag.close()
-        } else {
-            startOfTag.drop()
-        }
-    } else {
-        // Open a new ktx tag
-        val tag = parseKtxOpenTag()
-        if (tag != null && !tag.isClosed) {
-            tag.lambdaExpressionMarker = mark()
-            tag.functionLiteralMarker = mark()
-            parseKtxChildrenParameters()
-            tag.bodyMarker = mark()
-            markers.add(tag)
-        }
-    }
-}
-
-/*
- * KtxElement
- *  ;
- */
-private fun KotlinExpressionParsing.parseKtxTag() {
-    val startTag = parseKtxOpenTag()
-    if (startTag == null || startTag.isClosed) return
-
-    startTag.lambdaExpressionMarker = mark()
-    startTag.functionLiteralMarker = mark()
-    parseKtxChildrenParameters()
-
-    startTag.bodyMarker = mark()
-    parseStatements(false, startTag.tagName)
-    startTag.bodyMarker!!.done(BLOCK)
-    startTag.functionLiteralMarker!!.done(FUNCTION_LITERAL)
-    startTag.lambdaExpressionMarker!!.done(KTX_BODY_LAMBDA)
-
-    parseKtxCloseTag()
-    startTag.close()
-}
-
-private fun KotlinExpressionParsing.parseKtxChildrenParameters() {
-
-    myBuilder.enableNewlines()
-
-    if (at(ARROW)) {
-        //   { -> ...}
-        mark().done(VALUE_PARAMETER_LIST)
-        advance() // ARROW
-    } else if (at(IDENTIFIER) || at(COLON) || at(LPAR)) {
-        // Try to parse a simple name list followed by an ARROW
-        //   {a -> ...}
-        //   {a, b -> ...}
-        //   {(a, b) -> ... }
-        val rollbackMarker = mark()
-        val nextToken = lookahead(1)
-        val preferParamsToExpressions = nextToken === COMMA || nextToken === COLON
-        parseFunctionLiteralParameterList()
-
-        if (at(ARROW)) {
-            advance() // ARROW
-            rollbackMarker.drop()
-        } else if (preferParamsToExpressions && atCloseKtxTag()) {
-            rollbackMarker.drop()
-            expect(ARROW, "An -> is expected")
-        } else {
-            rollbackMarker.rollbackTo()
-            mark().done(VALUE_PARAMETER_LIST)
-        }
-    }
-}
-
-private fun KotlinExpressionParsing.parseKtxTagNameIdentifier(): String? {
-    val ref = mark()
-    return if (at(IDENTIFIER)) {
-        val identifierText = myBuilder.getTokenText()
-        advance() // IDENTIFIER
-        ref.done(REFERENCE_EXPRESSION)
-        identifierText
-    } else {
-        ref.error("Expected identifier as part of KTX tag name")
-        ref.rollbackTo()
-        null
-    }
-}
-
-private fun KotlinExpressionParsing.parseKtxTagName(): String {
-    var tagName = ""
-    var expression: PsiBuilder.Marker = mark()
-    tagName += parseKtxTagNameIdentifier()
-    var firstExpressionParsed = true
-
-    while (true) {
-        if (interruptedWithNewLine()) {
-            break
-        } else if (at(DOT)) {
-            advance() // DOT
-            if (!firstExpressionParsed) {
-                expression.drop()
-                expression = mark()
-            }
-            tagName += "." + parseKtxTagNameIdentifier()
-            if (firstExpressionParsed) {
-                expression.done(DOT_QUALIFIED_EXPRESSION)
-            } else {
-                firstExpressionParsed = true
-                continue
-            }
-        } else {
-            break
-        }
-        expression = expression.precede()
-    }
-
-    expression.drop()
-    return tagName
-}
-
-/*
- * KtxAttribute
- *  ;
- */
-private fun KotlinExpressionParsing.parseKtxAttribute() {
-    val marker = mark()
-    if (at(IDENTIFIER)) {
-        val attrKeyMark = mark()
-        advance()
-        attrKeyMark.done(REFERENCE_EXPRESSION)
-    } else {
-        errorWithRecovery("Expected attribute name",
-            ATTRIBUTE_FOLLOW
-        )
-    }
-
-    if (at(EQ)) {
-        advance()
-        parsePrefixExpression()
-    }
-    marker.done(KTX_ATTRIBUTE)
-}
-
-/*
- * KtxElement
- *  ;
- */
-private fun KotlinExpressionParsing.parseKtxOpenTag(): KtxMarkerStart? {
-
-    val marker = mark()
-
-    if (at(LT)) {
-        advance()
-    } else {
-        errorAndAdvance("Expecting a KTX Element")
-        marker.drop()
-        return null
-    }
-
-    val tagName = parseKtxTagName()
-    val result = KtxMarkerStart(tagName, marker)
-
-    while (at(IDENTIFIER)) {
-        parseKtxAttribute()
-        if (!atSet(ATTRIBUTE_FOLLOW)) {
-            errorAndAdvance("Expecting an attribute")
-        }
-    }
-
-    if (at(DIV)) {
-        advance()
-        return if (at(GT)) {
-            advance()
-            result.close()
-            result
-        } else {
-            result.close()
-            errorAndAdvance("Expecting `>` (end of KTX tag)")
-            result
-        }
-    } else if (at(GT)) {
-        advance()
-        return result
-    } else {
-        errorWithRecovery("Invalid KTX tag", EXPRESSION_FOLLOW_KTX)
-
-        if (at(DIV)) advance()
-        if (at(GT)) advance()
-        result.close()
-
-        return result
-    }
-}
-
-/*
- * KtxElement
- *  ;
- */
-private fun KotlinExpressionParsing.parseKtxCloseTag(): String? {
-    val marker = mark()
-
-    if (at(LT)) {
-        advance()
-    } else {
-        marker.error("Expected a KTX close tag")
-        return null
-    }
-
-    if (at(DIV)) {
-        advance()
-    } else {
-        marker.error("Expected tag to be a closing tag")
-        return null
-    }
-
-    val tagName = parseKtxTagName()
-
-    return if (at(GT)) {
-        advance()
-        marker.drop()
-        tagName
-    } else {
-        marker.error("Expected `>` (end of KTX close tag)")
-        tagName
-    }
-}
-
-class KtxMarkerStart(tagName: String, private var tagMarker: PsiBuilder.Marker) {
-    var tagName: String
-        internal set
-    internal var bodyMarker: PsiBuilder.Marker? = null
-    internal var functionLiteralMarker: PsiBuilder.Marker? = null
-    internal var lambdaExpressionMarker: PsiBuilder.Marker? = null
-    internal var isClosed: Boolean = false
-    private var closedAt: Throwable? = null
-
-    init {
-        this.tagName = tagName
-    }
-
-    fun close() {
-        if (closedAt != null) {
-            //    throw new RuntimeException("Already closed at", closedAt);
-        }
-        closedAt = Throwable("Previously closed here")
-        tagMarker.done(KTX_ELEMENT)
-        isClosed = true
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxTypeResolutionExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxTypeResolutionExtension.kt
deleted file mode 100644
index deda3b8..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeKtxTypeResolutionExtension.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.extensions.KtxTypeResolutionExtension
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import org.jetbrains.kotlin.resolve.calls.CallResolver
-import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
-import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
-import org.jetbrains.kotlin.types.expressions.ExpressionTypingFacade
-
-class ComposeKtxTypeResolutionExtension : KtxTypeResolutionExtension {
-
-    override fun visitKtxElement(
-        element: KtxElement,
-        context: ExpressionTypingContext,
-        facade: ExpressionTypingFacade,
-        callResolver: CallResolver
-    ) {
-        val ktxCallResolver =
-            KtxCallResolver(
-                callResolver,
-                facade,
-                element.project,
-                ComposableAnnotationChecker.get(element.project)
-            )
-
-        ktxCallResolver.initializeFromKtxElement(element, context)
-
-        val temporaryForKtxCall =
-            TemporaryTraceAndCache.create(context, "trace to resolve ktx call", element)
-
-        val resolvedKtxElementCall = ktxCallResolver.resolveFromKtxElement(
-            element,
-            context.replaceTraceAndCache(temporaryForKtxCall)
-        )
-
-        temporaryForKtxCall.commit()
-
-        context.trace.record(
-            ComposeWritableSlices.RESOLVED_KTX_CALL,
-            element,
-            resolvedKtxElementCall
-        )
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt
index b6e21a3..f7fffcb 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposePlugin.kt
@@ -76,36 +76,22 @@
     companion object {
 
         @Suppress("UNUSED_PARAMETER")
-        fun registerProjectExtensions(project: Project, configuration: CompilerConfiguration) {
-            StorageComponentContainerContributor.registerExtension(
-                project,
-                ComponentsClosedDeclarationChecker()
-            )
+        fun registerProjectExtensions(
+            project: Project,
+            configuration: CompilerConfiguration
+        ) {
             StorageComponentContainerContributor.registerExtension(
                 project,
                 ComposableAnnotationChecker()
             )
             StorageComponentContainerContributor.registerExtension(
                 project,
-                ChildAnnotationChecker()
-            )
-            StorageComponentContainerContributor.registerExtension(
-                project,
                 UnionAnnotationCheckerProvider()
             )
             StorageComponentContainerContributor.registerExtension(
                 project,
                 TryCatchComposableChecker()
             )
-            KtxParsingExtension.registerExtension(project,
-                ComposeKtxParsingExtension()
-            )
-            KtxTypeResolutionExtension.registerExtension(project,
-                ComposeKtxTypeResolutionExtension()
-            )
-            KtxControlFlowExtension.registerExtension(project,
-                ComposeKtxControlFlowExtension()
-            )
             ComposeDiagnosticSuppressor.registerExtension(
                 project,
                 ComposeDiagnosticSuppressor()
@@ -124,7 +110,6 @@
                 project,
                 ComposeCallResolutionInterceptorExtension()
             )
-
             StorageComponentContainerContributor.registerExtension(project,
                 FrameModelChecker()
             )
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeSyntheticIrExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeSyntheticIrExtension.kt
index 6d0e2e1..6e39e52 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeSyntheticIrExtension.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeSyntheticIrExtension.kt
@@ -16,102 +16,58 @@
 
 package androidx.compose.plugins.kotlin
 
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.ParameterDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
-import org.jetbrains.kotlin.descriptors.ValueDescriptor
-import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.ir.IrStatement
-import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
-import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
-import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
-import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
-import org.jetbrains.kotlin.ir.expressions.IrCall
-import org.jetbrains.kotlin.ir.expressions.IrConst
 import org.jetbrains.kotlin.ir.expressions.IrExpression
-import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
-import org.jetbrains.kotlin.ir.expressions.IrReturn
 import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
-import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
+import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
 import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
-import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
-import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
-import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
-import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
-import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
-import org.jetbrains.kotlin.ir.expressions.putValueArgument
-import org.jetbrains.kotlin.ir.expressions.putTypeArguments
-import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
-import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
-import org.jetbrains.kotlin.ir.util.referenceFunction
-import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.psi.KtCallExpression
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtLambdaExpression
-import org.jetbrains.kotlin.psi.KtPsiUtil
+import org.jetbrains.kotlin.psi.KtQualifiedExpression
 import org.jetbrains.kotlin.psi.KtSimpleNameExpression
-import org.jetbrains.kotlin.psi.KtxElement
 import org.jetbrains.kotlin.psi.psiUtil.endOffset
 import org.jetbrains.kotlin.psi.psiUtil.startOffset
+import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
 import org.jetbrains.kotlin.psi2ir.extensions.SyntheticIrExtension
+import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
 import org.jetbrains.kotlin.psi2ir.generators.ErrorExpressionGenerator
-import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
 import org.jetbrains.kotlin.psi2ir.generators.StatementGenerator
-import org.jetbrains.kotlin.psi2ir.generators.generateReceiver
-import org.jetbrains.kotlin.psi2ir.generators.getSuperQualifier
-import org.jetbrains.kotlin.psi2ir.generators.getTypeArguments
-import org.jetbrains.kotlin.psi2ir.generators.pregenerateCallReceivers
-import org.jetbrains.kotlin.psi2ir.intermediate.AccessorPropertyLValue
-import org.jetbrains.kotlin.psi2ir.intermediate.AssignmentReceiver
-import org.jetbrains.kotlin.psi2ir.intermediate.CallReceiver
-import org.jetbrains.kotlin.psi2ir.intermediate.FieldPropertyLValue
-import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue
-import org.jetbrains.kotlin.psi2ir.intermediate.PropertyLValueBase
-import org.jetbrains.kotlin.psi2ir.intermediate.SimpleCallReceiver
-import org.jetbrains.kotlin.psi2ir.intermediate.TransientReceiverValue
-import org.jetbrains.kotlin.psi2ir.unwrappedGetMethod
-import org.jetbrains.kotlin.psi2ir.unwrappedSetMethod
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import androidx.compose.plugins.kotlin.frames.buildWithScope
-import org.jetbrains.kotlin.descriptors.CallableDescriptor
-import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
-import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
-import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
-import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
-import org.jetbrains.kotlin.ir.expressions.typeParametersCount
-import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
-import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
-import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
+import org.jetbrains.kotlin.psi2ir.generators.generateCall
 import org.jetbrains.kotlin.psi2ir.generators.getResolvedCall
+import org.jetbrains.kotlin.psi2ir.generators.pregenerateCall
+import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
+import org.jetbrains.kotlin.util.OperatorNameConventions
 
 class ComposeSyntheticIrExtension : SyntheticIrExtension {
 
-    override fun visitKtxElement(
-        statementGenerator: StatementGenerator,
-        element: KtxElement
-    ): IrStatement {
-        val resolvedKtxCall = statementGenerator.context.bindingContext.get(
-            ComposeWritableSlices.RESOLVED_KTX_CALL,
-            element
-        ) ?: error(
-            "KTX Element encountered without a resolved KTX call. Something must have gone wrong " +
-                    "in type resolution."
-        )
-        val openTagName =
-            element.simpleTagName ?: element.qualifiedTagName ?: error("malformed element")
-        return statementGenerator.visitResolvedKtx(
-            element.startOffset,
-            element.endOffset,
-            element.body,
-            resolvedKtxCall,
-            openTagName
+    private fun StatementGenerator.visitCallExpressionWithoutInterception(
+        expression: KtCallExpression
+    ): IrExpression {
+        val resolvedCall = getResolvedCall(expression)
+            ?: return ErrorExpressionGenerator(this)
+                .generateErrorCall(expression)
+
+        if (resolvedCall is VariableAsFunctionResolvedCall) {
+            val functionCall = pregenerateCall(resolvedCall.functionCall)
+            return CallGenerator(this)
+                .generateCall(expression, functionCall, IrStatementOrigin.INVOKE)
+        }
+
+        val calleeExpression = expression.calleeExpression
+        val origin =
+            if (resolvedCall.resultingDescriptor.name == OperatorNameConventions.INVOKE &&
+                calleeExpression !is KtSimpleNameExpression &&
+                calleeExpression !is KtQualifiedExpression
+            )
+                IrStatementOrigin.INVOKE
+            else
+                null
+
+        return CallGenerator(this).generateCall(
+            expression.startOffsetSkippingComments,
+            expression.endOffset,
+            pregenerateCall(resolvedCall),
+            origin
         )
     }
 
@@ -123,1115 +79,81 @@
             ?: return ErrorExpressionGenerator(statementGenerator).generateErrorCall(element)
 
         val descriptor = resolvedCall.candidateDescriptor
-        if (descriptor !is ComposeCallResolutionInterceptorExtension.ComposableInvocationDescriptor)
-            return null
-        val resolvedKtxCall = descriptor.ktxCall
-        val openTagName = (element as? KtCallExpression)?.calleeExpression ?: element
-        val body = (
-                (resolvedKtxCall.emitOrCall as? EmitCallNode)?.inlineChildren as KtLambdaExpression?
-        )?.bodyExpression?.statements
-        return statementGenerator.visitResolvedKtx(
-            element.startOffset,
-            element.endOffset,
-            body,
-            resolvedKtxCall,
-            openTagName
-        )
+
+        if (descriptor is ComposableFunctionDescriptor) {
+            if (descriptor.isInline) {
+                return statementGenerator.visitCallExpressionWithoutInterception(element)
+            }
+            return statementGenerator.visitComposableCall(descriptor, element)
+        }
+        if (descriptor is ComposableEmitDescriptor) {
+            return statementGenerator.visitEmitCall(descriptor, element)
+        }
+
+        return null
     }
 
-    override fun visitSimpleNameExpression(
-        statementGenerator: StatementGenerator,
-        element: KtSimpleNameExpression
+    private fun StatementGenerator.visitEmitCall(
+        descriptor: ComposableEmitDescriptor,
+        expression: KtCallExpression
     ): IrExpression? {
-        if (true) return null
-        val resolvedCall = statementGenerator.getResolvedCall(element) ?: return null
-
-        val descriptor = resolvedCall.candidateDescriptor
-        if (descriptor !is
-                    ComposeCallResolutionInterceptorExtension.ComposableInvocationDescriptor) {
-            return null
-        }
-        val resolvedKtxCall = descriptor.ktxCall
-        val openTagName = (element as? KtCallExpression)?.calleeExpression ?: element
-        val body = (
-                (resolvedKtxCall.emitOrCall as? EmitCallNode)?.inlineChildren as KtLambdaExpression?
-        )?.bodyExpression?.statements
-        return statementGenerator.visitResolvedKtx(
-            element.startOffset,
-            element.endOffset,
-            body,
-            resolvedKtxCall,
-            openTagName
-        )
-    }
-
-    fun StatementGenerator.visitResolvedKtx(
-        startOffset: Int,
-        endOffset: Int,
-        body: List<KtExpression>?,
-        resolvedKtxCall: ResolvedKtxElementCall,
-        openTagName: KtExpression
-    ): IrExpression {
-
-        val irBuiltIns = context.irBuiltIns
-
-        val resolvedAttributes = resolvedKtxCall.usedAttributes.map { it.name to it }.toMap()
-
-        val statements = mutableListOf<IrStatement>()
-
-        val statementGenerator = this@visitResolvedKtx
-
-        // Convert tag attribute expressions
-        val attributeExpressions = resolvedAttributes.mapValues { (_, attribute) ->
-            val valueExpression = attribute.expression
-            val irValueExpression = KtPsiUtil.safeDeparenthesize(
-                valueExpression
-            ).accept(statementGenerator, null) as? IrExpression
-                ?: error("attributes need to be expressions")
-
-            if (irValueExpression is IrConst<*>) {
-                // For constant expression don't create the temporary.
-                ({ irValueExpression.copy() })
-            } else {
-                // Create a temporary variable to hold the value of the expression
-                val attributeType = attribute.type
-                val attributeVariable = statementGenerator.scope.createTemporaryVariable(
-                    irValueExpression,
-                    isMutable = false,
-                    type = attributeType,
-                    irType = attributeType.toIrType()
-                )
-
-                val attrVariableDeclaration =
-                    statementGenerator.context.symbolTable.declareVariable(
-                        valueExpression.startOffset, valueExpression.endOffset,
-                        IrDeclarationOrigin.DEFINED,
-                        attributeVariable.descriptor,
-                        attributeType.toIrType(),
-                        irValueExpression
-                    )
-                // OUTPUT: var _el_attr_name = <attribute expression>
-                statements.add(attrVariableDeclaration)
-
-                ({
-                    IrGetValueImpl(
-                        valueExpression.startOffset, valueExpression.endOffset,
-                        statementGenerator.context.symbolTable.referenceVariable(
-                            attributeVariable.descriptor
-                        )
-                    )
-                })
-            }
-        }.toMap()
-
-        fun getAttribute(name: String) = (attributeExpressions[name]
-            ?: error("Expected attribute $name"))()
-
-        // TODO(lmr): if this is a "get local variable" will this still work?
-        fun getComposer() = statementGenerator.getProperty(
-            openTagName.startOffset, openTagName.endOffset,
-            resolvedKtxCall.getComposerCall ?: error("Invalid KTX Call")
-        )
-
-        fun keyExpression(callInfo: ComposerCallInfo): IrExpression {
-            val joinKeyCall = callInfo.joinKeyCall ?: error("Expected joinKeyCall to be non-null")
-            val sourceKey = getKeyValue(
-                statementGenerator.scopeOwner,
-                startOffset
-            )
-            val keyValueExpressions = listOf<IrExpression>(
-                IrConstImpl.int(
-                    UNDEFINED_OFFSET,
-                    UNDEFINED_OFFSET,
-                    irBuiltIns.intType,
-                    sourceKey
-                )
-            ) + callInfo.pivotals.map { getAttribute(it.name) }
-            return keyValueExpressions
-                .reduce { left, right ->
-                    statementGenerator
-                        .callMethod(
-                            UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                            joinKeyCall,
-                            getComposer()
-                        )
-                        .apply {
-                            putValueArgument(0, left)
-                            putValueArgument(1, right)
-                        }
-                }
-        }
-
-        fun lambdaExpression(
-            descriptor: FunctionDescriptor,
-            kotlinType: KotlinType,
-            origin: IrDeclarationOrigin,
-            block: (statements: MutableList<IrStatement>) -> Unit
-        ) = statementGenerator.lambdaExpression(
-            openTagName.startOffset,
-            openTagName.endOffset,
-            descriptor,
-            kotlinType,
-            origin,
-            block
-        )
-
-        fun generateEmitOrCallNode(
-            callNode: EmitOrCallNode,
-            container: DeclarationDescriptor,
-            receiver: IrExpression? = null
-        ): IrExpression {
-            when (callNode) {
-                is EmitCallNode -> {
-                    val memoize = callNode.memoize
-                    val composerCall =
-                        memoize.composerCall ?: error("Expected composerCall to be non-null")
-
-                    val composerCallParameters =
-                        composerCall.resultingDescriptor.valueParameters.map {
-                            it.name to it
-                        }.toMap()
-                    fun getComposerCallParameter(name: Name) = composerCallParameters[name]
-                        ?: error("Expected $name parameter to exist")
-                    fun getComposerCallParameterType(name: Name) =
-                        getComposerCallParameter(name).type
-
-                    return statementGenerator.callMethod(
-                        startOffset,
-                        endOffset,
-                        composerCall,
-                        getComposer()
-                    ).apply {
-                        // Place the key parameter
-                        putValueArgument(
-                            getComposerCallParameter(KtxNameConventions.EMIT_KEY_PARAMETER),
-                            keyExpression(memoize)
-                        )
-
-                        // Place the ctor parameter
-                        // NOTE: this is always non-null for EmitCallNode
-                        val ctor = memoize.ctorCall ?: error("Expected ctorCall to be non-null")
-                        val ctorLambdaDescriptor = memoize.emitCtorFnDescriptor
-                            ?: error("Expected emitCtorFnDescriptor to be non-null")
-                        val ctorValueParameters = ctorLambdaDescriptor.valueParameters
-                        val ctorParameterType =
-                            getComposerCallParameterType(KtxNameConventions.EMIT_CTOR_PARAMETER)
-                        val ctorLambda =
-                            lambdaExpression(
-                                ctorLambdaDescriptor,
-                                ctorParameterType,
-                                IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
-                            ) { statements ->
-                            val ctorCall = statementGenerator.buildCtorCall(
-                                openTagName.startOffset,
-                                openTagName.endOffset,
-                                ctor,
-                                ctor.resultingDescriptor.original as ClassConstructorDescriptor,
-                                memoize.ctorCall.valueArguments.size
-                            ).apply {
-                                putValueParameters(
-                                    memoize.ctorParams,
-                                    statementGenerator,
-                                    ctorValueParameters
-                                ) {
-                                    getAttribute(it)
-                                }
-                            }
-                            // OUTPUT: return <ctor>(<arguments>)
-                            val scopeOwner =
-                                statementGenerator.context.symbolTable.referenceFunction(
-                                    ctorLambdaDescriptor
-                                )
-                            statements.add(
-                                IrReturnImpl(
-                                    openTagName.startOffset, openTagName.endOffset,
-                                    statementGenerator.context.irBuiltIns.nothingType,
-                                    scopeOwner, ctorCall
-                                )
-                            )
-                        }
-                        putValueArgument(
-                            getComposerCallParameter(KtxNameConventions.EMIT_CTOR_PARAMETER),
-                            ctorLambda
-                        )
-
-                        // Place the updater parameter
-                        val updaterLambdaDescriptor = memoize.emitUpdaterFnDescriptor
-                            ?: error("Expected emitUpdaterFnDescriptor to be non-null")
-                        val updaterParameterType =
-                            getComposerCallParameterType(KtxNameConventions.EMIT_UPDATER_PARAMETER)
-                        val updaterLambda = lambdaExpression(
-                            updaterLambdaDescriptor,
-                            updaterParameterType,
-                            IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
-                        ) { statements ->
-                            statements.addAll(
-                                memoize.validations.map { validation ->
-                                    statementGenerator.validationCall(
-                                        UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                                        memoizing = true,
-                                        validation = validation,
-                                        fnDescriptor = updaterLambdaDescriptor,
-                                        assignmentReceiver = validation.assignmentLambda
-                                            ?.extensionReceiverParameter
-                                            ?: error("expected extension receiver")
-                                    ) { name ->
-                                        getAttribute(name)
-                                    }
-                                }
-                            )
-
-                            statementGenerator.addReturn(statements, updaterLambdaDescriptor)
-                        }
-                        putValueArgument(
-                            getComposerCallParameter(KtxNameConventions.EMIT_UPDATER_PARAMETER),
-                            updaterLambda
-                        )
-
-                        val bodyStatements = body
-                        if (bodyStatements != null) {
-                            // Place the children parameter
-                            val bodyLambdaDescriptor = memoize.emitBodyFnDescriptor
-                                ?: error("Expected emitBodyFnDescriptor to be non-null")
-                            val bodyParameterType = getComposerCallParameterType(
-                                KtxNameConventions.EMIT_CHILDREN_PARAMETER
-                            )
-                            val bodyLambda = lambdaExpression(
-                                bodyLambdaDescriptor,
-                                bodyParameterType,
-                                IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
-                            ) { statements ->
-                                statements.addAll(
-                                    bodyStatements.map { it.accept(statementGenerator, null) }
-                                )
-                            }
-                            putValueArgument(
-                                getComposerCallParameter(
-                                    KtxNameConventions.EMIT_CHILDREN_PARAMETER
-                                ),
-                                bodyLambda
-                            )
-                        }
-                    }
-                }
-                is NonMemoizedCallNode -> {
-                    val resolvedCall =
-                        if (callNode.resolvedCall is VariableAsFunctionResolvedCall)
-                            callNode.resolvedCall.functionCall
-                        else callNode.resolvedCall
-
-                    var result: IrExpression = statementGenerator.buildCallOrCtor(
-                        startOffset,
-                        endOffset,
-                        resolvedCall = resolvedCall,
-                        descriptor = resolvedCall.resultingDescriptor as FunctionDescriptor,
-                        dispatchReceiver = receiver ?: attributeExpressions[TAG_KEY]?.invoke(),
-                        valueArgumentsCount = resolvedCall.valueArguments.size
-                    ).apply {
-                        putValueParameters(callNode.params, statementGenerator) {
-                            getAttribute(it)
-                        }
-                    }
-
-                    if (callNode.postAssignments.isNotEmpty()) {
-                        //     Foo()
-                        // turns into
-                        //     val x = Foo()
-                        //     x.prop = value
-                        //     x
-                        val elType = callNode.resolvedCall.resultingDescriptor.returnType
-                            ?: error("Expected returnType to be non-null")
-
-                        val elVarDescriptor = IrTemporaryVariableDescriptorImpl(
-                            container,
-                            Name.identifier("__el"),
-                            elType,
-                            false
-                        )
-
-                        val postAssignmentStatements = mutableListOf<IrStatement>()
-
-                        val elVarDecl = statementGenerator.context.symbolTable.declareVariable(
-                            UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                            IrDeclarationOrigin.DEFINED,
-                            elVarDescriptor,
-                            elType.toIrType(),
-                            result
-                        )
-
-                        postAssignmentStatements.add(elVarDecl)
-
-                        fun getEl() = IrGetValueImpl(
-                            UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                            statementGenerator.context.symbolTable.referenceVariable(
-                                elVarDescriptor
-                            )
-                        )
-
-                        for (assignment in callNode.postAssignments) {
-                            if (assignment.assignment == null) error("expected assignment")
-
-                            val statement = when (assignment.assignment.resultingDescriptor) {
-                                is PropertyDescriptor -> statementGenerator.assignmentReceiver(
-                                    UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                                    assignment.assignment,
-                                    getEl(),
-                                    elType
-                                ).assign(getAttribute(assignment.attribute.name))
-
-                                is FunctionDescriptor -> statementGenerator.callMethod(
-                                    UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                                    assignment.assignment,
-                                    getEl()
-                                ).apply {
-                                    putValueArgument(0, getAttribute(assignment.attribute.name))
-                                }
-
-                                else -> error("")
-                            }
-
-                            postAssignmentStatements.add(statement)
-                        }
-                        postAssignmentStatements.add(getEl())
-
-                        result = IrBlockImpl(
-                            UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                            type = elType.toIrType(),
-                            origin = null,
-                            statements = postAssignmentStatements
-                        )
-                    }
-
-                    // TODO(lmr): this doesn't work for what appears to be a broader compiler bug, but it is the more ideal
-                    // way to write this code. The above code does the same thing but we should switch it whenever the bug in
-                    // the compiler is fixed.
-//                    if (callNode.postAssignments.isNotEmpty()) {
-//                        if (callNode.applyCall == null) error("applyCall expected to be non-null")
-//                        if (callNode.applyLambdaDescriptor == null) error("applyLambdaDescriptor expected to be non-null")
-//                        if (callNode.applyLambdaType == null) error("applyLambdaType expected to be non-null")
-//
-//                        result = statementGenerator.buildCall(
-//                            element.startOffset,
-//                            element.endOffset,
-//                            resolvedCall = callNode.applyCall,
-//                            descriptor = callNode.applyCall.resultingDescriptor as FunctionDescriptor,
-//                            receiver = result
-//                        ).apply {
-//                            val applyLambda = lambdaExpression(callNode.applyLambdaDescriptor, callNode.applyLambdaType) { statements ->
-//                                val validator = statementGenerator.extensionReceiverOf(callNode.applyLambdaDescriptor)
-//                                    ?: error("Expected extension receiver")
-//
-//                                for (assignment in callNode.postAssignments) {
-//                                    if (assignment.assignment == null) error("expected assignmnet")
-//
-//                                    val statement = statementGenerator.callMethod(
-//                                        UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-//                                        assignment.assignment,
-//                                        validator
-//                                    ).apply {
-//                                        putValueArgument(0, getAttribute(assignment.attribute.name))
-//                                    }
-//                                    statements.add(statement)
-//                                }
-//                                statementGenerator.addReturn(statements, callNode.applyLambdaDescriptor)
-//                            }
-//                            putValueArgument(0, applyLambda)
-//                        }
-//                    }
-
-                    val nextCall = callNode.nextCall
-                    if (nextCall != null) {
-                        result = generateEmitOrCallNode(nextCall, container, result)
-                    }
-
-                    return result
-                }
-                is MemoizedCallNode -> {
-                    val memoize = callNode.memoize
-                    val composerCall =
-                        memoize.composerCall ?: error("Expected composerCall to be non-null")
-
-                    val composerCallParameters =
-                        composerCall.resultingDescriptor.valueParameters.map {
-                            it.name to it
-                        }.toMap()
-                    fun getComposerCallParameter(name: Name) =
-                        composerCallParameters[name] ?: error("Expected $name parameter to exist")
-                    fun getComposerCallParameterType(name: Name) =
-                        getComposerCallParameter(name).type
-
-                    return statementGenerator.callMethod(
-                        startOffset,
-                        endOffset,
-                        composerCall,
-                        getComposer()
-                    ).apply {
-                        // Place the key parameter
-                        putValueArgument(
-                            getComposerCallParameter(KtxNameConventions.CALL_KEY_PARAMETER),
-                            keyExpression(memoize)
-                        )
-
-                        // Place the ctor parameter
-                        if (memoize.ctorCall != null) {
-                            val ctorLambdaDescriptor = memoize.callCtorFnDescriptor
-                                ?: error("Expected callCtorFnDescriptor to be non-null")
-                            val ctorParameterType =
-                                getComposerCallParameterType(KtxNameConventions.CALL_CTOR_PARAMETER)
-                            val ctorLambda = lambdaExpression(
-                                ctorLambdaDescriptor,
-                                ctorParameterType,
-                                IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
-                            ) { statements ->
-                                val ctorCall = statementGenerator.buildCtorCall(
-                                    openTagName.startOffset,
-                                    openTagName.endOffset,
-                                    memoize.ctorCall,
-                                    memoize.ctorCall.resultingDescriptor.original
-                                            as ClassConstructorDescriptor,
-                                    memoize.ctorCall.valueArguments.size
-                                ).apply {
-                                    putValueParameters(memoize.ctorParams, statementGenerator) {
-                                        getAttribute(it)
-                                    }
-                                }
-                                // OUTPUT: return <ctor>(<arguments>)
-                                val scopeOwner =
-                                    statementGenerator.context.symbolTable.referenceFunction(
-                                        ctorLambdaDescriptor
-                                    )
-                                statements.add(
-                                    IrReturnImpl(
-                                        openTagName.startOffset, openTagName.endOffset,
-                                        statementGenerator.context.irBuiltIns.nothingType,
-                                        scopeOwner, ctorCall
-                                    )
-                                )
-                            }
-                            putValueArgument(
-                                getComposerCallParameter(KtxNameConventions.CALL_CTOR_PARAMETER),
-                                ctorLambda
-                            )
-                        }
-
-                        // Place the validation parameter
-                        val validateLambdaDescriptor = memoize.callInvalidFnDescriptor
-                            ?: error("Expected callInvalidFnDescriptor to be non-null")
-                        val validateParameterType =
-                            getComposerCallParameterType(KtxNameConventions.CALL_INVALID_PARAMETER)
-                        val memoizing = memoize.validations.all { it.attribute.isStable }
-                        val validations = memoize.validations
-                        val validateLambda =
-                            lambdaExpression(
-                                validateLambdaDescriptor,
-                                validateParameterType,
-                                IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
-                            ) { statements ->
-                            // all as one expression: a or b or c ... or z
-
-                            val validationCalls = validations
-                                .map { validation ->
-                                    if (validation.validationType == ValidationType.CHANGED &&
-                                        !memoizing)
-                                        IrConstImpl.constTrue(
-                                            UNDEFINED_OFFSET,
-                                            UNDEFINED_OFFSET,
-                                            irBuiltIns.booleanType
-                                        )
-                                    else
-                                        statementGenerator.validationCall(
-                                            UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                                            memoizing = memoizing,
-                                            validation = validation,
-                                            fnDescriptor = validateLambdaDescriptor,
-                                            assignmentReceiver = validateLambdaDescriptor
-                                                .valueParameters.firstOrNull()
-                                        ) { name ->
-                                            getAttribute(name)
-                                        }
-                                }
-                            when (validationCalls.size) {
-                                0 -> if (!memoizing) {
-                                    // If we are not memoizing we should always return true
-                                    statements.add(IrConstImpl.constTrue(
-                                        UNDEFINED_OFFSET,
-                                        UNDEFINED_OFFSET,
-                                        irBuiltIns.booleanType
-                                    ))
-                                }
-                                1 -> statements.add(validationCalls.single())
-                                else -> {
-                                    statements.add(
-                                        validationCalls.reduce { left, right ->
-                                            when {
-                                                left is IrConstImpl<*> -> right
-                                                right is IrConstImpl<*> -> left
-                                                else -> statementGenerator.callMethod(
-                                                    UNDEFINED_OFFSET, UNDEFINED_OFFSET,
-                                                    resolvedKtxCall.infixOrCall
-                                                        ?: error("Invalid KTX Call"),
-                                                    left
-                                                ).apply {
-                                                    putValueArgument(0, right)
-                                                }
-                                            }
-                                        }
-                                    )
-                                }
-                            }
-
-                            statementGenerator.addReturn(statements, validateLambdaDescriptor)
-                        }
-                        putValueArgument(
-                            getComposerCallParameter(KtxNameConventions.CALL_INVALID_PARAMETER),
-                            validateLambda
-                        )
-
-                        // Place the last argument, which is where the "call" takes place
-                        val bodyLambdaDescriptor = memoize.callBlockFnDescriptor
-                            ?: error("Expected callBlockFnDescriptor to be non-null")
-                        val bodyParameterType =
-                            getComposerCallParameterType(KtxNameConventions.CALL_BLOCK_PARAMETER)
-                        val bodyLambda =
-                            lambdaExpression(
-                                bodyLambdaDescriptor, bodyParameterType,
-                                IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
-                            ) { statements ->
-                            val nextReceiver =
-                                bodyLambdaDescriptor.valueParameters.firstOrNull()?.let {
-                                val receiverValue =
-                                    statementGenerator.context.symbolTable.referenceValue(it)
-                                IrGetValueImpl(
-                                    UNDEFINED_OFFSET,
-                                    UNDEFINED_OFFSET,
-                                    it.type.toIrType(),
-                                    receiverValue
-                                )
-                            }
-                            statements.add(
-                                generateEmitOrCallNode(
-                                    callNode.call,
-                                    bodyLambdaDescriptor,
-                                    nextReceiver)
-                            )
-                        }
-                        putValueArgument(
-                            getComposerCallParameter(KtxNameConventions.CALL_BLOCK_PARAMETER),
-                            bodyLambda
-                        )
-                    }
-                }
-                is ErrorNode -> error("KTX element resolved to error node. Cannot generate.")
-            }
-        }
-
-        statements.add(
-            generateEmitOrCallNode(resolvedKtxCall.emitOrCall, statementGenerator.scopeOwner)
-        )
-
+        // NOTE(lmr):
+        // we insert a block here with two calls:
+        //  1. a call to get the composer
+        //  2. the original call that would have been generated to the synthetic emit descriptor
+        //
+        // We need to do this here because this is the only place we can properly generate a
+        // resolved call in full generality, which we need to do for the composer. We then intercept
+        // this block in the lowering phase and generate the final code we want.
         return IrBlockImpl(
-            startOffset,
-            endOffset,
-            irBuiltIns.unitType,
-            null,
-            statements
-        )
-    }
-}
-
-private fun StatementGenerator.getProperty(
-    startOffset: Int,
-    endOffset: Int,
-    property: ResolvedCall<*>
-): IrCall {
-    val functionDescriptor = (property.resultingDescriptor as PropertyDescriptor).getter
-        ?: error("Unexpected type resolution")
-    return buildCall(
-        startOffset,
-        endOffset,
-        property,
-        functionDescriptor,
-        irStatementOrigin = IrStatementOrigin.GET_PROPERTY
-    )
-}
-
-private fun StatementGenerator.extensionReceiverOf(descriptor: FunctionDescriptor): IrExpression? {
-    return descriptor.extensionReceiverParameter?.let {
-        val receiverValue = context.symbolTable.referenceValue(it)
-        IrGetValueImpl(
-            UNDEFINED_OFFSET,
-            UNDEFINED_OFFSET,
-            it.type.toIrType(),
-            receiverValue
-        )
-    }
-}
-
-private fun StatementGenerator.addReturn(
-    statements: MutableList<IrStatement>,
-    descriptor: FunctionDescriptor
-) {
-    val count = statements.size
-    if (count >= 1) {
-        // Replace the last statement with a return
-        val lastStatement = statements[count - 1]
-        if (lastStatement !is IrReturn) {
-            val scopeOwner = context.symbolTable.referenceFunction(descriptor)
-            statements[count - 1] = IrReturnImpl(
-                lastStatement.startOffset,
-                lastStatement.endOffset,
-                context.irBuiltIns.nothingType,
-                scopeOwner,
-                lastStatement as IrExpression
+            expression.startOffset,
+            expression.endOffset,
+            descriptor.returnType?.toIrType() ?: context.irBuiltIns.unitType,
+            COMPOSABLE_EMIT_OR_CALL,
+            listOf(
+                CallGenerator(this).generateCall(
+                    expression.startOffsetSkippingComments,
+                    expression.endOffset,
+                    pregenerateCall(descriptor.composer),
+                    COMPOSABLE_EMIT_OR_CALL
+                ),
+                visitCallExpressionWithoutInterception(expression)
             )
-        }
-    }
-}
-
-private fun StatementGenerator.validationCall(
-    startOffset: Int,
-    endOffset: Int,
-    memoizing: Boolean,
-    validation: ValidatedAssignment,
-    fnDescriptor: FunctionDescriptor,
-    assignmentReceiver: ValueDescriptor?,
-    getAttribute: (String) -> IrExpression
-): IrCall {
-    val attribute = validation.attribute
-    val name = attribute.name
-    val attributeValue = getAttribute(name)
-
-    val validator = extensionReceiverOf(fnDescriptor)
-        ?: error("expected an extension receiver to validator lambda")
-
-    // for emit, fnDescriptor is Validator.(Value) -> Unit    or Validator.(Value, Element.(Value) -> Unit) -> Unit
-    // for call, fnDescriptor is Validator.(Value) -> Boolean or Validator.(Value, (Value) -> Unit) -> Boolean
-
-    // in emit, the element is passed through an extension parameter
-    // in call, the element is passed through a capture scope
-    val validationCall = (
-                if (memoizing) validation.validationCall
-                else validation.uncheckedValidationCall
-            ) ?: error("Expected validationCall to be non-null")
-    return callMethod(
-        UNDEFINED_OFFSET, UNDEFINED_OFFSET, validationCall,
-        validator
-    ).apply {
-        putValueArgument(0, attributeValue)
-        val assignment = validation.assignment
-        if (assignment != null && validation.validationType != ValidationType.CHANGED) {
-            val assignmentLambdaDescriptor = validation.assignmentLambda
-                ?: error("Expected assignmentLambda to be non-null")
-            val validationAssignment = lambdaExpression(
-                startOffset, endOffset,
-                assignmentLambdaDescriptor,
-                validationCall.resultingDescriptor.valueParameters[1].type,
-                IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
-            ) { statements ->
-                val parameterDefinition = validation.assignmentLambda.valueParameters.first()
-                val parameterReference = context.symbolTable.referenceValueParameter(
-                    parameterDefinition
-                )
-                val receiver = assignmentReceiver?.let {
-                    val receiverValue = context.symbolTable.referenceValue(assignmentReceiver)
-                    IrGetValueImpl(
-                        UNDEFINED_OFFSET,
-                        UNDEFINED_OFFSET,
-                        assignmentReceiver.type.toIrType(),
-                        receiverValue
-                    )
-                } ?: error("Expected an assignment receiver for validations that have assignments")
-
-                val assignmentStatement = callMethod(
-                    startOffset,
-                    endOffset,
-                    assignment,
-                    receiver
-                ).apply {
-                    putValueArgument(
-                        0, IrGetValueImpl(
-                            UNDEFINED_OFFSET,
-                            UNDEFINED_OFFSET,
-                            parameterReference
-                        )
-                    )
-                }
-                statements.add(assignmentStatement)
-                addReturn(statements, assignmentLambdaDescriptor)
-            }
-            putValueArgument(1, validationAssignment)
-        }
-    }
-}
-
-private fun IrMemberAccessExpression.putValueParameters(
-    parameters: List<ValueNode>,
-    statementGenerator: StatementGenerator,
-    ctorValueParameters: List<ValueParameterDescriptor> = emptyList(),
-    getAttribute: (String) -> IrExpression
-) {
-    parameters.forEachIndexed { index, parameter ->
-        when (parameter) {
-            is DefaultValueNode -> {
-                // do nothing
-            }
-            is ImplicitCtorValueNode -> {
-                val implicitLambdaParameterCandidates = ctorValueParameters.filter {
-                    it.type.isSubtypeOf(parameter.type)
-                }
-                assert(implicitLambdaParameterCandidates.size == 1) {
-                    if (implicitLambdaParameterCandidates.isEmpty())
-                        "missing implicit constructor parameter ${parameter.name}: ${
-                            parameter.type
-                        }"
-                    else "ambiguous implicit constructor parameters ${parameter.name}: ${
-                        parameter.type
-                    }"
-                }
-                val implicitCtorParameter = implicitLambdaParameterCandidates.single()
-                val implicitCtorParameterReference =
-                    statementGenerator.context.symbolTable.referenceValue(implicitCtorParameter)
-                with(statementGenerator) {
-                    putValueArgument(
-                        index,
-                        IrGetValueImpl(
-                            UNDEFINED_OFFSET,
-                            UNDEFINED_OFFSET,
-                            implicitCtorParameter.type.toIrType(),
-                            implicitCtorParameterReference
-                        )
-                    )
-                }
-            }
-            is AttributeNode -> {
-                if (parameter.descriptor !is ValueParameterDescriptor) {
-                    error("Expected ValueParameterDescriptor. Found: ${parameter.descriptor}")
-                }
-                putValueArgument(parameter.descriptor.index, getAttribute(parameter.name))
-            }
-        }
-    }
-}
-
-private fun StatementGenerator.callMethod(
-    startOffset: Int,
-    endOffset: Int,
-    function: ResolvedCall<*>,
-    dispatchReceiver: IrExpression
-): IrCall {
-    val resultingDescriptor = function.resultingDescriptor
-    val functionDescriptor = when (resultingDescriptor) {
-        is PropertyDescriptor -> resultingDescriptor.setter!!
-        is FunctionDescriptor -> resultingDescriptor
-        else -> error("Expected function or property descriptor")
-    }
-
-    return buildCall(startOffset, endOffset, function, functionDescriptor, dispatchReceiver)
-}
-
-private fun StatementGenerator.assignmentReceiver(
-    startOffset: Int,
-    endOffset: Int,
-    resolvedCall: ResolvedCall<*>,
-    dispatchReceiver: IrExpression,
-    dispatchReceiverType: KotlinType
-): AssignmentReceiver {
-    val descriptor = resolvedCall.resultingDescriptor as PropertyDescriptor
-
-    var dispatchReceiverValue = resolvedCall.dispatchReceiver?.let {
-        generateReceiver(startOffset, endOffset, it)
-    }
-    var extensionReceiverValue = resolvedCall.extensionReceiver?.let {
-        generateReceiver(startOffset, endOffset, it)
-    }
-
-    if (dispatchReceiverValue is TransientReceiverValue) {
-        dispatchReceiverValue = object : IntermediateValue {
-            override fun load(): IrExpression = dispatchReceiver
-            override val type: IrType
-                get() = dispatchReceiverType.toIrType()
-        }
-    }
-    if (extensionReceiverValue is TransientReceiverValue) {
-        extensionReceiverValue = object : IntermediateValue {
-            override fun load(): IrExpression = dispatchReceiver
-            override val type: IrType
-                get() = dispatchReceiverType.toIrType()
-        }
-    }
-
-    val propertyReceiver = SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue)
-
-    val superQualifier = getSuperQualifier(resolvedCall)
-
-    // TODO property imported from an object
-    return createPropertyLValue(
-        startOffset,
-        endOffset,
-        descriptor,
-        propertyReceiver,
-        getTypeArguments(resolvedCall),
-        KTX_TAG_ORIGIN,
-        superQualifier
-    )
-}
-
-private fun StatementGenerator.createPropertyLValue(
-    startOffset: Int,
-    endOffset: Int,
-    descriptor: PropertyDescriptor,
-    propertyReceiver: CallReceiver,
-    typeArgumentsMap: Map<TypeParameterDescriptor, KotlinType>?,
-    origin: IrStatementOrigin?,
-    superQualifier: ClassDescriptor?
-): PropertyLValueBase {
-    val superQualifierSymbol = superQualifier?.let { context.symbolTable.referenceClass(it) }
-
-    val getterDescriptor = descriptor.unwrappedGetMethod
-    val setterDescriptor = descriptor.unwrappedSetMethod
-
-    val getterSymbol = getterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
-    val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
-
-    val propertyIrType = descriptor.type.toIrType()
-    return if (getterSymbol != null || setterSymbol != null) {
-        val typeArgumentsList =
-            typeArgumentsMap?.let { typeArguments ->
-                descriptor.original.typeParameters.map { typeArguments[it]!!.toIrType() }
-            }
-        AccessorPropertyLValue(
-            context,
-            scope,
-            startOffset, endOffset, origin,
-            propertyIrType,
-            getterSymbol,
-            getterDescriptor,
-            setterSymbol,
-            setterDescriptor,
-            typeArgumentsList,
-            propertyReceiver,
-            superQualifierSymbol
         )
-    } else
-        FieldPropertyLValue(
-            context,
-            scope,
-            startOffset, endOffset, origin,
-            context.symbolTable.referenceField(descriptor),
-            propertyIrType,
-            propertyReceiver,
-            superQualifierSymbol
+    }
+
+    private fun StatementGenerator.visitComposableCall(
+        descriptor: ComposableFunctionDescriptor,
+        expression: KtCallExpression
+    ): IrExpression? {
+        // NOTE(lmr):
+        // we insert a block here with two calls:
+        //  1. a call to get the composer
+        //  2. the original call that would have been generated to the synthetic emit descriptor
+        //
+        // We need to do this here because this is the only place we can properly generate a
+        // resolved call in full generality, which we need to do for the composer. We then intercept
+        // this block in the lowering phase and generate the final code we want.
+        return IrBlockImpl(
+            expression.startOffset,
+            expression.endOffset,
+            descriptor.returnType?.toIrType() ?: context.irBuiltIns.unitType,
+            COMPOSABLE_EMIT_OR_CALL,
+            listOf(
+                CallGenerator(this).generateCall(
+                    expression.startOffsetSkippingComments,
+                    expression.endOffset,
+                    pregenerateCall(descriptor.composerCall),
+                    COMPOSABLE_EMIT_OR_CALL
+                ),
+                visitCallExpressionWithoutInterception(expression)
+            )
         )
-}
-
-private fun StatementGenerator.buildCallOrCtor(
-    startOffset: Int,
-    endOffset: Int,
-    resolvedCall: ResolvedCall<*>,
-    descriptor: CallableDescriptor,
-    valueArgumentsCount: Int,
-    dispatchReceiver: IrExpression? = null
-) = when (descriptor) {
-    is ClassConstructorDescriptor -> buildCtorCall(
-        startOffset,
-        endOffset,
-        resolvedCall,
-        descriptor,
-        valueArgumentsCount,
-        dispatchReceiver = dispatchReceiver
-    )
-    is FunctionDescriptor -> buildCall(
-        startOffset,
-        endOffset,
-        resolvedCall,
-        descriptor,
-        dispatchReceiver = dispatchReceiver
-    )
-    else -> error("Unrecognized descriptor $descriptor")
-}
-
-private fun StatementGenerator.buildCall(
-    startOffset: Int,
-    endOffset: Int,
-    resolvedCall: ResolvedCall<*>,
-    descriptor: FunctionDescriptor,
-    receiver: IrExpression? = null,
-    dispatchReceiver: IrExpression? = null,
-    extensionReceiver: IrExpression? = null,
-    irStatementOrigin: IrStatementOrigin? = null
-): IrCall {
-    val callBuilder = pregenerateCallReceivers(resolvedCall)
-    return callBuilder.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
-        val returnType = descriptor.returnType!!
-        val functionSymbol = context.symbolTable.referenceFunction(descriptor.original)
-        IrCallImpl(
-            startOffset, endOffset,
-            returnType.toIrType(),
-            functionSymbol,
-            descriptor,
-            resolvedCall.typeArguments.count(),
-            irStatementOrigin,
-            null
-        ).apply {
-            when (resolvedCall.explicitReceiverKind) {
-                ExplicitReceiverKind.DISPATCH_RECEIVER -> {
-                    this.dispatchReceiver = dispatchReceiver ?: receiver
-                            ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: extensionReceiverValue?.load()
-                }
-                ExplicitReceiverKind.EXTENSION_RECEIVER -> {
-                    this.dispatchReceiver = dispatchReceiver ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: receiver
-                            ?: extensionReceiverValue?.load()
-                }
-                ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> {
-                    this.dispatchReceiver = dispatchReceiver ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: extensionReceiverValue?.load()
-                }
-                ExplicitReceiverKind.BOTH_RECEIVERS -> {
-                    this.dispatchReceiver = dispatchReceiver ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: extensionReceiverValue?.load()
-                }
-            }
-            putTypeArguments(resolvedCall.typeArguments) { it.toIrType() }
-        }
-    } as IrCall
-}
-
-private fun StatementGenerator.buildCtorCall(
-    startOffset: Int,
-    endOffset: Int,
-    resolvedCall: ResolvedCall<*>,
-    descriptor: ClassConstructorDescriptor,
-    valueArgumentsCount: Int,
-    dispatchReceiver: IrExpression? = null,
-    extensionReceiver: IrExpression? = null
-): IrConstructorCall {
-    val callBuilder = pregenerateCallReceivers(resolvedCall)
-    return (callBuilder.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
-        val returnType = descriptor.returnType
-        val functionSymbol =
-            context.symbolTable.referenceFunction(descriptor.original) as IrConstructorSymbol
-        IrConstructorCallImpl(
-            startOffset, endOffset,
-            returnType.toIrType(),
-            functionSymbol,
-            descriptor,
-            typeArgumentsCount = descriptor.typeParametersCount,
-            constructorTypeArgumentsCount = 0,
-            valueArgumentsCount = valueArgumentsCount
-        ).apply {
-            when (resolvedCall.explicitReceiverKind) {
-                ExplicitReceiverKind.DISPATCH_RECEIVER -> {
-                    this.dispatchReceiver = dispatchReceiver ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: extensionReceiverValue?.load()
-                }
-                ExplicitReceiverKind.EXTENSION_RECEIVER -> {
-                    this.dispatchReceiver = dispatchReceiver ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: extensionReceiverValue?.load()
-                }
-                ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> {
-                    this.dispatchReceiver = dispatchReceiver ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: extensionReceiverValue?.load()
-                }
-                ExplicitReceiverKind.BOTH_RECEIVERS -> {
-                    this.dispatchReceiver = dispatchReceiver ?: dispatchReceiverValue?.load()
-                    this.extensionReceiver = extensionReceiver ?: extensionReceiverValue?.load()
-                }
-            }
-            putTypeArguments(resolvedCall.typeArguments) { it.toIrType() }
-        }
-    }) as IrConstructorCall
+    }
 }
 
 internal fun getKeyValue(descriptor: DeclarationDescriptor, startOffset: Int): Int =
     descriptor.fqNameSafe.toString().hashCode() xor startOffset
 
-private fun buildLambda(
-    statementGenerator: StatementGenerator,
-    context: GeneratorContext,
-    startOffset: Int,
-    endOffset: Int,
-    descriptor: FunctionDescriptor,
-    origin: IrDeclarationOrigin,
-    body: (statements: MutableList<IrStatement>) -> Unit
-): IrSimpleFunction {
-    return context.symbolTable.declareSimpleFunctionWithOverrides(
-        startOffset = startOffset,
-        endOffset = endOffset,
-        origin = origin,
-        descriptor = descriptor
-    )
-        .buildWithScope(context) { function ->
-            with(statementGenerator) {
-                fun declareParameter(descriptor: ParameterDescriptor) =
-                    context.symbolTable.declareValueParameter(
-                        startOffset = startOffset,
-                        endOffset = endOffset,
-                        origin = IrDeclarationOrigin.DEFINED,
-                        descriptor = descriptor,
-                        type = descriptor.type.toIrType()
-                    )
-
-                function.dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let {
-                    declareParameter(it)
-                }
-                function.extensionReceiverParameter = descriptor.extensionReceiverParameter?.let {
-                    declareParameter(it)
-                }
-                descriptor.valueParameters.mapTo(function.valueParameters) { declareParameter(it) }
-
-                val statements = mutableListOf<IrStatement>()
-                body(statements)
-                function.body = IrBlockBodyImpl(startOffset, endOffset, statements)
-                function.returnType = descriptor.returnType?.toIrType()
-                    ?: error("unable to find return type")
-            }
-        }
-}
-
-private fun StatementGenerator.lambdaExpression(
-    startOffset: Int,
-    endOffset: Int,
-    descriptor: FunctionDescriptor,
-    kotlinType: KotlinType,
-    origin: IrDeclarationOrigin,
-    block: (statements: MutableList<IrStatement>) -> Unit
-): IrExpression {
-    val declaration = buildLambda(
-        this,
-        context,
-        startOffset,
-        endOffset,
-        descriptor,
-        origin,
-        block
-    )
-    val type = kotlinType.toIrType()
-    return IrBlockImpl(
-        startOffset = startOffset,
-        endOffset = endOffset,
-        type = type,
-        // Important: The origin must be LAMBDA here or the JVM IR backend will create a class
-        // for function when it is inlined
-        origin = IrStatementOrigin.LAMBDA,
-        statements = mutableListOf(
-            declaration,
-            IrFunctionReferenceImpl(
-                startOffset = startOffset,
-                endOffset = endOffset,
-                type = type,
-                symbol = declaration.symbol,
-                descriptor = declaration.symbol.descriptor,
-                typeArgumentsCount = 0,
-                origin = IrStatementOrigin.LAMBDA
-            )
-        )
-    )
-}
-
-private fun String.jvmSafeChars() = map {
-    if (!it.isLetterOrDigit()) "${"$"}${it.toInt()}${"$"}" else "$it"
-}.joinToString(separator = "")
-
-internal val KTX_TAG_ORIGIN = object : IrStatementOriginImpl("KTX Tag") {}
\ No newline at end of file
+internal val COMPOSABLE_EMIT_OR_CALL =
+    object : IrStatementOriginImpl("Composable Emit Or Call") {}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt
index 0d23b0d..3ab9d97 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt
@@ -16,7 +16,19 @@
 
 package androidx.compose.plugins.kotlin
 
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
+import org.jetbrains.kotlin.name.ClassId
 import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.psi.KtCallExpression
+import org.jetbrains.kotlin.psi.KtFunction
+import org.jetbrains.kotlin.psi.KtFunctionLiteral
+import org.jetbrains.kotlin.psi.KtLambdaArgument
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
+import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
+import org.jetbrains.kotlin.resolve.descriptorUtil.module
 
 object ComposeUtils {
 
@@ -38,4 +50,24 @@
         // use !lower to capture non-alpha chars
         return name.startsWith("set") && name.length > 3 && !name[3].isLowerCase()
     }
+
+    fun isComposeComponent(descriptor: DeclarationDescriptor): Boolean {
+        if (descriptor !is ClassDescriptor) return false
+        val baseComponentDescriptor =
+            descriptor.module.findClassAcrossModuleDependencies(
+                ClassId.topLevel(
+                    FqName(ComposeUtils.generateComposePackageName() + ".Component")
+                )
+            ) ?: return false
+        return descriptor.isSubclassOf(baseComponentDescriptor)
+    }
+}
+
+fun KtFunction.isEmitInline(bindingContext: BindingContext): Boolean {
+    if (this !is KtFunctionLiteral) return false
+    if (parent?.parent !is KtLambdaArgument) return false
+    val call = parent?.parent?.parent as? KtCallExpression
+    val resolvedCall = call?.getResolvedCall(bindingContext)
+    return resolvedCall != null &&
+            resolvedCall.candidateDescriptor is ComposableEmitDescriptor
 }
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposerEmitMetadata.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposerMetadata.kt
similarity index 89%
rename from compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposerEmitMetadata.kt
rename to compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposerMetadata.kt
index 1342e62..e5619e6 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposerEmitMetadata.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposerMetadata.kt
@@ -21,6 +21,7 @@
 import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
 import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
 import org.jetbrains.kotlin.descriptors.CallableDescriptor
+import org.jetbrains.kotlin.descriptors.FunctionDescriptor
 import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
 import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
 import org.jetbrains.kotlin.descriptors.VariableDescriptor
@@ -37,7 +38,8 @@
 import org.jetbrains.kotlin.types.typeUtil.isNothingOrNullableNothing
 import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
 
-class ComposerEmitMetadata(
+class ComposerMetadata(
+    val type: KotlinType,
     // Set of valid upper bound types that were defined on the composer that can't have children
     // For android, this should be [View]
     private val emitSimpleUpperBoundTypes: Set<KotlinType>,
@@ -56,7 +58,8 @@
     //      fun <T : View> emit(key: Any, ctor: (context: Context) -> T, update: U<T>.() -> Unit)
     //
     // would produce a Pair of [View] to [Context]
-    private val emittableTypeToImplicitCtorTypes: List<Pair<List<KotlinType>, Set<KotlinType>>>
+    private val emittableTypeToImplicitCtorTypes: List<Pair<List<KotlinType>, Set<KotlinType>>>,
+    val callDescriptors: List<FunctionDescriptor>
 ) {
 
     companion object {
@@ -104,7 +107,7 @@
             callResolver: CallResolver,
             psiFactory: KtPsiFactory,
             resolutionContext: BasicCallResolutionContext
-        ): ComposerEmitMetadata {
+        ): ComposerMetadata {
             val emitSimpleUpperBoundTypes = mutableSetOf<KotlinType>()
             val emitCompoundUpperBoundTypes = mutableSetOf<KotlinType>()
             val emittableTypeToImplicitCtorTypes =
@@ -118,6 +121,14 @@
                 psiFactory
             )
 
+            val callCandidates = resolveComposerMethodCandidates(
+                KtxNameConventions.CALL,
+                resolutionContext,
+                composerType,
+                callResolver,
+                psiFactory
+            )
+
             for (candidate in emitCandidates.map { it.candidateDescriptor }) {
                 if (candidate.name != KtxNameConventions.EMIT) continue
                 if (candidate !is SimpleFunctionDescriptor) continue
@@ -153,10 +164,16 @@
                 }
             }
 
-            return ComposerEmitMetadata(
+            val callDescriptors = callCandidates.mapNotNull {
+                it.candidateDescriptor as? FunctionDescriptor
+            }
+
+            return ComposerMetadata(
+                composerType,
                 emitSimpleUpperBoundTypes,
                 emitCompoundUpperBoundTypes,
-                emittableTypeToImplicitCtorTypes
+                emittableTypeToImplicitCtorTypes,
+                callDescriptors
             )
         }
 
@@ -165,16 +182,15 @@
             callResolver: CallResolver,
             psiFactory: KtPsiFactory,
             resolutionContext: BasicCallResolutionContext
-        ): ComposerEmitMetadata {
+        ): ComposerMetadata {
             val meta = resolutionContext.trace.bindingContext[
-                    ComposeWritableSlices.COMPOSER_EMIT_METADATA,
+                    ComposeWritableSlices.COMPOSER_METADATA,
                     descriptor
             ]
             return if (meta == null) {
-                val built =
-                    build(descriptor.type, callResolver, psiFactory, resolutionContext)
+                val built = build(descriptor.type, callResolver, psiFactory, resolutionContext)
                 resolutionContext.trace.record(
-                    ComposeWritableSlices.COMPOSER_EMIT_METADATA,
+                    ComposeWritableSlices.COMPOSER_METADATA,
                     descriptor,
                     built
                 )
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/GeneratedKtxChildrenLambdaClassDescriptor.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/GeneratedKtxChildrenLambdaClassDescriptor.kt
deleted file mode 100644
index 6607a5d..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/GeneratedKtxChildrenLambdaClassDescriptor.kt
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor
-import org.jetbrains.kotlin.descriptors.Modality
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
-import org.jetbrains.kotlin.descriptors.SourceElement
-import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
-import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.descriptors.Visibilities
-import org.jetbrains.kotlin.descriptors.Visibility
-import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
-import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.LazyClassReceiverParameterDescriptor
-import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
-import org.jetbrains.kotlin.incremental.components.LookupLocation
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
-import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
-import org.jetbrains.kotlin.resolve.scopes.MemberScope
-import org.jetbrains.kotlin.storage.LockBasedStorageManager
-import org.jetbrains.kotlin.types.ClassTypeConstructorImpl
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.KotlinTypeFactory
-import org.jetbrains.kotlin.types.SimpleType
-import org.jetbrains.kotlin.types.TypeConstructor
-import org.jetbrains.kotlin.types.TypeProjection
-import org.jetbrains.kotlin.types.TypeSubstitution
-import org.jetbrains.kotlin.types.TypeSubstitutor
-import org.jetbrains.kotlin.types.TypeUtils
-import org.jetbrains.kotlin.utils.Printer
-
-open class GeneratedKtxChildrenLambdaClassDescriptor(
-    private val module: ModuleDescriptor,
-    private val containingDeclaration: DeclarationDescriptor,
-    private val variablesToCapture: List<KotlinType>,
-    functionType: KotlinType,
-    private val parameters: List<ValueParameterDescriptor>
-) : ClassDescriptor {
-
-    companion object {
-        private var index = 1
-    }
-
-    private val internalName by lazy {
-        Name.identifier("KTX_CHILD_${index++}")
-    }
-
-    override fun isInline(): Boolean = false
-    override fun getName() = internalName
-    override fun isExpect(): Boolean = false
-    override fun isActual(): Boolean = false
-    private val modality = Modality.FINAL
-    private val kind = ClassKind.CLASS
-    private val sourceElement = SourceElement.NO_SOURCE
-    override val annotations = Annotations.EMPTY
-    private lateinit var typeConstructor: TypeConstructor
-    private lateinit var supertypes: Collection<KotlinType>
-    private lateinit var defaultType: SimpleType
-    private lateinit var declaredTypeParameters: List<TypeParameterDescriptor>
-    private var unsubstitutedPrimaryConstructor: ClassConstructorDescriptor? = null
-
-    init {
-        initialize(emptyList(), listOf(functionType))
-    }
-
-    val capturedAccessesAsProperties by lazy {
-        variablesToCapture.mapIndexed { index, type ->
-            PropertyDescriptorImpl.create(
-                this,
-                Annotations.EMPTY,
-                Modality.FINAL,
-                Visibilities.PRIVATE,
-                false,
-                Name.identifier("p$index"),
-                CallableMemberDescriptor.Kind.SYNTHESIZED,
-                SourceElement.NO_SOURCE,
-                false,
-                false,
-                true,
-                true,
-                false,
-                false
-            ).apply {
-                setType(
-                    type,
-                    emptyList<TypeParameterDescriptor>(),
-                    thisAsReceiverParameter,
-                    null as ReceiverParameterDescriptor?
-                )
-                initialize(
-                    PropertyGetterDescriptorImpl(
-                        this,
-                        Annotations.EMPTY,
-                        Modality.FINAL,
-                        Visibilities.PRIVATE,
-                        false,
-                        false,
-                        false,
-                        CallableMemberDescriptor.Kind.SYNTHESIZED,
-                        null,
-                        SourceElement.NO_SOURCE
-                    ).apply {
-                        initialize(type)
-                    },
-                    PropertySetterDescriptorImpl(
-                        this,
-                        Annotations.EMPTY,
-                        Modality.FINAL,
-                        Visibilities.PRIVATE,
-                        false,
-                        false,
-                        false,
-                        CallableMemberDescriptor.Kind.SYNTHESIZED,
-                        null,
-                        SourceElement.NO_SOURCE
-                    ).apply {
-                        initializeDefault()
-                    }
-                )
-            }
-        }
-    }
-
-    val invokeDescriptor by lazy {
-        val functionNInterface =
-            module.findClassAcrossModuleDependencies(
-                ClassId.topLevel(FqName("kotlin.jvm.functions.Function" + parameters.size))
-            )!!
-        val overridenMethod =
-            functionNInterface.unsubstitutedMemberScope.getContributedFunctions(
-                Name.identifier("invoke"),
-                NoLookupLocation.FROM_BACKEND
-            ).single()
-        val newMethod = SimpleFunctionDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            Name.identifier("invoke"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE
-        )
-        newMethod.setSingleOverridden(overridenMethod)
-
-        val parameters = parameters.map {
-            ValueParameterDescriptorImpl(
-                newMethod,
-                it,
-                it.index,
-                it.annotations,
-                it.name,
-                it.type,
-                false,
-                false,
-                false,
-                null,
-                it.source
-            )
-        }
-
-        newMethod.initialize(
-            null,
-            this.thisAsReceiverParameter,
-            emptyList(),
-            parameters,
-            builtIns.unitType,
-            Modality.OPEN,
-            Visibilities.PUBLIC
-        )
-        newMethod
-    }
-
-    private val thisAsReceiverParameter = LazyClassReceiverParameterDescriptor(this)
-
-    fun initialize(
-        declaredTypeParameters: List<TypeParameterDescriptor>,
-        supertypes: Collection<KotlinType>
-    ) {
-        this.declaredTypeParameters = declaredTypeParameters
-        this.supertypes = supertypes
-        this.typeConstructor = ClassTypeConstructorImpl(
-            this,
-            declaredTypeParameters,
-            supertypes,
-            LockBasedStorageManager.NO_LOCKS
-        )
-        this.defaultType =
-            TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope,
-                KotlinTypeFactory.EMPTY_REFINED_TYPE_FACTORY)
-    }
-
-    override fun getCompanionObjectDescriptor(): ClassDescriptor? = null
-    override fun getConstructors(): Collection<ClassConstructorDescriptor> =
-        listOf(getUnsubstitutedPrimaryConstructor())
-    override fun getContainingDeclaration() = containingDeclaration
-    override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = declaredTypeParameters
-    override fun getKind(): ClassKind = kind
-    override fun getSealedSubclasses(): Collection<ClassDescriptor> = emptyList()
-
-    fun genScope(): MemberScope {
-
-        return object : MemberScope {
-
-            override fun getFunctionNames(): Set<Name> = setOf(Name.identifier("invoke"))
-
-            override fun getVariableNames(): Set<Name> = emptySet()
-
-            override fun getClassifierNames(): Set<Name>? = null
-
-            override fun getContributedClassifier(
-                name: Name,
-                location: LookupLocation
-            ): ClassifierDescriptor? = null
-
-            override fun getContributedDescriptors(
-                kindFilter: DescriptorKindFilter,
-                nameFilter: (Name) -> Boolean
-            ): Collection<DeclarationDescriptor> {
-                return emptyList()
-            }
-
-            override fun getContributedVariables(
-                name: Name,
-                location: LookupLocation
-            ): Collection<PropertyDescriptor> {
-                return capturedAccessesAsProperties
-            }
-
-            override fun getContributedFunctions(
-                name: Name,
-                location: LookupLocation
-            ): Collection<SimpleFunctionDescriptor> {
-                if (name.identifier == "invoke") {
-                    return listOf(invokeDescriptor)
-                }
-                return emptyList()
-            }
-
-            override fun printScopeStructure(p: Printer) {
-                p.println(this::class.java.simpleName)
-            }
-        }
-    }
-
-    override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope =
-        genScope()
-    override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = genScope()
-    override fun getStaticScope(): MemberScope = genScope()
-    override fun getUnsubstitutedInnerClassesScope(): MemberScope = genScope()
-    override fun getUnsubstitutedMemberScope(): MemberScope = genScope()
-
-    override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor {
-        unsubstitutedPrimaryConstructor?.let { return it }
-        val constructor = ClassConstructorDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            false,
-            SourceElement.NO_SOURCE
-        )
-
-        val parameters = variablesToCapture.mapIndexed { index, parameterType ->
-            ValueParameterDescriptorImpl(
-                constructor,
-                null, index, Annotations.EMPTY,
-                Name.identifier("p$index"),
-                parameterType,
-                false,
-                false,
-                false, null, SourceElement.NO_SOURCE
-            )
-        }
-
-        constructor.initialize(
-            parameters,
-            Visibilities.PUBLIC
-        )
-
-        constructor.apply {
-            returnType = containingDeclaration.defaultType
-        }
-
-        unsubstitutedPrimaryConstructor = constructor
-
-        return constructor
-    }
-
-    override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor =
-        error("Class $this can't be substituted")
-    override fun getThisAsReceiverParameter(): ReceiverParameterDescriptor = thisAsReceiverParameter
-    override fun getModality(): Modality = modality
-    override fun getOriginal(): ClassDescriptor = this
-    override fun getVisibility(): Visibility = Visibilities.PUBLIC
-    override fun getSource(): SourceElement = sourceElement
-    override fun getTypeConstructor(): TypeConstructor = typeConstructor
-    override fun getDefaultType(): SimpleType = defaultType
-    override fun isCompanionObject(): Boolean = false
-    override fun isData(): Boolean = false
-    override fun isInner(): Boolean = false
-    override fun isExternal(): Boolean = false
-
-    override fun <R : Any?, D : Any?> accept(
-        visitor: DeclarationDescriptorVisitor<R, D>,
-        data: D
-    ): R {
-        return visitor.visitClassDescriptor(this, data)
-    }
-
-    override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>) {
-        visitor.visitClassDescriptor(this, null)
-    }
-
-    override fun toString(): String = "GeneratedChildrenLambdaClassDescriptor($fqNameUnsafe)"
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/GeneratedViewClassDescriptor.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/GeneratedViewClassDescriptor.kt
deleted file mode 100644
index 7f91b8c..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/GeneratedViewClassDescriptor.kt
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor
-import org.jetbrains.kotlin.descriptors.Modality
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
-import org.jetbrains.kotlin.descriptors.SourceElement
-import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
-import org.jetbrains.kotlin.descriptors.Visibilities
-import org.jetbrains.kotlin.descriptors.Visibility
-import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
-import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.LazyClassReceiverParameterDescriptor
-import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
-import org.jetbrains.kotlin.incremental.components.LookupLocation
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
-import androidx.compose.plugins.kotlin.analysis.ComponentMetadata
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi.KtClass
-import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.module
-import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
-import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
-import org.jetbrains.kotlin.resolve.scopes.MemberScope
-import org.jetbrains.kotlin.storage.LockBasedStorageManager
-import org.jetbrains.kotlin.types.ClassTypeConstructorImpl
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.KotlinTypeFactory
-import org.jetbrains.kotlin.types.SimpleType
-import org.jetbrains.kotlin.types.TypeConstructor
-import org.jetbrains.kotlin.types.TypeProjection
-import org.jetbrains.kotlin.types.TypeSubstitution
-import org.jetbrains.kotlin.types.TypeSubstitutor
-import org.jetbrains.kotlin.types.TypeUtils
-import org.jetbrains.kotlin.utils.Printer
-
-open class GeneratedViewClassDescriptor(val metadata: ComponentMetadata) : ClassDescriptor {
-    private val module: ModuleDescriptor
-    private val containingDeclaration: ClassDescriptor
-
-    override fun isInline(): Boolean = false
-    override fun getName() =
-        Name.identifier(
-            (metadata.descriptor.findPsi() as KtClass).fqName!!.shortName().identifier +
-                    "WrapperView"
-        )
-
-    override fun isExpect(): Boolean = false
-    override fun isActual(): Boolean = false
-    private val modality = Modality.FINAL
-    private val kind = ClassKind.CLASS
-    private val sourceElement = SourceElement.NO_SOURCE
-    override val annotations = Annotations.EMPTY
-    private lateinit var typeConstructor: TypeConstructor
-    private lateinit var supertypes: Collection<KotlinType>
-    private lateinit var defaultType: SimpleType
-    private lateinit var declaredTypeParameters: List<TypeParameterDescriptor>
-    private var unsubstitutedPrimaryConstructor: ClassConstructorDescriptor? = null
-
-    val componentInstanceField by lazy {
-        PropertyDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            Modality.FINAL,
-            Visibilities.PRIVATE,
-            true,
-            Name.identifier("componentInstance"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE,
-            false,
-            false,
-            true,
-            true,
-            false,
-            false
-        ).apply {
-            setType(
-                KotlinTypeFactory.simpleType(
-                    Annotations.EMPTY,
-                    metadata.descriptor.typeConstructor,
-                    emptyList<TypeProjection>(),
-                    true
-                ),
-                emptyList<TypeParameterDescriptor>(),
-                thisAsReceiverParameter,
-                null as ReceiverParameterDescriptor?
-            )
-            initialize(
-                PropertyGetterDescriptorImpl(
-                    this,
-                    Annotations.EMPTY,
-                    Modality.FINAL,
-                    Visibilities.PRIVATE,
-                    false,
-                    false,
-                    false,
-                    CallableMemberDescriptor.Kind.SYNTHESIZED,
-                    null,
-                    SourceElement.NO_SOURCE
-                ).apply {
-                    initialize(metadata.descriptor.defaultType)
-                },
-                PropertySetterDescriptorImpl(
-                    this,
-                    Annotations.EMPTY,
-                    Modality.FINAL,
-                    Visibilities.PRIVATE,
-                    false,
-                    false,
-                    false,
-                    CallableMemberDescriptor.Kind.SYNTHESIZED,
-                    null,
-                    SourceElement.NO_SOURCE
-                ).apply {
-                    initializeDefault()
-                }
-            )
-        }
-    }
-
-    val dirtyField by lazy {
-        PropertyDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            Modality.FINAL,
-            Visibilities.PRIVATE,
-            true,
-            Name.identifier("dirty"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE,
-            false,
-            false,
-            true,
-            true,
-            false,
-            false
-        ).apply {
-            setType(
-                builtIns.booleanType,
-                emptyList<TypeParameterDescriptor>(),
-                thisAsReceiverParameter,
-                null as ReceiverParameterDescriptor?
-            )
-            initialize(
-                PropertyGetterDescriptorImpl(
-                    this,
-                    Annotations.EMPTY,
-                    Modality.FINAL,
-                    Visibilities.PRIVATE,
-                    false,
-                    false,
-                    false,
-                    CallableMemberDescriptor.Kind.SYNTHESIZED,
-                    null,
-                    SourceElement.NO_SOURCE
-                ).apply {
-                    initialize(builtIns.booleanType)
-                },
-                PropertySetterDescriptorImpl(
-                    this,
-                    Annotations.EMPTY,
-                    Modality.FINAL,
-                    Visibilities.PRIVATE,
-                    false,
-                    false,
-                    false,
-                    CallableMemberDescriptor.Kind.SYNTHESIZED,
-                    null,
-                    SourceElement.NO_SOURCE
-                ).apply {
-                    initializeDefault()
-                }
-            )
-        }
-    }
-
-    val onAttachDescriptor by lazy {
-        val newMethod = SimpleFunctionDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            Name.identifier("onAttachedToWindow"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE
-        )
-
-        newMethod.initialize(
-            null,
-            this.thisAsReceiverParameter,
-            emptyList(),
-            emptyList(),
-            builtIns.unitType,
-            Modality.OPEN,
-            Visibilities.PUBLIC
-        )
-        newMethod
-    }
-
-    val onDetachDescriptor by lazy {
-        val newMethod = SimpleFunctionDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            Name.identifier("onDetachedFromWindow"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE
-        )
-
-        newMethod.initialize(
-            null,
-            this.thisAsReceiverParameter,
-            emptyList(),
-            emptyList(),
-            builtIns.unitType,
-            Modality.OPEN,
-            Visibilities.PUBLIC
-        )
-        newMethod
-    }
-
-    init {
-        this.module = metadata.descriptor.module
-        val linearLayout =
-            module.findClassAcrossModuleDependencies(
-                ClassId.topLevel(FqName("android.widget.LinearLayout"))
-            )!!.defaultType
-        val viewTreeObserverDescriptor =
-            module.findClassAcrossModuleDependencies(
-                ClassId.topLevel(FqName("android.view.ViewTreeObserver"))
-            )!!
-        val preDrawListener = (
-                viewTreeObserverDescriptor.unsubstitutedInnerClassesScope.getContributedClassifier(
-                    Name.identifier("OnPreDrawListener"),
-                    NoLookupLocation.FROM_BACKEND
-                ) as ClassDescriptor).defaultType
-
-        initialize(emptyList(), listOf(linearLayout, preDrawListener))
-        this.containingDeclaration = metadata.descriptor
-    }
-
-    val onPreDraw by lazy {
-        val viewTreeObserverDescriptor =
-            module.findClassAcrossModuleDependencies(
-                ClassId.topLevel(FqName("android.view.ViewTreeObserver"))
-            )!!
-        val preDrawListener =
-            viewTreeObserverDescriptor.unsubstitutedInnerClassesScope.getContributedClassifier(
-                Name.identifier("OnPreDrawListener"), NoLookupLocation.FROM_BACKEND
-            ) as ClassDescriptor
-
-        val overriddenMethod = preDrawListener.unsubstitutedMemberScope.getContributedFunctions(
-            Name.identifier("onPreDraw"), NoLookupLocation.FROM_BACKEND
-        ).single()
-        val newMethod = SimpleFunctionDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            Name.identifier("onPreDraw"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE
-        )
-        newMethod.setSingleOverridden(overriddenMethod)
-
-        newMethod.initialize(
-            null,
-            this.thisAsReceiverParameter,
-            emptyList(),
-            emptyList(),
-            builtIns.booleanType,
-            Modality.OPEN,
-            Visibilities.PUBLIC
-        )
-        newMethod
-    }
-
-    val compositionContextField by lazy {
-        val compositionContextDescriptor = module.findClassAcrossModuleDependencies(
-            ClassId.topLevel(ComposeUtils.composeFqName("CompositionContext"))
-        )!!
-        PropertyDescriptorImpl.create(
-            this,
-            Annotations.EMPTY,
-            Modality.FINAL,
-            Visibilities.PRIVATE,
-            true,
-            Name.identifier("compositionContext"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE,
-            false,
-            false,
-            true,
-            true,
-            false,
-            false
-        ).apply {
-            setType(
-                compositionContextDescriptor.defaultType,
-                emptyList<TypeParameterDescriptor>(), thisAsReceiverParameter,
-                null as ReceiverParameterDescriptor?
-            )
-            initialize(
-                PropertyGetterDescriptorImpl(
-                    this,
-                    Annotations.EMPTY,
-                    Modality.FINAL,
-                    Visibilities.PRIVATE,
-                    false,
-                    false,
-                    false,
-                    CallableMemberDescriptor.Kind.SYNTHESIZED,
-                    null,
-                    SourceElement.NO_SOURCE
-                ).apply {
-                    initialize(compositionContextDescriptor.defaultType)
-                },
-                PropertySetterDescriptorImpl(
-                    this,
-                    Annotations.EMPTY,
-                    Modality.FINAL,
-                    Visibilities.PRIVATE,
-                    false,
-                    false,
-                    false,
-                    CallableMemberDescriptor.Kind.SYNTHESIZED,
-                    null,
-                    SourceElement.NO_SOURCE
-                ).apply {
-                    initializeDefault()
-                }
-            )
-        }
-    }
-
-    val attributeSetters: Collection<SimpleFunctionDescriptor> by lazy {
-
-        val output = mutableListOf<SimpleFunctionDescriptor>()
-
-        for (attr in metadata.getAttributeDescriptors()) {
-            val newMethod = SimpleFunctionDescriptorImpl.create(
-                metadata.wrapperViewDescriptor,
-                Annotations.EMPTY,
-                Name.identifier(
-                    ComposeUtils.setterMethodFromPropertyName(
-                        attr.name.identifier
-                    )
-                ),
-                CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE
-            )
-
-            newMethod.initialize(
-                null,
-                null,
-                emptyList(),
-                listOf(
-                    ValueParameterDescriptorImpl(
-                        newMethod,
-                        null,
-                        0,
-                        Annotations.EMPTY,
-                        attr.name,
-                        attr.type,
-                        false,
-                        false,
-                        false,
-                        null,
-                        SourceElement.NO_SOURCE
-                    )
-                ),
-                builtIns.unitType,
-                Modality.FINAL,
-                Visibilities.PUBLIC
-            )
-
-            output.add(newMethod)
-        }
-        output
-    }
-
-    private val thisAsReceiverParameter = LazyClassReceiverParameterDescriptor(this)
-
-    fun initialize(
-        declaredTypeParameters: List<TypeParameterDescriptor>,
-        supertypes: Collection<KotlinType>
-    ) {
-        this.declaredTypeParameters = declaredTypeParameters
-        this.supertypes = supertypes
-        this.typeConstructor =
-            ClassTypeConstructorImpl(
-                this,
-                declaredTypeParameters,
-                supertypes,
-                LockBasedStorageManager.NO_LOCKS
-            )
-        this.defaultType =
-            TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope,
-                KotlinTypeFactory.EMPTY_REFINED_TYPE_FACTORY)
-    }
-
-    override fun getCompanionObjectDescriptor(): ClassDescriptor? = null
-    override fun getConstructors(): Collection<ClassConstructorDescriptor> =
-        listOf(getUnsubstitutedPrimaryConstructor())
-    override fun getContainingDeclaration() = containingDeclaration
-    override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = declaredTypeParameters
-    override fun getKind(): ClassKind = kind
-    override fun getSealedSubclasses(): Collection<ClassDescriptor> = emptyList()
-
-    fun genScope(): MemberScope {
-
-        return object : MemberScope {
-
-            override fun getFunctionNames(): Set<Name> {
-                return setterMethodDescriptors.map { it.name }.toSet()
-            }
-
-            override fun getVariableNames(): Set<Name> {
-                return emptySet()
-            }
-
-            override fun getClassifierNames(): Set<Name>? = null
-
-            override fun getContributedClassifier(
-                name: Name,
-                location: LookupLocation
-            ): ClassifierDescriptor? {
-                return null
-            }
-
-            override fun getContributedDescriptors(
-                kindFilter: DescriptorKindFilter,
-                nameFilter: (Name) -> Boolean
-            ): Collection<DeclarationDescriptor> {
-                return emptyList()
-            }
-
-            override fun getContributedVariables(
-                name: Name,
-                location: LookupLocation
-            ): Collection<PropertyDescriptor> {
-                if (name.identifier == "componentInstance") {
-                    return listOf(componentInstanceField)
-                }
-                if (name.identifier == "compositionContext") {
-                    return listOf(compositionContextField)
-                }
-                if (name.identifier == "dirty") {
-                    return listOf(dirtyField)
-                }
-                return emptyList()
-            }
-
-            override fun getContributedFunctions(
-                name: Name,
-                location: LookupLocation
-            ): Collection<SimpleFunctionDescriptor> {
-                if (name.identifier == "onDetachedFromWindow") {
-                    return listOf(onDetachDescriptor)
-                }
-                if (name.identifier == "onAttachedToWindow") {
-                    return listOf(onAttachDescriptor)
-                }
-                if (name.identifier == "onPreDraw") {
-                    return listOf(onPreDraw)
-                }
-
-                return setterMethodDescriptors.filter { name == it.fqNameSafe.shortName() }
-            }
-
-            override fun printScopeStructure(p: Printer) {
-                p.println(this::class.java.simpleName)
-            }
-        }
-    }
-
-    override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope =
-        genScope()
-    override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = genScope()
-    override fun getStaticScope(): MemberScope = genScope()
-    override fun getUnsubstitutedInnerClassesScope(): MemberScope = genScope()
-    override fun getUnsubstitutedMemberScope(): MemberScope = genScope()
-
-    override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor {
-        unsubstitutedPrimaryConstructor?.let { return it }
-        val constructor = ClassConstructorDescriptorImpl.create(
-                this,
-                Annotations.EMPTY,
-                false,
-                SourceElement.NO_SOURCE
-        )
-        val contextParameter = ValueParameterDescriptorImpl(
-                constructor,
-                null, 0, Annotations.EMPTY,
-                Name.identifier("context"),
-                containingDeclaration.module.findClassAcrossModuleDependencies(
-                    ClassId.topLevel(FqName("android.content.Context"))
-                )!!.defaultType,
-                false,
-                false,
-                false, null, SourceElement.NO_SOURCE)
-        constructor.initialize(
-                listOf(contextParameter),
-                Visibilities.PUBLIC
-        )
-
-        constructor.apply {
-            returnType = containingDeclaration.defaultType
-        }
-
-        unsubstitutedPrimaryConstructor = constructor
-
-        return constructor
-    }
-
-    override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor =
-        error("Class $this can't be substituted")
-
-    override fun getThisAsReceiverParameter(): ReceiverParameterDescriptor = thisAsReceiverParameter
-
-    override fun getModality(): Modality = modality
-    override fun getOriginal(): ClassDescriptor = this
-    override fun getVisibility(): Visibility = Visibilities.PUBLIC
-    override fun getSource(): SourceElement = sourceElement
-    override fun getTypeConstructor(): TypeConstructor = typeConstructor
-    override fun getDefaultType(): SimpleType = defaultType
-
-    override fun isCompanionObject(): Boolean = false
-    override fun isData(): Boolean = false
-    override fun isInner(): Boolean = false
-    override fun isExternal(): Boolean = false
-
-    override fun <R : Any?, D : Any?> accept(
-        visitor: DeclarationDescriptorVisitor<R, D>,
-        data: D
-    ): R {
-        return visitor.visitClassDescriptor(this, data)
-    }
-
-    override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>) {
-        visitor.visitClassDescriptor(this, null)
-    }
-
-    override fun toString(): String = "GeneratedViewClassDescriptor($fqNameUnsafe)"
-
-    val setterMethodDescriptors: Collection<SimpleFunctionDescriptor> by lazy {
-        val descriptors = ArrayList<SimpleFunctionDescriptor>()
-        for (property in metadata.getAttributeDescriptors()) {
-
-            val unitType: SimpleType = this.builtIns.unitType
-            val methodName = "set" + property.name.identifier.substring(0, 1).toUpperCase() +
-                    property.name.identifier.substring(1)
-            val newMethod = SimpleFunctionDescriptorImpl.create(
-                this,
-                annotations,
-                Name.identifier(methodName),
-                CallableMemberDescriptor.Kind.SYNTHESIZED,
-                SourceElement.NO_SOURCE
-            )
-
-            val parameter = ValueParameterDescriptorImpl(
-                newMethod,
-                null, 0, Annotations.EMPTY,
-                property.name,
-                property.type,
-                false,
-                false,
-                false, null, SourceElement.NO_SOURCE)
-            newMethod.initialize(
-                null,
-                this.thisAsReceiverParameter,
-                emptyList(),
-                listOf(parameter),
-                unitType,
-                Modality.FINAL,
-                Visibilities.PUBLIC
-            )
-            descriptors.add(newMethod)
-        }
-
-        descriptors
-    }
-
-    var instanceCreatorFunction: SimpleFunctionDescriptor? = null
-    fun getInstanceCreatorFunction(
-        componentClassDescriptor: ClassDescriptor
-    ): SimpleFunctionDescriptor {
-        if (instanceCreatorFunction != null) return instanceCreatorFunction!!
-        val returnType: SimpleType = this.defaultType
-
-        // JvmStatic annotation was removed because it causes illegal bytecode to be generated due to a bug in the compiler.  Add it back once fixed.
-        // TODO: Annotations.create(listOf(AnnotationDescriptorImpl(componentClassDescriptor.module.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("kotlin.jvm.JvmStatic")))!!.defaultType, HashMap<Name, ConstantValue<*>>(), SourceElement.NO_SOURCE)))
-        val annotations = Annotations.EMPTY
-
-        val newMethod = SimpleFunctionDescriptorImpl.create(
-            componentClassDescriptor,
-            annotations,
-            Name.identifier("createInstance"),
-            CallableMemberDescriptor.Kind.SYNTHESIZED,
-            SourceElement.NO_SOURCE
-        )
-        val contextParameter = ValueParameterDescriptorImpl(
-                newMethod,
-                null, 0, Annotations.EMPTY,
-                Name.identifier("context"),
-                componentClassDescriptor.module.findClassAcrossModuleDependencies(
-                    ClassId.topLevel(FqName("android.content.Context"))
-                )!!.defaultType,
-                false,
-                false,
-                false, null, SourceElement.NO_SOURCE
-        )
-        newMethod.initialize(
-            null,
-            if (componentClassDescriptor.isCompanionObject)
-                componentClassDescriptor.thisAsReceiverParameter
-            else null,
-            emptyList(),
-            listOf(contextParameter),
-            returnType,
-            Modality.OPEN,
-            Visibilities.PUBLIC
-        )
-        instanceCreatorFunction = newMethod
-        return newMethod
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/KtxCallResolver.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/KtxCallResolver.kt
deleted file mode 100644
index 2a67f56..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/KtxCallResolver.kt
+++ /dev/null
@@ -1,3971 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import com.intellij.lang.ASTNode
-import com.intellij.openapi.project.Project
-import com.intellij.psi.impl.source.tree.LeafPsiElement
-import com.intellij.util.SmartList
-import org.jetbrains.kotlin.builtins.DefaultBuiltIns
-import org.jetbrains.kotlin.builtins.createFunctionType
-import org.jetbrains.kotlin.builtins.extractParameterNameFromFunctionTypeArgument
-import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
-import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
-import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
-import org.jetbrains.kotlin.builtins.isExtensionFunctionType
-import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
-import org.jetbrains.kotlin.descriptors.CallableDescriptor
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
-import org.jetbrains.kotlin.descriptors.FieldDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.Modality
-import org.jetbrains.kotlin.descriptors.ModuleDescriptor
-import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
-import org.jetbrains.kotlin.descriptors.ParameterDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
-import org.jetbrains.kotlin.descriptors.SourceElement
-import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
-import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
-import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.descriptors.VariableDescriptor
-import org.jetbrains.kotlin.descriptors.Visibilities
-import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
-import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
-import org.jetbrains.kotlin.diagnostics.Errors
-import org.jetbrains.kotlin.diagnostics.Severity
-import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
-import org.jetbrains.kotlin.diagnostics.reportFromPlugin
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi.Call
-import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
-import org.jetbrains.kotlin.psi.KtElement
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtLambdaArgument
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.psi.KtQualifiedExpression
-import org.jetbrains.kotlin.psi.KtReferenceExpression
-import org.jetbrains.kotlin.psi.KtSimpleNameExpression
-import org.jetbrains.kotlin.psi.KtTypeArgumentList
-import org.jetbrains.kotlin.psi.KtTypeProjection
-import org.jetbrains.kotlin.psi.KtValueArgumentList
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.LambdaArgument
-import org.jetbrains.kotlin.psi.ValueArgument
-import org.jetbrains.kotlin.psi.ValueArgumentName
-import androidx.compose.plugins.kotlin.analysis.ComposeDefaultErrorMessages
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices.IGNORE_COMPOSABLE_INTERCEPTION
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices.STABLE_TYPE
-import org.jetbrains.kotlin.builtins.KotlinBuiltIns
-import org.jetbrains.kotlin.builtins.isFunctionType
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.BindingTrace
-import org.jetbrains.kotlin.resolve.DescriptorFactory
-import org.jetbrains.kotlin.resolve.ObservableBindingTrace
-import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
-import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
-import org.jetbrains.kotlin.resolve.TraceEntryFilter
-import org.jetbrains.kotlin.resolve.calls.CallResolver
-import org.jetbrains.kotlin.resolve.calls.CallTransformer
-import org.jetbrains.kotlin.resolve.calls.checkers.UnderscoreUsageChecker
-import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
-import org.jetbrains.kotlin.resolve.calls.context.CallPosition
-import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
-import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
-import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
-import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
-import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
-import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatchStatus
-import org.jetbrains.kotlin.resolve.calls.model.ArgumentUnmapped
-import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl
-import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
-import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments
-import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
-import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
-import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
-import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil
-import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
-import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
-import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
-import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
-import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke
-import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl
-import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference
-import org.jetbrains.kotlin.resolve.calls.util.CallMaker
-import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
-import org.jetbrains.kotlin.resolve.descriptorUtil.module
-import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
-import org.jetbrains.kotlin.resolve.scopes.MemberScope
-import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
-import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
-import org.jetbrains.kotlin.resolve.scopes.receivers.PackageQualifier
-import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
-import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
-import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
-import org.jetbrains.kotlin.resolve.scopes.receivers.TypeAliasQualifier
-import org.jetbrains.kotlin.resolve.scopes.receivers.TypeParameterQualifier
-import org.jetbrains.kotlin.resolve.scopes.receivers.expression
-import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
-import org.jetbrains.kotlin.resolve.scopes.utils.findFirstFromMeAndParent
-import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
-import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
-import org.jetbrains.kotlin.synthetic.isVisibleOutside
-import org.jetbrains.kotlin.types.ErrorUtils
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.TypeConstructor
-import org.jetbrains.kotlin.types.TypeSubstitutor
-import org.jetbrains.kotlin.types.TypeUtils
-import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
-import org.jetbrains.kotlin.types.checker.KotlinTypeCheckerImpl
-import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
-import org.jetbrains.kotlin.types.expressions.ExpressionTypingFacade
-import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
-import org.jetbrains.kotlin.types.isError
-import org.jetbrains.kotlin.types.isNullable
-import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
-import org.jetbrains.kotlin.types.typeUtil.equalTypesOrNulls
-import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
-import org.jetbrains.kotlin.types.typeUtil.isNothingOrNullableNothing
-import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
-import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
-import org.jetbrains.kotlin.types.typeUtil.isUnit
-import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
-import org.jetbrains.kotlin.types.typeUtil.supertypes
-import org.jetbrains.kotlin.util.OperatorNameConventions
-import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
-import java.util.Locale
-import java.util.concurrent.atomic.AtomicBoolean
-
-/**
- * This class is used to resolve a KTX Element to the corresponding set of calls on the composer, and the individual calls for
- * each attribute, etc.
- */
-class KtxCallResolver(
-    callResolver: CallResolver,
-    private val nullableFacade: ExpressionTypingFacade?,
-    private val project: Project,
-    private val composableAnnotationChecker: ComposableAnnotationChecker
-) {
-    private val isDeprecatedKtxTagResolve: Boolean = nullableFacade != null
-
-    private val facade: ExpressionTypingFacade
-        get() = nullableFacade
-            ?: error("Cannot use ExpressionTypingFacade in call interception mode")
-
-    private val callResolver = NoInterceptionCallResolver(callResolver)
-
-    private class TempResolveInfo(
-        val valid: Boolean,
-        val trace: TemporaryTraceAndCache,
-        val unusedAttributes: Set<String>,
-        val usedAttributes: Set<String>,
-        val missingRequiredAttributes: List<DeclarationDescriptor>,
-        val build: () -> EmitOrCallNode
-    ) {
-        val attributesLeft: Int
-            get() = unusedAttributes.count { it != TAG_KEY }
-    }
-
-    private class TempParameterInfo(
-        val attribute: AttributeInfo,
-        val descriptor: DeclarationDescriptor,
-        val type: KotlinType
-    )
-
-    // NOTE(lmr): I am unsure of the performance consequences of using KtPsiFactory. it appears to create a file for every
-    // call, which seems like something we definitely do not want, but it's also used in resolving for(..) loops, so
-    // maybe it's not terrible.
-    private val psiFactory = KtPsiFactory(project, markGenerated = false)
-
-    // The type of the `composer` variable in scope of the KTX tag
-    private var composerType: KotlinType = builtIns.unitType
-    // A ResolvedCall to "get" the composer variable in scope of the KTX element.
-    private var composerResolvedCall: ResolvedCall<*>? = null
-    // A ResolvedCall to the `joinKey(Any, Any?)` method on the composer in scope.
-    private var joinKeyCall: ResolvedCall<*>? = null
-
-    private var infixOrCall: ResolvedCall<*>? = null
-
-    private lateinit var mainElement: KtElement
-
-    private lateinit var tagExpressions: List<KtExpression>
-
-    private lateinit var module: ModuleDescriptor
-
-    // Set of valid upper bound types that were defined on the composer that can't have children
-    // For android, this should be [View]
-    private val emitSimpleUpperBoundTypes = mutableSetOf<KotlinType>()
-
-    private fun KotlinType.isEmittable() =
-        !isError && !isNothingOrNullableNothing() && emitSimpleUpperBoundTypes.any {
-            isSubtypeOf(it)
-        }
-
-    // Set of valid upper bound types that were defined on the composer that can have children.
-    // For android, this would be [ViewGroup]
-    private val emitCompoundUpperBoundTypes = mutableSetOf<KotlinType>()
-
-    private fun KotlinType.isCompoundEmittable() = !isError &&
-            !this.isNothingOrNullableNothing() &&
-            emitCompoundUpperBoundTypes.any {
-                isSubtypeOf(it)
-            }
-
-    // The specification for `emit` on a composer allows for the `ctor` parameter to be a function type
-    // with any number of parameters. We allow for these parameters to be used as parameters in the
-    // Constructors that are emitted with a KTX tag. These parameters can be overridden with attributes
-    // in the KTX tag, but if there are required parameters with a type that matches one declared in the
-    // ctor parameter, we will resolve it automatically with the value passed in the `ctor` lambda.
-    //
-    // In order to do this resolution, we store a list of pairs of "upper bounds" to parameter types. For example,
-    // the following emit call:
-    //
-    //      fun <T : View> emit(key: Any, ctor: (context: Context) -> T, update: U<T>.() -> Unit)
-    //
-    // would produce a Pair of [View] to [Context]
-    private val emittableTypeToImplicitCtorTypes =
-        mutableListOf<Pair<List<KotlinType>, Set<KotlinType>>>()
-
-    private fun isImplicitConstructorParam(
-        param: ValueParameterDescriptor,
-        fn: CallableDescriptor
-    ): Boolean {
-        val returnType = fn.returnType ?: return false
-        val paramType = param.type
-        for ((upperBounds, implicitTypes) in emittableTypeToImplicitCtorTypes) {
-            if (!implicitTypes.any { it.isSubtypeOf(paramType) }) continue
-            if (!returnType.satisfiesConstraintsOf(upperBounds)) continue
-            return true
-        }
-        return false
-    }
-
-    fun initializeFromKtxElement(element: KtxElement, context: ExpressionTypingContext): Boolean {
-
-        module = context.scope.ownerDescriptor.module
-
-        // we want to report errors on the tag names (open and closing), and not the entire element, since
-        // that would be too noisy
-        tagExpressions = listOfNotNull(
-            element.simpleTagName,
-            element.simpleClosingTagName,
-            element.qualifiedTagName,
-            element.qualifiedClosingTagName
-        )
-
-        val result = resolveComposer(element, context)
-        return result
-    }
-
-    fun initializeFromCall(call: Call, context: ExpressionTypingContext): Boolean {
-        val callee = call.calleeExpression ?: error("Expected calleeExpression")
-
-        module = context.scope.ownerDescriptor.module
-
-        tagExpressions = listOf(callee)
-
-        val result = resolveComposer(callee, context)
-
-        return result
-    }
-
-    /**
-     * KTX tags are defined to resolve a "composer" in the scope of the tag itself, and then the tag translates into a call
-     * or a set of calls on that composer instance. This method should be called first, and will resolve the composer in scope
-     * and record various pieces of metadata about the composer that will make resolving the tag possible. If it returns false
-     * then something went wrong and you should not try and resolve the tag. If the method returns false, at least one
-     * diagnostic will have been added to the tag somewhere to indicate that there was a problem.
-     */
-    private fun resolveComposer(element: KtExpression, context: ExpressionTypingContext): Boolean {
-
-        // The composer is currently resolved as whatever is currently in scope with the name "composer".
-        val resolvedComposer = resolveVar(KtxNameConventions.COMPOSER, element, context)
-
-        if (!resolvedComposer.isSuccess) {
-            ComposeErrors.NO_COMPOSER_FOUND.report(context, tagExpressions)
-            return false
-        }
-
-        val composerResolvedCall = resolvedComposer.resultingCall.also { composerResolvedCall = it }
-
-        val descriptor = composerResolvedCall.resultingDescriptor
-
-        composerType = when (descriptor) {
-            is PropertyDescriptor -> descriptor.type
-            is VariableDescriptor -> descriptor.type
-            // if composer isn't a property or variable, we don't currently know how to resolve it...
-            else -> {
-                ComposeErrors.NO_COMPOSER_FOUND.report(context, tagExpressions)
-                return false
-            }
-        }
-
-        val emitCandidates = resolveComposerMethodCandidates(
-            element,
-            KtxNameConventions.EMIT,
-            context
-        )
-
-        for (candidate in emitCandidates.map { it.candidateDescriptor }) {
-            if (candidate.name != KtxNameConventions.EMIT) continue
-            if (candidate !is SimpleFunctionDescriptor) continue
-            val params = candidate.valueParameters
-            // NOTE(lmr): we could report diagnostics on some of these? it seems strange to emit diagnostics about a function
-            // that is not necessarily being used though. I think it's probably better to just ignore them here.
-
-            // the signature of emit that we are looking for has 3 or 4 parameters
-            if (params.size < 3 || params.size > 4) continue
-            val ctorParam = params.find { it.name == KtxNameConventions.EMIT_CTOR_PARAMETER }
-                ?: continue
-            if (!ctorParam.type.isFunctionTypeOrSubtype) continue
-
-            // the return type from the ctor param is the "upper bound" of the node type. It will often be a generic type with constraints.
-            val upperBounds = ctorParam.type.getReturnTypeFromFunctionType().upperBounds()
-
-            // the ctor param can have parameters itself, which we interpret as implicit parameter types that the composer knows how to
-            // automatically provide to the component. In the case of Android Views, this is how we automatically provide Context.
-            val implicitParamTypes = ctorParam.type.getValueParameterTypesFromFunctionType().map {
-                it.type
-            }
-
-            for (implicitType in implicitParamTypes) {
-                emittableTypeToImplicitCtorTypes.add(upperBounds to implicitParamTypes.toSet())
-            }
-
-            emitSimpleUpperBoundTypes.addAll(upperBounds)
-
-            if (params.any { it.name == KtxNameConventions.EMIT_CHILDREN_PARAMETER }) {
-                emitCompoundUpperBoundTypes.addAll(upperBounds)
-            }
-        }
-
-        if (emitSimpleUpperBoundTypes.isEmpty()) {
-
-            // if the composer has no valid `emit` candidates, but *does* valid `call` methods, we will report no errors.
-            // It's strange, but it's possible for a composer that only handles `call` to be useful. To be sure, we first
-            // look up all of the call candidates.
-            val callCandidates = resolveComposerMethodCandidates(
-                element,
-                KtxNameConventions.EMIT,
-                context
-            )
-
-            if (callCandidates.isEmpty()) {
-                ComposeErrors.INVALID_COMPOSER_IMPLEMENTATION.report(
-                    context,
-                    tagExpressions,
-                    composerType,
-                    "Couldn't find any valid `call(...)` or `emit(...)` methods"
-                )
-            }
-        }
-
-        val left = psiFactory.createSimpleName("a")
-        val right = psiFactory.createSimpleName("b")
-
-        context.trace.record(
-            BindingContext.EXPRESSION_TYPE_INFO, left, KotlinTypeInfo(
-                type = builtIns.booleanType,
-                dataFlowInfo = DataFlowInfo.EMPTY,
-                jumpOutPossible = false,
-                jumpFlowInfo = DataFlowInfo.EMPTY
-            )
-        )
-
-        context.trace.record(
-            BindingContext.EXPRESSION_TYPE_INFO, right, KotlinTypeInfo(
-                type = builtIns.booleanType,
-                dataFlowInfo = DataFlowInfo.EMPTY,
-                jumpOutPossible = false,
-                jumpFlowInfo = DataFlowInfo.EMPTY
-            )
-        )
-
-        infixOrCall = resolveInfixOr(context)
-
-        joinKeyCall = resolveJoinKey(
-            expressionToReportErrorsOn = tagExpressions.firstOrNull() ?: return false,
-            context = context
-        ) ?: run {
-            ComposeErrors.INVALID_COMPOSER_IMPLEMENTATION.report(
-                context,
-                tagExpressions,
-                composerType,
-                "Couldn't find valid method 'fun joinKey(Any, Any?): Any'"
-            )
-            return false
-        }
-
-        return true
-    }
-
-    fun resolveFromKtxElement(
-        element: KtxElement,
-        context: ExpressionTypingContext
-    ): ResolvedKtxElementCall {
-        mainElement = element
-
-        val openTagExpr = element.simpleTagName ?: element.qualifiedTagName
-            ?: error("shouldn't happen")
-        val closeTagExpr = element.simpleClosingTagName ?: element.qualifiedClosingTagName
-        val attributes = element.attributes
-
-        val tmpTraceAndCache = TemporaryTraceAndCache.create(
-            context,
-            "trace for ktx tag",
-            element
-        )
-
-        val contextToUse = context.replaceTraceAndCache(tmpTraceAndCache)
-
-        val attrInfos = mutableMapOf<String, AttributeInfo>()
-
-        for (attr in attributes) {
-            var key = attr.key
-            var value = attr.value
-            val name = key.getReferencedName()
-            var isPunned = false
-            if (attrInfos.contains(name)) {
-                contextToUse.trace.reportFromPlugin(
-                    ComposeErrors.DUPLICATE_ATTRIBUTE.on(key),
-                    ComposeDefaultErrorMessages
-                )
-            }
-            if (value == null && attr.equals != null) {
-                // this isn't punning because there is an equal sign, but there is not yet a value expression. this happens often
-                // when typing and with code completion. To deal with it, we just pass in a fake psi node as the value. This will
-                // result in some diagnostics, but it's okay. We want to continue to pass the attribute in as it can affect which
-                // target descriptor gets chosen.
-                value = psiFactory.createSimpleName("_")
-            }
-            if (isDeprecatedKtxTagResolve && value == null && attr.equals == null) {
-                // punning...
-                // punning has a single expression that both acts as reference to the value and to the property/setter. As a result, we
-                // need to save the descriptors that it targets into a different writable slice that we can surface later in a
-                // reference so that users cam Cmd-Click to either target. Additionally, for the purposes of codegen it's more important
-                // that the expression gets resolved to its *value*, and not its *target attribute*. In order to ensure this, we end up
-                // running `getTypeInfo` on any attributes that are punned before doing any other resolution.
-                val temporaryForPunning = TemporaryTraceAndCache.create(
-                    contextToUse, "trace to resolve reference for punning", key
-                )
-
-                facade.getTypeInfo(
-                    key,
-                    contextToUse.replaceTraceAndCache(temporaryForPunning)
-                )
-
-                temporaryForPunning.trace[BindingContext.REFERENCE_TARGET, key]?.let {
-                    // save the reference into a Set that we can use later in a custom reference
-                    temporaryForPunning.trace.recordAttributeKeyRef(key, it)
-                }
-
-                // in the case of a punned attribute, we create a fake psi node for the "key", or else some type resolution stuff will
-                // get messed up (for example, smart casting).
-                value = key
-                key = psiFactory.createSimpleName(name)
-                isPunned = true
-
-                temporaryForPunning.commit()
-            }
-
-            attrInfos[name] = AttributeInfo(
-                value = value ?: error("expected a value expression"),
-                key = key,
-                name = name,
-                isPunned = isPunned
-            )
-        }
-
-        // The tag expression and the body expression are both implicitly types of "attributes" for the tag, but they
-        // aren't explicitly names. As a result, we put them into the `attrInfos` map with special keys
-        element.bodyLambdaExpression?.let {
-            attrInfos[CHILDREN_KEY] =
-                AttributeInfo(
-                    value = it,
-                    key = null,
-                    name = CHILDREN_KEY,
-                    isPunned = false
-                )
-        }
-
-        // we want to resolve all reference targets on the open tag on the closing tag as well, but we don't want
-        // to have to execute the resolution code for both the open and close each time, so we create a binding
-        // trace that will observe for traces on the open tag and copy them over to the closing tag if one
-        // exists. We choose to only use this trace when we know that useful slices might show up on the tag.
-        var traceForOpenClose: BindingTrace = tmpTraceAndCache.trace
-        closeTagExpr?.let {
-            traceForOpenClose = referenceCopyingTrace(
-                openTagExpr,
-                closeTagExpr,
-                tmpTraceAndCache.trace
-            )
-        }
-        val receiver = resolveReceiver(
-            openTagExpr,
-            contextToUse.replaceBindingTrace(traceForOpenClose)
-        )
-
-        attrInfos[TAG_KEY] =
-            AttributeInfo(
-                value = when (receiver) {
-                    is ExpressionReceiver -> receiver.expression
-                    else -> openTagExpr
-                },
-                key = null,
-                name = TAG_KEY,
-                isPunned = false
-            )
-
-        val result = resolve(
-            openTagExpr,
-            closeTagExpr,
-            receiver,
-            attrInfos,
-            contextToUse
-        )
-
-        // Instead of committing the whole temp trace, we do so individually because there are some diagnostics that we are going
-        // to switch out with others.
-        tmpTraceAndCache.cache.commit()
-
-        // if the tag target is non-namespaced and there is a closing tag as well, the default "Import" quick fix will not
-        // work appropriately. To counteract this, we intercept UNRESOLVED_REFERENCE on the tag target specifically, and replace
-        // it with an UNRESOLVED_TAG diagnostic. We have our own import quickfix that knows how to handle this properly.
-        // Ideally in the long run we can fix this in a different / better way.
-        val isSimpleTag = openTagExpr is KtSimpleNameExpression && closeTagExpr != null
-
-        val diagnostics = tmpTraceAndCache.trace.bindingContext.diagnostics
-        for (diagnostic in diagnostics) {
-            if (isSimpleTag && diagnostic.psiElement in tagExpressions &&
-                diagnostic.factory == Errors.UNRESOLVED_REFERENCE) {
-                val refExpression = diagnostic.psiElement as KtReferenceExpression
-                // here we want to swallow this diagnostic and replace it with UNRESOLVED_TAG, so that the quickfix works properly:
-                context.trace.reportFromPlugin(
-                    ComposeErrors.UNRESOLVED_TAG.on(refExpression, refExpression),
-                    ComposeDefaultErrorMessages
-                )
-            } else {
-                context.trace.reportDiagnosticOnce(diagnostic)
-            }
-        }
-
-        // commit, but don't include diagnostics
-        tmpTraceAndCache.trace.commit({ _, _ -> true }, false)
-
-        return result
-    }
-
-    fun resolveFromCall(
-        call: Call,
-        context: ExpressionTypingContext
-    ): ResolvedKtxElementCall {
-        val callee = call.calleeExpression ?: error("Expected calleeExpression")
-
-        mainElement = callee
-
-        val openTagExpr = callee
-        val closeTagExpr = null
-
-        val tmpTraceAndCache = TemporaryTraceAndCache.create(
-            context,
-            "trace for ktx tag",
-            callee
-        )
-
-        val contextToUse = context.replaceTraceAndCache(tmpTraceAndCache)
-
-        val attrInfos = mutableMapOf<String, AttributeInfo>()
-
-        for (arg in call.valueArguments) {
-            if (arg is KtLambdaArgument) continue
-            val argName = arg.getArgumentName()
-
-            if (argName == null) TODO("indexed arguments not yet supported!")
-
-            val key = argName.referenceExpression
-            val value = arg.getArgumentExpression()
-            val name = argName.asName.asString()
-
-            // NOTE: We don't have to check for duplicate argument names, that will be done elsewhere.
-
-            // NOTE: We don't have to deal with punning. punning isn't supported in FCS.
-
-            attrInfos[name] = AttributeInfo(
-                value = value ?: error("expected a value expression"),
-                key = key,
-                name = name,
-                isPunned = false
-            )
-        }
-
-        for (arg in call.functionLiteralArguments) {
-            if (attrInfos.containsKey(CHILDREN_KEY))
-                error("Only one children argument supported at a time")
-            attrInfos[CHILDREN_KEY] =
-                AttributeInfo(
-                    value = arg.getLambdaExpression() ?: error("expected a value expression"),
-                    key = null,
-                    name = CHILDREN_KEY,
-                    isPunned = false
-                )
-        }
-
-        val receiver = resolveReceiver(openTagExpr, contextToUse)
-
-        attrInfos[TAG_KEY] =
-            AttributeInfo(
-                value = when (receiver) {
-                    is ExpressionReceiver -> receiver.expression
-                    else -> openTagExpr
-                },
-                key = null,
-                name = TAG_KEY,
-                isPunned = false
-            )
-
-        val result = resolve(
-            openTagExpr,
-            closeTagExpr,
-            receiver,
-            attrInfos,
-            contextToUse
-        )
-
-        tmpTraceAndCache.commit()
-        return result
-    }
-
-    fun resolveStartRestartGroup(
-        call: Call,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-        return resolveSubstitutableComposerMethod(
-            KtxNameConventions.STARTRESTARTGROUP,
-            listOf(builtIns.intType),
-            null,
-            call.calleeExpression ?: error("Could not find call expression"),
-            context
-        )
-    }
-
-    fun resolveEndRestartGroup(
-        call: Call,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-        return resolveSubstitutableComposerMethod(
-            KtxNameConventions.ENDRESTARTGROUP,
-            emptyList(),
-            null,
-            call.calleeExpression ?: error("Could not find call expression"),
-            context
-        )
-    }
-
-    fun resolveComposerCall() = composerResolvedCall
-
-    /**
-     * This call is the main function of this class, and will take in a KtxElement and return an object with all of the information
-     * necessary to generate the code for the KTX tag. This method will always return a result, but the result may contain errors
-     * and it is the responsibility of the consumer of this class to handle that properly.
-     */
-    private fun resolve(
-        openTagExpr: KtExpression,
-        closeTagExpr: KtExpression?,
-        receiver: Receiver?,
-        attrInfos: Map<String, AttributeInfo>,
-        context: ExpressionTypingContext
-    ): ResolvedKtxElementCall {
-
-        val usedAttributes = mutableSetOf<String>()
-
-        val missingRequiredAttributes = mutableListOf<DeclarationDescriptor>()
-
-        val emitOrCall = resolveChild(
-            openTagExpr,
-            ResolveStep.Root(openTagExpr, closeTagExpr),
-            makeCall(
-                openTagExpr,
-                receiver = receiver,
-                calleeExpression = when (openTagExpr) {
-                    is KtQualifiedExpression -> openTagExpr.selectorExpression
-                    is KtSimpleNameExpression -> openTagExpr
-                    else -> null
-                }
-            ),
-            attrInfos,
-            usedAttributes,
-            missingRequiredAttributes,
-            context,
-            recurseOnUnresolved = false
-        )
-
-        // TODO(lmr): validate that if it bottoms out at an emit(...) that it doesn't have any call(...)s
-
-        val errorNode = emitOrCall.errorNode()
-
-        errorNode?.let { error ->
-            when (error) {
-                is ErrorNode.NonCallableRoot -> {
-                    if (isDeprecatedKtxTagResolve) {
-                        val type = facade.getTypeInfo(
-                            openTagExpr,
-                            context.withThrowawayTrace(openTagExpr)
-                        ).type
-
-                        if (type != null) {
-                            ComposeErrors.INVALID_TAG_TYPE.report(
-                                context,
-                                tagExpressions,
-                                type,
-                                emitSimpleUpperBoundTypes
-                            )
-                        } else {
-                            ComposeErrors.INVALID_TAG_DESCRIPTOR.report(
-                                context,
-                                tagExpressions,
-                                emitSimpleUpperBoundTypes
-                            )
-                        }
-                    }
-                }
-                is ErrorNode.NonEmittableNonCallable -> {
-                    // TODO(lmr): diagnostic
-                    // TODO(lmr): we should probably put more info here, saying the composerType and stuff like that
-                    // "ktx tag terminated with type "Foo", which is neither an emittable, nor callable
-                    ComposeErrors.INVALID_TAG_TYPE.report(
-                        context,
-                        tagExpressions,
-                        error.type,
-                        emitSimpleUpperBoundTypes
-                    )
-                }
-                is ErrorNode.RecursionLimitAmbiguousAttributesError -> {
-                    ComposeErrors.AMBIGUOUS_ATTRIBUTES_DETECTED.report(
-                        context,
-                        tagExpressions,
-                        error.attributes
-                    )
-                }
-                is ErrorNode.RecursionLimitError -> {
-                    ComposeErrors.CALLABLE_RECURSION_DETECTED.report(context, tagExpressions)
-                }
-            }
-        }
-
-        val constantChecker = ConstantExpressionEvaluator(
-            project = project,
-            module = context.scope.ownerDescriptor.module,
-            languageVersionSettings = context.languageVersionSettings
-        )
-
-        val attributeNodes = emitOrCall
-            .allAttributes()
-            .mapNotNull { it as? AttributeNode }
-            .groupBy { it.name }
-
-        // we want to return a list of the used "AttributeNodes" to the top level call object that we return,
-        // so we dig through all of the attributes of the AST and return a unique list. For efficiency, whether
-        // or not an AttributeNode is "static" or not is not determined until now, since we don't want to have to
-        // calculate it multiple times for the same attribute, so as we loop through this list, we calculate
-        // whether it is static just once and then update all of the others as we go through them.
-        val usedAttributeNodes = attributeNodes
-            .mapValues { it.value.first() }
-            .values
-            .map { node ->
-                val static = isStatic(
-                    node.expression,
-                    context,
-                    node.type,
-                    constantChecker
-                )
-
-                val stable = isStable(
-                    node.type,
-                    context
-                )
-
-                // update all of the nodes in the AST as "static"
-                attributeNodes[node.name]?.forEach {
-                    it.isStatic = static
-                    it.isStable = stable
-                }
-
-                // return a node for the root of the AST that codegen can use
-                AttributeNode(
-                    name = node.name,
-                    descriptor = node.descriptor,
-                    expression = node.expression,
-                    type = node.type,
-                    isStatic = static,
-                    isStable = stable
-                )
-            }
-
-        // it's okay if the tag doesn't show up as used, so we remove it from this list
-        val unusedAttributes = (attrInfos - usedAttributes - TAG_KEY).toMutableMap()
-
-        if (isDeprecatedKtxTagResolve && unusedAttributes.isNotEmpty()) {
-
-            // if we have some unused attributes, we want to provide some helpful diagnostics on them, so we grab
-            // every possible attribute for the call. Note that we only want to run this (expensive) calculation in
-            // cases where there *were* unused attributes, so the clean compile path should avoid this.
-            val allPossibleAttributes = emitOrCall.allPossibleAttributes()
-
-            loop@ for (attr in unusedAttributes.values) {
-                when (attr.name) {
-                    CHILDREN_KEY -> {
-                        if (emitOrCall is EmitCallNode) {
-                            val type = emitOrCall.memoize.ctorCall?.resultingDescriptor?.returnType
-                                ?: error("expected a return type")
-                            if (!type.isCompoundEmittable()) {
-                                context.trace.reportFromPlugin(
-                                    ComposeErrors.CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED.on(
-                                        openTagExpr
-                                    ),
-                                    ComposeDefaultErrorMessages
-                                )
-                            } else {
-                                // this is a compound emittable, so we will interpret the children block as just code to execute
-                                unusedAttributes.remove(CHILDREN_KEY)
-                            }
-                        } else {
-                            facade.getTypeInfo(
-                                attr.value,
-                                context.replaceExpectedType(functionType().makeComposable(module))
-                            )
-                            val possibleChildren = allPossibleAttributes[CHILDREN_KEY]
-                                ?: emptyList()
-                            if (possibleChildren.isNotEmpty()) {
-                                context.trace.reportFromPlugin(
-                                    ComposeErrors.UNRESOLVED_CHILDREN.on(
-                                        openTagExpr,
-                                        possibleChildren.map { it.type }
-                                    ),
-                                    ComposeDefaultErrorMessages
-                                )
-                            } else {
-                                context.trace.reportFromPlugin(
-                                    ComposeErrors.CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED.on(
-                                        openTagExpr
-                                    ),
-                                    ComposeDefaultErrorMessages
-                                )
-                            }
-                        }
-                    }
-                    else -> {
-                        val exprToReportOn = if (attr.isPunned) attr.value else (attr.key
-                            ?: error("expected non-null key expression"))
-                        val valueType = facade.getTypeInfo(attr.value, context).type
-                        // if the value expression is an unresolved reference, we don't need to put a diagnostic on the key
-                        val valueIsUnresolvedRef = attr.value is KtReferenceExpression &&
-                                context.trace[BindingContext.REFERENCE_TARGET, attr.value] != null
-
-                        val descriptors = emitOrCall.resolvedCalls().flatMap {
-                            listOfNotNull(
-                                it.resultingDescriptor,
-                                it.resultingDescriptor.returnType?.let { t ->
-                                    if (t.isUnit()) null
-                                    else t.constructor.declarationDescriptor
-                                }
-                            )
-                        }
-
-                        // since extension functions won't show up if we just traverse the member scope of the types in our call,
-                        // we might be giving inaccurate diagnostics around what types are accepted for this attribute. Since we have
-                        // the name, we can search for all possible candidates of attributes on a given node. This is expensive, but
-                        // since we are only in the erroneous path, it shouldn't be a big deal.
-                        val attrsOfSameKey = resolveAttributeCandidatesGivenNameAndNode(
-                            emitOrCall,
-                            attr.name,
-                            context.withThrowawayTrace(openTagExpr)
-                        )
-
-                        if (attrsOfSameKey.isNotEmpty()) {
-                            // NOTE(lmr): it would be great if we could record multiple possible types here instead of just one for
-                            // autocomplete
-                            context.trace.record(
-                                BindingContext.EXPECTED_EXPRESSION_TYPE,
-                                attr.value,
-                                attrsOfSameKey.first().type
-                            )
-
-                            // even if the type doesn't match the attribute, we should resolve it to something
-                            context.trace.record(
-                                BindingContext.REFERENCE_TARGET,
-                                attr.key,
-                                attrsOfSameKey.first().descriptor
-                            )
-
-                            // we can add all of the possible key targets here so that the user can Command+Click to see the list of
-                            // possible values
-                            attrsOfSameKey.forEach {
-                                context.trace.recordAttributeKeyRef(exprToReportOn, it.descriptor)
-                            }
-                        }
-
-                        val diagnostic = when {
-                            attrsOfSameKey.isNotEmpty() && valueType != null ->
-                                ComposeErrors.MISMATCHED_ATTRIBUTE_TYPE.on(
-                                    exprToReportOn,
-                                    valueType,
-                                    attrsOfSameKey.map { it.type }.toSet()
-                                )
-                            attrsOfSameKey.isEmpty() && valueType != null ->
-                                ComposeErrors.UNRESOLVED_ATTRIBUTE_KEY.on(
-                                    exprToReportOn,
-                                    descriptors,
-                                    attr.name,
-                                    valueType
-                                )
-                            attrsOfSameKey.isNotEmpty() && valueType == null
-                                    && !valueIsUnresolvedRef ->
-                                ComposeErrors.MISMATCHED_ATTRIBUTE_TYPE.on(
-                                    exprToReportOn,
-                                    ErrorUtils.createErrorType("???"),
-                                    attrsOfSameKey.map { it.type }.toSet()
-                                )
-                            else ->
-                                ComposeErrors.UNRESOLVED_ATTRIBUTE_KEY_UNKNOWN_TYPE.on(
-                                    exprToReportOn,
-                                    descriptors,
-                                    attr.name
-                                )
-                        }
-
-                        context.trace.reportFromPlugin(diagnostic,
-                            ComposeDefaultErrorMessages
-                        )
-                    }
-                }
-            }
-        }
-
-        if (missingRequiredAttributes.isNotEmpty()) {
-            missingRequiredAttributes
-                .filter { !it.hasChildrenAnnotation() }
-                .ifNotEmpty {
-                    ComposeErrors.MISSING_REQUIRED_ATTRIBUTES.report(
-                        context,
-                        tagExpressions,
-                        this
-                    )
-                }
-            missingRequiredAttributes
-                .filter { it.hasChildrenAnnotation() }
-                .ifNotEmpty {
-                    ComposeErrors.MISSING_REQUIRED_CHILDREN.report(
-                        context,
-                        tagExpressions,
-                        first().typeAsAttribute()
-                    )
-                }
-        }
-
-        // for each attribute we've consumed, we want to go through and call `checkType` so that the type system can flow through to
-        // all of the attributes with the right type information (now that we know what types the attributes should have).
-        if (isDeprecatedKtxTagResolve) {
-            for (name in usedAttributes) {
-                val expr = attrInfos[name]?.value ?: continue
-                var type = usedAttributeNodes.find { it.name == name }?.type
-                if (type == null && name == CHILDREN_KEY) {
-                    type = functionType().makeComposable(module)
-                }
-
-                facade.checkType(
-                    expr,
-                    context.replaceExpectedType(type)
-                )
-            }
-        }
-
-        return ResolvedKtxElementCall(
-            usedAttributes = usedAttributeNodes,
-            unusedAttributes = unusedAttributes.keys.toList(),
-            emitOrCall = emitOrCall,
-            getComposerCall = composerResolvedCall,
-            emitSimpleUpperBoundTypes = emitSimpleUpperBoundTypes,
-            emitCompoundUpperBoundTypes = emitCompoundUpperBoundTypes,
-            infixOrCall = infixOrCall,
-            attributeInfos = attrInfos
-        )
-    }
-
-    private fun resolveAttributeCandidatesGivenNameAndNode(
-        node: EmitOrCallNode,
-        name: String,
-        context: ExpressionTypingContext
-    ): List<AttributeMeta> {
-        val setterName = Name.identifier(
-            ComposeUtils.setterMethodFromPropertyName(
-                name
-            )
-        )
-        val fakeSetterExpr = psiFactory.createSimpleName(setterName.asString())
-        val fakePropertyExpr = psiFactory.createSimpleName(name)
-        val contextToUse = context.replaceCollectAllCandidates(true)
-        val resolvedCalls = node.resolvedCalls()
-
-        val params = resolvedCalls
-            .flatMap { it.resultingDescriptor.valueParameters }
-            .filter { it.name.asString() == name }
-            .mapNotNull {
-                AttributeMeta(
-                    name = name,
-                    type = it.type,
-                    isChildren = it.hasChildrenAnnotation(),
-                    descriptor = it
-                )
-            }
-
-        val types = resolvedCalls
-            .mapNotNull { it.resultingDescriptor.returnType }
-            .filter { !it.isUnit() }
-
-        // setters, including extension setters
-        val setters = types
-            .flatMap { type ->
-                val call = makeCall(
-                    callElement = fakeSetterExpr,
-                    calleeExpression = fakeSetterExpr,
-                    receiver = TransientReceiver(type)
-                )
-
-                callResolver.resolveCallWithGivenName(
-                    BasicCallResolutionContext.create(
-                        contextToUse,
-                        call,
-                        CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-                        DataFlowInfoForArgumentsImpl(contextToUse.dataFlowInfo, call)
-                    ),
-                    call,
-                    fakeSetterExpr,
-                    setterName
-                ).allCandidates ?: emptyList()
-            }
-            .mapNotNull { it.resultingDescriptor as? SimpleFunctionDescriptor }
-            .mapNotNull {
-                when {
-                    it.valueParameters.size != 1 -> null
-                    it.returnType?.isUnit() == false -> null
-                    else -> AttributeMeta(
-                        name = name,
-                        type = it.valueParameters.first().type,
-                        isChildren = it.hasChildrenAnnotation(),
-                        descriptor = it
-                    )
-                }
-            }
-
-        val properties = types
-            .flatMap { type ->
-                val call = CallMaker.makePropertyCall(
-                    TransientReceiver(type),
-                    null,
-                    fakePropertyExpr
-                )
-
-                val contextForVariable = BasicCallResolutionContext.create(
-                    contextToUse,
-                    call,
-                    CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS
-                )
-
-                callResolver.resolveSimpleProperty(contextForVariable).allCandidates ?: emptyList()
-            }
-            .mapNotNull { it.resultingDescriptor as? PropertyDescriptor }
-            .map {
-                AttributeMeta(
-                    name = name,
-                    type = it.type,
-                    isChildren = it.hasChildrenAnnotation(),
-                    descriptor = it
-                )
-            }
-
-        return params + setters + properties
-    }
-
-    // pure. check where used
-    private fun shouldMemoizeResult(resolvedCall: ResolvedCall<*>): Boolean {
-        val descriptor = resolvedCall.resultingDescriptor
-        val returnType = descriptor.returnType ?: return false
-        return returnType.shouldMemoizeType() || descriptor.hasStatefulAnnotation()
-    }
-
-    private fun KotlinType.shouldMemoizeType(): Boolean {
-        if (isUnit() || isAnyOrNullableAny()) return false
-        val typeDescriptor = constructor.declarationDescriptor
-        return hasStatefulAnnotation() ||
-                supertypes().any { it.shouldMemoizeType() } ||
-                (typeDescriptor?.hasStatefulAnnotation() ?: false)
-    }
-
-    private fun resolveTagValidations(
-        kind: ComposerCallKind,
-        step: ResolveStep,
-        resolvedCall: ResolvedCall<*>,
-        receiverScope: KotlinType,
-        context: ExpressionTypingContext
-    ): List<ValidatedAssignment> {
-        if (step !is ResolveStep.Root) return emptyList()
-        val descriptor = resolvedCall.resultingDescriptor
-        when (resolvedCall.explicitReceiverKind) {
-            ExplicitReceiverKind.DISPATCH_RECEIVER -> {
-                val receiver = resolvedCall.dispatchReceiver as? ExpressionReceiver
-                    ?: return emptyList()
-                val (validationCall, uncheckedValidationCall, _) = resolveValidationCall(
-                    kind = kind,
-                    validationType = ValidationType.CHANGED,
-                    attrType = receiver.type,
-                    expressionToReportErrorsOn = receiver.expression,
-                    receiverScope = receiverScope,
-                    assignmentReceiverScope = null,
-                    context = context
-                )
-                return listOf(
-                    ValidatedAssignment(
-                        validationType = ValidationType.CHANGED,
-                        validationCall = validationCall,
-                        uncheckedValidationCall = uncheckedValidationCall,
-                        assignment = null,
-                        assignmentLambda = null,
-                        attribute = AttributeNode(
-                            name = TAG_KEY,
-                            isStatic = false,
-                            isStable = false,
-                            type = receiver.type,
-                            expression = receiver.expression,
-                            descriptor = descriptor
-                        )
-                    )
-                )
-            }
-            else -> return emptyList()
-        }
-    }
-
-    // Loop through all of the validated assignments for the child call and create validations for the parent call.
-    // The validations from the child call should be converted into CHANGED validations because if they were set/update we
-    // don't want to do anything but we do want changes in them to invalidate the whole group.
-    private fun collectValidations(
-        kind: ComposerCallKind,
-        current: List<ValidatedAssignment>,
-        children: List<AttributeNode>,
-        expression: KtExpression,
-        invalidReceiverScope: KotlinType,
-        attributes: Map<String, AttributeInfo>,
-        context: ExpressionTypingContext
-    ): List<ValidatedAssignment> {
-        val result = mutableMapOf<String, ValidatedAssignment>()
-
-        current.forEach {
-            result[it.attribute.name] = it
-        }
-
-        children.forEach {
-            if (result.containsKey(it.name)) return@forEach
-            val attr = attributes[it.name] ?: error("did not find attribute")
-            result[it.name] = it.asChangedValidatedAssignment(
-                kind = kind,
-                expressionToReportErrorsOn = attr.key ?: expression,
-                receiverScope = invalidReceiverScope,
-                context = context
-            )
-        }
-
-        return result.values.toList()
-    }
-
-    private fun resolveChild(
-        expression: KtExpression,
-        resolveStep: ResolveStep,
-        call: Call,
-        attributes: Map<String, AttributeInfo>,
-        usedAttributes: MutableSet<String>,
-        missingRequiredAttributes: MutableList<DeclarationDescriptor>,
-        context: ExpressionTypingContext,
-        recurseOnUnresolved: Boolean
-    ): EmitOrCallNode {
-        if (!resolveStep.canRecurse()) {
-            return when (resolveStep) {
-                is ResolveStep.Root -> error("should never happen")
-                is ResolveStep.Nested -> {
-                    resolveStep.constructNonMemoizedCallLinkedList()?.apply {
-                        nextCall = resolveStep.errorNode
-                    } ?: resolveStep.errorNode!!
-                }
-            }
-        }
-        val tmpForCandidates = TemporaryTraceAndCache.create(
-            context, "trace to resolve ktx element", expression
-        )
-        val results = getCandidates(
-            resolveStep,
-            call,
-            context.replaceTraceAndCache(tmpForCandidates)
-        )
-
-        if (results.allCandidates?.size == 0) {
-            return when (resolveStep) {
-                is ResolveStep.Root -> {
-                    // if the root tag failed to resolve to anything, then the tag isn't even callable. The call resolver will
-                    // add useful diagnostics in this case that we'd like to use, but it will only do it when we are not in
-                    // the "collectAllCandidates" mode. We just call `getCandidates` again to put all of the diagnostics on the element
-                    // that we want.
-                    getCandidates(resolveStep, call, context, collectAllCandidates = false)
-                    ErrorNode.NonCallableRoot()
-                }
-                is ResolveStep.Nested -> {
-                    val error = ErrorNode.NonEmittableNonCallable(resolveStep.calleeType)
-                    resolveStep.constructNonMemoizedCallLinkedList()?.apply { nextCall = error }
-                        ?: error
-                }
-            }
-        }
-
-        // TODO(lmr): we could have an optimization for results.isSuccess and attributes.size == 0 here
-
-        val resolveInfos = results.allCandidates!!.mapNotNull { result ->
-            val tmpForCandidate = TemporaryTraceAndCache.create(
-                context, "trace to resolve ktx element", expression
-            )
-
-            var trace: BindingTrace = tmpForCandidate.trace
-
-            if (resolveStep is ResolveStep.Root) {
-                resolveStep.closeExpr?.let {
-                    trace = referenceCopyingTrace(
-                        resolveStep.openExpr,
-                        resolveStep.closeExpr,
-                        tmpForCandidate.trace
-                    )
-                }
-                // not sure why this is needed, but it is
-                copyReferences(
-                    fromTrace = tmpForCandidate.trace,
-                    toTrace = trace,
-                    element = resolveStep.openExpr
-                )
-            }
-
-            val candidateContext = context
-                .replaceTraceAndCache(tmpForCandidate)
-                .replaceBindingTrace(trace)
-
-            val attrsUsedInCall = mutableSetOf<String>()
-
-            val attrsUsedInSets = mutableSetOf<String>()
-
-            val subMissingRequiredAttributes = mutableListOf<DeclarationDescriptor>()
-
-            val usedAttributeInfos = mutableListOf<TempParameterInfo>()
-
-            val candidateResults = resolveCandidate(
-                resolveStep,
-                result,
-                call,
-                attributes,
-                attrsUsedInCall,
-                usedAttributeInfos,
-                subMissingRequiredAttributes,
-                candidateContext
-            )
-
-            if (candidateResults.isNothing)
-                return@mapNotNull TempResolveInfo(
-                false,
-                tmpForCandidate,
-                (attributes - attrsUsedInCall).keys,
-                attrsUsedInCall,
-                subMissingRequiredAttributes
-            ) {
-                ErrorNode.ResolveError(results)
-            }
-
-            val resolvedCall = candidateResults.resultingCalls.first()
-
-            if (!candidateResults.isSuccess) {
-                when (candidateResults.resultCode) {
-                    OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH -> {
-                        resolvedCall.call.valueArguments.map {
-                            resolvedCall.getArgumentMapping(it)
-                        }.forEach {
-                            when (it) {
-                                is ArgumentMatch -> {
-                                    when (it.status) {
-                                        ArgumentMatchStatus.TYPE_MISMATCH -> {
-                                            if (!isDeprecatedKtxTagResolve) return@forEach
-                                            val attr =
-                                                attributes[it.valueParameter.name.asString()]
-                                                    ?: return@forEach
-                                            val key = attr.key ?: return@forEach
-                                            val type =
-                                                facade.getTypeInfo(
-                                                    attr.value,
-                                                    candidateContext
-                                                ).type ?: return@forEach
-                                            candidateContext.trace.reportFromPlugin(
-                                                ComposeErrors.MISMATCHED_ATTRIBUTE_TYPE.on(
-                                                    key,
-                                                    type,
-                                                    listOfNotNull(it.valueParameter.type)
-                                                ),
-                                                ComposeDefaultErrorMessages
-                                            )
-                                        }
-                                        ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES -> {
-                                            if (!isDeprecatedKtxTagResolve) return@forEach
-                                            val attr = attributes[it.valueParameter.name.asString()]
-                                                ?: return@forEach
-                                            val key = attr.key ?: return@forEach
-                                            val type =
-                                                facade.getTypeInfo(
-                                                    attr.value,
-                                                    candidateContext
-                                                ).type ?: return@forEach
-
-                                            candidateContext.trace.reportFromPlugin(
-                                                ComposeErrors.MISMATCHED_INFERRED_ATTRIBUTE_TYPE.on(
-                                                    key,
-                                                    type,
-                                                    listOfNotNull(it.valueParameter.type)
-                                                ),
-                                                ComposeDefaultErrorMessages
-                                            )
-                                        }
-                                        ArgumentMatchStatus.UNKNOWN -> {
-                                            // NOTE(lmr): This can happen with the implicit constructor params. ignore it
-                                        }
-                                        ArgumentMatchStatus.SUCCESS -> {
-                                            // do nothing
-                                        }
-                                        ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE -> {
-                                            // NOTE(lmr): This can happen when the attribute has no value expression, since
-                                            // we pass in a fake psi node for the value in that case.
-                                        }
-                                    }
-                                }
-                                is ArgumentUnmapped -> {
-                                    if (!recurseOnUnresolved) {
-                                        return@mapNotNull TempResolveInfo(
-                                            false,
-                                            tmpForCandidate,
-                                            (attributes - attrsUsedInCall).keys,
-                                            attrsUsedInCall,
-                                            subMissingRequiredAttributes
-                                        ) {
-                                            ErrorNode.ResolveError(
-                                                results
-                                            )
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE,
-                    OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES,
-                    OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER -> {
-                        if (!recurseOnUnresolved) {
-                            return@mapNotNull TempResolveInfo(
-                                false,
-                                tmpForCandidate,
-                                (attributes - attrsUsedInCall).keys,
-                                attrsUsedInCall,
-                                subMissingRequiredAttributes
-                            ) {
-                                ErrorNode.ResolveError(results)
-                            }
-                        } else {
-                            candidateContext.trace.recordFailedCandidates(
-                                mainElement,
-                                results.allCandidates
-                            )
-                        }
-                    }
-                    else -> {
-                        error("new kind of resolution problem. figure out why this happened...")
-                    }
-                }
-            }
-
-            if (
-                !descriptorsEqualWithSubstitution(
-                    resolvedCall.semanticCall.candidateDescriptor.original,
-                    result.semanticCall.candidateDescriptor.original,
-                    false
-                )
-            ) {
-                // if this happens, we've likely resolved the candidate to one of the other candidates, and we don't want that.
-                // we fail in this case, since it will succeed once we actually process the candidate that this resolved to.
-                return@mapNotNull TempResolveInfo(
-                    false,
-                    tmpForCandidate,
-                    (attributes - attrsUsedInCall).keys,
-                    attrsUsedInCall,
-                    subMissingRequiredAttributes
-                ) {
-                    ErrorNode.ResolveError(results)
-                }
-            }
-
-            val returnType = resolvedCall.resultingDescriptor.returnType ?: builtIns.unitType
-
-            val isStaticCall = isStaticTag(
-                resolveStep,
-                resolvedCall,
-                candidateContext
-            )
-
-            val shouldMemoizeCtor = returnType.isEmittable() || shouldMemoizeResult(resolvedCall)
-
-            if (returnType.isUnit()) {
-                // bottomed out
-
-                // it is important to pass in "result" here and not "resolvedCall" since "result" is the one that will have
-                // the composable annotation on it in the case of lambda invokes
-                if (
-                    !composableAnnotationChecker.shouldInvokeAsTag(
-                        candidateContext.trace, result
-                    )
-                ) {
-                    candidateContext.trace.reportFromPlugin(
-                        ComposeErrors.NON_COMPOSABLE_INVOCATION.on(
-                            expression,
-                            "Lambda variable",
-                            resolvedCall.semanticCall.resultingDescriptor
-                        ),
-                        ComposeDefaultErrorMessages
-                    )
-                }
-
-                return@mapNotNull TempResolveInfo(
-                    true, // TODO(lmr): valid
-                    tmpForCandidate,
-                    (attributes - attrsUsedInCall).keys,
-                    attrsUsedInCall,
-                    subMissingRequiredAttributes
-                ) {
-                    val composerCall = resolveComposerCall(
-                        constructedType = null, // or should we pass in Unit here?
-                        expressionToReportErrorsOn = expression,
-                        context = candidateContext
-                    )
-
-                    val invalidReceiverScope = composerCall
-                        ?.resultingDescriptor
-                        ?.valueParameters
-                        ?.first { it.name == KtxNameConventions.CALL_INVALID_PARAMETER }
-                        ?.type
-                        ?.getReceiverTypeFromFunctionType()
-                        ?: ErrorUtils.createErrorType("???")
-
-                    val tagValidations = resolveTagValidations(
-                        kind = ComposerCallKind.CALL,
-                        step = resolveStep,
-                        resolvedCall = resolvedCall,
-                        receiverScope = invalidReceiverScope,
-                        context = candidateContext
-                    )
-
-                    val pivotals = resolvePivotalAttributes(
-                        attributes,
-                        attrsUsedInCall,
-                        usedAttributeInfos,
-                        emptyList(),
-                        returnType
-                    )
-
-                    val nonMemoizedCall = NonMemoizedCallNode(
-                        resolvedCall = resolvedCall,
-                        params = resolvedCall.buildParamsFromAttributes(attributes),
-                        applyCall = null,
-                        applyLambdaDescriptor = null,
-                        applyLambdaType = null,
-                        postAssignments = emptyList(),
-                        nextCall = null
-                    )
-
-                    if (resolveStep is ResolveStep.Root) {
-                        MemoizedCallNode(
-                            memoize = ComposerCallInfo(
-                                context = candidateContext,
-                                composerCall = composerCall,
-                                pivotals = pivotals,
-                                joinKeyCall = joinKeyCall,
-                                ctorCall = null,
-                                ctorParams = emptyList(),
-                                validations = collectValidations(
-                                    kind = ComposerCallKind.CALL,
-                                    current = tagValidations,
-                                    children = nonMemoizedCall.consumedAttributes(),
-                                    expression = expression,
-                                    attributes = attributes,
-                                    invalidReceiverScope = invalidReceiverScope,
-                                    context = candidateContext
-                                )
-                            ),
-                            call = resolveStep.constructNonMemoizedCallLinkedList(nonMemoizedCall)
-                        )
-                    } else {
-                        resolveStep.constructNonMemoizedCallLinkedList(nonMemoizedCall)
-                    }
-                }
-            }
-
-            var inlineChildren: KtExpression? = null
-            if (returnType.isEmittable() == true) {
-
-                val composerCall = resolveComposerEmit(
-                    constructedType = returnType,
-                    hasBody = attributes.contains(CHILDREN_KEY),
-                    implicitCtorTypes = resolvedCall.call.valueArguments.mapNotNull {
-                        (it as? ImplicitCtorValueArgument)?.type
-                    },
-                    expressionToReportErrorsOn = expression,
-                    context = candidateContext
-                )
-                ?: return@mapNotNull TempResolveInfo(
-                    false,
-                    tmpForCandidate,
-                    (attributes - attrsUsedInCall - attrsUsedInSets).keys,
-                    attrsUsedInCall + attrsUsedInSets,
-                    subMissingRequiredAttributes
-                ) {
-                    ErrorNode.ResolveError(results)
-                }
-
-                if (attributes.contains(CHILDREN_KEY) && returnType.isCompoundEmittable()) {
-                    attrsUsedInSets.add(CHILDREN_KEY)
-                    inlineChildren = attributes.get(CHILDREN_KEY)!!.value
-                }
-
-                val updateReceiverScope = composerCall
-                    .resultingDescriptor
-                    .valueParameters
-                    .first { it.name == KtxNameConventions.EMIT_UPDATER_PARAMETER }
-                    .type
-                    .getReceiverTypeFromFunctionType() ?: error("Expected receiver type")
-
-                val setterValidations = resolveAllSetAttributes(
-                    kind = ComposerCallKind.EMIT,
-                    expressionToReportErrorsOn = expression,
-                    receiverScope = updateReceiverScope,
-                    type = returnType,
-                    attributes = attributes,
-                    attributesUsedInCall = attrsUsedInCall,
-                    consumedAttributes = attrsUsedInSets,
-                    missingRequiredAttributes = subMissingRequiredAttributes,
-                    shouldMemoizeCtor = shouldMemoizeCtor,
-                    context = candidateContext
-                )
-
-                val pivotals = resolvePivotalAttributes(
-                    attributes,
-                    attrsUsedInCall,
-                    usedAttributeInfos,
-                    setterValidations,
-                    returnType
-                )
-
-                return@mapNotNull TempResolveInfo(
-                    true,
-                    tmpForCandidate,
-                    (attributes - attrsUsedInCall - attrsUsedInSets).keys,
-                    attrsUsedInCall + attrsUsedInSets,
-                    subMissingRequiredAttributes
-                ) {
-                    EmitCallNode(
-                        memoize = ComposerCallInfo(
-                            context = candidateContext,
-                            composerCall = composerCall,
-                            pivotals = pivotals,
-                            joinKeyCall = joinKeyCall,
-                            ctorCall = resolvedCall,
-                            ctorParams = resolvedCall.buildParamsFromAttributes(attributes),
-                            validations = setterValidations
-                        ),
-                        inlineChildren = inlineChildren
-                    )
-                }
-            }
-
-            val composerCall = resolveComposerCall(
-                constructedType = if (shouldMemoizeCtor) returnType else null,
-                expressionToReportErrorsOn = expression,
-                context = candidateContext
-            )
-
-            // the "invalid" lambda is at a different argument index depending on whether or not there is a "ctor" param.
-            val invalidReceiverScope = composerCall
-                ?.resultingDescriptor
-                ?.valueParameters
-                ?.first { it.name == KtxNameConventions.CALL_INVALID_PARAMETER }
-                ?.type
-                ?.getReceiverTypeFromFunctionType()
-                ?: ErrorUtils.createErrorType("???")
-
-            val tagValidations = resolveTagValidations(
-                kind = ComposerCallKind.CALL,
-                step = resolveStep,
-                resolvedCall = resolvedCall,
-                receiverScope = invalidReceiverScope,
-                context = candidateContext
-            )
-
-            val setterValidations = resolveAllSetAttributes(
-                kind = ComposerCallKind.CALL,
-                expressionToReportErrorsOn = expression,
-                receiverScope = invalidReceiverScope,
-                type = returnType,
-                attributes = attributes,
-                attributesUsedInCall = attrsUsedInCall,
-                consumedAttributes = attrsUsedInSets,
-                missingRequiredAttributes = subMissingRequiredAttributes,
-                shouldMemoizeCtor = shouldMemoizeCtor,
-                context = candidateContext
-            )
-
-            val pivotals = resolvePivotalAttributes(
-                attributes,
-                attrsUsedInCall,
-                usedAttributeInfos,
-                setterValidations,
-                returnType
-            )
-
-            val attrsUsedInFollowingCalls = mutableSetOf<String>()
-
-            // TODO(lmr): clean this up a little bit
-            val postAssignments = if (!shouldMemoizeCtor) {
-                (tagValidations + setterValidations)
-                    .filter { it.validationType != ValidationType.CHANGED }
-            } else emptyList()
-
-            val allValidations = if (!shouldMemoizeCtor) {
-                (tagValidations + setterValidations).map { validation ->
-                    when (validation.validationType) {
-                        ValidationType.CHANGED -> validation
-                        ValidationType.UPDATE,
-                        ValidationType.SET -> resolveValidationCall(
-                            kind = ComposerCallKind.CALL,
-                            validationType = ValidationType.CHANGED,
-                            attrType = validation.attribute.type,
-                            expressionToReportErrorsOn = expression,
-                            receiverScope = invalidReceiverScope,
-                            assignmentReceiverScope = null,
-                            context = context
-                        ).let {
-                            val (validationCall, uncheckedValidationCall, _) = it
-                            ValidatedAssignment(
-                                validationType = ValidationType.CHANGED,
-                                validationCall = validationCall,
-                                uncheckedValidationCall = uncheckedValidationCall,
-                                assignment = null,
-                                attribute = validation.attribute,
-                                assignmentLambda = null
-                            )
-                        }
-                    }
-                }
-            } else tagValidations + setterValidations
-
-            val applyCall = if (!shouldMemoizeCtor) {
-                resolveApplyCallForType(returnType, candidateContext)
-            } else null
-
-            val applyLambdaType = if (!shouldMemoizeCtor)
-                functionType(receiverType = returnType)
-            else null
-            val applyLambdaDescriptor = if (!shouldMemoizeCtor) {
-                createFunctionDescriptor(
-                    applyLambdaType!!,
-                    candidateContext
-                )
-            } else null
-
-            val nonMemoizedCall = NonMemoizedCallNode(
-                resolvedCall = resolvedCall,
-                params = resolvedCall.buildParamsFromAttributes(attributes),
-                applyCall = applyCall,
-                applyLambdaDescriptor = applyLambdaDescriptor,
-                postAssignments = postAssignments,
-                applyLambdaType = applyLambdaType,
-                nextCall = null
-            )
-
-            val childCall = resolveChild(
-                expression,
-                resolveStep.recurse(
-                    calleeType = returnType,
-                    nonMemoizedCall = if (shouldMemoizeCtor) null else nonMemoizedCall,
-                    isStaticCall = isStaticCall,
-                    resolvedCall = resolvedCall,
-                    specifiedAttributes = attrsUsedInCall + attrsUsedInSets
-                ),
-                makeCall(
-                    psiFactory.createSimpleName("invoke"),
-                    dispatchReceiver = TransientReceiver(returnType)
-                ),
-                attributes,
-                attrsUsedInFollowingCalls,
-                subMissingRequiredAttributes,
-                candidateContext,
-                recurseOnUnresolved
-            )
-
-            val subUsedAttributes = attrsUsedInCall + attrsUsedInSets + attrsUsedInFollowingCalls
-
-            return@mapNotNull TempResolveInfo(
-                true, // TODO(lmr): valid
-                tmpForCandidate,
-                (attributes - subUsedAttributes).keys,
-                subUsedAttributes,
-                subMissingRequiredAttributes
-            ) {
-                if (shouldMemoizeCtor || resolveStep is ResolveStep.Root) {
-                    MemoizedCallNode(
-                        memoize = ComposerCallInfo(
-                            context = candidateContext,
-                            composerCall = composerCall,
-                            pivotals = pivotals,
-                            joinKeyCall = joinKeyCall,
-                            ctorCall = if (shouldMemoizeCtor)
-                                nonMemoizedCall.resolvedCall
-                            else null,
-                            ctorParams = if (shouldMemoizeCtor)
-                                nonMemoizedCall.params
-                            else emptyList(),
-                            validations = collectValidations(
-                                kind = ComposerCallKind.CALL,
-                                current = allValidations,
-                                children = childCall.consumedAttributes(),
-                                expression = expression,
-                                attributes = attributes,
-                                invalidReceiverScope = invalidReceiverScope,
-                                context = candidateContext
-                            )
-                        ),
-                        call = childCall
-                    )
-                } else {
-                    childCall
-                }
-            }
-        }
-            .sortedWith(Comparator { a, b ->
-                // TODO(lmr): should we also use missingRequiredAttributes to sort here?
-                if (a.attributesLeft != b.attributesLeft) {
-                    a.attributesLeft - b.attributesLeft
-                } else {
-                    (if (a.valid) 0 else 1) - (if (b.valid) 0 else 1)
-                }
-            }).toList()
-
-        val result = resolveInfos.first()
-
-        if (!recurseOnUnresolved && result.attributesLeft > 0 &&
-            !results.allCandidates.isNullOrEmpty()) {
-            // Looking up all possible combinations of resolved calls to satisfy a KTX element can be expensive, so normally we try to do as
-            // few lookups as possible. But if we failed (ie, there is for sure an error), then we go ahead and run it again with a flag
-            // set that explores all options so that we can provide the most meaningful diagnostics.
-            return resolveChild(
-                expression,
-                resolveStep,
-                call,
-                attributes,
-                usedAttributes,
-                missingRequiredAttributes,
-                context,
-                recurseOnUnresolved = true
-            )
-        }
-
-        val resultNode = result.build()
-        usedAttributes.addAll(result.usedAttributes)
-        missingRequiredAttributes.addAll(result.missingRequiredAttributes)
-        result.trace.commit()
-
-        if (resolveInfos.size > 1) {
-            val nextBest = resolveInfos[1]
-            if (result.attributesLeft == 0 && result.attributesLeft
-                == nextBest.attributesLeft && nextBest.valid) {
-                val nextNode = nextBest.build()
-                val primaryCalls = listOfNotNull(
-                    resultNode.primaryCall,
-                    nextNode.primaryCall
-                ).distinctBy { it.semanticCall.resultingDescriptor }
-                if (primaryCalls.size > 1) {
-                    ComposeErrors.AMBIGUOUS_KTX_CALL.report(
-                        context,
-                        tagExpressions,
-                        primaryCalls
-                    )
-                }
-            }
-        }
-        return resultNode
-    }
-
-    private fun resolvePivotalAttributes(
-        attributes: Map<String, AttributeInfo>,
-        attrsUsedInCall: Set<String>,
-        callParamInfos: List<TempParameterInfo>,
-        validations: List<ValidatedAssignment>,
-        returnType: KotlinType?
-    ): List<AttributeNode> {
-        val result = mutableListOf<AttributeNode>()
-
-        if (returnType == null || returnType.isUnit()) {
-            return callParamInfos
-                .filter { it.descriptor.hasPivotalAnnotation() }
-                .map {
-                    AttributeNode(
-                        name = it.attribute.name,
-                        descriptor = it.descriptor,
-                        type = it.type,
-                        expression = it.attribute.value,
-                        isStatic = false,
-                        isStable = false
-                    )
-                }
-        }
-
-        val validationSet = validations.map { it.attribute.name }.toSet()
-
-        // if you were in the ctor call but not in the sets, you *have* to be pivotal
-        for (info in callParamInfos) {
-            if (validationSet.contains(info.attribute.name)) continue
-            val attribute = attributes[info.attribute.name] ?: continue
-            result.add(
-                AttributeNode(
-                    name = info.attribute.name,
-                    descriptor = info.descriptor,
-                    type = info.type,
-                    expression = attribute.value,
-                    isStatic = false,
-                    isStable = false
-                )
-            )
-        }
-
-        // There are additional cases where attributes can be pivotal:
-        //   1. It is annotated as @Pivotal
-        //   2. It is a `val` ctor parameter
-        for (assignment in validations) {
-            val attribute = assignment.attribute
-            val name = attribute.name
-            val descriptor = attribute.descriptor
-
-            if (descriptor.hasPivotalAnnotation()) {
-                result.add(
-                    AttributeNode(
-                        name = name,
-                        descriptor = descriptor,
-                        type = attribute.type,
-                        expression = attribute.expression,
-                        isStatic = false,
-                        isStable = false
-                    )
-                )
-                continue
-            }
-            if (descriptor is PropertyDescriptor &&
-                attrsUsedInCall.contains(name) && !descriptor.isVar) {
-                result.add(
-                    AttributeNode(
-                        name = name,
-                        descriptor = descriptor,
-                        type = attribute.type,
-                        expression = attribute.expression,
-                        isStatic = false,
-                        isStable = false
-                    )
-                )
-                continue
-            }
-        }
-
-        return result
-    }
-
-    private fun ResolvedCall<*>.buildParamsFromAttributes(
-        attributes: Map<String, AttributeInfo>
-    ): List<ValueNode> {
-        val possbileChildrenParam = valueArguments.keys.possibleChildrenParameter
-        return valueArguments.map { (param, value) ->
-            val name = param.name.asString()
-            var type = param.type
-            var attr = attributes[name]
-
-            if (param.hasChildrenAnnotation() || (param == possbileChildrenParam && attr == null)) {
-                val childrenAttr = attributes[CHILDREN_KEY]
-                if (childrenAttr != null) {
-                    attr = childrenAttr
-                }
-                if (param.isComposableFromChildrenAnnotation()) {
-                    type = type.makeComposable(module)
-                }
-            }
-
-            if (value is DefaultValueArgument) {
-                return@map DefaultValueNode(
-                    name = name,
-                    descriptor = param,
-                    type = type
-                )
-            }
-
-            if (attr == null && isImplicitConstructorParam(param, resultingDescriptor)) {
-                return@map ImplicitCtorValueNode(
-                    name = name,
-                    descriptor = param,
-                    type = type
-                )
-            }
-
-            if (attr == null) {
-                error("Couldn't find attribute but expected to. param=$param name=$name")
-            }
-
-            AttributeNode(
-                name = attr.name,
-                isStatic = false,
-                isStable = false,
-                descriptor = param,
-                type = type,
-                expression = attr.value
-            )
-        }
-    }
-
-    // pure, can be moved out
-    private fun AttributeNode.asChangedValidatedAssignment(
-        kind: ComposerCallKind,
-        expressionToReportErrorsOn: KtExpression,
-        receiverScope: KotlinType,
-        context: ExpressionTypingContext
-    ): ValidatedAssignment {
-        val (validationCall, uncheckedValidationCall, _) = resolveValidationCall(
-            kind = kind,
-            validationType = ValidationType.CHANGED,
-            attrType = type,
-            expressionToReportErrorsOn = expressionToReportErrorsOn,
-            receiverScope = receiverScope,
-            assignmentReceiverScope = null,
-            context = context
-        )
-
-        return ValidatedAssignment(
-            validationType = ValidationType.CHANGED,
-            validationCall = validationCall,
-            uncheckedValidationCall = uncheckedValidationCall,
-            attribute = this,
-            assignment = null,
-            assignmentLambda = null
-        )
-    }
-
-    private fun resolveAllSetAttributes(
-        kind: ComposerCallKind,
-        expressionToReportErrorsOn: KtExpression,
-        receiverScope: KotlinType,
-        type: KotlinType?,
-        attributes: Map<String, AttributeInfo>,
-        attributesUsedInCall: Set<String>,
-        consumedAttributes: MutableSet<String>,
-        missingRequiredAttributes: MutableList<DeclarationDescriptor>,
-        shouldMemoizeCtor: Boolean,
-        context: ExpressionTypingContext
-    ): List<ValidatedAssignment> {
-        if (type == null) return emptyList()
-        val results = mutableListOf<ValidatedAssignment>()
-        var children: AttributeInfo? = null
-
-        val tempForAttributes = TemporaryTraceAndCache.create(
-            context, "temp for attributes", expressionToReportErrorsOn
-        )
-
-        val tempForValidations = TemporaryTraceAndCache.create(
-            context, "temp for validations", expressionToReportErrorsOn
-        )
-
-        for ((name, attribute) in attributes) {
-            if (name == TAG_KEY) continue
-            if (name == CHILDREN_KEY) {
-                children = attribute
-                continue
-            }
-            val keyExpr = attribute.key ?: error("key expected")
-
-            val expectedTypes = mutableListOf<KotlinType>()
-
-            var resolvedCall: ResolvedCall<*>? = null
-
-            // NOTE(lmr): A ktx element that has access (like its a recursive call or a nested class) to the private property
-            // of the tag will be able to set it as an attribute...  I'm not sure if that'a s good thing or not, but unless we
-            // do something extra, that is indeed possible. Perhaps it's something we should look into.
-
-            if (resolvedCall == null) {
-                resolvedCall = resolveAttributeAsSetter(
-                    type,
-                    attribute.name,
-                    keyExpr,
-                    attribute.value,
-                    attribute.isPunned,
-                    expectedTypes,
-                    context.replaceTraceAndCache(tempForAttributes)
-                )
-            }
-
-            if (resolvedCall == null) {
-                resolvedCall = resolveAttributeAsProperty(
-                    type,
-                    keyExpr,
-                    attribute.value,
-                    attribute.isPunned,
-                    expectedTypes,
-                    context.replaceTraceAndCache(tempForAttributes)
-                )
-            }
-
-            if (resolvedCall != null) {
-
-                val validationType = when {
-                    !shouldMemoizeCtor && attributesUsedInCall.contains(name) ->
-                        ValidationType.CHANGED
-                    attributesUsedInCall.contains(name) -> ValidationType.UPDATE
-                    else -> ValidationType.SET
-                }
-
-                val descriptor = resolvedCall.resultingDescriptor
-
-                val attrType = when (descriptor) {
-                    is FunctionDescriptor -> descriptor.valueParameters.firstOrNull()?.type
-                    is PropertyDescriptor -> descriptor.type
-                    else -> null
-                } ?: continue
-
-                val (validationCall, uncheckedValidationCall, lambdaDescriptor) =
-                    resolveValidationCall(
-                        kind = kind,
-                        expressionToReportErrorsOn = expressionToReportErrorsOn,
-                        receiverScope = receiverScope,
-                        assignmentReceiverScope = type,
-                        validationType = validationType,
-                        attrType = attrType,
-                        context = context.replaceTraceAndCache(tempForValidations)
-                    )
-
-                results.add(
-                    ValidatedAssignment(
-                        validationType = validationType,
-                        assignment = resolvedCall,
-                        assignmentLambda = lambdaDescriptor,
-                        attribute = AttributeNode(
-                            name = name,
-                            expression = attribute.value,
-                            type = attrType,
-                            descriptor = resolvedCall.resultingDescriptor,
-                            isStatic = false,
-                            isStable = false
-                        ),
-                        validationCall = validationCall,
-                        uncheckedValidationCall = uncheckedValidationCall
-                    )
-                )
-                consumedAttributes.add(name)
-            }
-        }
-
-        if (children != null) {
-            val childrenExpr = children.value
-
-            var resolvedCall: ResolvedCall<*>? = null
-
-            for (descriptor in getChildrenDescriptors(type, attributesUsedInCall, context)) {
-                if (resolvedCall != null) break
-
-                when (descriptor) {
-                    is PropertyDescriptor -> {
-                        resolvedCall = resolveChildrenAsProperty(
-                            type,
-                            descriptor,
-                            childrenExpr,
-                            context.replaceTraceAndCache(tempForAttributes),
-                            attributesUsedInCall.contains(CHILDREN_KEY)
-                        )
-                    }
-                    is SimpleFunctionDescriptor -> {
-                        resolvedCall = resolveChildrenAsSetter(
-                            type,
-                            descriptor,
-                            childrenExpr,
-                            context.replaceTraceAndCache(tempForAttributes)
-                        )
-                    }
-                }
-            }
-            if (resolvedCall != null) {
-
-                val descriptor = resolvedCall.resultingDescriptor
-
-                val validationType = when {
-                    attributesUsedInCall.contains(CHILDREN_KEY) -> ValidationType.UPDATE
-                    else -> ValidationType.SET
-                }
-
-                val attrName = when (descriptor) {
-                    is SimpleFunctionDescriptor ->
-                        ComposeUtils.propertyNameFromSetterMethod(
-                            descriptor.name.asString()
-                        )
-                    is PropertySetterDescriptor -> descriptor.correspondingProperty.name.asString()
-                    else -> descriptor.name.asString()
-                }
-
-                attributes[attrName]?.let {
-                    if (attributesUsedInCall.contains(attrName) &&
-                        attributesUsedInCall.contains(CHILDREN_KEY)) {
-                        // if they were both already used in the call, then this diagnostic will already have been reported, and we
-                        // can ignore it
-                    } else {
-                        // they are providing a named attribute for a @Children attribute while also providing a children
-                        // body. This is illegal.
-                        context.trace.reportFromPlugin(
-                            ComposeErrors.CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE.on(
-                                it.key!!,
-                                attrName
-                            ),
-                            ComposeDefaultErrorMessages
-                        )
-                    }
-                    consumedAttributes.add(attrName)
-                }
-
-                val attrType = when (descriptor) {
-                    is FunctionDescriptor -> descriptor.valueParameters.firstOrNull()?.type
-                        ?: error("Expected single parameter setter")
-                    is PropertyDescriptor -> descriptor.type
-                    else -> error("Unknown callable type encountered")
-                }
-
-                val (validationCall, uncheckedValidationCall, lambdaDescriptor) =
-                    resolveValidationCall(
-                        kind = kind,
-                        expressionToReportErrorsOn = expressionToReportErrorsOn,
-                        receiverScope = receiverScope,
-                        assignmentReceiverScope = type,
-                        validationType = validationType,
-                        attrType = attrType,
-                        context = context.replaceTraceAndCache(tempForValidations)
-                    )
-
-                results.add(
-                    ValidatedAssignment(
-                        validationType = when {
-                            attributesUsedInCall.contains(CHILDREN_KEY) -> ValidationType.UPDATE
-                            else -> ValidationType.SET
-                        },
-                        assignment = resolvedCall,
-                        assignmentLambda = lambdaDescriptor,
-                        attribute = AttributeNode(
-                            name = CHILDREN_KEY,
-                            expression = children.value,
-                            type = attrType,
-                            descriptor = resolvedCall.resultingDescriptor,
-                            isStatic = false,
-                            isStable = false
-                        ),
-                        validationCall = validationCall,
-                        uncheckedValidationCall = uncheckedValidationCall
-                    )
-                )
-                consumedAttributes.add(CHILDREN_KEY)
-            }
-        }
-
-        if (!type.isUnit()) {
-            val cls = type.constructor.declarationDescriptor as? ClassDescriptor
-                ?: error("unexpected classifier descriptor")
-            val requiredAttributes = cls.unsubstitutedMemberScope
-                .getContributedDescriptors()
-                .mapNotNull { it as? PropertyDescriptor }
-                // NOTE(lmr): I think we should consider not marking lateinit properties as required. It would maybe align
-                // ourselves more with the language semantic of `lateinit`
-                .filter {
-                    it.isLateInit && it.visibility.isVisibleOutside() &&
-                            !Visibilities.isPrivate(it.visibility)
-                }
-                .filter { !it.hasHiddenAttributeAnnotation() }
-
-            requiredAttributes
-                .filter { !consumedAttributes.contains(it.name.asString()) }
-                .filter { !it.hasChildrenAnnotation() }
-                .ifNotEmpty { missingRequiredAttributes.addAll(this) }
-
-            requiredAttributes
-                .filter { it.hasChildrenAnnotation() }
-                .filter { !consumedAttributes.contains(it.name.asString()) &&
-                        !consumedAttributes.contains(CHILDREN_KEY) }
-                .ifNotEmpty { missingRequiredAttributes.addAll(this) }
-        }
-
-        tempForAttributes.commit()
-        tempForValidations.commit()
-        return results
-    }
-
-    // pure, can be moved out. used in resolveAllSetAttrs
-    private fun getChildrenDescriptors(
-        type: KotlinType,
-        attributesUsedInCall: Set<String>,
-        context: ExpressionTypingContext
-    ): List<DeclarationDescriptor> {
-        val descriptor = type.constructor.declarationDescriptor
-        return when (descriptor) {
-            is ClassDescriptor -> {
-                // We have to be careful here because if the property was defined as a constructor parameter, then the @Children
-                // annotation will be on the parameter descriptor, *not* on the property descriptor. These aren't linked in any real
-                // sense at the descriptor level, so we have to find the primary constructor and just use the convention of the
-                // parameter named of the constructor being the same as the property.
-                val ctorParameters = descriptor.unsubstitutedPrimaryConstructor?.valueParameters
-                    ?: emptyList()
-                val shouldIncludeCtorParam = attributesUsedInCall.contains(CHILDREN_KEY)
-                fun DeclarationDescriptor.isChildrenCtorParam(): Boolean {
-                    if (!shouldIncludeCtorParam) return false
-                    if (this !is PropertyDescriptor) return false
-                    val param = ctorParameters.firstOrNull { p -> name == p.name } ?: return false
-                    return param.hasChildrenAnnotation()
-                }
-                descriptor
-                    .unsubstitutedMemberScope
-                    .getContributedDescriptors()
-                    .filter { it.hasChildrenAnnotation() || it.isChildrenCtorParam() }
-                    .filter {
-                        // if it's a property descriptor, we are only interested if it has a setter
-                        if (it is PropertyDescriptor) it.setter != null else true
-                    }
-                    .filter {
-                        // we want to make sure the descriptor is actually visible from the callsite
-                        it is DeclarationDescriptorWithVisibility &&
-                                Visibilities.isVisibleIgnoringReceiver(
-                                    it,
-                                    context.scope.ownerDescriptor
-                                )
-                    }
-            }
-            else -> emptyList()
-        }
-    }
-
-    private fun resolveAttributeAsSetter(
-        instanceType: KotlinType,
-        name: String,
-        keyExpr: KtReferenceExpression,
-        valueExpr: KtExpression,
-        isPunned: Boolean,
-        expectedTypes: MutableCollection<KotlinType>,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-        val setterName = Name.identifier(
-            ComposeUtils.setterMethodFromPropertyName(
-                name
-            )
-        )
-        val receiver = TransientReceiver(instanceType)
-
-        val call = makeCall(
-            keyExpr,
-            calleeExpression = keyExpr,
-            valueArguments = listOf(CallMaker.makeValueArgument(valueExpr)),
-            receiver = receiver
-        )
-
-        val temporaryForFunction = TemporaryTraceAndCache.create(
-            context, "trace to resolve as function call", keyExpr
-        )
-
-        val results = callResolver.computeTasksAndResolveCall<FunctionDescriptor>(
-            BasicCallResolutionContext.create(
-                context.replaceTraceAndCache(temporaryForFunction),
-                call,
-                CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-                DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
-            ),
-            setterName,
-            keyExpr,
-            NewResolutionOldInference.ResolutionKind.Function
-        )
-
-        if (results.isNothing) {
-            return null
-        }
-
-        if (results.isAmbiguity || temporaryForFunction.trace.hasTypeMismatchErrorsOn(valueExpr)) {
-            expectedTypes.addAll(
-                results.resultingCalls.mapNotNull {
-                    it.resultingDescriptor.valueParameters.firstOrNull()
-                }.map { it.type }
-            )
-            return null
-        }
-
-        val resolvedCall = OverloadResolutionResultsUtil.getResultingCall(results, context)
-            ?: return null
-
-        if (isPunned) {
-            context.trace.recordAttributeKeyRef(valueExpr, resolvedCall.resultingDescriptor)
-        }
-        temporaryForFunction.commit()
-
-        return resolvedCall
-    }
-
-    private fun resolveAttributeAsProperty(
-        instanceType: KotlinType,
-        keyExpr: KtSimpleNameExpression,
-        valueExpr: KtExpression,
-        isPunned: Boolean,
-        expectedTypes: MutableCollection<KotlinType>,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-
-        // NOTE(lmr): I'm not sure what the consequences are of using the tagExpr as the receiver...
-        val receiver = TransientReceiver(instanceType)
-
-        val temporaryForVariable = TemporaryTraceAndCache.create(
-            context, "trace to resolve as local variable or property", keyExpr
-        )
-
-        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
-
-        val call = CallMaker.makePropertyCall(receiver, null, keyExpr)
-
-        val contextForVariable = BasicCallResolutionContext.create(
-            contextToUse,
-            call,
-            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS
-        )
-
-        val results = callResolver.resolveSimpleProperty(contextForVariable)
-
-        if (results.isNothing) {
-            return null
-        }
-
-        val resolvedCall = OverloadResolutionResultsUtil.getResultingCall(results, contextToUse)
-            ?: return null
-
-        val descriptor = resolvedCall.resultingDescriptor as PropertyDescriptor
-        val expectedType = descriptor.type
-
-        if (isDeprecatedKtxTagResolve) {
-            facade.getTypeInfo(
-                valueExpr,
-                contextToUse
-                    .replaceExpectedType(expectedType)
-                    .replaceCallPosition(CallPosition.PropertyAssignment(keyExpr))
-            )
-        }
-
-        if (temporaryForVariable.trace.hasTypeMismatchErrorsOn(valueExpr)) {
-            expectedTypes.add(expectedType)
-            return null
-        }
-
-        if (descriptor.setter == null) {
-            // NOTE(lmr): we probably shouldn't do this. if this ends up being a cross-module compile, then the
-            // setter will be gone. I'm not sure the right way to figure out whether or not a property is
-            // settable or not...
-            return null
-        }
-
-        if (isPunned) {
-            context.trace.recordAttributeKeyRef(valueExpr, resolvedCall.resultingDescriptor)
-        }
-
-        temporaryForVariable.commit()
-
-        return resolvedCall
-    }
-
-    private fun resolveChildrenAsSetter(
-        instanceType: KotlinType,
-        childrenDescriptor: SimpleFunctionDescriptor,
-        childrenExpr: KtExpression,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-        val setterName = childrenDescriptor.name
-
-        val valueArguments = listOf(CallMaker.makeValueArgument(childrenExpr))
-        val receiver = TransientReceiver(instanceType)
-        val call = makeCall(
-            childrenExpr,
-            valueArguments = valueArguments,
-            receiver = receiver,
-            calleeExpression = childrenExpr // NOTE(lmr): this seems wrong
-        )
-
-        val temporaryForFunction = TemporaryTraceAndCache.create(
-            context, "trace to resolve as function call", childrenExpr
-        )
-
-        val refExpr = psiFactory.createSimpleName(setterName.identifier)
-
-        val results = callResolver.computeTasksAndResolveCall<FunctionDescriptor>(
-            BasicCallResolutionContext.create(
-                context.replaceTraceAndCache(temporaryForFunction),
-                call,
-                CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-                DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
-            ),
-            setterName,
-            refExpr,
-            NewResolutionOldInference.ResolutionKind.Function
-        )
-
-        if (results.isNothing) {
-            return null
-        }
-
-        if (temporaryForFunction.trace.hasTypeMismatchErrorsOn(childrenExpr)) {
-            return null
-        }
-        // TODO(lmr): should we check isSuccess here or anything like that?
-
-        val resolvedCall = OverloadResolutionResultsUtil.getResultingCall(results, context)
-            ?: return null
-
-        temporaryForFunction.commit()
-
-        if (isDeprecatedKtxTagResolve) {
-            facade.getTypeInfo(
-                childrenExpr,
-                context.replaceExpectedType(
-                    resolvedCall.resultingDescriptor.valueParameters.first().type
-                )
-            )
-        }
-        return resolvedCall
-    }
-
-    private fun resolveChildrenAsProperty(
-        instanceType: KotlinType,
-        propertyDescriptor: PropertyDescriptor,
-        childrenExpr: KtExpression,
-        context: ExpressionTypingContext,
-        shouldIncludeCtorParam: Boolean
-    ): ResolvedCall<*>? {
-        val temporaryForVariable = TemporaryTraceAndCache.create(
-            context, "trace to resolve as local variable or property", childrenExpr
-        )
-
-        val receiver = TransientReceiver(instanceType)
-
-        val call = makeCall(
-            childrenExpr,
-            calleeExpression = childrenExpr,
-            receiver = receiver
-        )
-
-        val contextForVariable = BasicCallResolutionContext.create(
-            context.replaceTraceAndCache(temporaryForVariable),
-            call,
-            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS
-        )
-
-        val results = callResolver.computeTasksAndResolveCall<PropertyDescriptor>(
-            contextForVariable,
-            propertyDescriptor.name,
-            TracingStrategy.EMPTY,
-            NewResolutionOldInference.ResolutionKind.Variable
-        )
-
-        if (results.isNothing) {
-            return null
-        }
-
-        val resolvedCall = OverloadResolutionResultsUtil.getResultingCall(results, context)
-            ?: return null
-
-        val composableFromChildrenAnnotation = (propertyDescriptor.containingDeclaration
-                as? ClassDescriptor)?.let { containingDeclaration ->
-                val ctorParameters =
-                    containingDeclaration.unsubstitutedPrimaryConstructor?.valueParameters
-                        ?: emptyList()
-                fun DeclarationDescriptor.isComposableChildrenCtorParam(): Boolean {
-                    if (!shouldIncludeCtorParam) return false
-                    if (this !is PropertyDescriptor) return false
-                    val param = ctorParameters.firstOrNull { p -> name == p.name } ?: return false
-                    return param.isComposableFromChildrenAnnotation()
-                }
-                resolvedCall.resultingDescriptor.isComposableFromChildrenAnnotation() ||
-                        resolvedCall.resultingDescriptor.isComposableChildrenCtorParam()
-            } ?: false
-
-        val expectedType =
-            if (composableFromChildrenAnnotation)
-                (resolvedCall.resultingDescriptor).type.makeComposable(module)
-            else (resolvedCall.resultingDescriptor).type
-
-        if (isDeprecatedKtxTagResolve) {
-            facade.getTypeInfo(
-                childrenExpr,
-                context
-                    .replaceTraceAndCache(temporaryForVariable)
-                    .replaceExpectedType(expectedType)
-                    .replaceCallPosition(CallPosition.PropertyAssignment(null))
-            )
-        }
-
-        if (temporaryForVariable.trace.hasTypeMismatchErrorsOn(childrenExpr)) {
-            return null
-        }
-
-        temporaryForVariable.commit()
-
-        return resolvedCall
-    }
-
-    private fun resolveCandidate(
-        step: ResolveStep,
-        candidate: ResolvedCall<FunctionDescriptor>,
-        original: Call,
-        attributes: Map<String, AttributeInfo>,
-        usedAttributes: MutableSet<String>,
-        usedAttributeInfos: MutableList<TempParameterInfo>,
-        missingRequiredAttributes: MutableList<DeclarationDescriptor>,
-        context: ExpressionTypingContext
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        val valueArguments = mutableListOf<ValueArgument>()
-
-        val referencedDescriptor = candidate.semanticCall.resultingDescriptor
-
-        val dispatchReceiver = candidate.semanticCall.dispatchReceiver ?: candidate.dispatchReceiver
-
-        val stableParamNames = referencedDescriptor.hasStableParameterNames()
-
-        val possibleChildrenParameter =
-            candidate.resultingDescriptor.valueParameters.possibleChildrenParameter
-
-        for (param in candidate.resultingDescriptor.valueParameters) {
-            val name = param.name.asString()
-            val attr = attributes[name]
-            var arg: ValueArgument? = null
-
-            if (arg == null && (param.hasChildrenAnnotation() ||
-                        param == possibleChildrenParameter)) {
-                val childrenAttr = attributes[CHILDREN_KEY]
-                if (childrenAttr != null) {
-                    usedAttributes.add(CHILDREN_KEY)
-                    var type = param.type
-                    if (param.isComposableFromChildrenAnnotation()) {
-                        type = type.makeComposable(module)
-                    }
-
-                    usedAttributeInfos.add(
-                        TempParameterInfo(
-                            attribute = childrenAttr,
-                            descriptor = param,
-                            type = type
-                        )
-                    )
-
-                    arg = childrenAttr.toValueArgument(name, stableParamNames)
-
-                    if (attr != null) {
-                        // they are providing a named attribute for a @Children attribute while also providing a children
-                        // body. This is illegal.
-                        context.trace.reportFromPlugin(
-                            ComposeErrors.CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE.on(
-                                attr.key!!,
-                                attr.name
-                            ),
-                            ComposeDefaultErrorMessages
-                        )
-                        usedAttributes.add(attr.name)
-                    }
-                }
-            }
-
-            if (arg == null && attr != null) {
-                usedAttributes.add(name)
-                usedAttributeInfos.add(
-                    TempParameterInfo(
-                        attribute = attr,
-                        descriptor = param,
-                        type = param.type
-                    )
-                )
-                context.trace.record(BindingContext.REFERENCE_TARGET, attr.key, param)
-                if (attr.isPunned) {
-                    context.trace.recordAttributeKeyRef(attr.value, param)
-                }
-                arg = attr.toValueArgument(attr.name, stableParamNames)
-            }
-
-            if (arg == null && isImplicitConstructorParam(param, referencedDescriptor)) {
-                arg = ImplicitCtorValueArgument(param.type)
-            }
-
-            if (arg != null) {
-                valueArguments.add(arg)
-            } else if (!param.declaresDefaultValue()) {
-                // missing required parameter!
-                if (dispatchReceiver?.type?.isExtensionFunctionType == true &&
-                    param == candidate.resultingDescriptor.valueParameters[0]) {
-                    // in this case, the missing parameter is an extension parameter... and it will be provided implicitly. We don't want
-                    // to diagnose this as a missing attribute. If it is missing, the call resolver will add a diagnostic anyway.
-                } else {
-                    missingRequiredAttributes.add(param)
-                }
-            }
-        }
-
-        val call = makeCall(
-            original.callElement,
-            valueArguments = valueArguments,
-            calleeExpression = original.calleeExpression,
-            receiver = original.explicitReceiver,
-            dispatchReceiver = dispatchReceiver
-        )
-
-        val contextForVariable = BasicCallResolutionContext.create(
-            context,
-            call,
-            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-            DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
-        )
-
-        return when (step) {
-            is ResolveStep.Root -> callResolver.resolveFunctionCall(contextForVariable)
-            is ResolveStep.Nested -> forceResolveCallForInvoke(step.calleeType, contextForVariable)
-        }
-    }
-
-    private fun getCandidates(
-        step: ResolveStep,
-        call: Call,
-        context: ExpressionTypingContext,
-        collectAllCandidates: Boolean = true
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        val contextForVariable = BasicCallResolutionContext.create(
-            context,
-            call,
-            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-            DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
-        ).replaceCollectAllCandidates(collectAllCandidates)
-
-        return when (step) {
-            is ResolveStep.Root -> callResolver.resolveFunctionCall(contextForVariable)
-            is ResolveStep.Nested -> forceResolveCallForInvoke(step.calleeType, contextForVariable)
-        }
-    }
-
-    private fun resolveReceiver(
-        expression: KtExpression,
-        context: ExpressionTypingContext
-    ): Receiver? {
-        if (expression !is KtQualifiedExpression) return null
-        val currentContext = context
-            .replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)
-            .replaceContextDependency(ContextDependency.INDEPENDENT)
-
-        expression.elementChain(currentContext)
-
-        val receiverExpr = expression.receiverExpression
-
-        val qualifier = context.trace.get(BindingContext.QUALIFIER, receiverExpr)
-
-        val receiverTypeInfo = when {
-            !isDeprecatedKtxTagResolve -> error("in here")
-            qualifier == null -> facade.getTypeInfo(receiverExpr, currentContext)
-            else -> KotlinTypeInfo(null, currentContext.dataFlowInfo)
-        }
-
-        // TODO(lmr): inspect jumps and nullability. We cant allow tags that can be null or return early
-        val receiverType = receiverTypeInfo.type
-            ?: ErrorUtils.createErrorType("Type for " + receiverExpr.text)
-
-        return context.trace.get(BindingContext.QUALIFIER, receiverExpr)
-            ?: ExpressionReceiver.create(receiverExpr, receiverType, context.trace.bindingContext)
-    }
-
-    private fun makeValueArgument(
-        type: KotlinType,
-        context: ExpressionTypingContext,
-        forceType: Boolean = false
-    ): ValueArgument {
-        val fakeExpr = psiFactory.createSimpleName("tmpVar")
-
-        context.trace.record(
-            BindingContext.EXPRESSION_TYPE_INFO, fakeExpr, KotlinTypeInfo(
-                type = type,
-                dataFlowInfo = DataFlowInfo.EMPTY,
-                jumpOutPossible = false,
-                jumpFlowInfo = DataFlowInfo.EMPTY
-            )
-        )
-
-        if (forceType) {
-            context.trace.record(BindingContext.PROCESSED, fakeExpr, true)
-        }
-
-        return CallMaker.makeValueArgument(fakeExpr)
-    }
-
-    private fun resolveJoinKey(
-        expressionToReportErrorsOn: KtExpression,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-
-        return resolveSubstitutableComposerMethod(
-            KtxNameConventions.JOINKEY,
-            listOf(
-                builtIns.anyType,
-                builtIns.anyType
-            ),
-            null,
-            expressionToReportErrorsOn,
-            context
-        )
-    }
-
-    private fun resolveInfixOr(context: ExpressionTypingContext): ResolvedCall<*> {
-        val orName = Name.identifier("or")
-        val left = psiFactory.createSimpleName("a")
-        val right = psiFactory.createSimpleName("b")
-        val operator = psiFactory.createSimpleName(orName.identifier)
-
-        context.trace.record(
-            BindingContext.EXPRESSION_TYPE_INFO, left, KotlinTypeInfo(
-                type = builtIns.booleanType,
-                dataFlowInfo = DataFlowInfo.EMPTY,
-                jumpOutPossible = false,
-                jumpFlowInfo = DataFlowInfo.EMPTY
-            )
-        )
-
-        context.trace.record(
-            BindingContext.EXPRESSION_TYPE_INFO, right, KotlinTypeInfo(
-                type = builtIns.booleanType,
-                dataFlowInfo = DataFlowInfo.EMPTY,
-                jumpOutPossible = false,
-                jumpFlowInfo = DataFlowInfo.EMPTY
-            )
-        )
-
-        return callResolver.resolveCallWithGivenName(
-            context,
-            makeCall(
-                callElement = left,
-                calleeExpression = operator,
-                receiver = ExpressionReceiver.create(
-                    left,
-                    builtIns.booleanType,
-                    context.trace.bindingContext
-                ),
-                valueArguments = listOf(CallMaker.makeValueArgument(right))
-            ),
-            operator,
-            Name.identifier("or")
-        ).resultingCall
-    }
-
-    private fun resolveApplyCallForType(
-        type: KotlinType,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*> {
-        val apply = psiFactory.createSimpleName("apply")
-
-        val results = callResolver.resolveCallWithGivenName(
-            context,
-            makeCall(
-                callElement = apply,
-                calleeExpression = apply,
-                receiver = TransientReceiver(type),
-                valueArguments = listOf(
-                    makeValueArgument(
-                        functionType(receiverType = type),
-                        context
-                    )
-                )
-            ),
-            apply,
-            Name.identifier("apply")
-        )
-        return results.resultingCall
-    }
-
-    private fun resolveComposerEmit(
-        implicitCtorTypes: List<KotlinType>,
-        constructedType: KotlinType,
-        hasBody: Boolean,
-        expressionToReportErrorsOn: KtExpression,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-        return resolveSubstitutableComposerMethod(
-            KtxNameConventions.EMIT,
-            listOfNotNull(
-                builtIns.anyType,
-                functionType(
-                    parameterTypes = implicitCtorTypes,
-                    returnType = constructedType
-                ),
-                functionType(),
-                if (hasBody) functionType() else null
-            ),
-            constructedType,
-            expressionToReportErrorsOn,
-            context
-        )
-    }
-
-    private fun resolveComposerMethodCandidates(
-        element: KtExpression,
-        name: Name,
-        context: ExpressionTypingContext
-    ): Collection<ResolvedCall<*>> {
-        val calleeExpression = psiFactory.createSimpleName(name.asString())
-
-        val methodCall = makeCall(
-            callElement = element,
-            calleeExpression = calleeExpression,
-            receiver = TransientReceiver(composerType)
-        )
-
-        val contextForVariable = BasicCallResolutionContext.create(
-            context,
-            methodCall,
-            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-            DataFlowInfoForArgumentsImpl(context.dataFlowInfo, methodCall)
-        )
-
-        val results = callResolver.resolveCallWithGivenName(
-            // it's important that we use "collectAllCandidates" so that extension functions get included
-            contextForVariable.replaceCollectAllCandidates(true),
-            methodCall,
-            calleeExpression,
-            name
-        )
-
-        return results.allCandidates ?: emptyList()
-    }
-
-    private fun resolveComposerCall(
-        constructedType: KotlinType?,
-        expressionToReportErrorsOn: KtExpression,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-
-        // call signature is:
-        // ==================
-        // key: Any, invalid: V.() -> Boolean, block: () -> Unit
-        // key: Any, ctor: () -> T, invalid: V.(T) -> Boolean, block: (T) -> Unit
-
-        return resolveSubstitutableComposerMethod(
-            KtxNameConventions.CALL,
-            listOfNotNull(
-                builtIns.anyType,
-                constructedType?.let {
-                    functionType(returnType = constructedType)
-                },
-                functionType(
-                    parameterTypes = listOfNotNull(constructedType),
-                    returnType = builtIns.booleanType
-                ),
-                functionType(
-                    parameterTypes = listOfNotNull(
-                        constructedType
-                    )
-                )
-            ),
-            constructedType,
-            expressionToReportErrorsOn,
-            context
-        )
-    }
-
-    private fun resolveSingleValidationCall(
-        expressionToReportErrorsOn: KtExpression,
-        receiverScope: KotlinType,
-        validationType: ValidationType,
-        checked: Boolean,
-        attrType: KotlinType,
-        lambdaArg: ValueArgument?,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-        val temporaryForVariable = TemporaryTraceAndCache.create(
-            context, "trace to resolve variable", expressionToReportErrorsOn
-        )
-        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
-        val name = validationType.name.toLowerCase(Locale.ROOT).let {
-            if (!checked) (it + "Unchecked") else it
-        }
-        val calleeExpression = psiFactory.createSimpleName(name)
-        val call = makeCall(
-            callElement = calleeExpression,
-            calleeExpression = calleeExpression,
-            valueArguments = listOfNotNull(
-                makeValueArgument(attrType, contextToUse, forceType = true),
-                lambdaArg
-            ),
-            receiver = TransientReceiver(receiverScope)
-        )
-        val results = callResolver.resolveCallWithGivenName(
-            BasicCallResolutionContext.create(
-                contextToUse,
-                call,
-                CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-                DataFlowInfoForArgumentsImpl(contextToUse.dataFlowInfo, call)
-            ),
-            call,
-            calleeExpression,
-            Name.identifier(name)
-        )
-
-        if (results.isSuccess) return results.resultingCall
-
-        if (results.resultCode == OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
-
-            // NOTE(lmr): We know the type of the attribute at this point, but it's possible for the validation call to require
-            // some help in order to do the type inference for the call. We are just guessing here that the type is going to be
-            // the attribute type, and not something more complicated. It is kind of a bummer that we need this and I wonder if
-            // there isn't a cleaner way to do this.
-
-            for (candidate in results.resultingCalls) {
-
-                val typeParam = candidate.typeArguments.keys.singleOrNull() ?: continue
-
-                if (!attrType.satisfiesConstraintsOf(typeParam)) continue
-
-                val nextTempTrace = TemporaryTraceAndCache.create(
-                    context, "trace to resolve variable", expressionToReportErrorsOn
-                )
-
-                val nextContext = context
-                    .replaceTraceAndCache(nextTempTrace)
-                    .replaceCollectAllCandidates(false)
-
-                val substitutor = TypeSubstitutor.create(
-                    mapOf(
-                        typeParam.typeConstructor to attrType.asTypeProjection()
-                    )
-                )
-
-                val nextCall = makeCall(
-                    callElement = expressionToReportErrorsOn,
-                    calleeExpression = calleeExpression,
-                    receiver = TransientReceiver(composerType),
-                    valueArguments = candidate.candidateDescriptor.valueParameters.map {
-                        makeValueArgument(it.type, nextContext)
-                    }
-                )
-
-                val nextResults = callResolver.resolveCallWithKnownCandidate(
-                    nextCall,
-                    TracingStrategyImpl.create(calleeExpression, nextCall),
-                    BasicCallResolutionContext.create(
-                        nextContext,
-                        nextCall,
-                        CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-                        DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
-                    ),
-                    ResolutionCandidate.create(
-                        nextCall,
-                        candidate.candidateDescriptor,
-                        candidate.dispatchReceiver,
-                        candidate.explicitReceiverKind,
-                        substitutor
-                    ),
-                    DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
-                )
-
-                if (nextResults.isSuccess) {
-                    nextTempTrace.commit()
-                    return nextResults.resultingCall
-                }
-            }
-        }
-
-        return null
-    }
-
-    private fun resolveValidationCall(
-        kind: ComposerCallKind,
-        expressionToReportErrorsOn: KtExpression,
-        receiverScope: KotlinType,
-        assignmentReceiverScope: KotlinType?,
-        validationType: ValidationType,
-        attrType: KotlinType,
-        context: ExpressionTypingContext
-    ): Triple<ResolvedCall<*>?, ResolvedCall<*>?, FunctionDescriptor?> {
-        val temporaryForVariable = TemporaryTraceAndCache.create(
-            context, "trace to resolve variable", expressionToReportErrorsOn
-        )
-        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
-
-        val includeLambda = validationType != ValidationType.CHANGED
-
-        // for call:
-        // ValidatorType.set(AttrType, (AttrType) -> Unit): Boolean
-        // ValidatorType.update(AttrType, (AttrType) -> Unit): Boolean
-        // ValidatorType.changed(AttrType): Boolean
-
-        // for emit:
-        // ValidatorType.set(AttrType, ElementType.(AttrType) -> Unit): Unit
-        // ValidatorType.update(AttrType, ElementType.(AttrType) -> Unit): Unit
-        // ValidatorType.changed(AttrType): Unit
-
-        val lambdaType = when {
-            includeLambda && kind == ComposerCallKind.EMIT -> functionType(
-                parameterTypes = listOf(attrType),
-                receiverType = assignmentReceiverScope
-            )
-            includeLambda && kind == ComposerCallKind.CALL -> functionType(
-                parameterTypes = listOf(attrType)
-            )
-            else -> null
-        }
-        val lambdaArg = lambdaType?.let { makeValueArgument(it, contextToUse) }
-        val lambdaDescriptor = lambdaType?.let {
-            createFunctionDescriptor(
-                it,
-                contextToUse
-            )
-        }
-
-        val validationCall = resolveSingleValidationCall(
-            expressionToReportErrorsOn = expressionToReportErrorsOn,
-            receiverScope = receiverScope,
-            validationType = validationType,
-            checked = true,
-            attrType = attrType,
-            lambdaArg = lambdaArg,
-            context = context
-        )
-
-        val uncheckedValidationCall = resolveSingleValidationCall(
-            expressionToReportErrorsOn = expressionToReportErrorsOn,
-            receiverScope = receiverScope,
-            validationType = validationType,
-            checked = false,
-            attrType = attrType,
-            lambdaArg = lambdaArg,
-            context = context
-        )
-
-        return Triple(validationCall, uncheckedValidationCall, lambdaDescriptor)
-    }
-
-    private fun resolveSubstitutableComposerMethod(
-        methodName: Name,
-        argumentTypes: List<KotlinType>,
-        typeToSubstitute: KotlinType?,
-        expressionToReportErrorsOn: KtExpression,
-        context: ExpressionTypingContext
-    ): ResolvedCall<*>? {
-        val temporaryForVariable = TemporaryTraceAndCache.create(
-            context, "trace to resolve variable", expressionToReportErrorsOn
-        )
-        val contextToUse = context.replaceTraceAndCache(temporaryForVariable)
-
-        val composerExpr = psiFactory.createSimpleName(methodName.asString())
-
-        val call = makeCall(
-            callElement = expressionToReportErrorsOn,
-            calleeExpression = composerExpr,
-            receiver = TransientReceiver(composerType),
-            valueArguments = argumentTypes.map { makeValueArgument(it, contextToUse) }
-        )
-
-        val results = callResolver.resolveCallWithGivenName(
-            BasicCallResolutionContext.create(
-                contextToUse,
-                call,
-                CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-                DataFlowInfoForArgumentsImpl(contextToUse.dataFlowInfo, call)
-            ),
-            call,
-            composerExpr,
-            methodName
-        )
-
-        if (results.isSuccess) return results.resultingCall
-
-        if (typeToSubstitute == null) return null
-
-        val candidates = if (context.collectAllCandidates)
-            results.allCandidates ?: emptyList()
-        else results.resultingCalls
-
-        for (candidate in candidates) {
-
-            val typeParam = candidate.candidateDescriptor.typeParameters.singleOrNull() ?: continue
-
-            if (!typeToSubstitute.satisfiesConstraintsOf(typeParam)) continue
-
-            val nextTempTrace = TemporaryTraceAndCache.create(
-                context, "trace to resolve variable", expressionToReportErrorsOn
-            )
-
-            val nextContext = context
-                .replaceTraceAndCache(nextTempTrace)
-                .replaceCollectAllCandidates(false)
-
-            val substitutor = TypeSubstitutor.create(
-                mapOf(
-                    typeParam.typeConstructor to typeToSubstitute.asTypeProjection()
-                )
-            )
-
-            val nextCall = makeCall(
-                callElement = expressionToReportErrorsOn,
-                calleeExpression = composerExpr,
-                receiver = TransientReceiver(composerType),
-                valueArguments = candidate.candidateDescriptor.valueParameters.map {
-                    makeValueArgument(it.type, nextContext)
-                }
-            )
-
-            val nextResults = callResolver.resolveCallWithKnownCandidate(
-                nextCall,
-                TracingStrategyImpl.create(composerExpr, nextCall),
-                BasicCallResolutionContext.create(
-                    nextContext,
-                    nextCall,
-                    CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-                    DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
-                ),
-                ResolutionCandidate.create(
-                    nextCall,
-                    candidate.candidateDescriptor,
-                    candidate.dispatchReceiver,
-                    candidate.explicitReceiverKind,
-                    substitutor
-                ),
-                DataFlowInfoForArgumentsImpl(nextContext.dataFlowInfo, nextCall)
-            )
-
-            if (nextResults.isSuccess) {
-                nextTempTrace.commit()
-                return nextResults.resultingCall
-            }
-        }
-
-        return if (context.collectAllCandidates) null
-        else resolveSubstitutableComposerMethod(
-            methodName,
-            argumentTypes,
-            typeToSubstitute,
-            expressionToReportErrorsOn,
-            context.replaceCollectAllCandidates(true)
-        )
-    }
-
-    private fun resolveVar(
-        name: Name,
-        expr: KtExpression,
-        context: ExpressionTypingContext
-    ): OverloadResolutionResults<CallableDescriptor> {
-        val temporaryForVariable = TemporaryTraceAndCache.create(
-            context, "trace to resolve variable", expr
-        )
-        val call = makeCall(expr)
-        val contextForVariable = BasicCallResolutionContext.create(
-            context.replaceTraceAndCache(temporaryForVariable),
-            call,
-            CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
-            DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)
-        )
-        return callResolver.computeTasksAndResolveCall<CallableDescriptor>(
-            contextForVariable,
-            name,
-            TracingStrategy.EMPTY,
-            NewResolutionOldInference.ResolutionKind.Variable
-        )
-    }
-
-    private fun KtQualifiedExpression.elementChain(context: ExpressionTypingContext) {
-        val moduleDescriptor = context.scope.ownerDescriptor.module
-        val trace = context.trace
-        val scopeForFirstPart = context.scope
-
-        val path = asQualifierPartList()
-        val firstPart = path.first()
-        var currentDescriptor: DeclarationDescriptor? = scopeForFirstPart.findDescriptor(firstPart)
-        currentDescriptor =
-            currentDescriptor ?: moduleDescriptor.getPackage(FqName.topLevel(firstPart.name)).let {
-                if (it.isEmpty()) null else it
-            }
-
-        if (currentDescriptor == null) return
-        else storeSimpleNameExpression(firstPart.expression!!, currentDescriptor, trace)
-
-        // TODO(lmr): we need to add visibility checks into this function...
-        for (qualifierPartIndex in 1 until path.size) {
-            val qualifierPart = path[qualifierPartIndex]
-
-            val nextPackageOrClassDescriptor =
-                when (currentDescriptor) {
-                    // TODO(lmr): i wonder if we could allow this for Ktx. Seems like a nice to have
-                    // TODO type aliases as qualifiers? (would break some assumptions in TypeResolver)
-                    is TypeAliasDescriptor -> null
-                    is ClassDescriptor -> {
-                        var next: DeclarationDescriptor? = null
-                        next = next
-                            ?: currentDescriptor.unsubstitutedInnerClassesScope.findDescriptor(
-                                qualifierPart
-                            )
-                        if (currentDescriptor.kind == ClassKind.OBJECT) {
-                            next = next
-                                ?: currentDescriptor.unsubstitutedMemberScope.findDescriptor(
-                                    qualifierPart
-                                )
-                        }
-                        val cod = currentDescriptor.companionObjectDescriptor
-                        if (cod != null) {
-                            next = next
-                                ?: cod.unsubstitutedMemberScope.findDescriptor(qualifierPart)
-                        }
-                        next = next ?: currentDescriptor.staticScope.findDescriptor(qualifierPart)
-                        next
-                    }
-                    is PackageViewDescriptor -> {
-                        val packageView =
-                            if (qualifierPart.typeArguments == null) {
-                                moduleDescriptor.getPackage(
-                                    currentDescriptor.fqName.child(qualifierPart.name)
-                                )
-                            } else null
-                        if (packageView != null && !packageView.isEmpty()) {
-                            packageView
-                        } else {
-                            currentDescriptor.memberScope.findDescriptor(qualifierPart)
-                        }
-                    }
-                    is VariableDescriptor -> {
-                        currentDescriptor.type.memberScope.findDescriptor(qualifierPart)
-                    }
-                    else -> null
-                }
-
-            if (nextPackageOrClassDescriptor == null) return
-            else storeSimpleNameExpression(
-                qualifierPart.expression!!,
-                nextPackageOrClassDescriptor,
-                trace
-            )
-
-            currentDescriptor = nextPackageOrClassDescriptor
-        }
-    }
-
-    private fun storeSimpleNameExpression(
-        expression: KtSimpleNameExpression,
-        descriptor: DeclarationDescriptor,
-        trace: BindingTrace
-    ) {
-        trace.record(BindingContext.REFERENCE_TARGET, expression, descriptor)
-        UnderscoreUsageChecker.checkSimpleNameUsage(descriptor, expression, trace)
-
-        val qualifier = when (descriptor) {
-            is PackageViewDescriptor -> PackageQualifier(expression, descriptor)
-            is ClassDescriptor -> ClassQualifier(expression, descriptor)
-            is TypeParameterDescriptor -> TypeParameterQualifier(expression, descriptor)
-            is TypeAliasDescriptor -> descriptor.classDescriptor?.let {
-                TypeAliasQualifier(expression, descriptor, it)
-            }
-            else -> null
-        }
-
-        if (qualifier != null) {
-            trace.record(BindingContext.QUALIFIER, qualifier.expression, qualifier)
-        }
-    }
-
-    // call resolver extension
-    private fun forceResolveCallForInvoke(
-        calleeType: KotlinType,
-        context: BasicCallResolutionContext
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        val fake = psiFactory.createSimpleName(OperatorNameConventions.INVOKE.asString())
-        val expressionReceiver = ExpressionReceiver.create(
-            fake,
-            calleeType,
-            context.trace.bindingContext
-        )
-        val call = CallTransformer.CallForImplicitInvoke(
-            context.call.explicitReceiver, expressionReceiver, context.call,
-            false
-        )
-        val tracingForInvoke = TracingStrategyForInvoke(fake, call, calleeType)
-        return resolveCallForInvoke(context.replaceCall(call), tracingForInvoke)
-    }
-
-    // callResolver extension
-    private fun resolveCallForInvoke(
-        context: BasicCallResolutionContext,
-        tracing: TracingStrategy
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        return callResolver.computeTasksAndResolveCall<FunctionDescriptor>(
-            context, OperatorNameConventions.INVOKE, tracing,
-            NewResolutionOldInference.ResolutionKind.Invoke
-        )
-    }
-}
-
-// move these to naming conventions???
-const val CHILDREN_KEY = "<children>"
-const val TAG_KEY = "<tag>"
-
-// general utils
-// ==============================
-
-private fun ExpressionTypingContext.withThrowawayTrace(expression: KtExpression) =
-    replaceTraceAndCache(
-        TemporaryTraceAndCache.create(
-            this,
-            "Throwaway trace and cache",
-            expression
-        )
-    )
-
-private val builtIns = DefaultBuiltIns.Instance
-
-fun makeCall(
-    callElement: KtElement,
-    calleeExpression: KtExpression? = null,
-    valueArguments: List<ValueArgument> = emptyList(),
-    receiver: Receiver? = null,
-    dispatchReceiver: ReceiverValue? = null
-): Call {
-    return object : Call {
-        override fun getDispatchReceiver(): ReceiverValue? = dispatchReceiver
-        override fun getValueArgumentList(): KtValueArgumentList? = null
-        override fun getTypeArgumentList(): KtTypeArgumentList? = null
-        override fun getExplicitReceiver(): Receiver? = receiver
-        override fun getCalleeExpression(): KtExpression? = calleeExpression
-        override fun getValueArguments(): List<ValueArgument> = valueArguments
-        override fun getCallElement(): KtElement = callElement
-        override fun getFunctionLiteralArguments(): List<LambdaArgument> = emptyList()
-        override fun getTypeArguments(): List<KtTypeProjection> = emptyList()
-        override fun getCallType(): Call.CallType = Call.CallType.DEFAULT
-        override fun getCallOperationNode(): ASTNode? = null
-    }
-}
-
-private fun functionType(
-    parameterTypes: List<KotlinType> = emptyList(),
-    annotations: Annotations = Annotations.EMPTY,
-    returnType: KotlinType = builtIns.unitType,
-    receiverType: KotlinType? = null
-): KotlinType = createFunctionType(
-    builtIns = builtIns,
-    annotations = annotations,
-    parameterNames = null,
-    parameterTypes = parameterTypes,
-    receiverType = receiverType,
-    returnType = returnType
-)
-
-fun createFunctionDescriptor(
-    type: KotlinType,
-    context: ExpressionTypingContext
-): FunctionDescriptor {
-    return AnonymousFunctionDescriptor(
-        context.scope.ownerDescriptor,
-        Annotations.EMPTY,
-        CallableMemberDescriptor.Kind.SYNTHESIZED,
-        SourceElement.NO_SOURCE,
-        false
-    ).apply {
-        initialize(
-            type.getReceiverTypeFromFunctionType()?.let {
-                DescriptorFactory.createExtensionReceiverParameterForCallable(
-                    this,
-                    it,
-                    Annotations.EMPTY)
-            },
-            null,
-            emptyList(),
-            type.getValueParameterTypesFromFunctionType().mapIndexed { i, t ->
-                ValueParameterDescriptorImpl(
-                    containingDeclaration = this,
-                    original = null,
-                    index = i,
-                    annotations = Annotations.EMPTY,
-                    name = t.type.extractParameterNameFromFunctionTypeArgument()
-                        ?: Name.identifier("p$i"),
-                    outType = t.type,
-                    declaresDefaultValue = false,
-                    isCrossinline = false,
-                    isNoinline = false,
-                    varargElementType = null,
-                    source = SourceElement.NO_SOURCE
-                )
-            },
-            type.getReturnTypeFromFunctionType(),
-            Modality.FINAL,
-            Visibilities.LOCAL,
-            null
-        )
-        isOperator = false
-        isInfix = false
-        isExternal = false
-        isInline = false
-        isTailrec = false
-        isSuspend = false
-        isExpect = false
-        isActual = false
-    }
-}
-
-private fun KotlinType.satisfiesConstraintsOf(T: TypeParameterDescriptor): Boolean {
-    return T.upperBounds.all { isSubtypeOf(it) }
-}
-
-fun KotlinType.satisfiesConstraintsOf(bounds: List<KotlinType>): Boolean {
-    return bounds.all { isSubtypeOf(it) }
-}
-
-// We want to return null in cases where types mismatch, so we use this heuristic to find out. I think there might be a more robust
-// way to find this out, but I'm not sure what it would be
-private fun BindingTrace.hasTypeMismatchErrorsOn(element: KtElement): Boolean =
-    bindingContext.diagnostics.forElement(element).any { it.severity == Severity.ERROR }
-
-private fun KtExpression.asQualifierPartList(): List<QualifiedExpressionResolver.QualifierPart> {
-    val result = SmartList<QualifiedExpressionResolver.QualifierPart>()
-
-    fun addQualifierPart(expression: KtExpression?): Boolean {
-        if (expression is KtSimpleNameExpression) {
-            result.add(
-                QualifiedExpressionResolver.ExpressionQualifierPart(
-                    expression.getReferencedNameAsName(),
-                    expression
-                )
-            )
-            return true
-        }
-        return false
-    }
-
-    var expression: KtExpression? = this
-    while (true) {
-        if (addQualifierPart(expression)) break
-        if (expression !is KtQualifiedExpression) break
-
-        addQualifierPart(expression.selectorExpression)
-
-        expression = expression.receiverExpression
-    }
-
-    return result.asReversed()
-}
-
-private fun HierarchicalScope.findDescriptor(
-    part: QualifiedExpressionResolver.QualifierPart
-): DeclarationDescriptor? {
-    return findFirstFromMeAndParent {
-        it.findVariable(part.name, part.location)
-            ?: it.findFunction(part.name, part.location)
-            ?: it.findClassifier(part.name, part.location)
-    }
-}
-
-private fun MemberScope.findDescriptor(
-    part: QualifiedExpressionResolver.QualifierPart
-): DeclarationDescriptor? {
-    return this.getContributedClassifier(part.name, part.location)
-        ?: getContributedFunctions(part.name, part.location).singleOrNull()
-        ?: getContributedVariables(part.name, part.location).singleOrNull()
-}
-
-private fun KtExpression?.refExpressions(): List<KtReferenceExpression> = when (this) {
-    is KtReferenceExpression -> listOf(this)
-    is KtDotQualifiedExpression ->
-        selectorExpression.refExpressions() + receiverExpression.refExpressions()
-    else -> emptyList()
-}
-
-fun KotlinType.upperBounds(): List<KotlinType> {
-    return if (isTypeParameter()) {
-        TypeUtils.getTypeParameterDescriptorOrNull(this)?.upperBounds ?: emptyList()
-    } else {
-        listOf(this)
-    }
-}
-
-private fun AttributeInfo.toValueArgument(name: String, named: Boolean): ValueArgument {
-    val argumentName = if (named) object : ValueArgumentName {
-        override val asName: Name
-            get() = Name.identifier(name)
-        override val referenceExpression: KtSimpleNameExpression?
-            get() = key
-    } else null
-    return object : ValueArgument {
-        override fun getArgumentExpression() = value
-        override fun getArgumentName() = argumentName
-        override fun isNamed() = named
-        override fun asElement(): KtElement = value
-        override fun getSpreadElement(): LeafPsiElement? = null
-        override fun isExternal() = true
-    }
-}
-
-private fun DeclarationDescriptor.typeAsAttribute() = when (this) {
-    is PropertyDescriptor -> type
-    is ParameterDescriptor -> type
-    is SimpleFunctionDescriptor -> valueParameters.first().type
-    else -> error("unknown descriptor type")
-}
-
-/**
- * This function was copied verbatim from descriptorUtils.kt from ide-common.  For some reason, importing this method into our module
- * would not work and would cause a NoClassDefFound exception.
- */
-private fun descriptorsEqualWithSubstitution(
-    descriptor1: DeclarationDescriptor?,
-    descriptor2: DeclarationDescriptor?,
-    checkOriginals: Boolean = true
-): Boolean {
-    if (descriptor1 == descriptor2) return true
-    if (descriptor1 == null || descriptor2 == null) return false
-    if (checkOriginals && descriptor1.original != descriptor2.original) return false
-    if (descriptor1 !is CallableDescriptor) return true
-    descriptor2 as CallableDescriptor
-
-    val typeChecker = KotlinTypeCheckerImpl.withAxioms(
-        object : KotlinTypeChecker.TypeConstructorEquality {
-            override fun equals(a: TypeConstructor, b: TypeConstructor): Boolean {
-                val typeParam1 = a.declarationDescriptor as? TypeParameterDescriptor
-                val typeParam2 = b.declarationDescriptor as? TypeParameterDescriptor
-                if (typeParam1 != null && typeParam2 != null &&
-                    typeParam1.containingDeclaration == descriptor1 &&
-                    typeParam2.containingDeclaration == descriptor2
-                ) {
-                    return typeParam1.index == typeParam2.index
-                }
-
-                return a == b
-            }
-        }
-    )
-
-    if (!typeChecker.equalTypesOrNulls(descriptor1.returnType, descriptor2.returnType)) return false
-
-    val parameters1 = descriptor1.valueParameters
-    val parameters2 = descriptor2.valueParameters
-    if (parameters1.size != parameters2.size) return false
-    for ((param1, param2) in parameters1.zip(parameters2)) {
-        if (!typeChecker.equalTypes(param1.type, param2.type)) return false
-    }
-    // NOTE(lmr): edit
-    // this check was added
-    if (descriptor1.javaClass !== descriptor2.javaClass) return false
-    // NOTE(lmr): /end
-    return true
-}
-
-// trace util
-// ========================
-private fun referenceCopyingTrace(
-    from: KtExpression,
-    to: KtExpression,
-    trace: TemporaryBindingTrace
-): BindingTrace {
-    val openTagExpressions = from.refExpressions()
-    val closeTagExpressions = to.refExpressions()
-
-    if (openTagExpressions.size != closeTagExpressions.size) return trace
-
-    val elMap = openTagExpressions.zip(closeTagExpressions).toMap()
-
-    val observableTrace = ObservableBindingTrace(trace)
-
-    observableTrace.addHandler(BindingContext.REFERENCE_TARGET) { _, key, value ->
-        val otherRefExpr = elMap[key]
-        if (otherRefExpr != null) {
-            trace.record(
-                BindingContext.REFERENCE_TARGET,
-                otherRefExpr,
-                value
-            )
-        }
-    }
-
-    return observableTrace
-}
-
-private fun copyReferences(
-    fromTrace: TemporaryBindingTrace,
-    toTrace: BindingTrace,
-    element: KtExpression
-) {
-    val references = element.refExpressions()
-    val filter = TraceEntryFilter { slice, key ->
-        slice === BindingContext.REFERENCE_TARGET && key in references
-    }
-    fromTrace.addOwnDataTo(toTrace, filter, false)
-}
-
-// util classes
-// ========================
-private class ImplicitCtorValueArgument(val type: KotlinType) : ValueArgument {
-    override fun getArgumentExpression(): KtExpression? = null
-    override fun getArgumentName(): ValueArgumentName? = null
-    override fun isNamed(): Boolean = false
-    override fun asElement(): KtElement = error("tried to get element")
-    override fun getSpreadElement(): LeafPsiElement? = null
-    override fun isExternal(): Boolean = true
-}
-
-class AttributeInfo(
-    val value: KtExpression,
-    val key: KtSimpleNameExpression?,
-    val name: String,
-    val isPunned: Boolean
-)
-
-private sealed class ResolveStep(
-    private val attributes: Set<String>,
-    private val isValid: Boolean,
-    private val trail: IntArray,
-    val errorNode: ErrorNode?
-) {
-    class Root(
-        val openExpr: KtExpression,
-        val closeExpr: KtExpression?
-    ) : ResolveStep(emptySet(), true, intArrayOf(1, 1, 1), null)
-
-    class Nested(
-        val calleeType: KotlinType,
-        val nonMemoizedCall: NonMemoizedCallNode?,
-        val isStaticCall: Boolean,
-        val parent: ResolveStep,
-        attributes: Set<String>,
-        isValid: Boolean,
-        trail: IntArray,
-        errorNode: ErrorNode?
-    ) : ResolveStep(attributes, isValid, trail, errorNode) {
-        fun constructNonMemoizedCallLinkedList(): NonMemoizedCallNode? {
-            return nonMemoizedCall?.let { parent.constructNonMemoizedCallLinkedList(it) }
-        }
-    }
-
-    fun recurse(
-        calleeType: KotlinType,
-        nonMemoizedCall: NonMemoizedCallNode?,
-        isStaticCall: Boolean,
-        resolvedCall: ResolvedCall<*>,
-        specifiedAttributes: Set<String>
-    ): ResolveStep {
-        val possibleAttributes = resolvedCall.resultingDescriptor.valueParameters.map {
-            it.name.asString()
-        }.toSet()
-        var errorNode: ErrorNode? = null
-        // steps in the recursion cannot define attributes that conflict with previous steps
-        val intersection = attributes.intersect(possibleAttributes)
-        val hasDuplicates = intersection.isNotEmpty()
-
-        if (hasDuplicates) {
-            // TODO(lmr): it would be nice if we also grabbed the descriptors that these attributes were on
-            errorNode = ErrorNode.RecursionLimitAmbiguousAttributesError(intersection)
-        }
-
-        // we require that at least one of the last three steps has had an attribute that was used.
-        // we could tweak this. Potentially the "hasDuplicates" test is more than enough to prevent
-        // infinite recursion.
-        val nextTrail = intArrayOf(trail[1], trail[2], specifiedAttributes.size)
-        val trailIsValid = nextTrail.sum() > 0
-
-        if (!trailIsValid) {
-            errorNode = ErrorNode.RecursionLimitError()
-        }
-
-        return Nested(
-            calleeType = calleeType,
-            nonMemoizedCall = nonMemoizedCall,
-            isStaticCall = isStaticCall,
-            parent = this,
-            attributes = attributes + possibleAttributes,
-            isValid = !hasDuplicates && trailIsValid,
-            trail = nextTrail,
-            errorNode = errorNode
-        )
-    }
-
-    fun constructNonMemoizedCallLinkedList(
-        nonMemoizedCall: NonMemoizedCallNode
-    ): NonMemoizedCallNode {
-        var call = nonMemoizedCall
-        var node = this
-        while (node is Nested) {
-            val prevCall = node.nonMemoizedCall ?: break
-            node = node.parent
-            call = NonMemoizedCallNode(
-                resolvedCall = prevCall.resolvedCall,
-                params = prevCall.params,
-                applyCall = prevCall.applyCall,
-                applyLambdaDescriptor = prevCall.applyLambdaDescriptor,
-                postAssignments = prevCall.postAssignments,
-                applyLambdaType = prevCall.applyLambdaType,
-                nextCall = call
-            )
-        }
-        return call
-    }
-
-    fun canRecurse(): Boolean = isValid
-}
-
-// static checking
-// ==========================
-private fun isStatic(
-    expression: KtExpression,
-    context: ExpressionTypingContext,
-    expectedType: KotlinType?,
-    constantChecker: ConstantExpressionEvaluator
-): Boolean {
-    val constValue = constantChecker.evaluateExpression(expression, context.trace, expectedType)
-    return constValue != null
-}
-
-private fun isStaticTag(
-    step: ResolveStep,
-    resolvedCall: ResolvedCall<*>,
-    context: ExpressionTypingContext
-): Boolean {
-    return when (step) {
-        is ResolveStep.Root -> when (step.openExpr) {
-            is KtQualifiedExpression -> {
-                val parts = step.openExpr.asQualifierPartList()
-                val targets = parts
-                    .mapNotNull { it.expression }
-                    .mapNotNull { context.trace[BindingContext.REFERENCE_TARGET, it] }
-
-                if (parts.size != targets.size) return false
-
-                val first = targets.first()
-
-                if (!first.isRoot()) return false
-
-                for (target in targets) {
-                    val isValid = isValidStaticQualifiedPart(target)
-                    if (!isValid)
-                        return false
-                }
-                // TODO(lmr): is there more we need to do here?
-                return true
-            }
-            is KtSimpleNameExpression -> {
-                when (resolvedCall) {
-                    is VariableAsFunctionResolvedCall -> {
-                        val variableDescriptor = resolvedCall.variableCall.candidateDescriptor
-                        if (variableDescriptor.isVar) return false
-                        if (variableDescriptor.isConst) return true
-                        val isRoot = variableDescriptor.isRoot()
-                        when (variableDescriptor) {
-                            is PropertyDescriptor ->
-                                (variableDescriptor.getter?.isDefault ?: false) && isRoot
-                            else -> false
-                        }
-                    }
-                    else -> true
-                }
-            }
-            else -> false
-        }
-        is ResolveStep.Nested -> step.isStaticCall
-    }
-}
-
-private fun isValidStaticQualifiedPart(target: DeclarationDescriptor): Boolean {
-    return when (target) {
-        is ClassDescriptor -> when {
-            target.kind == ClassKind.OBJECT -> true
-            target.isCompanionObject -> true
-            else -> false
-        }
-        is ClassConstructorDescriptor -> true
-        is PropertyDescriptor -> when {
-            target.isVar -> false
-            target.isConst -> true
-            target.getter?.isDefault == true -> true
-            else -> false
-        }
-        is FieldDescriptor -> isValidStaticQualifiedPart(target.correspondingProperty)
-        is SimpleFunctionDescriptor -> true
-        else -> {
-            false
-        }
-    }
-}
-
-private fun isStable(type: KotlinType?, context: ExpressionTypingContext): Boolean {
-    return type?.let {
-        val trace = context.trace
-        val calculated = trace.get(STABLE_TYPE, it)
-        if (calculated == null) {
-            val isStable = !it.isError && !it.isSpecialType && (
-                    KotlinBuiltIns.isPrimitiveType(it) ||
-                    it.isFunctionType ||
-                    it.isMarkedStable() ||
-                            (type.isNullable() && isStable(it.makeNotNullable(), context)))
-            trace.record(STABLE_TYPE, it, isStable)
-            isStable
-        } else calculated
-    } ?: false
-}
-
-private fun DeclarationDescriptor.isRoot() =
-    containingDeclaration?.containingDeclaration is ModuleDescriptor
-
-private fun BindingTrace.recordAttributeKeyRef(expr: KtExpression?, value: DeclarationDescriptor) {
-    val key = expr as? KtReferenceExpression ?: error("expected a KtReferenceExpression")
-    val prev = get(ComposeWritableSlices.ATTRIBUTE_KEY_REFERENCE_TARGET, key) ?: emptySet()
-    record(ComposeWritableSlices.ATTRIBUTE_KEY_REFERENCE_TARGET, key, prev + value)
-}
-
-private fun BindingTrace.recordFailedCandidates(
-    expr: KtElement,
-    results: Collection<ResolvedCall<FunctionDescriptor>>?
-) {
-    if (results == null) return
-    val prev = get(ComposeWritableSlices.FAILED_CANDIDATES, expr) ?: emptyList()
-    record(ComposeWritableSlices.FAILED_CANDIDATES, expr, prev + results)
-}
-
-enum class ComposerCallKind { CALL, EMIT }
-
-private val ResolvedCall<*>.semanticCall: ResolvedCall<*>
-    get() = when (this) {
-        is VariableAsFunctionResolvedCall -> variableCall
-        else -> this
-    }
-
-private val Collection<ValueParameterDescriptor>.possibleChildrenParameter:
-        ValueParameterDescriptor?
-    get() = maxBy { it.index }?.let { if (it.type.isFunctionType) it else null }
-
-class NoInterceptionCallResolver(private val callResolver: CallResolver) {
-    fun resolveCallWithGivenName(
-        context: ResolutionContext<*>,
-        call: Call,
-        name: Name,
-        tracing: TracingStrategy
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        context.trace.record(IGNORE_COMPOSABLE_INTERCEPTION, call, true)
-        return callResolver.resolveCallWithGivenName(
-            context,
-            call,
-            name,
-            tracing
-        )
-    }
-
-    fun resolveCallWithGivenName(
-        context: ResolutionContext<*>,
-        call: Call,
-        functionReference: KtReferenceExpression,
-        name: Name
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        context.trace.record(IGNORE_COMPOSABLE_INTERCEPTION, call, true)
-        return callResolver.resolveCallWithGivenName(
-            context,
-            call,
-            functionReference,
-            name
-        )
-    }
-
-    fun resolveCallWithKnownCandidate(
-        call: Call,
-        tracing: TracingStrategy,
-        context: ResolutionContext<*>,
-        candidate: ResolutionCandidate<FunctionDescriptor>,
-        dataFlowInfoForArguments: MutableDataFlowInfoForArguments?
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        context.trace.record(IGNORE_COMPOSABLE_INTERCEPTION, call, true)
-        return callResolver.resolveCallWithKnownCandidate(
-            call,
-            tracing,
-            context,
-            candidate,
-            dataFlowInfoForArguments
-        )
-    }
-
-    fun resolveSimpleProperty(
-        context: BasicCallResolutionContext
-    ): OverloadResolutionResults<VariableDescriptor> {
-        return callResolver.resolveSimpleProperty(
-            context
-        )
-    }
-
-    fun resolveFunctionCall(
-        context: BasicCallResolutionContext
-    ): OverloadResolutionResults<FunctionDescriptor> {
-        context.trace.record(IGNORE_COMPOSABLE_INTERCEPTION, context.call, true)
-        return callResolver.resolveFunctionCall(
-            context
-        )
-    }
-
-    fun <T : CallableDescriptor> computeTasksAndResolveCall(
-        context: BasicCallResolutionContext,
-        name: Name,
-        tracing: TracingStrategy,
-        kind: NewResolutionOldInference.ResolutionKind
-    ): OverloadResolutionResults<T> {
-        context.trace.record(IGNORE_COMPOSABLE_INTERCEPTION, context.call, true)
-        return callResolver.computeTasksAndResolveCall(
-            context,
-            name,
-            tracing,
-            kind
-        )
-    }
-
-    fun <T : CallableDescriptor> computeTasksAndResolveCall(
-        context: BasicCallResolutionContext,
-        name: Name,
-        referenceExpression: KtReferenceExpression,
-        kind: NewResolutionOldInference.ResolutionKind
-    ): OverloadResolutionResults<T> {
-        context.trace.record(IGNORE_COMPOSABLE_INTERCEPTION, context.call, true)
-        return callResolver.computeTasksAndResolveCall(
-            context,
-            name,
-            referenceExpression,
-            kind
-        )
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ResolvedKtxElementCall.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ResolvedKtxElementCall.kt
deleted file mode 100644
index 5c0eb78..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ResolvedKtxElementCall.kt
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.backend.common.push
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
-import org.jetbrains.kotlin.renderer.DescriptorRenderer
-import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy
-import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
-import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
-
-sealed class ValueNode(
-    val name: String,
-    val type: KotlinType,
-    val descriptor: DeclarationDescriptor
-)
-
-class DefaultValueNode(
-    name: String,
-    type: KotlinType,
-    descriptor: DeclarationDescriptor
-) : ValueNode(name, type, descriptor)
-
-class ImplicitCtorValueNode(
-    name: String,
-    type: KotlinType,
-    descriptor: DeclarationDescriptor
-) : ValueNode(name, type, descriptor) {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (javaClass != other?.javaClass) return false
-
-        other as ImplicitCtorValueNode
-
-        if (name != other.name) return false
-
-        return true
-    }
-
-    override fun hashCode(): Int {
-        return name.hashCode()
-    }
-}
-
-class AttributeNode(
-    name: String,
-    var isStatic: Boolean,
-    var isStable: Boolean,
-    val expression: KtExpression,
-    type: KotlinType,
-    descriptor: DeclarationDescriptor
-) : ValueNode(name, type, descriptor) {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (javaClass != other?.javaClass) return false
-
-        other as AttributeNode
-
-        if (name != other.name) return false
-
-        return true
-    }
-
-    override fun hashCode(): Int {
-        return name.hashCode()
-    }
-}
-
-enum class ValidationType {
-    CHANGED,
-    SET,
-    UPDATE
-}
-
-class ValidatedAssignment(
-    val validationType: ValidationType,
-    val validationCall: ResolvedCall<*>?,
-    val uncheckedValidationCall: ResolvedCall<*>?,
-    val assignment: ResolvedCall<*>?,
-    val assignmentLambda: FunctionDescriptor?,
-    val attribute: AttributeNode
-)
-
-private fun getParamFnDescriptorFromCall(
-    name: Name,
-    call: ResolvedCall<*>?,
-    context: ExpressionTypingContext
-): FunctionDescriptor? {
-    val param = call?.resultingDescriptor?.valueParameters?.firstOrNull {
-        it.name == name
-    } ?: return null
-    return createFunctionDescriptor(param.type, context)
-}
-
-class ComposerCallInfo(
-    context: ExpressionTypingContext,
-    val composerCall: ResolvedCall<*>?,
-    val pivotals: List<AttributeNode>,
-    val joinKeyCall: ResolvedCall<*>?,
-    val ctorCall: ResolvedCall<*>?,
-    val ctorParams: List<ValueNode>,
-    val validations: List<ValidatedAssignment>
-) {
-    val emitCtorFnDescriptor =
-        getParamFnDescriptorFromCall(
-            KtxNameConventions.EMIT_CTOR_PARAMETER,
-            composerCall,
-            context
-        )
-    val emitUpdaterFnDescriptor =
-        getParamFnDescriptorFromCall(
-            KtxNameConventions.EMIT_UPDATER_PARAMETER,
-            composerCall,
-            context
-        )
-    val emitBodyFnDescriptor =
-        getParamFnDescriptorFromCall(
-            KtxNameConventions.EMIT_CHILDREN_PARAMETER,
-            composerCall,
-            context
-        )
-    val callCtorFnDescriptor =
-        getParamFnDescriptorFromCall(
-            KtxNameConventions.CALL_CTOR_PARAMETER,
-            composerCall,
-            context
-        )
-    val callInvalidFnDescriptor =
-        getParamFnDescriptorFromCall(
-            KtxNameConventions.CALL_INVALID_PARAMETER,
-            composerCall,
-            context
-        )
-    val callBlockFnDescriptor =
-        getParamFnDescriptorFromCall(
-            KtxNameConventions.CALL_BLOCK_PARAMETER,
-            composerCall,
-            context
-        )
-
-    fun allAttributes(): List<ValueNode> =
-        ctorParams.filter { it !is ImplicitCtorValueNode } + validations.map { it.attribute }
-}
-
-class AttributeMeta(
-    val name: String,
-    val type: KotlinType,
-    val isChildren: Boolean,
-    val descriptor: DeclarationDescriptor
-)
-
-sealed class EmitOrCallNode {
-    abstract fun allAttributes(): List<ValueNode>
-    abstract fun print(): String
-
-    inline fun <T> collect(visitor: (EmitOrCallNode) -> T?): List<T> {
-        val results = mutableListOf<T>()
-        var node: EmitOrCallNode? = this
-        while (node != null) {
-            visitor(node)?.let { results.add(it) }
-            node = when (node) {
-                is MemoizedCallNode -> node.call
-                is NonMemoizedCallNode -> node.nextCall
-                is EmitCallNode -> null
-                is ErrorNode -> null
-            }
-        }
-        return results
-    }
-
-    fun resolvedCalls(): List<ResolvedCall<*>> {
-        return when (this) {
-            is MemoizedCallNode -> listOfNotNull(memoize.ctorCall) + call.resolvedCalls()
-            is NonMemoizedCallNode ->
-                listOf(resolvedCall) + (nextCall?.resolvedCalls() ?: emptyList())
-            is EmitCallNode -> listOfNotNull(memoize.ctorCall)
-            is ErrorNode.ResolveError -> results.allCandidates?.toList() ?: emptyList()
-            is ErrorNode -> emptyList()
-        }
-    }
-
-    fun allPossibleAttributes(): Map<String, List<AttributeMeta>> {
-        val collector = mutableMapOf<String, MutableList<AttributeMeta>>()
-        collectPossibleAttributes(collector)
-        return collector
-    }
-
-    private fun collectPossibleAttributes(
-        collector: MutableMap<String, MutableList<AttributeMeta>>
-    ) {
-        when (this) {
-            is ErrorNode -> Unit
-            is MemoizedCallNode -> {
-                collectPossibleAttributes(
-                    memoize.ctorCall?.resultingDescriptor as? FunctionDescriptor, collector
-                )
-                call.collectPossibleAttributes(collector)
-            }
-            is NonMemoizedCallNode -> {
-                collectPossibleAttributes(
-                    resolvedCall.resultingDescriptor as? FunctionDescriptor, collector
-                )
-                nextCall?.collectPossibleAttributes(collector)
-            }
-            is EmitCallNode -> {
-                collectPossibleAttributes(
-                    memoize.ctorCall?.resultingDescriptor as? FunctionDescriptor, collector
-                )
-            }
-        }
-    }
-
-    private fun collectPossibleAttributes(
-        callDescriptor: FunctionDescriptor?,
-        collector: MutableMap<String, MutableList<AttributeMeta>>
-    ) {
-        callDescriptor?.let {
-            it.valueParameters.forEachIndexed { index, param ->
-                collector.multiPut(
-                    AttributeMeta(
-                        name = param.name.asString(),
-                        type = param.type,
-                        descriptor = param,
-                        isChildren = param.hasChildrenAnnotation() ||
-                                it.valueParameters.size - 1 == index
-                    )
-                )
-            }
-        }
-        callDescriptor?.returnType?.let { type ->
-            val cls = type.constructor.declarationDescriptor as? ClassDescriptor ?: return
-            cls.unsubstitutedMemberScope.getContributedDescriptors().forEach {
-                when (it) {
-                    is SimpleFunctionDescriptor -> {
-                        if (ComposeUtils.isSetterMethodName(
-                                it.name.asString()
-                            ) && it.valueParameters.size == 1) {
-                            val name = ComposeUtils.propertyNameFromSetterMethod(it.name.asString())
-                            collector.multiPut(
-                                AttributeMeta(
-                                    name = name,
-                                    type = it.valueParameters.first().type,
-                                    descriptor = it,
-                                    isChildren = it.hasChildrenAnnotation()
-                                )
-                            )
-                        }
-                    }
-                    is PropertyDescriptor -> {
-                        collector.multiPut(
-                            AttributeMeta(
-                                name = it.name.asString(),
-                                type = it.type,
-                                descriptor = it,
-                                isChildren = it.hasChildrenAnnotation()
-                            )
-                        )
-                    }
-                }
-            }
-        }
-    }
-
-    fun errorNode(): ErrorNode? {
-        return when (this) {
-            is ErrorNode -> this
-            is MemoizedCallNode -> call.errorNode()
-            is NonMemoizedCallNode -> nextCall?.errorNode()
-            is EmitCallNode -> null
-        }
-    }
-}
-
-sealed class CallNode : EmitOrCallNode()
-
-sealed class ErrorNode : EmitOrCallNode() {
-    override fun allAttributes(): List<ValueNode> = emptyList()
-    override fun print(): String = "<ERROR:${javaClass.simpleName}>"
-
-    class NonEmittableNonCallable(val type: KotlinType) : ErrorNode()
-    class RecursionLimitAmbiguousAttributesError(val attributes: Set<String>) : ErrorNode()
-    class RecursionLimitError : ErrorNode()
-    class NonCallableRoot : ErrorNode()
-    class ResolveError(val results: OverloadResolutionResults<FunctionDescriptor>) : ErrorNode()
-}
-
-class NonMemoizedCallNode(
-    val resolvedCall: ResolvedCall<*>,
-    val params: List<ValueNode>,
-    val postAssignments: List<ValidatedAssignment>,
-    val applyCall: ResolvedCall<*>?,
-    val applyLambdaDescriptor: FunctionDescriptor?,
-    val applyLambdaType: KotlinType?,
-    var nextCall: EmitOrCallNode?
-) : CallNode() {
-    override fun allAttributes(): List<ValueNode> = params
-    override fun print(): String = buildString {
-        self("NonMemoizedCallNode")
-        attr("resolvedCall", resolvedCall) { it.print() }
-        attr("params", params) { it.print() }
-        list("postAssignments", postAssignments) { it.print() }
-        attr("nextCall", nextCall) { it.print() }
-    }
-}
-
-class MemoizedCallNode(
-    val memoize: ComposerCallInfo,
-    val call: EmitOrCallNode
-) : CallNode() {
-    override fun allAttributes(): List<ValueNode> = call.allAttributes() + memoize.allAttributes()
-    override fun print(): String = buildString {
-        self("MemoizedCallNode")
-        attr("memoize", memoize) { it.print() }
-        attr("call", call) { it.print() }
-    }
-}
-
-class EmitCallNode(
-    val memoize: ComposerCallInfo,
-    val inlineChildren: KtExpression?
-) : EmitOrCallNode() {
-    override fun allAttributes(): List<ValueNode> = memoize.allAttributes()
-    override fun print() = buildString {
-        self("EmitCallNode")
-        attr("memoize", memoize) { it.print() }
-    }
-}
-
-class ResolvedKtxElementCall(
-    val usedAttributes: List<AttributeNode>,
-    val unusedAttributes: List<String>,
-    val emitOrCall: EmitOrCallNode,
-    val getComposerCall: ResolvedCall<*>?,
-    val emitSimpleUpperBoundTypes: Set<KotlinType>,
-    val emitCompoundUpperBoundTypes: Set<KotlinType>,
-    val infixOrCall: ResolvedCall<*>?,
-    val attributeInfos: Map<String, AttributeInfo>
-)
-
-class ResolvedRestartCalls(
-    val composer: ResolvedCall<*>,
-    val startRestartGroup: ResolvedCall<*>,
-    val endRestartGroup: ResolvedCall<*>
-)
-
-fun ComposerCallInfo?.consumedAttributes(): List<AttributeNode> {
-    if (this == null) return emptyList()
-    return pivotals +
-            ctorParams.mapNotNull { it as? AttributeNode } +
-            validations.map { it.attribute }
-}
-
-fun EmitOrCallNode?.consumedAttributes(): List<AttributeNode> {
-    return when (this) {
-        is MemoizedCallNode -> memoize.consumedAttributes() + call.consumedAttributes()
-        is NonMemoizedCallNode ->
-            params.mapNotNull { it as? AttributeNode } + nextCall.consumedAttributes()
-        is EmitCallNode -> memoize.consumedAttributes()
-        is ErrorNode -> emptyList()
-        null -> emptyList()
-    }
-}
-
-val EmitOrCallNode.primaryCall: ResolvedCall<*>?
-    get() = when (this) {
-        is MemoizedCallNode -> memoize.ctorCall ?: call.primaryCall
-        is NonMemoizedCallNode -> resolvedCall
-        is EmitCallNode -> memoize.ctorCall
-        is ErrorNode -> null
-    }
-
-fun List<ValueNode>.print(): String {
-    return if (isEmpty()) "<empty>"
-    else joinToString(", ") { it.print() }
-}
-
-fun ValueNode.print(): String = when (this) {
-    is AttributeNode -> name
-    is ImplicitCtorValueNode -> "(implicit)$name"
-    is DefaultValueNode -> "(default)$name"
-}
-
-fun ResolvedKtxElementCall.print() = buildString {
-    self("ResolvedKtxElementCall")
-    attr("emitOrCall", emitOrCall) { it.print() }
-    attr("usedAttributes", usedAttributes) { it.print() }
-    attr("unusedAttributes", unusedAttributes) {
-        it.joinToString(separator = ", ").let { s -> if (s.isBlank()) "<empty>" else s }
-    }
-}
-
-fun ComposerCallInfo.print() = buildString {
-    self("ComposerCallInfo")
-    attr("composerCall", composerCall) { it.print() }
-    attr("pivotals", pivotals) { it.print() }
-    attr("joinKeyCall", joinKeyCall) { it.print() }
-    attr("ctorCall", ctorCall) { it.print() }
-    attr("ctorParams", ctorParams) { it.print() }
-    list("validations", validations) { it.print() }
-}
-
-fun AttributeNode.print() = name
-fun ResolvedCall<*>.print() = DESC_RENDERER.render(resultingDescriptor)
-fun ValidatedAssignment.print() = buildString {
-    self("ValidatedAssignment(${validationType.name})")
-    attr("validationCall", validationCall) { it.print() }
-    attr("assignment", assignment) { it.print() }
-    attr("attribute", attribute) { it.print() }
-}
-
-val DESC_RENDERER = DescriptorRenderer.COMPACT_WITHOUT_SUPERTYPES.withOptions {
-    parameterNamesInFunctionalTypes = false
-    renderConstructorKeyword = false
-    classifierNamePolicy = ClassifierNamePolicy.SHORT
-    includeAdditionalModifiers = false
-    unitReturnType = false
-    withoutTypeParameters = true
-    parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE
-    defaultParameterValueRenderer = null
-    renderUnabbreviatedType = false
-}
-
-fun StringBuilder.self(name: String) {
-    append(name)
-    appendln(":")
-}
-
-fun <T> StringBuilder.attr(name: String, obj: T?, printer: (T) -> String) {
-    append("  ")
-    append(name)
-    append(" = ")
-    if (obj == null) {
-        appendln("<null>")
-    } else {
-        appendln(printer(obj).indentExceptFirstLine("  ").trim())
-    }
-}
-
-fun String.indentExceptFirstLine(indent: String = "    "): String =
-    lineSequence()
-        .drop(1)
-        .map {
-            when {
-                it.isBlank() -> {
-                    when {
-                        it.length < indent.length -> indent
-                        else -> it
-                    }
-                }
-                else -> indent + it
-            }
-        }
-        .joinToString("\n", prefix = lineSequence().first() + "\n")
-
-fun <T> StringBuilder.list(name: String, obj: Collection<T>, printer: (T) -> String) {
-    append("  ")
-    append(name)
-    if (obj.isEmpty()) {
-        appendln(" = <empty>")
-    } else {
-        appendln(" =")
-        obj.forEach {
-            append("    - ")
-            appendln(printer(it).indentExceptFirstLine("      ").trim())
-        }
-    }
-}
-
-private fun <T, V> MutableMap<T, MutableList<V>>.multiPut(key: T, value: V) {
-    val current = get(key)
-    if (current != null) {
-        current.push(value)
-    } else {
-        put(key, mutableListOf(value))
-    }
-}
-
-private fun MutableMap<String, MutableList<AttributeMeta>>.multiPut(value: AttributeMeta) {
-    multiPut(value.name, value)
-    if (value.isChildren) {
-        multiPut(CHILDREN_KEY, value)
-    }
-}
-
-/*
-
-fun ResolvedCall<*>.printCode(params: List<AttributeNode>): String {
-    return ""
-}
-
-fun ValidatedAssignment.printCode(): String {
-    val name = attribute.name
-    var result = "${validationType.name.toLowerCase()}($name)"
-    when (validationType) {
-        ValidationType.UPDATE -> {
-            result += " { $name = it }"
-        }
-        ValidationType.SET -> {
-            result += " { $name = it }"
-        }
-        ValidationType.CHANGED -> Unit
-    }
-    return result
-}
-
-fun ComposerCallInfo.printCode(methodName: String, itName: String, block: StringBuilder.() -> Unit) = buildString {
-    append(methodName)
-    append("(")
-    val joinKey = (listOf("#k") + pivotals.map { it.name }).joinToString(
-        separator = ",",
-        prefix = "jk(",
-        postfix = ")"
-    )
-    val ctor = if (ctorCall == null) "null"
-    else "{ ${ctorCall.printCode(ctorParams)} }"
-
-    val invalid = validations.joinToString(
-        separator = " + ",
-        prefix = "{ ",
-        postfix = " }",
-        transform = ValidatedAssignment::printCode
-    )
-
-    appendln("call($joinKey, $ctor, $invalid) { $itName ->")
-    val sb = StringBuilder()
-    sb.block()
-    appendln(sb.toString().prependIndent("  ").trim())
-    appendln("}")
-
-}
-
-fun ResolvedKtxElementCall.printCode() = buildString {
-    when (emitOrCall) {
-        is MemoizedCallNode -> {
-            append(emitOrCall.memoize?.printCode("call", "f") {
-                append("f()")
-            })
-        }
-        is NonMemoizedCallNode -> {
-
-        }
-        is EmitCallNode -> {
-
-        }
-    }
-}
-
-*/
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Stateful.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ResolvedRestartCalls.kt
similarity index 70%
rename from compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Stateful.kt
rename to compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ResolvedRestartCalls.kt
index 49d29f8..9bf1eaa 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Stateful.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ResolvedRestartCalls.kt
@@ -14,14 +14,12 @@
  * limitations under the License.
  */
 
-package androidx.compose
+package androidx.compose.plugins.kotlin
 
-/**
- * @suppress
- */
-@Target(
-    AnnotationTarget.FUNCTION,
-    AnnotationTarget.CLASS,
-    AnnotationTarget.ANNOTATION_CLASS
-)
-annotation class Stateful
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+
+class ResolvedRestartCalls(
+    val composer: ResolvedCall<*>,
+    val startRestartGroup: ResolvedCall<*>,
+    val endRestartGroup: ResolvedCall<*>
+)
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/StaticWrapperCreatorFunctionResolveExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/StaticWrapperCreatorFunctionResolveExtension.kt
deleted file mode 100644
index add0f33..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/StaticWrapperCreatorFunctionResolveExtension.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
-import org.jetbrains.kotlin.name.Name
-import androidx.compose.plugins.kotlin.analysis.ComponentMetadata
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
-import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
-import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
-
-class StaticWrapperCreatorFunctionResolveExtension() : SyntheticResolveExtension {
-
-    override fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? {
-        return if (ComponentMetadata.isComposeComponent(thisDescriptor))
-            Name.identifier("R4HStaticRenderCompanion")
-        else null
-    }
-
-    override fun generateSyntheticClasses(
-        thisDescriptor: ClassDescriptor,
-        name: Name,
-        ctx: LazyClassContext,
-        declarationProvider: ClassMemberDeclarationProvider,
-        result: MutableSet<ClassDescriptor>
-    ) {
-        super.generateSyntheticClasses(thisDescriptor, name, ctx, declarationProvider, result)
-
-        if (ComponentMetadata.isComposeComponent(thisDescriptor)) {
-            val wrapperViewDescriptor =
-                ComponentMetadata.fromDescriptor(thisDescriptor).wrapperViewDescriptor
-            if (wrapperViewDescriptor.name == name) result.add(wrapperViewDescriptor)
-        }
-    }
-
-    override fun generateSyntheticMethods(
-        thisDescriptor: ClassDescriptor,
-        name: Name,
-        bindingContext: BindingContext,
-        fromSupertypes: List<SimpleFunctionDescriptor>,
-        result: MutableCollection<SimpleFunctionDescriptor>
-    ) {
-        if (!ComponentMetadata.isComponentCompanion(thisDescriptor)) return
-        if (name != Name.identifier("createInstance")) return
-
-        val containingClass = thisDescriptor.containingDeclaration as? ClassDescriptor ?: return
-        val wrapperView = ComponentMetadata.fromDescriptor(containingClass).wrapperViewDescriptor
-        result.add(wrapperView.getInstanceCreatorFunction(thisDescriptor))
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/TryCatchComposableChecker.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/TryCatchComposableChecker.kt
index 3466b42..9cc10a1 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/TryCatchComposableChecker.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/TryCatchComposableChecker.kt
@@ -16,15 +16,14 @@
 
 package androidx.compose.plugins.kotlin
 
+import androidx.compose.plugins.kotlin.analysis.ComposeDefaultErrorMessages
+import androidx.compose.plugins.kotlin.analysis.ComposeErrors
 import com.intellij.psi.PsiElement
 import org.jetbrains.kotlin.container.StorageComponentContainer
 import org.jetbrains.kotlin.container.useInstance
 import org.jetbrains.kotlin.descriptors.ModuleDescriptor
 import org.jetbrains.kotlin.diagnostics.reportFromPlugin
 import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
-import org.jetbrains.kotlin.psi.KtFunction
-import androidx.compose.plugins.kotlin.analysis.ComposeDefaultErrorMessages
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
 import org.jetbrains.kotlin.platform.TargetPlatform
 import org.jetbrains.kotlin.platform.jvm.isJvm
 import org.jetbrains.kotlin.psi.KtTryExpression
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ValidatedAssignment.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ValidatedAssignment.kt
new file mode 100644
index 0000000..2272ab9
--- /dev/null
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ValidatedAssignment.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.plugins.kotlin
+
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.descriptors.FunctionDescriptor
+import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
+import org.jetbrains.kotlin.types.KotlinType
+
+class ValidatedAssignment(
+    val validationType: ValidationType,
+    val validationCall: ResolvedCall<*>?,
+    val uncheckedValidationCall: ResolvedCall<*>?,
+    val assignment: ResolvedCall<*>?,
+    val assignmentLambda: FunctionDescriptor?, // needed?
+    val type: KotlinType,
+    val name: String,
+    val descriptor: DeclarationDescriptor
+)
+
+enum class ValidationType {
+    CHANGED,
+    SET,
+    UPDATE
+}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/WrapperViewSettersGettersResolveExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/WrapperViewSettersGettersResolveExtension.kt
deleted file mode 100644
index 08c84dd..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/WrapperViewSettersGettersResolveExtension.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
-import org.jetbrains.kotlin.name.Name
-import androidx.compose.plugins.kotlin.analysis.ComponentMetadata
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
-
-class WrapperViewSettersGettersResolveExtension : SyntheticResolveExtension {
-    override fun generateSyntheticMethods(
-        thisDescriptor: ClassDescriptor,
-        name: Name,
-        bindingContext: BindingContext,
-        fromSupertypes: List<SimpleFunctionDescriptor>,
-        result: MutableCollection<SimpleFunctionDescriptor>
-    ) {
-        if (!ComponentMetadata.isWrapperView(thisDescriptor)) return
-
-        result.addAll((thisDescriptor as GeneratedViewClassDescriptor).attributeSetters)
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComponentMetadata.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComponentMetadata.kt
deleted file mode 100644
index f9355d4..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComponentMetadata.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-package androidx.compose.plugins.kotlin.analysis
-
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.Visibilities
-import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import androidx.compose.plugins.kotlin.GeneratedViewClassDescriptor
-import androidx.compose.plugins.kotlin.ComposeUtils
-import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
-import org.jetbrains.kotlin.resolve.descriptorUtil.module
-
-/**
- * ComponentMetadata takes in a DeclarationDescriptor and interprets it as a component.
- * All assumptions about the Component API (public and private) should reside in this class.
- *
- * A ComponentMetadata can be used to get Compose synthetic method descriptors on a component,
- * as well as descriptors for the various synthetic helper classes.
- */
-class ComponentMetadata(val descriptor: ClassDescriptor) {
-    // TODO(lmr): ClassDescriptor won't handle SFCs. Consider how to refactor.
-
-    val wrapperViewDescriptor by lazy {
-        GeneratedViewClassDescriptor(this)
-    }
-
-    init {
-        if (!isComposeComponent(
-                descriptor
-            )
-        )
-            throw IllegalArgumentException("Not a component: " + descriptor::class)
-    }
-
-    companion object {
-        // Use DeclarationDescriptor as the primary key (instead of PSI), because the PSI doesn't
-        // exist for synthetic descriptors
-        private val cache = HashMap<DeclarationDescriptor, ComponentMetadata>()
-
-        fun isComponentCompanion(cls: ClassDescriptor): Boolean {
-            if (!cls.isCompanionObject) return false
-            if (!cls.name.identifier.contains("R4HStaticRenderCompanion")) return false
-            val containingClass = cls.containingDeclaration as? ClassDescriptor ?: return false
-            if (!isComposeComponent(
-                    containingClass
-                )
-            ) return false
-            return true
-        }
-
-        fun isComposeComponent(descriptor: DeclarationDescriptor): Boolean {
-            if (descriptor !is ClassDescriptor) return false
-            val baseComponentDescriptor =
-                descriptor.module.findClassAcrossModuleDependencies(
-                    ClassId.topLevel(
-                        FqName(ComposeUtils.generateComposePackageName() + ".Component")
-                    )
-                ) ?: return false
-            return descriptor.isSubclassOf(baseComponentDescriptor)
-        }
-
-        fun isWrapperView(descriptor: DeclarationDescriptor): Boolean {
-            return descriptor is GeneratedViewClassDescriptor
-        }
-
-        fun fromDescriptor(descriptor: ClassDescriptor): ComponentMetadata {
-            if (!cache.containsKey(descriptor)) cache[descriptor] =
-                ComponentMetadata(descriptor)
-            return cache[descriptor]!!
-        }
-    }
-
-    fun getAttributeDescriptors(): List<PropertyDescriptor> {
-        return descriptor.unsubstitutedMemberScope.getContributedDescriptors()
-            .mapNotNull { it as? PropertyDescriptor }
-            .filter {
-                it.containingDeclaration == descriptor && !Visibilities.isPrivate(it.visibility) &&
-                        it.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE
-            }
-            .sortedBy { it.name }
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt
index 26917c0..baa2c2b 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeDefaultErrorMessages.kt
@@ -31,27 +31,6 @@
             "Model objects do not support inheritance"
         )
         MAP.put(
-            ComposeErrors.MISMATCHED_ATTRIBUTE_TYPE,
-            "<html>Type Mismatch.<br/>Required: {1}<br/>Found: {0}</html>",
-            Renderers.RENDER_TYPE,
-            Renderers.commaSeparated(Renderers.RENDER_TYPE)
-        )
-        MAP.put(
-            ComposeErrors.MISMATCHED_INFERRED_ATTRIBUTE_TYPE,
-            "<html>Type Mismatch.<br/>Required: {1}<br/>Found: {0}</html>",
-            Renderers.RENDER_TYPE,
-            Renderers.commaSeparated(Renderers.RENDER_TYPE)
-        )
-        MAP.put(
-            ComposeErrors.CALLABLE_RECURSION_DETECTED,
-            "Recursion detected"
-        )
-        MAP.put(
-            ComposeErrors.AMBIGUOUS_ATTRIBUTES_DETECTED,
-            "KTX call targets resulted in ambiguous attributes: {0}",
-            Renderers.commaSeparated(Renderers.STRING)
-        )
-        MAP.put(
             ComposeErrors.INVALID_COMPOSER_IMPLEMENTATION,
             "Composer of type ''{0}'' was found to be an invalid Composer implementation. " +
                     "Reason: {1}",
@@ -59,40 +38,6 @@
             Renderers.STRING
         )
         MAP.put(
-            ComposeErrors.UNRESOLVED_CHILDREN,
-            "<html>Mismatched children body type.<br/>Expected: {0}</html>",
-            Renderers.commaSeparated(Renderers.RENDER_TYPE)
-        )
-        MAP.put(
-            ComposeErrors.UNRESOLVED_ATTRIBUTE_KEY,
-            "No valid attribute on ''{0}'' found with key ''{1}'' and type ''{2}''",
-            Renderers.commaSeparated(Renderers.COMPACT),
-            Renderers.STRING,
-            Renderers.RENDER_TYPE
-        )
-        MAP.put(
-            ComposeErrors.UNRESOLVED_ATTRIBUTE_KEY_UNKNOWN_TYPE,
-            "No valid attribute on ''{0}'' found with key ''{1}''",
-            Renderers.commaSeparated(Renderers.COMPACT),
-            Renderers.STRING
-        )
-        MAP.put(
-            ComposeErrors.MISMATCHED_ATTRIBUTE_TYPE_NO_SINGLE_PARAM_SETTER_FNS,
-            "Setters with multiple arguments are currently unsupported. Found: ''{0}''",
-            Renderers.COMPACT
-        )
-        MAP.put(
-            ComposeErrors.MISSING_REQUIRED_ATTRIBUTES,
-            "Missing required attributes: {0}",
-            Renderers.commaSeparated(Renderers.COMPACT)
-        )
-        MAP.put(
-            ComposeErrors.INVALID_TAG_TYPE,
-            "Invalid KTX tag type. Found ''{0}'', Expected ''{1}''",
-            Renderers.RENDER_TYPE,
-            Renderers.commaSeparated(Renderers.RENDER_TYPE)
-        )
-        MAP.put(
             ComposeErrors.SUSPEND_FUNCTION_USED_AS_SFC,
             "Suspend functions are not allowed to be used as Components"
         )
@@ -101,69 +46,23 @@
             "Only Unit-returning functions are allowed to be used as Components"
         )
         MAP.put(
-            ComposeErrors.INVALID_TAG_DESCRIPTOR,
-            "Invalid KTX tag type. Expected ''{0}''",
-            Renderers.commaSeparated(Renderers.RENDER_TYPE)
-        )
-        MAP.put(
             ComposeErrors.SVC_INVOCATION,
             "Stateless Functional Components (SFCs) should not be invoked, use <{0} /> " +
                     "syntax instead",
             Renderers.STRING
         )
         MAP.put(
-            ComposeErrors.NON_COMPOSABLE_INVOCATION,
-            "{0} `{1}` must be marked as @Composable in order to be used as a KTX tag",
-            Renderers.STRING,
-            Renderers.COMPACT
-        )
-        MAP.put(
-            ComposeErrors.KTX_IN_NON_COMPOSABLE,
-            "Functions containing KTX Tags should be marked with the @Composable annotation"
-        )
-        MAP.put(
             ComposeErrors.COMPOSABLE_INVOCATION_IN_NON_COMPOSABLE,
             "Functions which invoke @Composable functions must be marked with the @Composable " +
                     "annotation"
         )
         MAP.put(
-            ComposeErrors.UNRESOLVED_TAG,
-            "Unresolved reference: {0}",
-            Renderers.ELEMENT_TEXT
-        )
-        MAP.put(
-            ComposeErrors.CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE,
-            "Attribute {0} is provided as the body of the element and therefore can't " +
-                    "simultaneously be provided as a keyed attribute.",
-            Renderers.STRING
-        )
-        MAP.put(
-            ComposeErrors.CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED,
-            "Element has a children body provided, but no @Children declarations were found"
-        )
-        MAP.put(
-            ComposeErrors.MISSING_REQUIRED_CHILDREN,
-            "A children body of type '{0}' is required",
-            Renderers.RENDER_TYPE
-        )
-        MAP.put(
             ComposeErrors.ILLEGAL_ASSIGN_TO_UNIONTYPE,
             "Value of type {0} can't be assigned to union type {1}.",
             RENDER_COLLECTION_OF_TYPES,
             RENDER_COLLECTION_OF_TYPES
         )
         MAP.put(
-            ComposeErrors.AMBIGUOUS_KTX_CALL,
-            "Ambiguous targets. {0}",
-            Renderers.AMBIGUOUS_CALLS
-        )
-        MAP.put(
-            ComposeErrors.CHILDREN_MUST_BE_LAST,
-            "Children annotation must only occur on last parameter.  This annotation is " +
-                    "deprecated (move children to be last parameter, make it @Composable, and " +
-                    "remove the @Children annotation.)."
-        )
-        MAP.put(
             ComposeErrors.ILLEGAL_TRY_CATCH_AROUND_COMPOSABLE,
             "Try catch is not supported around composable function invocations."
         )
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java
index 810ce18..c54e713 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeErrors.java
@@ -44,54 +44,18 @@
     DiagnosticFactory0<PsiElement> OPEN_MODEL = DiagnosticFactory0.create(ERROR);
     DiagnosticFactory0<PsiElement> UNSUPPORTED_MODEL_INHERITANCE = DiagnosticFactory0.create(ERROR);
 
-    DiagnosticFactory3<KtElement, Collection<DeclarationDescriptor>, String, KotlinType>
-            UNRESOLVED_ATTRIBUTE_KEY = DiagnosticFactory3.create(ERROR);
-    DiagnosticFactory2<KtElement, Collection<DeclarationDescriptor>, String>
-            UNRESOLVED_ATTRIBUTE_KEY_UNKNOWN_TYPE = DiagnosticFactory2.create(ERROR);
-    DiagnosticFactory2<KtElement, KotlinType, Collection<KotlinType>>
-            MISMATCHED_ATTRIBUTE_TYPE = DiagnosticFactory2.create(ERROR);
-    DiagnosticFactory2<KtElement, KotlinType, Collection<KotlinType>>
-            MISMATCHED_INFERRED_ATTRIBUTE_TYPE = DiagnosticFactory2.create(ERROR);
-    DiagnosticFactory1<KtElement, Collection<KotlinType>>
-            UNRESOLVED_CHILDREN = DiagnosticFactory1.create(ERROR);
-    DiagnosticFactory1<KtElement, SimpleFunctionDescriptor>
-            MISMATCHED_ATTRIBUTE_TYPE_NO_SINGLE_PARAM_SETTER_FNS = DiagnosticFactory1.create(ERROR);
-    DiagnosticFactory1<KtElement, Collection<DeclarationDescriptor>>
-            MISSING_REQUIRED_ATTRIBUTES = DiagnosticFactory1.create(ERROR);
-    DiagnosticFactory2<KtElement, KotlinType, Collection<KotlinType>>
-            INVALID_TAG_TYPE = DiagnosticFactory2.create(ERROR);
-    DiagnosticFactory0<KtElement>
-            CALLABLE_RECURSION_DETECTED = DiagnosticFactory0.create(ERROR);
-    DiagnosticFactory1<KtElement, Collection<String>>
-            AMBIGUOUS_ATTRIBUTES_DETECTED = DiagnosticFactory1.create(ERROR);
-    DiagnosticFactory1<KtElement, Collection<KotlinType>>
-            INVALID_TAG_DESCRIPTOR = DiagnosticFactory1.create(ERROR);
     DiagnosticFactory1<KtElement, String>
             SVC_INVOCATION = DiagnosticFactory1.create(ERROR);
-    DiagnosticFactory2<KtElement, String, DeclarationDescriptor>
-            NON_COMPOSABLE_INVOCATION = DiagnosticFactory2.create(WARNING);
     DiagnosticFactory0<KtElement>
             SUSPEND_FUNCTION_USED_AS_SFC = DiagnosticFactory0.create(ERROR);
     DiagnosticFactory0<PsiElement>
-            KTX_IN_NON_COMPOSABLE = DiagnosticFactory0.create(WARNING);
-    DiagnosticFactory0<PsiElement>
             COMPOSABLE_INVOCATION_IN_NON_COMPOSABLE = DiagnosticFactory0.create(WARNING);
     DiagnosticFactory0<KtElement>
             INVALID_TYPE_SIGNATURE_SFC = DiagnosticFactory0.create(ERROR);
-    DiagnosticFactory1<KtElement, KtReferenceExpression>
-            UNRESOLVED_TAG = DiagnosticFactory1.create(ERROR);
     DiagnosticFactory0<KtElement>
             NO_COMPOSER_FOUND = DiagnosticFactory0.create(ERROR);
     DiagnosticFactory2<KtElement, KotlinType, String>
             INVALID_COMPOSER_IMPLEMENTATION = DiagnosticFactory2.create(ERROR);
-    DiagnosticFactory1<KtElement, Collection<ResolvedCall<?>>>
-            AMBIGUOUS_KTX_CALL = DiagnosticFactory1.create(ERROR);
-    DiagnosticFactory1<KtElement, String>
-            CHILDREN_ATTR_USED_AS_BODY_AND_KEYED_ATTRIBUTE = DiagnosticFactory1.create(ERROR);
-    DiagnosticFactory0<KtElement>
-            CHILDREN_PROVIDED_BUT_NO_CHILDREN_DECLARED = DiagnosticFactory0.create(ERROR);
-    DiagnosticFactory1<KtElement, KotlinType>
-            MISSING_REQUIRED_CHILDREN = DiagnosticFactory1.create(ERROR);
     DiagnosticFactory2<KtExpression, Collection<KotlinType>, Collection<KotlinType>>
             ILLEGAL_ASSIGN_TO_UNIONTYPE = DiagnosticFactory2.create(ERROR);
     DiagnosticFactory0<KtElement>
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeWritableSlices.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeWritableSlices.kt
index 4b96dd0..b2df5aa 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeWritableSlices.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/analysis/ComposeWritableSlices.kt
@@ -1,11 +1,11 @@
 package androidx.compose.plugins.kotlin.analysis
 
 import androidx.compose.plugins.kotlin.ComposableAnnotationChecker
-import androidx.compose.plugins.kotlin.ComposerEmitMetadata
-import androidx.compose.plugins.kotlin.ResolvedKtxElementCall
+import androidx.compose.plugins.kotlin.ComposerMetadata
 import androidx.compose.plugins.kotlin.ResolvedRestartCalls
 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
+import org.jetbrains.kotlin.descriptors.ParameterDescriptor
 import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
 import org.jetbrains.kotlin.descriptors.VariableDescriptor
 import org.jetbrains.kotlin.psi.Call
@@ -20,13 +20,6 @@
 object ComposeWritableSlices {
     val COMPOSABLE_ANALYSIS: WritableSlice<KtElement, ComposableAnnotationChecker.Composability> =
         BasicWritableSlice(RewritePolicy.DO_NOTHING)
-    val RESOLVED_KTX_CALL: WritableSlice<KtElement, ResolvedKtxElementCall> =
-        BasicWritableSlice(RewritePolicy.DO_NOTHING)
-    val ATTRIBUTE_KEY_REFERENCE_TARGET:
-            WritableSlice<KtReferenceExpression, Set<DeclarationDescriptor>> =
-        BasicWritableSlice(REWRITES_ALLOWED)
-    val FAILED_CANDIDATES: WritableSlice<KtElement, Collection<ResolvedCall<FunctionDescriptor>>> =
-        BasicWritableSlice(REWRITES_ALLOWED)
     val FCS_CALL_WITHIN_COMPOSABLE: WritableSlice<KtElement, Boolean> =
         BasicWritableSlice(RewritePolicy.DO_NOTHING)
     val FCS_RESOLVEDCALL_COMPOSABLE: WritableSlice<KtElement, Boolean> =
@@ -39,10 +32,12 @@
         BasicWritableSlice(RewritePolicy.DO_NOTHING)
     val RESTART_CALLS: WritableSlice<SimpleFunctionDescriptor, ResolvedRestartCalls> =
         BasicWritableSlice(RewritePolicy.DO_NOTHING)
-    val COMPOSER_EMIT_METADATA: WritableSlice<VariableDescriptor, ComposerEmitMetadata> =
+    val COMPOSER_METADATA: WritableSlice<VariableDescriptor, ComposerMetadata> =
         BasicWritableSlice(RewritePolicy.DO_NOTHING)
     val IGNORE_COMPOSABLE_INTERCEPTION: WritableSlice<Call, Boolean> =
         BasicWritableSlice(RewritePolicy.DO_NOTHING)
+    val IS_EMIT_CHILDREN_PARAMETER: WritableSlice<ParameterDescriptor, Boolean> =
+        BasicWritableSlice(RewritePolicy.DO_NOTHING)
 }
 
 private val REWRITES_ALLOWED = object : RewritePolicy {
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/ir/IrKtxAttribute.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/ir/IrKtxAttribute.kt
deleted file mode 100644
index 2aad490..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/ir/IrKtxAttribute.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package androidx.compose.plugins.kotlin.compiler.ir
-
-import org.jetbrains.kotlin.ir.IrKtxStatement
-import org.jetbrains.kotlin.ir.expressions.IrExpression
-import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
-import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.psiUtil.endOffset
-import org.jetbrains.kotlin.psi.psiUtil.startOffset
-
-class IrKtxAttribute(
-    val element: KtxAttribute,
-    val value: IrExpression
-) : IrKtxStatement {
-    override val startOffset = element.startOffset
-    override val endOffset = element.endOffset
-    override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
-        visitor.visitKtxStatement(this, data)
-    override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) =
-        value.accept(visitor, data)
-    override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        throw UnsupportedOperationException(
-            "This temporary placeholder node must be manually transformed, not visited"
-        )
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/ir/Utilities.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/ir/Utilities.kt
deleted file mode 100644
index 43ee538..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/ir/Utilities.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package androidx.compose.plugins.kotlin.compiler.ir
-
-import org.jetbrains.kotlin.ir.IrElement
-import org.jetbrains.kotlin.ir.IrKtxStatement
-import org.jetbrains.kotlin.ir.declarations.IrDeclaration
-import org.jetbrains.kotlin.ir.util.withScope
-import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
-import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
-
-fun IrElement.find(filter: (descriptor: IrElement) -> Boolean): Collection<IrElement> {
-    val elements: MutableList<IrElement> = mutableListOf()
-    accept(object : IrElementVisitorVoid {
-        override fun visitElement(element: IrElement) {
-            if (filter(element)) elements.add(element)
-            element.acceptChildren(this, null)
-        }
-        override fun visitKtxStatement(expression: IrKtxStatement, data: Nothing?) {
-            expression.acceptChildren(this, null)
-        }
-    }, null)
-    return elements
-}
-
-inline fun <T : IrDeclaration> T.buildWithScope(
-    context: GeneratorContext,
-    builder: (T) -> Unit
-): T =
-    also { irDeclaration ->
-        context.symbolTable.withScope(irDeclaration.descriptor) {
-            builder(irDeclaration)
-        }
-    }
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableCallTransformer.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableCallTransformer.kt
new file mode 100644
index 0000000..dfb430e
--- /dev/null
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableCallTransformer.kt
@@ -0,0 +1,869 @@
+package androidx.compose.plugins.kotlin.compiler.lower
+
+import androidx.compose.plugins.kotlin.COMPOSABLE_EMIT_OR_CALL
+import androidx.compose.plugins.kotlin.ComposableEmitDescriptor
+import androidx.compose.plugins.kotlin.ComposableFunctionDescriptor
+import androidx.compose.plugins.kotlin.EmitChildrenValueParameterDescriptor
+import androidx.compose.plugins.kotlin.KtxNameConventions
+import androidx.compose.plugins.kotlin.ValidatedAssignment
+import androidx.compose.plugins.kotlin.ValidationType
+import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
+import androidx.compose.plugins.kotlin.hasPivotalAnnotation
+import androidx.compose.plugins.kotlin.isMarkedStable
+import androidx.compose.plugins.kotlin.isSpecialType
+import org.jetbrains.kotlin.backend.common.FileLoweringPass
+import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
+import org.jetbrains.kotlin.backend.common.peek
+import org.jetbrains.kotlin.backend.common.pop
+import org.jetbrains.kotlin.backend.common.push
+import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.builtins.extractParameterNameFromFunctionTypeArgument
+import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
+import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
+import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
+import org.jetbrains.kotlin.builtins.isFunctionType
+import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
+import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.descriptors.FunctionDescriptor
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.descriptors.ParameterDescriptor
+import org.jetbrains.kotlin.descriptors.PropertyDescriptor
+import org.jetbrains.kotlin.descriptors.SourceElement
+import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
+import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
+import org.jetbrains.kotlin.descriptors.Visibilities
+import org.jetbrains.kotlin.descriptors.annotations.Annotations
+import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
+import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
+import org.jetbrains.kotlin.ir.IrStatement
+import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
+import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
+import org.jetbrains.kotlin.ir.builders.IrBlockBuilder
+import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
+import org.jetbrains.kotlin.ir.builders.irBlock
+import org.jetbrains.kotlin.ir.builders.irBlockBody
+import org.jetbrains.kotlin.ir.builders.irCall
+import org.jetbrains.kotlin.ir.builders.irFalse
+import org.jetbrains.kotlin.ir.builders.irGet
+import org.jetbrains.kotlin.ir.builders.irInt
+import org.jetbrains.kotlin.ir.builders.irReturn
+import org.jetbrains.kotlin.ir.builders.irReturnUnit
+import org.jetbrains.kotlin.ir.builders.irTemporary
+import org.jetbrains.kotlin.ir.builders.irTrue
+import org.jetbrains.kotlin.ir.builders.parent
+import org.jetbrains.kotlin.ir.declarations.IrDeclaration
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrFile
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.getIrValueParameter
+import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
+import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
+import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
+import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
+import org.jetbrains.kotlin.ir.expressions.IrBlock
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrConst
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression
+import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
+import org.jetbrains.kotlin.ir.expressions.IrGetValue
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
+import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
+import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
+import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
+import org.jetbrains.kotlin.ir.expressions.getValueArgument
+import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
+import org.jetbrains.kotlin.ir.expressions.putTypeArguments
+import org.jetbrains.kotlin.ir.expressions.putValueArgument
+import org.jetbrains.kotlin.ir.expressions.typeParametersCount
+import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
+import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
+import org.jetbrains.kotlin.ir.types.IrType
+import org.jetbrains.kotlin.ir.types.toKotlinType
+import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
+import org.jetbrains.kotlin.ir.util.TypeTranslator
+import org.jetbrains.kotlin.ir.util.endOffset
+import org.jetbrains.kotlin.ir.util.referenceFunction
+import org.jetbrains.kotlin.ir.util.startOffset
+import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
+import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
+import org.jetbrains.kotlin.js.translate.callTranslator.getReturnType
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.psi2ir.findFirstFunction
+import org.jetbrains.kotlin.resolve.DescriptorFactory
+import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
+import org.jetbrains.kotlin.types.KotlinType
+import org.jetbrains.kotlin.types.isError
+import org.jetbrains.kotlin.types.isNullable
+import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
+
+class ComposableCallTransformer(val context: JvmBackendContext) :
+    IrElementTransformerVoid(),
+    FileLoweringPass {
+
+    private val typeTranslator =
+        TypeTranslator(
+            context.ir.symbols.externalSymbolTable,
+            context.state.languageVersionSettings,
+            context.builtIns
+        ).apply {
+            constantValueGenerator = ConstantValueGenerator(
+                context.state.module,
+                context.ir.symbols.externalSymbolTable
+            )
+            constantValueGenerator.typeTranslator = this
+        }
+
+    private val builtIns = context.irBuiltIns
+
+    private val orFunctionDescriptor = builtIns.builtIns.booleanType.memberScope
+        .findFirstFunction("or") { it is FunctionDescriptor && it.isInfix }
+
+    private val jvmContext get() = context
+
+    private val symbolTable get() = context.ir.symbols.externalSymbolTable
+
+    private fun KotlinType?.isStable(): Boolean {
+        if (this == null) return false
+
+        val trace = jvmContext.state.bindingTrace
+        val calculated = trace.get(ComposeWritableSlices.STABLE_TYPE, this)
+        return if (calculated == null) {
+            val isStable = !isError &&
+                    !isSpecialType &&
+                    (
+                        KotlinBuiltIns.isPrimitiveType(this) ||
+                        isFunctionType ||
+                        isMarkedStable() ||
+                        (
+                            isNullable() &&
+                            makeNotNullable().isStable()
+                        )
+                    )
+            trace.record(ComposeWritableSlices.STABLE_TYPE, this, isStable)
+            isStable
+        } else calculated
+    }
+
+    override fun lower(irFile: IrFile) {
+        irFile.transformChildrenVoid(this)
+    }
+
+    val declarationStack = mutableListOf<IrFunction>()
+
+    override fun visitFunction(declaration: IrFunction): IrStatement {
+        try {
+            declarationStack.push(declaration)
+            return super.visitFunction(declaration)
+        } finally {
+            declarationStack.pop()
+        }
+    }
+
+    override fun visitBlock(expression: IrBlock): IrExpression {
+        if (expression.origin != COMPOSABLE_EMIT_OR_CALL) {
+            return super.visitBlock(expression)
+        }
+
+        assert(expression.statements.size == 2)
+        // the first statement should represent the call to get the composer
+        // the second statement should represent the composable call or emit
+        val (first, second) = expression.statements
+        val composerCall = when {
+            first is IrCall -> first
+            // the psi->IR phase seems to generate coercions to UNIT, so we won't just find the
+            // bare call here.
+            first is IrTypeOperatorCall &&
+            first.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT &&
+            first.argument is IrCall -> first.argument as IrCall
+            else -> error("Couldn't find composer call in block")
+        }
+
+        val emitOrCall = when {
+            second is IrCall -> second
+            // the psi -> IR phase seems to generate argument reordering blocks when calls are
+            // made with named arguments out of order. In this case we need to find the last
+            // statement
+            second is IrBlock &&
+            second.origin == IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL &&
+            second.statements.last() is IrCall -> second.statements.last() as IrCall
+            else -> error("Couldn't find composable call in block")
+        }
+
+        val descriptor = emitOrCall.descriptor
+
+        return when {
+            descriptor.isInline -> expression
+            descriptor is ComposableFunctionDescriptor -> {
+                val transformedComposerCall = composerCall.transformChildren()
+                val transformed = emitOrCall.transformChildren()
+
+                context.createIrBuilder(declarationStack.last().symbol).irBlock {
+                    +irComposableCall(transformedComposerCall, transformed, descriptor)
+                }
+            }
+            descriptor is ComposableEmitDescriptor -> {
+                val transformedComposerCall = composerCall.transformChildren()
+                val transformed = emitOrCall.transformChildren()
+                context.createIrBuilder(declarationStack.last().symbol).irBlock {
+                    +irComposableEmit(transformedComposerCall, transformed, descriptor)
+                }
+            }
+            else -> error("dont know what to do")
+        }
+    }
+
+    private fun IrExpression.isReorderTemporaryVariable(): Boolean {
+        return this is IrGetValue &&
+                symbol.owner.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
+    }
+
+    private fun IrExpression.unwrapReorderTemporaryVariable(): IrExpression {
+        val getValue = this as IrGetValue
+        val variable = getValue.symbol.owner as IrVariableImpl
+        return variable.initializer!!
+    }
+
+    private fun IrBlockBuilder.irComposableCall(
+        composerCall: IrCall,
+        original: IrCall,
+        descriptor: ComposableFunctionDescriptor
+    ): IrExpression {
+        val composerTemp = irTemporary(composerCall)
+
+        /*
+
+        Foo(text="foo")
+
+        // transforms into
+
+        val attr_text = "foo"
+        composer.call(
+            key = 123,
+            invalid = { changed(attr_text) },
+            block = { Foo(attr_text) }
+        )
+         */
+        val composer = descriptor.composerCall.resultingDescriptor as PropertyDescriptor
+
+        // TODO(lmr): the way we grab temporaries here feels wrong. We should investigate the right
+        // way to do this. Additionally, we are creating temporary vars for variables which is
+        // causing larger stack space than needed in our generated code.
+
+        val irGetArguments = original
+            .descriptor
+            .valueParameters
+            .map {
+                val arg = original.getValueArgument(it)
+                it to getParameterExpression(it, arg)
+            }
+
+        val tmpDispatchReceiver = original.dispatchReceiver?.let { irTemporary(it) }
+        val tmpExtensionReceiver = original.extensionReceiver?.let { irTemporary(it) }
+
+        // TODO(lmr): come up with a better way to find this?
+        val callDescriptor = descriptor
+            .composerMetadata
+            .callDescriptors
+            .first { it.typeParametersCount == 0 }
+
+        val joinKeyDescriptor = composer
+            .type
+            .memberScope
+            .findFirstFunction(KtxNameConventions.JOINKEY.identifier) {
+                it.valueParameters.size == 2
+            }
+
+        val callParameters = callDescriptor.valueParameters
+            .map { it.name to it }
+            .toMap()
+
+        fun getCallParameter(name: Name) = callParameters[name]
+            ?: error("Expected $name parameter to exist")
+
+        return irCall(
+            callee = symbolTable.referenceFunction(callDescriptor),
+            type = builtIns.unitType // TODO(lmr): refactor call(...) to return a type
+        ).apply {
+            dispatchReceiver = irGet(composerTemp)
+
+            putValueArgument(
+                getCallParameter(KtxNameConventions.CALL_KEY_PARAMETER),
+                irGroupKey(
+                    original = original,
+                    getComposer = { irGet(composerTemp) },
+                    joinKey = joinKeyDescriptor,
+                    pivotals = irGetArguments.mapNotNull { (param, getExpr) ->
+                        val expr = getExpr()
+                        if (expr == null) null
+                        else if (!param.hasPivotalAnnotation()) null
+                        else expr
+                    }
+                )
+            )
+
+            val invalidParameter = getCallParameter(KtxNameConventions.CALL_INVALID_PARAMETER)
+
+            val validatorType = invalidParameter.type.getReceiverTypeFromFunctionType()
+                ?: error("Expected validator type to be on receiver of the invalid lambda")
+
+            val changedDescriptor = validatorType
+                .memberScope
+                .findFirstFunction("changed") { it.typeParametersCount == 1 }
+
+            val validatedArguments: List<IrExpression> =
+                irGetArguments.mapNotNull { (_, getExpr) -> getExpr() } +
+                listOfNotNull(
+                    tmpDispatchReceiver?.let { irGet(it) },
+                    tmpExtensionReceiver?.let { irGet(it) }
+                )
+
+            val isSkippable = validatedArguments.all { it.type.toKotlinType().isStable() }
+
+            putValueArgument(
+                invalidParameter,
+                irLambdaExpression(
+                    original.startOffset,
+                    original.endOffset,
+                    descriptor = createFunctionDescriptor(
+                        type = invalidParameter.type,
+                        owner = descriptor.containingDeclaration
+                    ),
+                    type = invalidParameter.type.toIrType()
+                ) { fn ->
+                    if (!isSkippable) {
+                        // if it's not skippable, we don't validate any arguments.
+                        +irReturn(irTrue())
+                    } else {
+                        val validationCalls = validatedArguments
+                            .map {
+                                irChangedCall(
+                                    changedDescriptor = changedDescriptor,
+                                    receiver = irGet(fn.extensionReceiverParameter!!),
+                                    attributeValue = it
+                                )
+                            }
+
+                        // all as one expression: a or b or c ... or z
+                        +irReturn(when (validationCalls.size) {
+                            0 -> irFalse()
+                            1 -> validationCalls.single()
+                            else -> validationCalls.reduce { accumulator, value ->
+                                when {
+                                    // if it is a constant, the value is `false`
+                                    accumulator is IrConst<*> -> value
+                                    value is IrConst<*> -> accumulator
+                                    else -> irOr(accumulator, value)
+                                }
+                            }
+                        })
+                    }
+                }
+            )
+
+            val blockParameter = getCallParameter(KtxNameConventions.CALL_BLOCK_PARAMETER)
+
+            putValueArgument(
+                blockParameter,
+                irLambdaExpression(
+                    original.startOffset,
+                    original.endOffset,
+                    descriptor = createFunctionDescriptor(
+                        type = blockParameter.type,
+                        owner = descriptor.containingDeclaration
+                    ),
+                    type = blockParameter.type.toIrType()
+                ) {
+                    +irCall(
+                        callee = symbolTable.referenceFunction(descriptor.underlyingDescriptor),
+                        type = original.type
+                    ).apply {
+                        copyTypeArgumentsFrom(original)
+
+                        dispatchReceiver = tmpDispatchReceiver?.let { irGet(it) }
+                        extensionReceiver = tmpExtensionReceiver?.let { irGet(it) }
+
+                        irGetArguments.forEach { (param, getExpr) ->
+                            putValueArgument(param, getExpr())
+                        }
+                    }
+                }
+            )
+        }
+    }
+
+    private fun isChildrenParameter(desc: ValueParameterDescriptor, expr: IrExpression): Boolean {
+        return expr is IrFunctionExpression &&
+            expr.origin == IrStatementOrigin.LAMBDA &&
+            desc is EmitChildrenValueParameterDescriptor
+    }
+
+    private fun IrBlockBuilder.getParameterExpression(
+        desc: ValueParameterDescriptor,
+        expr: IrExpression?
+    ): () -> IrExpression? {
+        if (expr == null)
+            return { null }
+        if (expr.isReorderTemporaryVariable()) {
+            return getParameterExpression(desc, expr.unwrapReorderTemporaryVariable())
+        }
+        return when {
+            expr is IrConst<*> ->
+                ({ expr.copy() })
+            isChildrenParameter(desc, expr) ->
+                ({ expr })
+            else -> {
+                val temp = irTemporary(
+                    expr,
+                    typeHint = desc.type,
+                    irType = desc.type.toIrType()
+                )
+                ({ irGet(temp) })
+            }
+        }
+    }
+
+    private fun IrBlockBuilder.irComposableEmit(
+        composerCall: IrCall,
+        original: IrCall,
+        descriptor: ComposableEmitDescriptor
+    ): IrExpression {
+        val composerTemp = irTemporary(composerCall)
+        /*
+
+        TextView(text="foo")
+
+        // transforms into
+
+        val attr_text = "foo"
+        composer.emit(
+            key = 123,
+            ctor = { context -> TextView(context) },
+            update = { set(attr_text) { text -> this.text = text } }
+        )
+         */
+
+        val parametersByName = descriptor
+            .valueParameters
+            .mapNotNull { desc ->
+                original.getValueArgument(desc)?.let { desc to it }
+            }
+            .map { (desc, expr) ->
+                desc.name.asString() to getParameterExpression(desc, expr)
+            }
+            .toMap()
+
+        val emitCall = descriptor.emitCall
+        val emitFunctionDescriptor = emitCall.candidateDescriptor
+
+        val emitParameters = emitFunctionDescriptor.valueParameters
+            .map { it.name to it }
+            .toMap()
+
+        fun getEmitParameter(name: Name) = emitParameters[name]
+            ?: error("Expected $name parameter to exist")
+
+        val emitFunctionSymbol = symbolTable.referenceFunction(emitFunctionDescriptor)
+
+        val joinKeyDescriptor = descriptor.composer
+            .getReturnType()
+            .memberScope
+            .findFirstFunction(KtxNameConventions.JOINKEY.identifier) {
+                it.valueParameters.size == 2
+            }
+
+        fun irGetParameter(name: String): IrExpression = parametersByName[name]?.invoke()
+                ?: error("No parameter found with name $name")
+
+        return irCall(
+            callee = emitFunctionSymbol,
+            type = builtIns.unitType
+        ).apply {
+            dispatchReceiver = irGet(composerTemp)
+            // TODO(lmr): extensionReceiver.
+            // We would want to do this to enable "emit" and "call" implementations that are
+            // extensions on the composer
+
+            putTypeArguments(emitCall.typeArguments) { it.toIrType() }
+
+            putValueArgument(
+                getEmitParameter(KtxNameConventions.EMIT_KEY_PARAMETER),
+                irGroupKey(
+                    original = original,
+                    getComposer = { irGet(composerTemp) },
+                    joinKey = joinKeyDescriptor,
+                    pivotals = descriptor.pivotals.map { irGetParameter(it) }
+                )
+            )
+
+            val ctorParam = getEmitParameter(KtxNameConventions.EMIT_CTOR_PARAMETER)
+
+            val ctorLambdaDescriptor = createFunctionDescriptor(ctorParam.type)
+
+            putValueArgument(
+                ctorParam,
+                irLambdaExpression(
+                    original.startOffset,
+                    original.endOffset,
+                    descriptor = ctorLambdaDescriptor,
+                    type = ctorParam.type.toIrType()
+                ) { fn ->
+
+                    val ctorCall = descriptor.ctorCall
+
+                    val ctorCallSymbol = symbolTable.referenceConstructor(
+                        ctorCall.candidateDescriptor as ClassConstructorDescriptor
+                    )
+
+                    +irReturn(irCall(ctorCallSymbol).apply {
+                        putTypeArguments(ctorCall.typeArguments) { it.toIrType() }
+                        ctorLambdaDescriptor.valueParameters.zip(
+                            ctorCall
+                                .candidateDescriptor!!
+                                .valueParameters
+                        ) { a, b ->
+                            putValueArgument(
+                                b,
+                                irGet(fn.getIrValueParameter(a))
+                            )
+                        }
+                        descriptor.ctorParams.forEach { name ->
+                            val param = ctorCall
+                                .candidateDescriptor
+                                .valueParameters
+                                .firstOrNull { it.name.identifier == name }
+                            if (param != null) {
+                                putValueArgument(
+                                    param,
+                                    irGetParameter(name)
+                                )
+                            }
+                        }
+                    })
+                }
+            )
+
+            val updateParam = getEmitParameter(KtxNameConventions
+                .EMIT_UPDATER_PARAMETER)
+
+            val updateLambdaDescriptor = createFunctionDescriptor(updateParam.type)
+
+            putValueArgument(
+                updateParam,
+                irLambdaExpression(
+                    original.startOffset,
+                    original.endOffset,
+                    descriptor = updateLambdaDescriptor,
+                    type = updateParam.type.toIrType()
+                ) { fn ->
+                    descriptor.validations.forEach {
+                        // set(attr_text) { text -> this.text = text }
+                        val arg = irGetParameter(it.name)
+                        +irValidatedAssignment(
+                            arg.startOffset,
+                            arg.endOffset,
+                            memoizing = true,
+                            validation = it,
+                            receiver = irGet(fn.extensionReceiverParameter!!),
+                            attributeValue = arg
+                        )
+                    }
+                    +irReturnUnit()
+                }
+            )
+
+            if (descriptor.hasChildren) {
+                val bodyParam = getEmitParameter(KtxNameConventions.EMIT_CHILDREN_PARAMETER)
+
+                val childrenExpr = irGetParameter("\$CHILDREN")
+
+                putValueArgument(
+                    bodyParam,
+                    childrenExpr
+                )
+            }
+        }
+    }
+
+    private fun IrBuilderWithScope.irGroupKey(
+        original: IrCall,
+        joinKey: FunctionDescriptor,
+        getComposer: () -> IrExpression,
+        pivotals: List<IrExpression>
+    ): IrExpression {
+        val keyValueExpression = irInt(original.sourceLocationHash())
+        return if (pivotals.isEmpty()) keyValueExpression
+        else (listOf(keyValueExpression) + pivotals).reduce { accumulator, value ->
+            irCall(
+                callee = symbolTable.referenceFunction(joinKey),
+                type = joinKey.returnType!!.toIrType()
+            ).apply {
+                dispatchReceiver = getComposer()
+                putValueArgument(0, accumulator)
+                putValueArgument(1, value)
+            }
+        }
+    }
+
+    private fun IrCall.sourceLocationHash(): Int {
+        return descriptor.fqNameSafe.toString().hashCode() xor startOffset
+    }
+
+    private fun IrBuilderWithScope.irChangedCall(
+        changedDescriptor: FunctionDescriptor,
+        receiver: IrExpression,
+        attributeValue: IrExpression
+    ): IrExpression {
+        // TODO(lmr): make it so we can use the "changed" overloads with primitive types.
+        // Right now this is causing a lot of boxing/unboxing for primitives
+        return if (attributeValue is IrConst<*>) irFalse()
+        else irCall(
+            callee = symbolTable.referenceFunction(changedDescriptor),
+            type = changedDescriptor.returnType?.toIrType()!!
+        ).apply {
+            putTypeArgument(0, attributeValue.type)
+            dispatchReceiver = receiver
+            putValueArgument(0, attributeValue)
+        }
+    }
+
+    private fun IrBuilderWithScope.irOr(
+        left: IrExpression,
+        right: IrExpression
+    ): IrExpression {
+        return irCall(
+            callee = symbolTable.referenceFunction(orFunctionDescriptor),
+            type = builtIns.booleanType
+        ).apply {
+            dispatchReceiver = left
+            putValueArgument(0, right)
+        }
+    }
+
+    private fun IrBuilderWithScope.irValidatedAssignment(
+        startOffset: Int,
+        endOffset: Int,
+        memoizing: Boolean,
+        validation: ValidatedAssignment,
+        receiver: IrExpression,
+        attributeValue: IrExpression
+    ): IrExpression {
+        // for emit, fnDescriptor is Validator.(Value) -> Unit    or Validator.(Value, Element.(Value) -> Unit) -> Unit
+        // for call, fnDescriptor is Validator.(Value) -> Boolean or Validator.(Value, (Value) -> Unit) -> Boolean
+
+        // in emit, the element is passed through an extension parameter
+        // in call, the element is passed through a capture scope
+        val validationCall =
+            if (memoizing) validation.validationCall
+            else validation.uncheckedValidationCall
+
+        if (validationCall == null) error("Expected validationCall to be non-null")
+
+        val validationCallDescriptor = validationCall.candidateDescriptor as FunctionDescriptor
+
+        return irCall(
+            callee = symbolTable.referenceFunction(validationCallDescriptor),
+            type = validationCallDescriptor.returnType?.toIrType()!!
+        ).apply {
+
+            dispatchReceiver = receiver
+            // TODO(lmr): extensionReceiver.
+            // This might be something we want to be able to do in the cases where we want to
+            // build extension `changed(...)`  or `set(..) { ... }` methods
+
+            putTypeArguments(validationCall.typeArguments) { it.toIrType() }
+
+            putValueArgument(0, attributeValue)
+            val assignment = validation.assignment
+            if (assignment != null && validation.validationType != ValidationType.CHANGED) {
+                val assignmentLambdaDescriptor = validation.assignmentLambda
+                    ?: error("Expected assignmentLambda to be non-null")
+                val assignmentDescriptor = assignment.candidateDescriptor.original
+
+                val assignmentSymbol = when (assignmentDescriptor) {
+                    is PropertyDescriptor -> symbolTable.referenceFunction(
+                        assignmentDescriptor.setter!!
+                    )
+                    else -> symbolTable.referenceFunction(assignmentDescriptor)
+                }
+                val assignmentValueParameterDescriptor = assignmentLambdaDescriptor
+                        .valueParameters[0]
+
+                putValueArgument(
+                    1,
+                    irLambdaExpression(
+                        startOffset,
+                        endOffset,
+                        assignmentLambdaDescriptor,
+                        validationCallDescriptor.valueParameters[1].type.toIrType()
+                    ) { fn ->
+                        +irReturn(
+                            irCall(
+                                callee = assignmentSymbol,
+                                type = builtIns.unitType
+                            ).apply {
+                                putTypeArguments(assignment.typeArguments) { it.toIrType() }
+                                when (assignment.explicitReceiverKind) {
+                                    ExplicitReceiverKind.DISPATCH_RECEIVER -> {
+                                        dispatchReceiver = irGet(fn.extensionReceiverParameter!!)
+                                    }
+                                    ExplicitReceiverKind.EXTENSION_RECEIVER -> {
+                                        extensionReceiver = irGet(fn.extensionReceiverParameter!!)
+                                    }
+                                    ExplicitReceiverKind.BOTH_RECEIVERS -> {
+                                        // NOTE(lmr): This should not be possible. This would have
+                                        // to be an extension method on the ComposerUpdater class
+                                        // itself for the emittable type.
+                                        error("Extension instance methods are not allowed for " +
+                                                "assignments")
+                                    }
+                                    ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> {
+                                        // NOTE(lmr): This is not possible
+                                        error("Static methods are invalid for assignments")
+                                    }
+                                }
+                                putValueArgument(
+                                    0,
+                                    irGet(
+                                        fn.getIrValueParameter(assignmentValueParameterDescriptor)
+                                    )
+                                )
+                            }
+                        )
+                    }
+                )
+            }
+        }
+    }
+
+    private fun IrBuilderWithScope.irLambdaExpression(
+        startOffset: Int,
+        endOffset: Int,
+        descriptor: FunctionDescriptor,
+        type: IrType,
+        body: IrBlockBodyBuilder.(IrFunction) -> Unit
+    ): IrExpression {
+        val symbol = IrSimpleFunctionSymbolImpl(descriptor)
+
+        val returnType = descriptor.returnType!!.toIrType()
+
+        val lambda = IrFunctionImpl(
+            startOffset, endOffset,
+            IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA,
+            symbol,
+            returnType
+        ).also {
+            it.parent = scope.getLocalDeclarationParent()
+            it.createParameterDeclarations()
+            it.body = jvmContext
+                .createIrBuilder(symbol)
+                .irBlockBody { body(it) }
+        }
+
+        return irBlock(
+            startOffset = startOffset,
+            endOffset = endOffset,
+            origin = IrStatementOrigin.LAMBDA,
+            resultType = type
+        ) {
+            +lambda
+            +IrFunctionReferenceImpl(
+                startOffset = startOffset,
+                endOffset = endOffset,
+                type = type,
+                symbol = symbol,
+                descriptor = descriptor,
+                typeArgumentsCount = descriptor.typeParametersCount,
+                origin = IrStatementOrigin.LAMBDA
+            )
+        }
+    }
+
+    private fun IrFunction.createParameterDeclarations() {
+        fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl(
+            this.startOffset ?: UNDEFINED_OFFSET,
+            this.endOffset ?: UNDEFINED_OFFSET,
+            IrDeclarationOrigin.DEFINED,
+            this,
+            type.toIrType(),
+            (this as? ValueParameterDescriptor)?.varargElementType?.toIrType()
+        ).also {
+            it.parent = this@createParameterDeclarations
+        }
+
+        fun TypeParameterDescriptor.irTypeParameter() = IrTypeParameterImpl(
+            this.startOffset ?: UNDEFINED_OFFSET,
+            this.endOffset ?: UNDEFINED_OFFSET,
+            IrDeclarationOrigin.DEFINED,
+            IrTypeParameterSymbolImpl(this)
+        ).also {
+            it.parent = this@createParameterDeclarations
+        }
+
+        dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.irValueParameter()
+        extensionReceiverParameter = descriptor.extensionReceiverParameter?.irValueParameter()
+
+        assert(valueParameters.isEmpty())
+        descriptor.valueParameters.mapTo(valueParameters) { it.irValueParameter() }
+
+        assert(typeParameters.isEmpty())
+        descriptor.typeParameters.mapTo(typeParameters) { it.irTypeParameter() }
+    }
+
+    private fun KotlinType.toIrType(): IrType = typeTranslator.translateType(this)
+
+    private fun IrBuilderWithScope.createFunctionDescriptor(
+        type: KotlinType,
+        owner: DeclarationDescriptor = scope.scopeOwner
+    ): FunctionDescriptor {
+        return AnonymousFunctionDescriptor(
+            owner,
+            Annotations.EMPTY,
+            CallableMemberDescriptor.Kind.SYNTHESIZED,
+            SourceElement.NO_SOURCE,
+            false
+        ).apply {
+            initialize(
+                type.getReceiverTypeFromFunctionType()?.let {
+                    DescriptorFactory.createExtensionReceiverParameterForCallable(
+                        this,
+                        it,
+                        Annotations.EMPTY)
+                },
+                null,
+                emptyList(),
+                type.getValueParameterTypesFromFunctionType().mapIndexed { i, t ->
+                    ValueParameterDescriptorImpl(
+                        containingDeclaration = this,
+                        original = null,
+                        index = i,
+                        annotations = Annotations.EMPTY,
+                        name = t.type.extractParameterNameFromFunctionTypeArgument()
+                            ?: Name.identifier("p$i"),
+                        outType = t.type,
+                        declaresDefaultValue = false,
+                        isCrossinline = false,
+                        isNoinline = false,
+                        varargElementType = null,
+                        source = SourceElement.NO_SOURCE
+                    )
+                },
+                type.getReturnTypeFromFunctionType(),
+                Modality.FINAL,
+                Visibilities.LOCAL,
+                null
+            )
+            isOperator = false
+            isInfix = false
+            isExternal = false
+            isInline = false
+            isTailrec = false
+            isSuspend = false
+            isExpect = false
+            isActual = false
+        }
+    }
+}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeFcsPatcher.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeFcsPatcher.kt
deleted file mode 100644
index dd567cb..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeFcsPatcher.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package androidx.compose.plugins.kotlin.compiler.lower
-
-import org.jetbrains.kotlin.backend.common.FileLoweringPass
-import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
-import org.jetbrains.kotlin.ir.declarations.IrFile
-import org.jetbrains.kotlin.ir.expressions.IrCall
-import org.jetbrains.kotlin.ir.expressions.IrExpression
-import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
-import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
-import androidx.compose.plugins.kotlin.ComposeCallResolutionInterceptorExtension
-
-class ComposeFcsPatcher(val context: JvmBackendContext) :
-    IrElementTransformerVoid(),
-    FileLoweringPass {
-
-    override fun lower(irFile: IrFile) {
-        irFile.transformChildrenVoid(this)
-    }
-
-    override fun visitCall(expression: IrCall): IrExpression {
-        if (expression.descriptor is
-                    ComposeCallResolutionInterceptorExtension.ComposableInvocationDescriptor) {
-        //    System.out.println("******"+expression.descriptor.name)
-        //    return IrBlockImpl(expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, null, emptyList())
-            TODO("Implement me")
-        }
-        return super.visitCall(expression)
-    }
-}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt
index 3640d89..1697900 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt
@@ -54,6 +54,7 @@
 import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
 import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
 import androidx.compose.plugins.kotlin.getKeyValue
+import androidx.compose.plugins.kotlin.isEmitInline
 import org.jetbrains.kotlin.backend.common.lower.irIfThen
 import org.jetbrains.kotlin.backend.common.lower.irNot
 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -109,13 +110,16 @@
         super.visitFunction(declaration)
 
         // Only insert observe scopes in non-empty composable function
-        if (declaration.body == null) return declaration
-        if (!isComposable(declaration)) return declaration
+        if (declaration.body == null)
+            return declaration
+        if (!isComposable(declaration))
+            return declaration
 
         val descriptor = declaration.descriptor
 
         // Do not insert observe scope in an inline function
-        if (descriptor.isInline) return declaration
+        if (descriptor.isInline)
+            return declaration
 
         // Do not insert an observe scope in an inline composable lambda
         descriptor.findPsi()?.let { psi ->
@@ -123,15 +127,19 @@
                 if (InlineUtil.isInlinedArgument(
                         it,
                         context.state.bindingContext,
-                        true
+                        false
                     )
                 )
                     return declaration
+                if (it.isEmitInline(context.state.bindingContext)) {
+                    return declaration
+                }
             }
         }
 
         // Do not insert an observe scope if the funciton has a return result
-        if (descriptor.returnType.let { it == null || !it.isUnit() }) return declaration
+        if (descriptor.returnType.let { it == null || !it.isUnit() })
+            return declaration
 
         // Check if the descriptor has restart scope calls resolved
         val bindingContext = context.state.bindingContext
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/WrapperViewGenerator.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/WrapperViewGenerator.kt
deleted file mode 100644
index b2a8571..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/WrapperViewGenerator.kt
+++ /dev/null
@@ -1,435 +0,0 @@
-package androidx.compose.plugins.kotlin.compiler.lower
-/*
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.ir.IrStatement
-import org.jetbrains.kotlin.ir.declarations.*
-import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
-import org.jetbrains.kotlin.ir.expressions.impl.*
-import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
-import org.jetbrains.kotlin.ir.util.createParameterDeclarations
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
-import androidx.compose.plugins.kotlin.ComposeUtils
-import androidx.compose.plugins.kotlin.ComponentMetadata
-import androidx.compose.plugins.kotlin.buildWithScope
-import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
-
-fun generateWrapperView(context: GeneratorContext, componentMetadata: ComponentMetadata): IrClass {
-    val syntheticClassDescriptor = componentMetadata.wrapperViewDescriptor
-    val wrapperViewIrClass = context.symbolTable.declareClass(-1, -1, IrDeclarationOrigin.DEFINED, syntheticClassDescriptor)
-
-    wrapperViewIrClass.createParameterDeclarations()
-    val wrapperViewReceiverSymbol = wrapperViewIrClass.thisReceiver!!
-    wrapperViewIrClass.declarations.add(generateConstructor(wrapperViewReceiverSymbol, context, componentMetadata))
-    wrapperViewIrClass.declarations.addAll(generateProperties(context, componentMetadata))
-    wrapperViewIrClass.declarations.add(generateOnAttachFunction(wrapperViewReceiverSymbol, context, componentMetadata))
-    wrapperViewIrClass.declarations.add(generateOnDetachFunction(wrapperViewReceiverSymbol, context, componentMetadata))
-    wrapperViewIrClass.declarations.add(generateOnPreDrawFunction(wrapperViewReceiverSymbol, context, componentMetadata))
-    wrapperViewIrClass.declarations.addAll(generateAttributeSetterFunctions(context, componentMetadata))
-
-    return wrapperViewIrClass
-}
-
-private fun generateConstructor(wrapperViewAsThisReceiver: IrValueParameter, context: GeneratorContext, componentMetadata: ComponentMetadata): IrConstructor {
-    val syntheticClassDescriptor = componentMetadata.wrapperViewDescriptor
-    return context.symbolTable.declareConstructor(
-        -1,
-        -1,
-        IrDeclarationOrigin.DEFINED,
-        syntheticClassDescriptor.unsubstitutedPrimaryConstructor
-    )
-        .buildWithScope(context) { constructor ->
-            constructor.createParameterDeclarations()
-            context.symbolTable.introduceValueParameter(wrapperViewAsThisReceiver)
-            val getThisExpr = IrGetValueImpl(-1, -1, wrapperViewAsThisReceiver.symbol)
-
-            val statements = mutableListOf<IrStatement>()
-            val superConstructor =
-                context.symbolTable.referenceConstructor(componentMetadata.wrapperViewDescriptor.getSuperClassNotAny()!!.constructors.single { it.valueParameters.size == 1 })
-            val superCall = IrDelegatingConstructorCallImpl(-1, -1, superConstructor, superConstructor.descriptor, 0).apply {
-                putValueArgument(0, IrGetValueImpl(-1, -1, constructor.valueParameters[0].symbol))
-            }
-
-            statements.add(superCall)
-
-
-            val linearLayoutClass =
-                context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("android.widget.LinearLayout")))!!
-            val linearLayoutParamsClass = linearLayoutClass.unsubstitutedMemberScope.getContributedClassifier(
-                Name.identifier("LayoutParams"),
-                NoLookupLocation.FROM_BACKEND
-            )!! as ClassDescriptor
-            val linearLayoutParamsConstructor =
-                context.symbolTable.referenceConstructor(linearLayoutParamsClass.constructors.single { it.valueParameters.size == 2 && it.valueParameters[0].type == context.moduleDescriptor.builtIns.intType }!!)
-
-            val layoutParams = IrCallImpl(
-                -1, -1, linearLayoutParamsClass.defaultType,
-                linearLayoutParamsConstructor,
-                linearLayoutParamsConstructor.descriptor, null
-            )
-            layoutParams.putValueArgument(
-                0, IrGetFieldImpl(
-                    -1, -1, context.symbolTable.referenceField(
-                        linearLayoutParamsClass.staticScope.getContributedVariables(
-                            Name.identifier("MATCH_PARENT"), NoLookupLocation.FROM_BACKEND
-                        ).single()
-                    )
-                )
-            )
-            layoutParams.putValueArgument(
-                1, IrGetFieldImpl(
-                    -1, -1, context.symbolTable.referenceField(
-                        linearLayoutParamsClass.staticScope.getContributedVariables(
-                            Name.identifier("WRAP_CONTENT"), NoLookupLocation.FROM_BACKEND
-                        ).single()
-                    )
-                )
-            )
-
-            val setLayoutParamsFunction = linearLayoutClass.unsubstitutedMemberScope.getContributedFunctions(
-                Name.identifier("setLayoutParams"),
-                NoLookupLocation.FROM_BACKEND
-            ).single()
-            statements.add(IrInstanceInitializerCallImpl(-1, -1, context.symbolTable.referenceClass(syntheticClassDescriptor)))
-            val setLayoutParamsCall = org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl(
-                -1, -1, context.moduleDescriptor.builtIns.unitType,
-                context.symbolTable.referenceSimpleFunction(setLayoutParamsFunction),
-                setLayoutParamsFunction, null
-            )
-            setLayoutParamsCall.dispatchReceiver = getThisExpr
-            setLayoutParamsCall.putValueArgument(0, layoutParams)
-            statements.add(setLayoutParamsCall)
-
-
-            val componentInstanceProperty = syntheticClassDescriptor.componentInstanceField
-            val componentConstructorDescriptor = componentMetadata.descriptor.unsubstitutedPrimaryConstructor!!
-            val componentConstructor = context.symbolTable.referenceConstructor(componentConstructorDescriptor)
-            val componentConstructorCall = IrCallImpl(
-                -1, -1, componentMetadata.descriptor.defaultType,
-                componentConstructor,
-                componentConstructorDescriptor, null
-            )
-            // this.componentInstance = ComponentClass()
-            statements.add(
-                IrSetFieldImpl(
-                    -1,
-                    -1,
-                    context.symbolTable.referenceField(componentInstanceProperty),
-                    getThisExpr,
-                    componentConstructorCall
-                )
-            )
-
-            // this.dirty = true
-            statements.add(
-                IrSetFieldImpl(
-                    -1, -1,
-                    context.symbolTable.referenceField(syntheticClassDescriptor.dirtyField),
-                    getThisExpr,
-                    IrConstImpl.boolean(-1, -1, context.builtIns.booleanType, true)
-                )
-            )
-
-            val ccClass =
-                context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(ComposeUtils.composeFqName("CompositionContext")))!!
-
-            val ccCreateDescriptor = ccClass
-                .companionObjectDescriptor
-                ?.unsubstitutedMemberScope
-                ?.getContributedFunctions(Name.identifier("create"), NoLookupLocation.FROM_BACKEND)
-                ?.single()!!
-
-            val ccCreateCall = IrCallImpl(
-                -1, -1,
-                context.symbolTable.referenceSimpleFunction(ccCreateDescriptor),
-                ccCreateDescriptor
-            )
-
-            ccCreateCall.dispatchReceiver = IrGetObjectValueImpl(
-                -1, -1,
-                ccClass.companionObjectDescriptor!!.defaultType,
-                context.symbolTable.referenceClass(ccClass.companionObjectDescriptor!!)
-            )
-
-            // context (Context)
-            ccCreateCall.putValueArgument(0, IrGetValueImpl(-1, -1, constructor.valueParameters[0].symbol))
-
-            // this (ViewGroup)
-            ccCreateCall.putValueArgument(1, getThisExpr)
-
-            // this.componentInstance (Component)
-            ccCreateCall.putValueArgument(
-                2, IrGetFieldImpl(
-                    -1, -1,
-                    context.symbolTable.referenceField(componentInstanceProperty),
-                    getThisExpr
-                )
-            )
-
-            // this.compositionContext = CompositionContext.create(context, this, instance)
-            statements.add(
-                IrSetFieldImpl(
-                    -1, -1,
-                    context.symbolTable.referenceField(syntheticClassDescriptor.compositionContextField),
-                    getThisExpr,
-                    ccCreateCall
-                )
-            )
-
-            constructor.body = IrBlockBodyImpl(-1, -1, statements)
-        }
-}
-
-private fun generateOnAttachFunction(wrapperViewAsThisReceiver: IrValueParameter, context: GeneratorContext, componentMetadata: ComponentMetadata): IrFunction {
-    val syntheticClassDescriptor = componentMetadata.wrapperViewDescriptor
-    val functionDescriptor = syntheticClassDescriptor.onAttachDescriptor
-    val viewDescriptor = context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("android.view.View")))!!
-        val viewGroupDescriptor =
-        context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("android.view.ViewGroup")))!!
-    val viewTreeObserverDescriptor =
-        context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("android.view.ViewTreeObserver")))!!
-    return context.symbolTable.declareSimpleFunction(-1, -1, IrDeclarationOrigin.DEFINED, functionDescriptor)
-        .buildWithScope(context) { irFunction ->
-            irFunction.createParameterDeclarations()
-            context.symbolTable.introduceValueParameter(wrapperViewAsThisReceiver)
-            val getThisExpr = IrGetValueImpl(-1, -1, wrapperViewAsThisReceiver.symbol)
-
-            val superFunction = viewGroupDescriptor.unsubstitutedMemberScope.getContributedFunctions(
-                Name.identifier("onAttachedToWindow"),
-                NoLookupLocation.FROM_BACKEND
-            ).single()
-            val superCall = IrCallImpl(
-                -1, -1,
-                context.moduleDescriptor.builtIns.unitType,
-                context.symbolTable.referenceSimpleFunction(superFunction),
-                superFunction
-                , null, null, context.symbolTable.referenceClass(syntheticClassDescriptor.getSuperClassNotAny()!!)
-            )
-            superCall.dispatchReceiver = getThisExpr
-
-            val getViewTreeObserverFunction = viewDescriptor
-                .unsubstitutedMemberScope
-                .getContributedFunctions(Name.identifier("getViewTreeObserver"), NoLookupLocation.FROM_BACKEND)
-                .single()
-            val getViewTreeObserverCall = IrCallImpl(
-                -1, -1,
-                context.symbolTable.referenceSimpleFunction(getViewTreeObserverFunction)
-            )
-            getViewTreeObserverCall.dispatchReceiver = getThisExpr
-
-            val addOnPreDrawListenerFunction = viewTreeObserverDescriptor
-                .unsubstitutedMemberScope
-                .getContributedFunctions(Name.identifier("addOnPreDrawListener"), NoLookupLocation.FROM_BACKEND)
-                .single()
-
-            val addOnPreDrawListenerCall = IrCallImpl(
-                -1, -1,
-                context.symbolTable.referenceSimpleFunction(addOnPreDrawListenerFunction)
-            )
-
-            addOnPreDrawListenerCall.dispatchReceiver = getViewTreeObserverCall
-            addOnPreDrawListenerCall.putValueArgument(0, getThisExpr)
-
-            irFunction.body = IrBlockBodyImpl(-1, -1, listOf(superCall, addOnPreDrawListenerCall))
-        }
-}
-
-private fun generateOnDetachFunction(wrapperViewAsThisReceiver: IrValueParameter, context: GeneratorContext, componentMetadata: ComponentMetadata): IrFunction {
-    val syntheticClassDescriptor = componentMetadata.wrapperViewDescriptor
-    val functionDescriptor = syntheticClassDescriptor.onDetachDescriptor
-    val viewDescriptor = context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("android.view.View")))!!
-    val viewGroupDescriptor =
-        context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("android.view.ViewGroup")))!!
-    val viewTreeObserverDescriptor =
-        context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName("android.view.ViewTreeObserver")))!!
-    return context.symbolTable.declareSimpleFunction(-1, -1, IrDeclarationOrigin.DEFINED, functionDescriptor)
-        .buildWithScope(context) { irFunction ->
-            irFunction.createParameterDeclarations()
-            context.symbolTable.introduceValueParameter(wrapperViewAsThisReceiver)
-            val getThisExpr = IrGetValueImpl(-1, -1, wrapperViewAsThisReceiver.symbol)
-
-            val superFunction = viewGroupDescriptor.unsubstitutedMemberScope.getContributedFunctions(
-                Name.identifier("onDetachedFromWindow"),
-                NoLookupLocation.FROM_BACKEND
-            ).single()
-            val superCall = IrCallImpl(
-                -1, -1,
-                context.moduleDescriptor.builtIns.unitType,
-                context.symbolTable.referenceSimpleFunction(superFunction),
-                superFunction
-                , null, null, context.symbolTable.referenceClass(syntheticClassDescriptor.getSuperClassNotAny()!!)
-            )
-            superCall.dispatchReceiver = getThisExpr
-
-            val getViewTreeObserverFunction = viewDescriptor
-                .unsubstitutedMemberScope
-                .getContributedFunctions(Name.identifier("getViewTreeObserver"), NoLookupLocation.FROM_BACKEND)
-                .single()
-            val getViewTreeObserverCall = IrCallImpl(
-                -1, -1,
-                context.symbolTable.referenceSimpleFunction(getViewTreeObserverFunction)
-            )
-            getViewTreeObserverCall.dispatchReceiver = getThisExpr
-
-            val removeOnPreDrawListenerFunction = viewTreeObserverDescriptor
-                .unsubstitutedMemberScope
-                .getContributedFunctions(Name.identifier("removeOnPreDrawListener"), NoLookupLocation.FROM_BACKEND)
-                .single()
-
-            val removeOnPreDrawListenerCall = IrCallImpl(
-                -1, -1,
-                context.symbolTable.referenceSimpleFunction(removeOnPreDrawListenerFunction)
-            )
-
-            removeOnPreDrawListenerCall.dispatchReceiver = getViewTreeObserverCall
-            removeOnPreDrawListenerCall.putValueArgument(0, getThisExpr)
-
-            irFunction.body = IrBlockBodyImpl(-1, -1, listOf(superCall, removeOnPreDrawListenerCall))
-        }
-}
-
-private fun generateOnPreDrawFunction(wrapperViewAsThisReceiver: IrValueParameter, context: GeneratorContext, componentMetadata: ComponentMetadata): IrFunction {
-    val syntheticClassDescriptor = componentMetadata.wrapperViewDescriptor
-    val functionDescriptor = syntheticClassDescriptor.onPreDraw
-    val compositionContextDescriptor =
-        context.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(ComposeUtils.composeFqName("CompositionContext")))!!
-    return context.symbolTable.declareSimpleFunction(-1, -1, IrDeclarationOrigin.DEFINED, functionDescriptor)
-        .buildWithScope(context) { irFunction ->
-            irFunction.createParameterDeclarations()
-            context.symbolTable.introduceValueParameter(wrapperViewAsThisReceiver)
-            val getThisExpr = IrGetValueImpl(-1, -1, wrapperViewAsThisReceiver.symbol)
-
-
-            val getDirtyCall = IrGetFieldImpl(
-                -1, -1,
-                context.symbolTable.referenceField(syntheticClassDescriptor.dirtyField),
-                getThisExpr
-            )
-
-            val setDirtyFalseCall = IrSetFieldImpl(
-                -1, -1,
-                context.symbolTable.referenceField(syntheticClassDescriptor.dirtyField),
-                getThisExpr,
-                IrConstImpl.boolean(-1, -1, context.builtIns.booleanType, false)
-            )
-
-            val getCompositionContextCall = IrGetFieldImpl(
-                -1, -1,
-                context.symbolTable.referenceField(syntheticClassDescriptor.compositionContextField),
-                getThisExpr
-            )
-
-            val recomposeFromRootFunction = compositionContextDescriptor
-                .unsubstitutedMemberScope
-                .getContributedFunctions(Name.identifier("recompose"), NoLookupLocation.FROM_BACKEND)
-                .single()
-            val recomposeFromRootExpr = IrCallImpl(
-                -1, -1,
-                context.symbolTable.referenceFunction(recomposeFromRootFunction)
-            ).apply {
-                dispatchReceiver = getCompositionContextCall
-                putValueArgument(0, IrGetFieldImpl(
-                    -1,
-                    -1,
-                    context.symbolTable.referenceField(syntheticClassDescriptor.componentInstanceField),
-                    getThisExpr
-                ))
-            }
-
-            val ifDirtyExpr = IrIfThenElseImpl(
-                -1, -1,
-                context.builtIns.unitType,
-                getDirtyCall,
-
-                IrBlockImpl(
-                    -1, -1,
-                    context.builtIns.unitType,
-                    null,
-                    listOf(recomposeFromRootExpr, setDirtyFalseCall)
-                )
-            )
-
-            val returnTrue = IrReturnImpl(-1, -1, irFunction.symbol, IrConstImpl.boolean(-1, -1, context.builtIns.booleanType, true))
-
-            irFunction.body = IrBlockBodyImpl(-1, -1, listOf(ifDirtyExpr, returnTrue))
-        }
-}
-
-private fun generateAttributeSetterFunctions(context: GeneratorContext, componentMetadata: ComponentMetadata): Collection<IrFunction> {
-    val output = mutableListOf<IrFunction>()
-    for (functionDescriptor in componentMetadata.wrapperViewDescriptor.setterMethodDescriptors) {
-        val irFunction = context.symbolTable.declareSimpleFunction(-1, -1, IrDeclarationOrigin.DEFINED, functionDescriptor)
-            .buildWithScope(context) { irFunction ->
-                irFunction.createParameterDeclarations()
-                val wrapperViewAsThisReceiver = irFunction.dispatchReceiverParameter!!.symbol
-
-                val componentInstanceField = componentMetadata.wrapperViewDescriptor.componentInstanceField
-                context.symbolTable.introduceValueParameter(irFunction.valueParameters[0])
-
-                val componentAttribute = componentMetadata.getAttributeDescriptors()
-                    .single({ it.name.identifier == ComposeUtils.propertyNameFromSetterMethod(irFunction.name.identifier) })
-
-                val componentInstance = IrGetFieldImpl(
-                    -1,
-                    -1,
-                    context.symbolTable.referenceField(componentInstanceField),
-                    IrGetValueImpl(-1, -1, wrapperViewAsThisReceiver)
-                )
-
-                val newAttributeValue =
-                    IrGetValueImpl(-1, -1, context.symbolTable.referenceValueParameter(functionDescriptor.valueParameters[0]))
-
-                val setAttributeOnComponentInstruction =
-                    if (componentAttribute.setter != null) {
-                        val setAttributeOnComponentCall = IrSetterCallImpl(
-                            -1,
-                            -1,
-                            context.symbolTable.referenceFunction(componentAttribute.setter!!),
-                            componentAttribute.setter!!,
-                            0
-                        )
-                        setAttributeOnComponentCall.dispatchReceiver = componentInstance
-                        setAttributeOnComponentCall.putValueArgument(0, newAttributeValue)
-                        setAttributeOnComponentCall
-                    } else {
-                        IrSetFieldImpl(-1, -1, context.symbolTable.referenceField(componentAttribute), componentInstance, newAttributeValue)
-                    }
-
-                // TODO: Invalidate the WrapperView using Leland's new WrapperView API (pending commit of that API)
-
-                irFunction.body = IrBlockBodyImpl(-1, -1, listOf(setAttributeOnComponentInstruction /*, invalidateCall */))
-            }
-        output.add(irFunction)
-    }
-    return output
-}
-
-
-private fun generateProperties(context: GeneratorContext, componentMetadata: ComponentMetadata) = listOf(
-    context.symbolTable.declareField(
-        -1, -1,
-        IrDeclarationOrigin.DEFINED,
-        componentMetadata
-            .wrapperViewDescriptor
-            .componentInstanceField
-    ),
-    context.symbolTable.declareField(
-        -1, -1,
-        IrDeclarationOrigin.DEFINED,
-        componentMetadata
-            .wrapperViewDescriptor
-            .compositionContextField
-    ),
-    context.symbolTable.declareField(
-        -1, -1,
-        IrDeclarationOrigin.DEFINED,
-        componentMetadata
-            .wrapperViewDescriptor
-            .dirtyField
-    )
-)
-        */
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/diagnosticsUtils.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/diagnosticsUtils.kt
deleted file mode 100644
index d6fd0f9..0000000
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/diagnosticsUtils.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.kotlin
-
-import com.intellij.psi.PsiElement
-import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
-import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
-import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2
-import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
-import org.jetbrains.kotlin.diagnostics.reportFromPlugin
-import androidx.compose.plugins.kotlin.analysis.ComposeDefaultErrorMessages
-import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
-
-fun <E : PsiElement> DiagnosticFactory0<E>.report(
-    context: ExpressionTypingContext,
-    elements: Collection<E>
-) {
-    elements.forEach {
-        context.trace.reportFromPlugin(
-            on(it),
-            ComposeDefaultErrorMessages
-        )
-    }
-}
-
-fun <E : PsiElement, T1> DiagnosticFactory1<E, T1>.report(
-    context: ExpressionTypingContext,
-    elements: Collection<E>,
-    value1: T1
-) {
-    elements.forEach {
-        context.trace.reportFromPlugin(
-            on(it, value1),
-            ComposeDefaultErrorMessages
-        )
-    }
-}
-
-fun <E : PsiElement, T1, T2> DiagnosticFactory2<E, T1, T2>.report(
-    context: ExpressionTypingContext,
-    elements: Collection<E>,
-    value1: T1,
-    value2: T2
-) {
-    elements.forEach {
-        context.trace.reportFromPlugin(
-            on(it, value1, value2),
-            ComposeDefaultErrorMessages
-        )
-    }
-}
-
-fun <E : PsiElement, T1, T2, T3> DiagnosticFactory3<E, T1, T2, T3>.report(
-    context: ExpressionTypingContext,
-    elements: Collection<E>,
-    value1: T1,
-    value2: T2,
-    value3: T3
-) {
-    elements.forEach {
-        context.trace.reportFromPlugin(
-            on(it, value1, value2, value3),
-            ComposeDefaultErrorMessages
-        )
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/frames/FrameIrTransformer.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/frames/FrameIrTransformer.kt
index ad5f7a65..a46fc4e 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/frames/FrameIrTransformer.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/frames/FrameIrTransformer.kt
@@ -48,7 +48,6 @@
 import org.jetbrains.kotlin.incremental.components.LookupLocation
 import org.jetbrains.kotlin.incremental.components.NoLookupLocation
 import org.jetbrains.kotlin.ir.IrElement
-import org.jetbrains.kotlin.ir.IrKtxStatement
 import org.jetbrains.kotlin.ir.IrStatement
 import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
 import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
@@ -628,10 +627,6 @@
             if (filter(element)) elements.add(element)
             element.acceptChildren(this, null)
         }
-
-        override fun visitKtxStatement(expression: IrKtxStatement, data: Nothing?) {
-            expression.acceptChildren(this, null)
-        }
     }, null)
     return elements
 }
@@ -648,11 +643,6 @@
                 }
             }
         }
-
-        override fun visitKtxStatement(expression: IrKtxStatement, data: Nothing?) {
-            if (!result)
-                expression.acceptChildren(this, null)
-        }
     }, null)
     return result
 }
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/AttributeInfoExtractor.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/AttributeInfoExtractor.kt
deleted file mode 100644
index 0971090..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/AttributeInfoExtractor.kt
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.idea
-
-import org.jetbrains.kotlin.builtins.extractParameterNameFromFunctionTypeArgument
-import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
-import org.jetbrains.kotlin.descriptors.CallableDescriptor
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
-import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.descriptors.VariableDescriptor
-import org.jetbrains.kotlin.descriptors.annotations.Annotated
-import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
-import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
-import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
-import org.jetbrains.kotlin.idea.caches.resolve.util.getResolveScope
-import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
-import org.jetbrains.kotlin.idea.inspections.collections.isFunctionOfAnyKind
-import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.isChildOf
-import org.jetbrains.kotlin.psi.KtDeclaration
-import org.jetbrains.kotlin.psi.KtFile
-import androidx.compose.plugins.kotlin.ComposeUtils
-import androidx.compose.plugins.kotlin.ResolvedKtxElementCall
-import androidx.compose.plugins.kotlin.hasHiddenAttributeAnnotation
-import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
-import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
-import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.TypeProjection
-import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
-import org.jetbrains.kotlin.types.typeUtil.isUnit
-import org.jetbrains.kotlin.types.typeUtil.supertypes
-
-data class AttributeInfo(
-    val name: String,
-    val type: KotlinType
-) {
-    var isImmediate: Boolean = false
-    var isRequired: Boolean = false
-    var isExtension: Boolean = false
-    var isChildren: Boolean = false
-    var isPivotal: Boolean = false
-    var isImported: Boolean = false
-    var descriptor: DeclarationDescriptor? = null
-    var contributingDescriptor: ClassifierDescriptor? = null
-    var extensionType: KotlinType? = null
-}
-
-class AttributeInfoExtractor(
-    file: KtFile,
-    // TODO(jdemeulenaere): Remove those params and try to share more code instead.
-    private val visibilityFilter: (DeclarationDescriptor) -> Boolean,
-    declarationTranslator: (KtDeclaration) -> KtDeclaration? = { it },
-    private val ktxCall: ResolvedKtxElementCall? = null
-) {
-    private val module = file.findModuleDescriptor()
-    private val composeComponentDescriptor =
-        module.findClassAcrossModuleDependencies(
-            ClassId.topLevel(ComposeUtils.composeFqName("Component"))
-        )
-    private val androidViewDescriptor =
-        module.findClassAcrossModuleDependencies(
-            ClassId.topLevel(FqName("android.view.View"))
-        )
-    private val indicesHelper = KotlinIndicesHelper(
-        file.getResolutionFacade(),
-        getResolveScope(file),
-        visibilityFilter,
-        declarationTranslator,
-        file = file
-    )
-
-    private val ktxCallResolvedCalls by lazy { ktxCall?.emitOrCall?.resolvedCalls() ?: emptyList() }
-    private val referrableDescriptors by lazy {
-        ktxCallResolvedCalls
-            .map {
-                val resultingDescriptor = it.resultingDescriptor
-                val result: DeclarationDescriptor = when {
-                    it is VariableAsFunctionResolvedCall -> it.variableCall.candidateDescriptor
-                    resultingDescriptor is ConstructorDescriptor ->
-                        resultingDescriptor.constructedClass
-                    else -> resultingDescriptor
-                }
-                result
-            }
-    }
-
-    private val instanceTypes by lazy {
-        ktxCallResolvedCalls
-            .mapNotNull { it.resultingDescriptor.returnType }
-            .filter { !it.isUnit() }
-    }
-
-    private fun isDescriptorReferredTo(descriptor: DeclarationDescriptor?): Boolean {
-        return descriptor in referrableDescriptors
-    }
-
-    fun extract(tagDescriptor: DeclarationDescriptor, receiver: (Sequence<AttributeInfo>) -> Unit) {
-        when (tagDescriptor) {
-            is ClassDescriptor -> {
-                receiver(
-                    tagDescriptor
-                        .constructors
-                        .filter { visibilityFilter(it) }
-                        .flatMap { it.valueParameters }
-                        .asSequence()
-                        .mapNotNull { it.constructAttributeInfo(isImported = true) }
-                )
-
-                receiver(
-                    tagDescriptor
-                        .unsubstitutedMemberScope
-                        .getContributedDescriptors()
-                        .filter { it.isValidAttribute() }
-                        .filter { visibilityFilter(it) }
-                        .asSequence()
-                        .mapNotNull { it.constructAttributeInfo(isImported = true) }
-                )
-
-                val defaultType = tagDescriptor.defaultType
-                receiver(
-                    indicesHelper
-                        .getCallableTopLevelExtensions(
-                            callTypeAndReceiver = CallTypeAndReceiver.DEFAULT,
-                            receiverTypes = listOf(defaultType),
-                            nameFilter = { true },
-                            declarationFilter = { true }
-                        )
-                        .filter { it.isValidAttribute() }
-                        // We don't `.filter { visibilityFilter(it) }` as KotlinIndicesHelper was instantiated with that filter already.
-                        .asSequence()
-                        .mapNotNull { it.constructAttributeInfo(isImported = true) }
-                )
-            }
-            is FunctionDescriptor -> {
-                receiver(
-                    tagDescriptor
-                        .valueParameters
-                        .asSequence()
-                        .mapNotNull { it.constructAttributeInfo(isImported = true) }
-                )
-            }
-            is VariableDescriptor -> {
-                if (tagDescriptor.type.isFunctionOfAnyKind()) {
-                    receiver(
-                        tagDescriptor.type
-                            .getValueParameterTypesFromFunctionType()
-                            .asSequence()
-                            .mapNotNull { it.constructAttributeInfo() }
-                    )
-                }
-            }
-        }
-    }
-
-    private fun DeclarationDescriptor.isValidAttribute(): Boolean {
-        return when (this) {
-            is FunctionDescriptor -> {
-                when {
-                    valueParameters.size != 1 -> false
-                    returnType?.isUnit() != true -> false
-                    // only void setters are allowed
-                    else -> ComposeUtils.isSetterMethodName(name.identifier)
-                }
-            }
-            is PropertyDescriptor -> isVar
-            else -> false
-        }
-    }
-
-    // TODO(jdemeulenaere): This kind of code is duplicated multiple times in different files. Extract and refactor in a single extension.
-    private val composeChildrenAnnotationFqName = ComposeUtils.composeFqName("Children")
-    private fun Annotated.hasChildrenAnnotation() =
-        annotations.hasAnnotation(composeChildrenAnnotationFqName)
-
-    private fun TypeProjection.constructAttributeInfo(): AttributeInfo? {
-        return AttributeInfo(
-            name = type.extractParameterNameFromFunctionTypeArgument()?.asString() ?: return null,
-            type = type
-        ).also {
-            it.descriptor = null
-            it.isChildren = type.hasChildrenAnnotation()
-            it.isRequired = true
-            it.isExtension = false
-            it.isImmediate = true
-            it.isImported = true
-            it.isPivotal = false
-            it.contributingDescriptor = null
-            it.extensionType = null
-        }
-    }
-
-    private fun DeclarationDescriptor.constructAttributeInfo(isImported: Boolean): AttributeInfo? {
-        if (shouldFilter(this)) return null
-
-        return AttributeInfo(
-            name = when (this) {
-                is FunctionDescriptor -> ComposeUtils.propertyNameFromSetterMethod(name.asString())
-                else -> name.asString()
-            },
-            type = when (this) {
-                is FunctionDescriptor -> valueParameters.firstOrNull()?.type ?: return null
-                is PropertyDescriptor -> type
-                is ValueParameterDescriptor -> type
-                else -> return null
-            }
-        ).also {
-            it.descriptor = this
-            it.isChildren = hasChildrenAnnotation()
-            it.isRequired = when (this) {
-                is PropertyDescriptor -> {
-                    isLateInit || !isVar
-                }
-                is FunctionDescriptor -> false
-                is ValueParameterDescriptor -> {
-                    !hasDefaultValue()
-                }
-                else -> false
-            }
-            it.isExtension = isExtension
-            it.isImmediate = when {
-                this is CallableMemberDescriptor && kind ==
-                        CallableMemberDescriptor.Kind.FAKE_OVERRIDE -> false
-                isDescriptorReferredTo(containingDeclaration) -> true
-                containingDeclaration is ConstructorDescriptor &&
-                        isDescriptorReferredTo(containingDeclaration?.containingDeclaration) -> true
-                else -> false
-            }
-            it.isImported = isImported
-            it.isPivotal = when (this) {
-                is PropertyDescriptor -> !isVar && !isExtension
-                is ValueParameterDescriptor -> {
-                    // TODO(lmr): decide if we still want/need this with new type resolution
-                    false // in this case there is no component instance, so nothing is pivotal
-                }
-                else -> false
-            }
-            it.contributingDescriptor = when (this) {
-                is FunctionDescriptor -> getContributingDescriptor(this)
-                is PropertyDescriptor -> getContributingDescriptor(this)
-                else -> null
-            }
-            it.extensionType = when (this) {
-                is FunctionDescriptor -> getExtensionType(this)
-                is PropertyDescriptor -> getExtensionType(this)
-                else -> null
-            }
-        }
-    }
-
-    private fun getContributingDescriptor(d: CallableMemberDescriptor): ClassifierDescriptor? {
-        return DescriptorUtils.unwrapFakeOverride(d).containingDeclaration as? ClassifierDescriptor
-    }
-
-    private fun getExtensionType(d: CallableDescriptor): KotlinType? {
-        val receiverParameter = d.extensionReceiverParameter ?: return null
-
-        if (receiverParameter.value.original.type.isTypeParameter()) {
-            return receiverParameter.value.original.type.supertypes().firstOrNull()
-        }
-        return receiverParameter.type
-    }
-
-    private val kotlinxAndroidSyntheticFqname = FqName("kotlinx.android.synthetic")
-    private fun shouldFilter(d: DeclarationDescriptor): Boolean {
-        if (d.fqNameSafe.isChildOf(kotlinxAndroidSyntheticFqname)) return true
-        if (d.hasHiddenAttributeAnnotation()) return true
-        val name = d.name.asString()
-
-        when (name) {
-            "_firstFrameRecord",
-            "setRecompose" -> {
-                if (d is CallableMemberDescriptor) {
-                    val realDescriptor = getContributingDescriptor(d)
-                    if (realDescriptor != null && realDescriptor != d &&
-                        realDescriptor == composeComponentDescriptor) {
-                        return true
-                    }
-                }
-            }
-        }
-
-        // NOTE(lmr): View subclasses all have constructors with these params. We handle view creation somewhat automatically, and
-        // we don't want these params to show up in the autocomplete despite people technically being able to use them. This is
-        // kind of a gross way of removing them but seems to be a reasonably effective strategy.
-        when (name) {
-            "context",
-            "attrs",
-            "defStyle",
-            "defStyleRes",
-            "defStyleAttr" -> {
-                if (
-                    d is ValueParameterDescriptor &&
-                    d.containingDeclaration is ConstructorDescriptor
-                ) {
-                    val cd = d.containingDeclaration.containingDeclaration as? ClassDescriptor
-                    if (
-                        cd != null &&
-                        androidViewDescriptor != null &&
-                        cd.isSubclassOf(androidViewDescriptor)
-                    ) {
-                        return true
-                    }
-                }
-            }
-        }
-
-        return false
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/ComposeBundle.java b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/ComposeBundle.java
deleted file mode 100644
index 25702d5..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/ComposeBundle.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package androidx.compose.plugins.idea;
-
-import com.intellij.CommonBundle;
-
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.PropertyKey;
-
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-import java.util.ResourceBundle;
-
-/**
- * Compose resource bundle
- */
-public class ComposeBundle {
-    private static Reference<ResourceBundle> sOurBundle;
-
-    @NonNls
-    private static final String BUNDLE = "androidx.compose.plugins.idea.ComposeBundle";
-
-    private ComposeBundle() {
-    }
-
-    /**
-     * Get a message by key
-     * @param key The key for the message
-     * @param params Substitution parameters
-     * @return the localized message
-     */
-    @NotNull
-    public static String message(
-            @NonNls @PropertyKey(resourceBundle = BUNDLE) String key,
-            Object... params
-    ) {
-        return CommonBundle.message(getBundle(), key, params);
-    }
-
-    private static ResourceBundle getBundle() {
-        ResourceBundle bundle = null;
-        if (sOurBundle != null) bundle = sOurBundle.get();
-        if (bundle == null) {
-            bundle = ResourceBundle.getBundle(BUNDLE);
-            sOurBundle = new SoftReference<ResourceBundle>(bundle);
-        }
-        return bundle;
-    }
-}
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/Utils.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/Utils.kt
deleted file mode 100644
index 7140099..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/Utils.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.idea
-
-import com.intellij.psi.PsiComment
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiErrorElement
-import com.intellij.psi.PsiWhiteSpace
-import org.jetbrains.kotlin.psi.KtBlockExpression
-import org.jetbrains.kotlin.psi.psiUtil.nextLeaf
-import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
-
-internal inline fun <reified T : PsiElement> PsiElement.parentOfType(): T? {
-    var node: PsiElement? = this
-    while (node != null) {
-        if (node is T) return node
-        node = node.parent
-    }
-    return null
-}
-
-private val nonWhiteSpaceFilter = { it: PsiElement ->
-    when (it) {
-        is PsiWhiteSpace -> false
-        is PsiComment -> false
-        is KtBlockExpression -> false
-        is PsiErrorElement -> false
-        else -> true
-    }
-}
-internal fun PsiElement.getNextLeafIgnoringWhitespace(includeSelf: Boolean = false): PsiElement? =
-    if (includeSelf && nonWhiteSpaceFilter(this)) this else nextLeaf(
-        nonWhiteSpaceFilter
-    )
-
-internal fun PsiElement.getPrevLeafIgnoringWhitespace(includeSelf: Boolean = false): PsiElement? =
-    if (includeSelf && nonWhiteSpaceFilter(this)) this else prevLeaf(
-        nonWhiteSpaceFilter
-    )
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/BaseComposeCompletionSession.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/BaseComposeCompletionSession.kt
deleted file mode 100644
index d27a59a..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/BaseComposeCompletionSession.kt
+++ /dev/null
@@ -1,152 +0,0 @@
-package androidx.compose.plugins.idea.completion
-
-import com.intellij.codeInsight.completion.CompletionParameters
-import com.intellij.codeInsight.completion.CompletionResultSet
-import com.intellij.psi.JavaPsiFacade
-import com.intellij.psi.PsiClass
-import org.jetbrains.kotlin.builtins.extractParameterNameFromFunctionTypeArgument
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
-import org.jetbrains.kotlin.descriptors.VariableDescriptor
-import org.jetbrains.kotlin.descriptors.annotations.Annotated
-import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
-import org.jetbrains.kotlin.idea.completion.CompletionSession
-import org.jetbrains.kotlin.idea.completion.CompletionSessionConfiguration
-import org.jetbrains.kotlin.idea.completion.ToFromOriginalFileMapper
-import org.jetbrains.kotlin.idea.core.ExpectedInfo
-import org.jetbrains.kotlin.idea.core.isExcludedFromAutoImport
-import org.jetbrains.kotlin.idea.core.isVisible
-import org.jetbrains.kotlin.idea.inspections.collections.isFunctionOfAnyKind
-import org.jetbrains.kotlin.idea.util.getResolutionScope
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtExpression
-import androidx.compose.plugins.kotlin.ComposeUtils
-import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
-import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
-import org.jetbrains.kotlin.types.KotlinType
-
-abstract class BaseComposeCompletionSession(
-    configuration: CompletionSessionConfiguration,
-    parameters: CompletionParameters,
-    toFromOriginalFileMapper: ToFromOriginalFileMapper,
-    resultSet: CompletionResultSet
-) : CompletionSession(configuration, parameters, toFromOriginalFileMapper, resultSet) {
-    override val descriptorKindFilter: DescriptorKindFilter?
-        get() = TODO("not implemented")
-    override val expectedInfos: Collection<ExpectedInfo>
-        get() = emptyList()
-
-    protected val cursorElement = expression ?: error("expression cannot be null")
-    protected val module = resolutionFacade.moduleDescriptor
-
-    protected val scope = cursorElement.getResolutionScope(bindingContext, resolutionFacade)
-
-    protected val composeComponentDescriptor =
-        module.findClassAcrossModuleDependencies(
-            ClassId.topLevel(ComposeUtils.composeFqName("Component"))
-        )
-    protected val androidViewDescriptor =
-        module.findClassAcrossModuleDependencies(
-            ClassId.topLevel(FqName("android.view.View"))
-        )
-    protected val androidViewGroupDescriptor =
-        module.findClassAcrossModuleDependencies(
-            ClassId.topLevel(FqName("android.view.ViewGroup"))
-        )
-
-    protected val composeChildrenAnnotationFqName = ComposeUtils.composeFqName("Children")
-    protected val composeComposableAnnotationFqName = ComposeUtils.composeFqName("Composable")
-
-    protected val psiFacade = JavaPsiFacade.getInstance(project)
-
-    protected val androidViewPsiClass = psiFacade.findClass("android.view.View", searchScope)
-    protected val androidViewGroupPsiClass =
-        psiFacade.findClass("android.view.ViewGroup", searchScope)
-
-    protected fun DeclarationDescriptor.isVisibleDescriptor(): Boolean {
-        if (this is TypeParameterDescriptor && !isTypeParameterVisible(this))
-            return false
-
-        if (this is DeclarationDescriptorWithVisibility) {
-            return isVisible(
-                cursorElement,
-                callTypeAndReceiver.receiver as? KtExpression,
-                bindingContext,
-                resolutionFacade
-            )
-        }
-
-        if (isExcludedFromAutoImport(file.project, file)) return false
-
-        return true
-    }
-
-    private fun isTypeParameterVisible(typeParameter: TypeParameterDescriptor): Boolean {
-        val owner = typeParameter.containingDeclaration
-        var parent: DeclarationDescriptor? = inDescriptor
-        while (parent != null) {
-            if (parent == owner) return true
-            if (parent is ClassDescriptor && !parent.isInner) return false
-            parent = parent.containingDeclaration
-        }
-        return true
-    }
-
-    protected fun Annotated.hasChildrenAnnotation() =
-        annotations.hasAnnotation(composeChildrenAnnotationFqName)
-    protected fun Annotated.hasComposableAnnotation() =
-        annotations.hasAnnotation(composeComposableAnnotationFqName)
-
-    protected fun DeclarationDescriptor.allowsChildren(): Boolean {
-        return when (this) {
-            is ClassDescriptor -> when {
-                androidViewGroupDescriptor != null && isSubclassOf(androidViewGroupDescriptor) ->
-                    true
-                unsubstitutedMemberScope.getContributedDescriptors().any {
-                    it.hasChildrenAnnotation()
-                } -> true
-                unsubstitutedPrimaryConstructor?.valueParameters?.any {
-                    it.hasChildrenAnnotation()
-                } ?: false -> true
-                else -> false
-            }
-            is FunctionDescriptor -> when {
-                valueParameters.any { it.hasChildrenAnnotation() } -> true
-                else -> false
-            }
-            is VariableDescriptor -> when {
-                type.isFunctionOfAnyKind() && type.arguments.any {
-                    it.type.hasChildrenAnnotation()
-                } -> true
-                else -> false
-            }
-            else -> false
-        }
-    }
-
-    protected fun PsiClass.allowsChildren(): Boolean {
-        // TODO(lmr): if it's a subclass of ViewGroup is a reasonable first order approximation of whether or not it
-        // accepts children or not, but it is not a perfect test by any means. Many "leaf" views subclass ViewGroups
-        // and handle laying out their own children. Perhaps we should have a manually curated list of these?
-        return isSubclassOf(androidViewGroupPsiClass)
-    }
-
-    protected fun PsiClass.isSubclassOf(other: PsiClass?): Boolean {
-        if (other == null) return false
-        var cls: PsiClass? = this
-        while (cls != null) {
-            if (cls == other) return true
-            cls = cls.superClass
-        }
-        return false
-    }
-
-    protected fun KotlinType.functionParameterNames(): List<String> =
-        if (isFunctionOfAnyKind()) arguments.mapNotNull {
-            it.type.extractParameterNameFromFunctionTypeArgument()?.asString()
-        } else emptyList()
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeAttributeCompletionSession.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeAttributeCompletionSession.kt
deleted file mode 100644
index 51a5616..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeAttributeCompletionSession.kt
+++ /dev/null
@@ -1,234 +0,0 @@
-package androidx.compose.plugins.idea.completion
-
-import com.intellij.codeInsight.AutoPopupController
-import com.intellij.codeInsight.completion.CompletionParameters
-import com.intellij.codeInsight.completion.CompletionResultSet
-import com.intellij.codeInsight.completion.CompletionSorter
-import com.intellij.codeInsight.completion.InsertHandler
-import com.intellij.codeInsight.lookup.LookupElement
-import com.intellij.codeInsight.lookup.LookupElementBuilder
-import com.intellij.codeInsight.lookup.LookupElementPresentation
-import com.intellij.codeInsight.lookup.LookupElementRenderer
-import com.intellij.openapi.util.Key
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.ui.JBColor
-import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.idea.completion.CompletionSessionConfiguration
-import org.jetbrains.kotlin.idea.completion.ToFromOriginalFileMapper
-import org.jetbrains.kotlin.idea.completion.isArtificialImportAliasedDescriptor
-import org.jetbrains.kotlin.idea.util.ImportInsertHelper
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.KtxLambdaExpression
-import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import androidx.compose.plugins.idea.AttributeInfo
-import androidx.compose.plugins.idea.AttributeInfoExtractor
-import androidx.compose.plugins.idea.parentOfType
-import org.jetbrains.kotlin.renderer.DescriptorRenderer
-import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
-import org.jetbrains.kotlin.types.typeUtil.isUnit
-
-class ComposeAttributeCompletionSession(
-    configuration: CompletionSessionConfiguration,
-    parameters: CompletionParameters,
-    toFromOriginalFileMapper: ToFromOriginalFileMapper,
-    resultSet: CompletionResultSet
-) : BaseComposeCompletionSession(configuration, parameters, toFromOriginalFileMapper, resultSet) {
-
-    private val elementExpr = cursorElement.parentOfType<KtxElement>()
-        ?: error("no ktx element found")
-    private val usedAttributes = elementExpr.getChildrenOfType<KtxAttribute>()
-    private val hasChildrenLambda =
-        elementExpr.getChildrenOfType<KtxLambdaExpression>().isNotEmpty()
-    private val usedAttributesNameSet = usedAttributes.mapNotNull {
-            attr -> attr.key?.getIdentifier()?.text
-    }.toSet()
-
-    fun isValid() = nullableKtxCall != null
-
-    private val nullableKtxCall =
-        bindingContext.get(ComposeWritableSlices.RESOLVED_KTX_CALL, elementExpr)
-
-    private val ktxCall get() = nullableKtxCall
-        ?: error("no tag info found on element. Call isValid() before using this class")
-
-    private val ktxCallResolvedCalls by lazy {
-        val failedCandidates = bindingContext.get(
-            ComposeWritableSlices.FAILED_CANDIDATES,
-            elementExpr
-        ) ?: emptyList()
-        val resolvedCalls = ktxCall.emitOrCall.resolvedCalls()
-        resolvedCalls + failedCandidates
-    }
-    private val referrableDescriptors by lazy {
-        ktxCallResolvedCalls
-            .map {
-                val resultingDescriptor = it.resultingDescriptor
-                val result: DeclarationDescriptor = when {
-                    it is VariableAsFunctionResolvedCall -> it.variableCall.candidateDescriptor
-                    resultingDescriptor is ConstructorDescriptor ->
-                        resultingDescriptor.constructedClass
-                    else -> resultingDescriptor
-                }
-                result
-            }
-    }
-
-    private val instanceTypes by lazy {
-        ktxCallResolvedCalls
-            .mapNotNull { it.resultingDescriptor.returnType }
-            .filter { !it.isUnit() }
-    }
-
-    private val attributeInfoExtractor = AttributeInfoExtractor(
-        file = file,
-        visibilityFilter = { it.isVisibleDescriptor() },
-        declarationTranslator = { toFromOriginalFileMapper.toSyntheticFile(it) },
-        ktxCall = nullableKtxCall
-    )
-
-    private fun AttributeInfo.constructLookupElement(): LookupElement? {
-        val extensionType = extensionType
-        val contributingDescriptor = contributingDescriptor
-
-        if (usedAttributesNameSet.contains(name)) return null
-
-        // if the user has defined a chilren lambda already, there is no need to add a children attribute to the
-        // autocomplete list
-        if (hasChildrenLambda && isChildren) return null
-
-        // NOTE(lmr): if the attribute is a setter function, the parameter name can often be useful. we should consider using its
-        // name somewhere in here: (attr.descriptor as SimpleFunctionDescriptor).valueParameters.single().name
-
-        var isImmediate = isImmediate
-
-        var myTailText = "=..."
-
-        if (isExtension && extensionType != null) {
-            if (extensionType in instanceTypes) {
-                isImmediate = true
-            }
-            val klass = SHORT_NAMES_RENDERER.renderType(extensionType)
-            myTailText += " (extension on $klass)"
-        }
-
-        if (!isImmediate && !isExtension && contributingDescriptor != null) {
-            val klass = SHORT_NAMES_RENDERER.renderClassifierName(contributingDescriptor)
-            myTailText += " (from $klass)"
-        }
-
-        if (isRequired) {
-            myTailText += " (required)"
-        }
-        if (isPivotal) {
-            myTailText += " (pivotal)"
-        }
-
-        val renderer = object : LookupElementRenderer<LookupElement>() {
-            override fun renderElement(
-                element: LookupElement?,
-                presentation: LookupElementPresentation?
-            ) {
-                if (presentation == null) return
-                with(presentation) {
-                    itemText = name
-                    isItemTextBold = when {
-                        isImmediate || isRequired -> true
-                        else -> false
-                    }
-                    itemTextForeground = when {
-                        isPivotal -> JBColor.RED
-                        isRequired -> JBColor.BLUE
-                        isImmediate -> JBColor.BLACK
-                        else -> JBColor.darkGray
-                    }
-                    typeText = SHORT_NAMES_RENDERER.renderType(type)
-                    if (isExtension) {
-                        appendTailTextItalic(myTailText, true)
-                    } else {
-                        appendTailText(myTailText, true)
-                    }
-                }
-            }
-        }
-
-        return LookupElementBuilder
-            .create(this, name)
-            .withRenderer(renderer)
-            .withInsertHandler(attributeInsertionHandler)
-            .apply {
-                putUserData(DESCRIPTOR, descriptor)
-                putUserData(Weighers.ATTRIBUTE_INFO_KEY, this@constructLookupElement)
-            }
-    }
-
-    override fun doComplete() {
-        for (descriptor in referrableDescriptors) {
-            attributeInfoExtractor.extract(descriptor) { attributeInfos ->
-                attributeInfos.forEach {
-                    // TODO(lmr): use it.getPossibleValues(project) here to get some of the int enum values as well
-                    it.constructLookupElement()?.let { collector.addElement(it) }
-                }
-                flushToResultSet()
-            }
-        }
-    }
-
-    override fun createSorter(): CompletionSorter {
-        return super.createSorter()
-            .weighAfter(
-                "prefix",
-                Weighers.IsRequiredAttribute,
-                Weighers.IsImmediateAttribute,
-                Weighers.IsImported,
-                Weighers.IsChildAttribute
-            )
-    }
-
-    private val attributeInsertionHandler = InsertHandler<LookupElement> { context, item ->
-        val document = context.document
-        val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
-        psiDocumentManager.commitAllDocuments()
-        item.getUserData(DESCRIPTOR)?.let { descriptor ->
-            if (DescriptorUtils.isTopLevelDeclaration(descriptor) &&
-                !descriptor.isArtificialImportAliasedDescriptor) {
-                ImportInsertHelper.getInstance(context.project)
-                    .importDescriptor(context.file as KtFile, descriptor)
-            }
-        }
-        psiDocumentManager.doPostponedOperationsAndUnblockDocument(document)
-
-        val token = context.file.findElementAt(context.startOffset) ?: return@InsertHandler
-        val ktxAttribute = token.parent.parent as? KtxAttribute ?: return@InsertHandler
-
-        // If the attribute has an equals sign already, then we don't need to insert it...
-        if (ktxAttribute.node.findChildByType(KtTokens.EQ) != null) return@InsertHandler
-
-        // NOTE: If we introduce attribute "punning", we will need to do the right thing here...
-
-        val tailOffset = context.tailOffset
-        val moveCaret = context.editor.caretModel.offset == tailOffset
-        val textToInsert = "="
-        document.insertString(tailOffset, textToInsert)
-
-        if (moveCaret) {
-            // move after the '='
-            context.editor.caretModel.moveToOffset(tailOffset + 1)
-
-            // since they just created a new attribute and need to fill out the expression, we might as well open up the autocomplete!
-            AutoPopupController.getInstance(context.project)?.scheduleAutoPopup(context.editor)
-        }
-    }
-
-    companion object {
-        val DESCRIPTOR = Key<DeclarationDescriptor>("compose.descriptor")
-        private val SHORT_NAMES_RENDERER = DescriptorRenderer.SHORT_NAMES_IN_TYPES.withOptions {
-            parameterNamesInFunctionalTypes = false
-        }
-    }
-}
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeCompletionContributor.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeCompletionContributor.kt
deleted file mode 100644
index e1576ae..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeCompletionContributor.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package androidx.compose.plugins.idea.completion
-
-import com.intellij.codeInsight.completion.CompletionContributor
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiWhiteSpace
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtPsiUtil
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.psiUtil.endOffset
-import androidx.compose.plugins.idea.parentOfType
-
-class ComposeCompletionContributor : CompletionContributor() {
-
-    @Suppress("OverridingDeprecatedMember")
-    override fun invokeAutoPopup(position: PsiElement, typeChar: Char): Boolean {
-        when (typeChar) {
-            ' ' -> {
-                if (position.parent?.parent is KtxAttribute) {
-                    // user hit space immediately after an attribute value
-                    return true
-                }
-                val ktxElement = position.parentOfType<KtxElement>() ?: return false
-                val openTag = ktxElement.simpleTagName ?: ktxElement.qualifiedTagName
-                ?: return false
-                // user hit space immediately after the open tag
-                if (position.endOffset == openTag.endOffset) return true
-                if (position is PsiWhiteSpace && position.parent == ktxElement) {
-                    val gt = ktxElement.node.findChildByType(KtTokens.GT) ?: return false
-                    // user hit space in between attributes
-                    if (position.endOffset < gt.startOffset) return true
-                }
-            }
-            '<' -> {
-                if (position.parent is KtxElement) {
-                    // this also happens inside of a KTX Body in some cases
-                    return true
-                }
-                if (KtPsiUtil.isStatementContainer(position.parent)) {
-                    // if the user types a bracket inside of a block, there is a high probability that they are
-                    // starting a ktx tag
-                    return true
-                }
-            }
-        }
-        @Suppress("DEPRECATION")
-        return super.invokeAutoPopup(position, typeChar)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeCompletionExtension.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeCompletionExtension.kt
deleted file mode 100644
index 3dcd7888..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeCompletionExtension.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package androidx.compose.plugins.idea.completion
-
-import com.intellij.codeInsight.completion.CompletionParameters
-import com.intellij.codeInsight.completion.CompletionResultSet
-import org.jetbrains.kotlin.idea.completion.CompletionSessionConfiguration
-import org.jetbrains.kotlin.idea.completion.KotlinCompletionExtension
-import org.jetbrains.kotlin.idea.completion.ToFromOriginalFileMapper
-import org.jetbrains.kotlin.idea.editor.fixers.range
-import org.jetbrains.kotlin.lexer.KtTokens.EQ
-import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.idea.parentOfType
-
-class ComposeCompletionExtension : KotlinCompletionExtension() {
-    override fun perform(parameters: CompletionParameters, result: CompletionResultSet): Boolean {
-        val expr = parameters.position
-        val superParent = expr.parent?.parent
-
-        when (superParent) {
-            is KtDotQualifiedExpression -> {
-                val ktxEl = superParent.parentOfType<KtxElement>()
-                if (ktxEl != null && ktxEl.qualifiedTagName?.range?.contains(expr.range) == true) {
-                    return performKtxTagCompletion(parameters, result)
-                }
-            }
-            is KtxElement -> {
-                return performKtxTagCompletion(parameters, result)
-            }
-            is KtxAttribute -> {
-                if (expr.parent?.prevSibling?.node?.elementType == EQ) {
-                    // we are inside of a ktx expression value... use normal autocomplete
-                    return false
-                }
-                return performKtxAttributeCompletion(parameters, result)
-            }
-        }
-
-        return false
-    }
-
-    private fun performKtxAttributeCompletion(
-        params: CompletionParameters,
-        result: CompletionResultSet
-    ): Boolean {
-        val session = ComposeAttributeCompletionSession(
-            CompletionSessionConfiguration(params),
-            params,
-            ToFromOriginalFileMapper.create(params),
-            result
-        )
-
-        if (!session.isValid()) return false
-
-        session.complete()
-
-        return true
-    }
-
-    private fun performKtxTagCompletion(
-        params: CompletionParameters,
-        result: CompletionResultSet
-    ): Boolean {
-        ComposeTagCompletionSession(
-            CompletionSessionConfiguration(params),
-            params,
-            ToFromOriginalFileMapper.create(params),
-            result
-        ).complete()
-
-        return true
-    }
-}
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeTagCompletionSession.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeTagCompletionSession.kt
deleted file mode 100644
index 837c6e3..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/ComposeTagCompletionSession.kt
+++ /dev/null
@@ -1,716 +0,0 @@
-package androidx.compose.plugins.idea.completion
-
-import com.intellij.codeInsight.AutoPopupController
-import com.intellij.codeInsight.completion.AllClassesGetter
-import com.intellij.codeInsight.completion.CompletionParameters
-import com.intellij.codeInsight.completion.CompletionResultSet
-import com.intellij.codeInsight.completion.CompletionSorter
-import com.intellij.codeInsight.completion.InsertHandler
-import com.intellij.codeInsight.completion.InsertionContext
-import com.intellij.codeInsight.lookup.LookupElement
-import com.intellij.codeInsight.lookup.LookupElementBuilder
-import com.intellij.codeInsight.lookup.LookupElementPresentation
-import com.intellij.codeInsight.lookup.LookupElementRenderer
-import com.intellij.lang.jvm.JvmModifier
-import com.intellij.openapi.util.Iconable
-import com.intellij.openapi.util.Key
-import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiLiteral
-import com.intellij.psi.PsiWhiteSpace
-import com.intellij.ui.JBColor
-import com.intellij.util.PlatformIcons
-import org.jetbrains.kotlin.asJava.classes.KtLightClass
-import org.jetbrains.kotlin.builtins.DefaultBuiltIns
-import org.jetbrains.kotlin.descriptors.CallableDescriptor
-import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.Modality
-import org.jetbrains.kotlin.descriptors.ParameterDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.VariableDescriptor
-import org.jetbrains.kotlin.idea.KotlinDescriptorIconProvider
-import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor
-import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
-import org.jetbrains.kotlin.idea.completion.CompletionSessionConfiguration
-import org.jetbrains.kotlin.idea.completion.KindWeigher
-import org.jetbrains.kotlin.idea.completion.ToFromOriginalFileMapper
-import org.jetbrains.kotlin.idea.completion.asNameFilter
-import org.jetbrains.kotlin.idea.completion.isArtificialImportAliasedDescriptor
-import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
-import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
-import org.jetbrains.kotlin.idea.refactoring.hasIdentifiersOnly
-import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
-import org.jetbrains.kotlin.idea.util.ImportInsertHelper
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.load.java.JvmAnnotationNames
-import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.psiUtil.endOffset
-import org.jetbrains.kotlin.psi.psiUtil.isIdentifier
-import org.jetbrains.kotlin.psi.psiUtil.nextLeaf
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import androidx.compose.plugins.idea.parentOfType
-import org.jetbrains.kotlin.renderer.render
-import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
-import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
-import org.jetbrains.kotlin.types.typeUtil.isUnit
-import org.jetbrains.kotlin.util.OperatorNameConventions.INVOKE
-
-class ComposeTagCompletionSession(
-    configuration: CompletionSessionConfiguration,
-    parameters: CompletionParameters,
-    toFromOriginalFileMapper: ToFromOriginalFileMapper,
-    resultSet: CompletionResultSet
-) : BaseComposeCompletionSession(configuration, parameters, toFromOriginalFileMapper, resultSet) {
-
-    private val elementExpr = cursorElement.parentOfType<KtxElement>()
-        ?: error("no ktx element found")
-    private val nullableKtxCall =
-        bindingContext.get(ComposeWritableSlices.RESOLVED_KTX_CALL, elementExpr)
-
-    private val emitUpperBounds by lazy {
-        if (nullableKtxCall == null || nullableKtxCall.getComposerCall == null)
-            listOf(DefaultBuiltIns.Instance.any)
-        else nullableKtxCall.emitSimpleUpperBoundTypes
-            .mapNotNull { it.constructor.declarationDescriptor as? ClassDescriptor }
-    }
-
-    private val emitUpperBoundsPsi by lazy {
-        emitUpperBounds.mapNotNull { psiFacade.findClass(it.fqNameSafe.asString(), searchScope) }
-    }
-
-    private val indiceshelper = KotlinIndicesHelper(
-        resolutionFacade,
-        searchScope,
-        { true },
-        filterOutPrivate = true,
-        declarationTranslator = { toFromOriginalFileMapper.toSyntheticFile(it) },
-        file = file
-    )
-
-    private fun PsiClass.isEmittable(): Boolean {
-        return when {
-            isSyntheticKotlinClass() -> false
-            isAnnotationType -> false
-            isInterface -> false
-            isEnum -> false
-            hasModifier(JvmModifier.ABSTRACT) -> false
-            emitUpperBoundsPsi.any { isSubclassOf(it) } -> true
-            else -> false
-        }
-    }
-
-    private fun PsiClass.isSyntheticKotlinClass(): Boolean {
-        if ('$' !in name!!) return false // optimization to not analyze annotations of all classes
-        val metadata = modifierList?.findAnnotation(JvmAnnotationNames.METADATA_FQ_NAME.asString())
-        return (metadata?.findAttributeValue(JvmAnnotationNames.KIND_FIELD_NAME) as?
-                PsiLiteral)?.value == KotlinClassHeader.Kind.SYNTHETIC_CLASS.id
-    }
-
-    private fun DeclarationDescriptor.childrenParameterNames(): List<String> {
-        when (this) {
-            is ClassDescriptor -> {
-                val descriptor =
-                    unsubstitutedMemberScope.getContributedDescriptors().firstOrNull {
-                        it.hasChildrenAnnotation()
-                    } ?: unsubstitutedPrimaryConstructor?.valueParameters?.firstOrNull {
-                        it.hasChildrenAnnotation()
-                    } ?: return emptyList()
-
-                return when (descriptor) {
-                    is ParameterDescriptor -> descriptor.type.functionParameterNames()
-                    is PropertyDescriptor -> descriptor.type.functionParameterNames()
-                    is FunctionDescriptor ->
-                        descriptor.valueParameters.firstOrNull()?.type?.functionParameterNames()
-                            ?: emptyList()
-                    else -> emptyList()
-                }
-            }
-            is FunctionDescriptor -> {
-                val descriptor = valueParameters.firstOrNull { it.hasChildrenAnnotation() }
-                    ?: return emptyList()
-                return descriptor.type.functionParameterNames()
-            }
-            is VariableDescriptor -> {
-                val childTypeArg = type.arguments.firstOrNull { it.type.hasChildrenAnnotation() }
-                    ?: return emptyList()
-                return childTypeArg.type.functionParameterNames()
-            }
-        }
-
-        return emptyList()
-    }
-
-    private fun DeclarationDescriptor.constructLookupElement(): LookupElement? {
-        val isVisible = isVisibleDescriptor()
-        val parentFqName = fqNameSafe.parent()
-
-        val fileFqName = file.packageFqName
-
-        val packageText = if (fileFqName != parentFqName) parentFqName.render() else ""
-
-        val tailText = if (packageText.isNotBlank()) " ($packageText)" else ""
-
-        val allowsChildren = allowsChildren()
-        val parameterNames = if (allowsChildren) childrenParameterNames() else emptyList()
-
-        val presentableText =
-            if (allowsChildren && parameterNames.isNotEmpty())
-                "<${name.asString()}> ${parameterNames.joinToString()} -> ... </${name.asString()}>"
-            else if (allowsChildren)
-                "<${name.asString()}>...</${name.asString()}>"
-            else
-                "<${name.asString()} />"
-
-        val descriptor = this
-        val psiDecl = when (descriptor) {
-            is ConstructorDescriptor -> descriptor.containingDeclaration
-            else -> descriptor
-        }
-
-        val renderer = object : LookupElementRenderer<LookupElement>() {
-            override fun renderElement(
-                element: LookupElement?,
-                presentation: LookupElementPresentation?
-            ) {
-                if (presentation == null) return
-                with(presentation) {
-                    val psiElement = DescriptorToSourceUtilsIde.getAnyDeclaration(project, psiDecl)
-                    itemText = presentableText
-                    isItemTextBold = isVisible
-                    icon = KotlinDescriptorIconProvider.getIcon(
-                        descriptor,
-                        psiElement,
-                        Iconable.ICON_FLAG_VISIBILITY
-                    )
-                    appendTailText(tailText, true)
-                }
-            }
-        }
-
-        return LookupElementBuilder.create(this, name.asString())
-            .withRenderer(renderer)
-            .withInsertHandler(tagInsertionHandler)
-            .apply {
-                putUserData(ALLOWS_CHILDREN, allowsChildren)
-                putUserData(DESCRIPTOR, this@constructLookupElement)
-                putUserData(Weighers.IS_IMPORTED_KEY, isVisible)
-            }
-    }
-
-    private fun PsiClass.constructLookupElement(): LookupElement? {
-        val parentFqName = getKotlinFqName()?.parent() ?: return null
-
-        val name = name ?: return null
-
-        val fileFqName = file.packageFqName
-
-        val packageText = if (fileFqName != parentFqName) parentFqName.render() else ""
-
-        val tailText = if (packageText.isNotBlank()) " ($packageText)" else ""
-
-        val allowsChildren = allowsChildren()
-        // TODO: we should look for parameter names in the cases where views have @Children properties that have parameters
-        val parameterNames = emptyList<String>()
-
-        val presentableText =
-            if (allowsChildren && parameterNames.isNotEmpty())
-                "<$name> ${parameterNames.joinToString()} -> ... </$name>"
-            else if (allowsChildren)
-                "<$name>...</$name>"
-            else
-                "<$name />"
-
-        val psiClass = this
-
-        val renderer = object : LookupElementRenderer<LookupElement>() {
-            override fun renderElement(
-                element: LookupElement?,
-                presentation: LookupElementPresentation?
-            ) {
-                if (presentation == null) return
-                with(presentation) {
-                    itemText = presentableText
-                    isItemTextBold = false
-                    icon = psiClass.getIcon(Iconable.ICON_FLAG_VISIBILITY)
-                    appendTailText(tailText, true)
-                }
-            }
-        }
-
-        return LookupElementBuilder.create(this, name)
-            .withRenderer(renderer)
-            .withInsertHandler(psiClassTagInsertionHandler)
-            .apply {
-                putUserData(ALLOWS_CHILDREN, allowsChildren)
-                putUserData(PSI_CLASS, this@constructLookupElement)
-                putUserData(Weighers.IS_IMPORTED_KEY, false)
-            }
-    }
-
-    private fun FqName.constructLookupElement(): LookupElement? {
-        val renderer = object : LookupElementRenderer<LookupElement>() {
-            override fun renderElement(
-                element: LookupElement?,
-                presentation: LookupElementPresentation?
-            ) {
-                with(presentation ?: return) {
-                    itemText = "<${this@constructLookupElement}.* />"
-                    itemTextForeground = JBColor.lightGray
-                    icon = PlatformIcons.PACKAGE_ICON
-                }
-            }
-        }
-
-        return LookupElementBuilder.create(pathSegments().last().asString())
-            .withRenderer(renderer)
-            .withInsertHandler(packageInsertionHandler)
-            .apply {
-                putUserData(Weighers.IS_IMPORTED_KEY, false)
-            }
-    }
-
-    private enum class ComposableKind(val valid: Boolean) {
-        // This is used internally. public functions should never return this as a result.
-        UNKNOWN(false),
-        // This type cannot be used in a tag because it is either uninvokable, or invokable and returning a type which is itself "INVALID"
-        INVALID(false),
-        // This type can be used in a tag but the "terminal" invoke (the one returning Unit) is not marked as @Composable
-        UNIT_TERMINAL(true),
-        // This type can be used in a tag because it is either invokable and marked as @Composable, or invokable and returning a type
-        // which is itself "COMPOSABLE"
-        COMPOSABLE(true)
-    }
-
-    private inner class ValidTagHelper {
-        private val index = mutableMapOf<KotlinType, ComposableKind>()
-        private val invokeFns = mutableMapOf<KotlinType, MutableList<KotlinType>>()
-
-        fun getComposability(type: KotlinType?): ComposableKind {
-            if (type == null) return ComposableKind.INVALID
-            val kind = index[type] ?: ComposableKind.UNKNOWN
-            return when (kind) {
-                ComposableKind.UNKNOWN -> {
-                    // temporarily set the composability of this type to INVALID, so we don't get into a cycle
-                    index[type] =
-                        ComposableKind.INVALID
-
-                    // there might be an invoke function that goes to another type, in which case
-                    // we need to check the composability of the return type
-                    var max = invokeFns[type]
-                        ?.map { getComposability(it) }
-                        ?.maxBy { it.ordinal }
-                        ?: ComposableKind.INVALID
-
-                    // if we are still invalid, we check to see if any invoke functions are defined on the
-                    // type. This is needed because the indicesHelper doesn't seem to go through classes in
-                    // other modules
-                    if (max == ComposableKind.INVALID &&
-                        type.memberScope.getFunctionNames().contains(INVOKE)) {
-                        type
-                            .memberScope
-                            .getContributedFunctions(INVOKE, NoLookupLocation.FROM_IDE)
-                            .filter { it.name == INVOKE && it.isOperator }
-                            .forEach { invoke ->
-                                addInvoke(type, invoke.returnType
-                                    ?: DefaultBuiltIns.Instance.unitType, invoke)
-                            }
-
-                        index[type]?.let { max = it }
-                    }
-
-                    // It's possible we have new invokeFns now, so we check again
-                    if (max == ComposableKind.INVALID) {
-                        max = invokeFns[type]
-                            ?.map { getComposability(it) }
-                            ?.maxBy { it.ordinal }
-                                ?: ComposableKind.INVALID
-                    }
-
-                    // if we are still invalid, we want to check the composability of our immediate
-                    // super-types
-                    if (max == ComposableKind.INVALID) {
-                        max = type
-                            .immediateSupertypes()
-                            .map { getComposability(it) }
-                            .maxBy { it.ordinal }
-                                ?: ComposableKind.INVALID
-                    }
-
-                    // at this point we've exhausted all options, so we should set the composability
-                    // of this type
-                    index[type] = max
-                    max
-                }
-                ComposableKind.INVALID,
-                ComposableKind.UNIT_TERMINAL,
-                ComposableKind.COMPOSABLE -> kind
-            }
-        }
-
-        fun addInvoke(type: KotlinType, returnType: KotlinType, descriptor: FunctionDescriptor) {
-            val isUnit = returnType.isUnit()
-            val isComposable = descriptor.hasComposableAnnotation()
-
-            index[type] = when {
-                isComposable -> ComposableKind.COMPOSABLE
-                isUnit -> ComposableKind.UNIT_TERMINAL
-                else -> ComposableKind.UNKNOWN
-            }
-            if (!isUnit) {
-                invokeFns.multiPut(type, returnType)
-            }
-        }
-    }
-
-    private fun ClassDescriptor.isEmittable(): Boolean {
-        return emitUpperBounds.any { isSubclassOf(it) }
-    }
-
-    private fun CallableDescriptor.isImmediatelyComposable(): Boolean {
-        return when (this) {
-            is FunctionDescriptor -> returnType?.isUnit() == true && hasComposableAnnotation()
-            is VariableDescriptor -> hasComposableAnnotation() || type.hasComposableAnnotation() ||
-                    hasChildrenAnnotation() || type.hasChildrenAnnotation()
-            else -> false
-        }
-    }
-
-    private fun collectComposable(
-        d: DeclarationDescriptor,
-        type: KotlinType?,
-        tagHelper: ValidTagHelper
-    ) {
-        val kind = tagHelper.getComposability(type)
-        if (kind == ComposableKind.INVALID) {
-            // at this point we can just throw it on the floor?
-        } else {
-            val element = d.constructLookupElement()
-            if (element != null) collector.addElement(element)
-        }
-    }
-
-    private fun collectDescriptor(d: DeclarationDescriptor, tagHelper: ValidTagHelper) {
-        when (d) {
-            is ClassDescriptor -> {
-                if (d.modality == Modality.ABSTRACT) return
-                if (d.kind == ClassKind.INTERFACE) return
-                if (!d.isVisibleDescriptor()) return
-                if (d.isEmittable()) {
-                    val element = d.constructLookupElement()
-                    if (element != null) collector.addElement(element)
-                } else {
-                    collectComposable(d, d.defaultType, tagHelper)
-                }
-            }
-            is CallableDescriptor -> {
-                if (d.isImmediatelyComposable()) {
-                    val element = d.constructLookupElement()
-                    if (element != null) collector.addElement(element)
-                } else {
-                    val type = when (d) {
-                        is FunctionDescriptor -> d.returnType
-                        is VariableDescriptor -> d.type
-                        else -> null
-                    }
-                    collectComposable(d, type, tagHelper)
-                }
-            }
-            else -> {
-                // TODO(lmr): are there valid cases here?
-            }
-        }
-    }
-
-    override fun doComplete() {
-        val receiverText = callTypeAndReceiver.receiver?.text
-        val receiverFqName = receiverText?.let { FqName(it) }
-
-        val tagHelper = ValidTagHelper()
-
-        indiceshelper.getMemberOperatorsByName(INVOKE.identifier).forEach { x ->
-            val dispatchReceiver = x.dispatchReceiverParameter
-            val extensionReceiver = x.extensionReceiverParameter
-            if (extensionReceiver == null && dispatchReceiver != null) {
-                tagHelper.addInvoke(
-                    dispatchReceiver.type,
-                    x.returnType ?: DefaultBuiltIns.Instance.unitType,
-                    x
-                )
-            }
-        }
-
-        indiceshelper.getTopLevelExtensionOperatorsByName(INVOKE.identifier).forEach { x ->
-            val dispatchReceiver = x.dispatchReceiverParameter
-            val extensionReceiver = x.extensionReceiverParameter
-            if (extensionReceiver != null && dispatchReceiver == null) {
-                tagHelper.addInvoke(
-                    extensionReceiver.type,
-                    x.returnType ?: DefaultBuiltIns.Instance.unitType,
-                    x
-                )
-            }
-        }
-
-        if (receiverTypes != null && receiverTypes.isNotEmpty()) {
-            receiverTypes
-                .flatMap { it.type.memberScope.getContributedDescriptors() }
-                .asSequence()
-                .forEach { collectDescriptor(it, tagHelper) }
-            flushToResultSet()
-        }
-
-        if (callTypeAndReceiver.receiver != null) {
-            if (receiverFqName != null) {
-                module
-                    .getPackage(receiverFqName)
-                    .memberScope
-                    .getContributedDescriptors()
-                    .forEach { collectDescriptor(it, tagHelper) }
-                flushToResultSet()
-            }
-        } else {
-            doSimpleCompleteNew(tagHelper)
-        }
-
-        doPackageNameCompletion()
-    }
-
-    private fun doSimpleCompleteNew(tagHelper: ValidTagHelper) {
-        // 1. scoped declarations that are marked @Composable or emittable
-        scope
-            .collectAllFromMeAndParent { s -> s.getContributedDescriptors() }
-            .asIterable()
-            .forEach { collectDescriptor(it, tagHelper) }
-
-        flushToResultSet()
-
-        // 2. top level kotlin classes that are "emittable"
-        //
-        // throw away those that we know can't also be valid composables. keep the ones that might be.
-        indiceshelper.getKotlinClasses({ true }).forEach { d ->
-            if (d.modality == Modality.ABSTRACT) return@forEach
-            if (d.kind == ClassKind.INTERFACE) return@forEach
-            if (!d.isVisibleDescriptor()) return@forEach
-            if (d.isEmittable()) {
-                val element = d.constructLookupElement()
-                if (element != null) collector.addElement(element)
-            } else {
-                collectComposable(d, d.defaultType, tagHelper)
-            }
-        }
-        flushToResultSet()
-
-        // 3. top level callables that are marked @Composable
-        //
-        // As a first order approximation, we will only capture non-nested composables here. keep the rest.
-        indiceshelper.processTopLevelCallables({ true }) { d ->
-            // if it is a constructor, we will capture it in the getKotlinClasses(...) call above
-            if (d is ClassConstructorDescriptor) return@processTopLevelCallables
-            if (!d.isVisibleDescriptor()) return@processTopLevelCallables
-            if (d.isImmediatelyComposable()) {
-                val element = d.constructLookupElement()
-                if (element != null) collector.addElement(element)
-            } else {
-                val type = when (d) {
-                    is FunctionDescriptor -> d.returnType
-                    is VariableDescriptor -> d.type
-                    else -> null
-                }
-                collectComposable(d, type, tagHelper)
-            }
-        }
-        flushToResultSet()
-
-        // 4. top level java classes that are "emittable"
-        AllClassesGetter.processJavaClasses(
-            prefixMatcher,
-            project,
-            searchScope
-        ) { psiClass: PsiClass ->
-            if (psiClass is KtLightClass) {
-                // Kotlin class should have already been added as kotlin element before
-                return@processJavaClasses true
-            }
-            // TODO(lmr): deal with visibility here somehow?
-            if (!psiClass.isEmittable()) {
-                // filter out synthetic classes produced by Kotlin compiler
-                return@processJavaClasses true
-            }
-            val element = psiClass.constructLookupElement()
-            if (element != null) collector.addElement(element)
-            return@processJavaClasses true
-        }
-
-        flushToResultSet()
-    }
-
-    private fun doPackageNameCompletion() {
-        val receiverText = callTypeAndReceiver.receiver?.text
-        val receiverFqName = receiverText?.let { FqName(it) }
-        val prefixFqName = receiverFqName ?: FqName.ROOT
-        val prefixString = receiverFqName?.asString() ?: ""
-
-        val packageNames = PackageIndexUtil.getSubPackageFqNames(
-            prefixFqName,
-            searchScope,
-            project,
-            prefixMatcher.asNameFilter()
-        ).filter { it.hasIdentifiersOnly() }.toMutableSet()
-
-        psiFacade.findPackage(prefixString)?.getSubPackages(searchScope)?.forEach { psiPackage ->
-            val name = psiPackage.name
-
-            if (name?.isIdentifier() == true) {
-                if (prefixString.isBlank()) {
-                    packageNames.add(FqName(name))
-                } else {
-                    packageNames.add(FqName("$prefixString.$name"))
-                }
-            }
-        }
-
-        packageNames.forEach {
-            val element = it.constructLookupElement()
-            if (element != null) {
-                collector.addElement(element)
-            }
-        }
-
-        flushToResultSet()
-    }
-
-    override fun createSorter(): CompletionSorter {
-        return super.createSorter()
-            .weighBefore(
-                KindWeigher.toString(),
-                Weighers.IsImported
-            )
-    }
-
-    private val tagInsertionHandler = InsertHandler<LookupElement> { context, item ->
-        val descriptor = item.getUserData(DESCRIPTOR) ?: return@InsertHandler
-        val allowsChildren = item.getUserData(ALLOWS_CHILDREN) ?: false
-        val prefix = callTypeAndReceiver.receiver?.text?.let { "$it." } ?: ""
-        val tagName = "$prefix${item.lookupString}"
-        insertHandler(descriptor, context, allowsChildren, tagName)
-    }
-
-    private val psiClassTagInsertionHandler = InsertHandler<LookupElement> { context, item ->
-        val psiClass = item.getUserData(PSI_CLASS) ?: return@InsertHandler
-        val descriptor = psiClass.getJavaClassDescriptor(resolutionFacade) ?: return@InsertHandler
-        val allowsChildren = item.getUserData(ALLOWS_CHILDREN) ?: false
-        val prefix = callTypeAndReceiver.receiver?.text?.let { "$it." } ?: ""
-        val tagName = "$prefix${item.lookupString}"
-        insertHandler(descriptor, context, allowsChildren, tagName)
-    }
-
-    private val packageInsertionHandler = InsertHandler<LookupElement> { context, _ ->
-        val document = context.document
-        val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
-        psiDocumentManager.commitAllDocuments()
-        psiDocumentManager.doPostponedOperationsAndUnblockDocument(document)
-
-        val token = context.file.findElementAt(context.startOffset) ?: return@InsertHandler
-        val ktxElement = token.parentOfType<KtxElement>() ?: return@InsertHandler
-        val tagName = ktxElement.simpleTagName ?: ktxElement.qualifiedTagName
-        ?: return@InsertHandler
-
-        val tailOffset = context.tailOffset
-        val moveCaret = context.editor.caretModel.offset == tailOffset
-        // if the inserted text is at the end of the tag name, we have more to type
-        if (tagName.endOffset != context.editor.caretModel.offset) return@InsertHandler
-
-        val textToInsert = "."
-
-        document.insertString(tailOffset, textToInsert)
-
-        if (moveCaret) {
-            context.editor.caretModel.moveToOffset(tailOffset + 1)
-        }
-
-        AutoPopupController.getInstance(context.project)?.scheduleAutoPopup(context.editor)
-    }
-
-    private fun insertHandler(
-        descriptor: DeclarationDescriptor,
-        context: InsertionContext,
-        allowsChildren: Boolean,
-        tagName: String
-    ) {
-        val document = context.document
-        val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
-
-        psiDocumentManager.commitAllDocuments()
-        if (DescriptorUtils.isTopLevelDeclaration(descriptor) &&
-            !descriptor.isArtificialImportAliasedDescriptor) {
-            ImportInsertHelper.getInstance(context.project)
-                .importDescriptor(context.file as KtFile, descriptor)
-        }
-        psiDocumentManager.doPostponedOperationsAndUnblockDocument(document)
-
-        val token = context.file.findElementAt(context.startOffset) ?: return
-        val ktxElement = token.parentOfType<KtxElement>() ?: return
-        val mightWrapBody = ktxElement.nextLeaf {
-            it !is PsiWhiteSpace && it.textLength > 0
-        }?.text != "}"
-        val gt = ktxElement.node.findChildByType(KtTokens.GT)
-        // if the tag has a GT token, then we don't need to close it
-        if (gt != null) return
-
-        val parameterNames: List<String> =
-            if (allowsChildren) descriptor.childrenParameterNames() else emptyList()
-
-        val tailOffset = context.tailOffset
-        val moveCaret = context.editor.caretModel.offset == tailOffset
-        val textToInsert = buildString {
-            if (allowsChildren) {
-                append(">")
-                if (parameterNames.isNotEmpty()) {
-                    append(" ${parameterNames.joinToString()} ->")
-                    if (!mightWrapBody) append(" ")
-                }
-                if (!mightWrapBody) append("</$tagName>")
-            } else append(" />")
-        }
-
-        document.insertString(tailOffset, textToInsert)
-
-        if (moveCaret) {
-            val addedSpace = if (!allowsChildren) 1 else 0
-
-            context.editor.caretModel.moveToOffset(tailOffset + addedSpace)
-
-            // TODO: Check if any attributes are valid, and if so, open autocomplete in `attributes` mode
-            // since they just created a new tag, they might want to add some attributes.
-            // AutoPopupController.getInstance(context.project)?.scheduleAutoPopup(context.editor)
-        }
-    }
-
-    companion object {
-        val ALLOWS_CHILDREN = Key<Boolean>("compose.allows_children")
-        val DESCRIPTOR = Key<DeclarationDescriptor>("compose.descriptor")
-        val PSI_CLASS = Key<PsiClass>("compose.psiClass")
-    }
-}
-
-private fun <T, V> MutableMap<T, MutableList<V>>.multiPut(key: T, value: V) {
-    val current = get(key)
-    if (current != null) {
-        current.add(value)
-    } else {
-        put(key, mutableListOf(value))
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/Weighers.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/Weighers.kt
deleted file mode 100644
index 6c82740..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/completion/Weighers.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package androidx.compose.plugins.idea.completion
-
-import com.intellij.codeInsight.lookup.LookupElement
-import com.intellij.codeInsight.lookup.LookupElementWeigher
-import com.intellij.codeInsight.lookup.WeighingContext
-import com.intellij.openapi.util.Key
-import androidx.compose.plugins.idea.AttributeInfo
-
-object Weighers {
-    val IS_IMPORTED_KEY = Key<Boolean>("compose.is_imported")
-    val ATTRIBUTE_INFO_KEY = Key<AttributeInfo>("compose.attribute_info")
-
-    val IsImported = object : LookupElementWeigher("compose.importedWeigher") {
-        override fun weigh(element: LookupElement, context: WeighingContext) =
-            if (element.getUserData(IS_IMPORTED_KEY) == true) -1 else 0
-    }
-
-    abstract class AttributeInfoWeigher(key: String) : LookupElementWeigher(key) {
-        override fun weigh(element: LookupElement, context: WeighingContext) =
-            element.getUserData(ATTRIBUTE_INFO_KEY)?.let { weigh(it) } ?: 0
-        abstract fun weigh(info: AttributeInfo): Int
-    }
-
-    val IsImmediateAttribute =
-        object : AttributeInfoWeigher("compose.isImmediateAttributeWeigher") {
-            override fun weigh(info: AttributeInfo): Int = if (info.isImmediate) -1 else 0
-        }
-    val IsRequiredAttribute =
-        object : AttributeInfoWeigher("compose.isRequiredAttributeWeigher") {
-            override fun weigh(info: AttributeInfo): Int = if (info.isRequired) -1 else 0
-        }
-
-    val IsChildAttribute = object : AttributeInfoWeigher("compose.isChildAttributeWeigher") {
-        override fun weigh(info: AttributeInfo): Int = if (info.isChildren) 1 else 0
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/ComposeUnresolvedTagAnnotator.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/ComposeUnresolvedTagAnnotator.kt
deleted file mode 100644
index ca0ce86..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/ComposeUnresolvedTagAnnotator.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.codeInspection.ProblemHighlightType
-import com.intellij.lang.annotation.AnnotationHolder
-import com.intellij.lang.annotation.Annotator
-import com.intellij.openapi.progress.ProcessCanceledException
-import com.intellij.psi.PsiElement
-import org.jetbrains.kotlin.diagnostics.Diagnostic
-import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
-import org.jetbrains.kotlin.diagnostics.Errors
-import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtVisitorVoid
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
-import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingUtil
-
-/**
- * This class adds a red highlight to tag names in KTX elements that are unresolved. This could be done
- * by default by just using the `UNRESOLVED_REFERENCE` diagnostic, but we have decided not to use that
- * diagnostic in this case because the "Add Import" quick fix that it causes breaks in the case of
- * Open/Close KTX tags. Instead, we use our own `UNRESOLVED_TAG` diagnostic, which we register our own
- * quick fix for, and we also add the red highlight here.
- */
-class ComposeUnresolvedTagAnnotator : Annotator {
-    override fun annotate(element: PsiElement, holder: AnnotationHolder) {
-        val ktFile = element.containingFile as? KtFile ?: return
-
-        if (!KotlinHighlightingUtil.shouldHighlight(ktFile)) return
-
-        val analysisResult = ktFile.analyzeWithAllCompilerChecks()
-        if (analysisResult.isError()) {
-            throw ProcessCanceledException(analysisResult.error)
-        }
-
-        val bindingContext = analysisResult.bindingContext
-        val diagnostics = bindingContext.diagnostics
-
-        element.accept(object : KtVisitorVoid() {
-            override fun visitKtxElement(element: KtxElement) {
-                element.simpleTagName?.let {
-                    if (diagnostics.forElement(it).any {
-                            it.realDiagnosticFactory == ComposeErrors.UNRESOLVED_TAG
-                        }) {
-                        holder.createErrorAnnotation(it, null).apply {
-                            highlightType = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
-                        }
-                    }
-                }
-                element.simpleClosingTagName?.let {
-                    if (diagnostics.forElement(it).any {
-                            it.realDiagnosticFactory == ComposeErrors.UNRESOLVED_TAG
-                        }) {
-                        holder.createErrorAnnotation(it, null).apply {
-                            highlightType = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
-                        }
-                    }
-                }
-            }
-        })
-    }
-}
-
-private val Diagnostic.realDiagnosticFactory: DiagnosticFactory<*>
-    get() =
-        when (factory) {
-            Errors.PLUGIN_ERROR -> Errors.PLUGIN_ERROR.cast(this).a.factory
-            Errors.PLUGIN_WARNING -> Errors.PLUGIN_WARNING.cast(this).a.factory
-            Errors.PLUGIN_INFO -> Errors.PLUGIN_INFO.cast(this).a.factory
-            else -> factory
-        }
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxAttributeAutoParensHandler.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxAttributeAutoParensHandler.kt
deleted file mode 100644
index aa8957e..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxAttributeAutoParensHandler.kt
+++ /dev/null
@@ -1,167 +0,0 @@
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.codeInsight.editorActions.TypedHandlerDelegate
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.editor.EditorModificationUtil
-import com.intellij.openapi.editor.ex.EditorEx
-import com.intellij.openapi.fileTypes.FileType
-import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiErrorElement
-import com.intellij.psi.PsiFile
-import com.intellij.psi.tree.TokenSet
-import org.jetbrains.kotlin.KtNodeTypes
-import org.jetbrains.kotlin.idea.completion.handlers.isCharAt
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
-import org.jetbrains.kotlin.psi.psiUtil.startOffset
-import androidx.compose.plugins.idea.parentOfType
-
-class KtxAttributeAutoParensHandler : TypedHandlerDelegate() {
-
-    private fun EditorEx.prevCharIs(char: Char): Boolean {
-        return document.charsSequence.isCharAt(caretModel.offset - 2, char)
-    }
-
-    private fun wrapWithParensIfAtEndOfAttribute(
-        file: PsiFile,
-        editor: EditorEx,
-        project: Project
-    ): Boolean {
-        if (editor.caretModel.caretCount > 1) return false
-
-        PsiDocumentManager.getInstance(project).commitDocument(editor.document)
-
-        val el = file.findElementAt(editor.caretModel.offset - 1)
-        val errorElement = el?.parent as? PsiErrorElement ?: return false
-        if (errorElement.parent !is KtxElement) return false
-        val attr =
-            errorElement.getPrevSiblingIgnoringWhitespaceAndComments(withItself = false) as?
-                    KtxAttribute ?: return false
-        val valueExpr = attr.value ?: return false
-
-        // This can happen if someone has started a parenthesized element with an open paren but hasn't typed the close paren yet. If
-        // this is the case, insert only the close paren
-        if (valueExpr.node.elementType ==
-            KtNodeTypes.PARENTHESIZED && valueExpr.lastChild is PsiErrorElement) {
-            editor.document.insertString(editor.caretModel.offset, ")")
-        } else {
-            editor.document.insertString(valueExpr.startOffset, "(")
-            editor.document.insertString(editor.caretModel.offset, ")")
-        }
-        return true
-    }
-
-    private fun wrapValueExpressionIfNotTagCloseForChar(
-        c: Char,
-        file: PsiFile,
-        editor: EditorEx
-    ): Boolean {
-
-        if (editor.caretModel.caretCount > 1) return false
-
-        val el = file.findElementAt(editor.caretModel.offset - 1) ?: return false
-        val ktxElement = el.parentOfType<KtxElement>() ?: return false
-
-        val bracketElements = ktxElement.node.getChildren(BRACKET_SET)
-        val gtCount = bracketElements.count { it.elementType == KtTokens.GT }
-        val divCount = bracketElements.count { it.elementType == KtTokens.DIV }
-
-        // there is no GT so the tag is unclosed, we definitely don't want to do anything here...
-        if (gtCount == 0) return false
-
-        val offset = editor.caretModel.offset
-
-        // if we are typing after the first close bracket, we don't want to do anything
-        if (bracketElements.first { it.elementType == KtTokens.GT }.startOffset < offset)
-            return false
-
-        when (c) {
-            '>' -> {
-                if (gtCount <= 1 && !(gtCount == 1 && divCount == 1)) return false
-            }
-            '/' -> {
-                if (divCount == 0) return false
-            }
-            else -> return false
-        }
-
-        // if we made it here, we can attempt to wrap the value expression we are in...
-
-        val attr = el.getPrevSiblingIgnoringWhitespaceAndComments(withItself = true) as?
-                KtxAttribute ?: return false
-        val valueExpr = attr.value ?: return false
-
-        // This can happen if someone has started a parenthesized element with an open paren but hasn't typed the close paren yet. If
-        // this is the case, insert only the close paren
-        if (valueExpr.node.elementType == KtNodeTypes.PARENTHESIZED &&
-            valueExpr.lastChild is PsiErrorElement) {
-            editor.document.insertString(editor.caretModel.offset, "$c)")
-            EditorModificationUtil.moveCaretRelatively(editor, 1)
-        } else {
-            editor.document.insertString(valueExpr.startOffset, "(")
-            editor.document.insertString(editor.caretModel.offset, "$c)")
-            EditorModificationUtil.moveCaretRelatively(editor, 1)
-        }
-
-        return true
-    }
-
-    override fun beforeCharTyped(
-        c: Char,
-        project: Project,
-        editor: Editor,
-        file: PsiFile,
-        fileType: FileType
-    ): Result {
-        val editorEx = editor as EditorEx
-        when (c) {
-            '>' -> {
-                val didWrap = wrapValueExpressionIfNotTagCloseForChar(c, file, editorEx)
-                if (didWrap) return Result.STOP
-            }
-            '/' -> {
-                val didWrap = wrapValueExpressionIfNotTagCloseForChar(c, file, editorEx)
-                if (didWrap) return Result.STOP
-            }
-        }
-        return Result.CONTINUE
-    }
-
-    override fun charTyped(
-        c: Char,
-        project: Project,
-        editor: Editor,
-        file: PsiFile
-    ): Result {
-        val editorEx = editor as EditorEx
-        when (c) {
-            // equality
-            '=' -> {
-                if (editorEx.prevCharIs('=') || editorEx.prevCharIs('!')) {
-                    val didWrap = wrapWithParensIfAtEndOfAttribute(file, editorEx, project)
-                    if (didWrap) return Result.STOP
-                }
-            }
-            // single char binary operators, excluding '/' and '>'
-            '+', '-', '%', '|', '&', '*', '<' -> {
-                val didWrap = wrapWithParensIfAtEndOfAttribute(file, editorEx, project)
-                if (didWrap) return Result.STOP
-            }
-            // nullary ?:
-            ':' -> {
-                if (editorEx.prevCharIs('?')) {
-                    val didWrap = wrapWithParensIfAtEndOfAttribute(file, editorEx, project)
-                    if (didWrap) return Result.STOP
-                }
-            }
-        }
-        return Result.CONTINUE
-    }
-
-    companion object {
-        private val BRACKET_SET = TokenSet.create(KtTokens.DIV, KtTokens.GT)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEditorOptions.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEditorOptions.kt
deleted file mode 100644
index 47e8703..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEditorOptions.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.openapi.components.PersistentStateComponent
-import com.intellij.openapi.components.ServiceManager
-import com.intellij.openapi.components.State
-import com.intellij.openapi.components.Storage
-import com.intellij.util.xmlb.XmlSerializerUtil
-
-@State(name = "KtxEditorOptions", storages = [Storage(file = "\$APP_CONFIG$/ktx.xml")])
-class KtxEditorOptions : PersistentStateComponent<KtxEditorOptions> {
-    companion object {
-        fun getInstance(): KtxEditorOptions {
-            return ServiceManager.getService(KtxEditorOptions::class.java)
-        }
-    }
-
-    var enableXmlToKtxConversion = true
-    var enableAddComposableAnnotation = true
-    var donTShowKtxConversionDialog = false
-    var donTShowAddComposableAnnotationDialog = false
-
-    override fun getState(): KtxEditorOptions? {
-        return this
-    }
-
-    override fun loadState(state: KtxEditorOptions) {
-        XmlSerializerUtil.copyBean(state, this)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEditorOptionsConfigurable.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEditorOptionsConfigurable.kt
deleted file mode 100644
index 8f5e45a..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEditorOptionsConfigurable.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.openapi.options.BeanConfigurable
-import com.intellij.openapi.options.UnnamedConfigurable
-
-class KtxEditorOptionsConfigurable : BeanConfigurable<KtxEditorOptions>(
-    KtxEditorOptions.getInstance()
-), UnnamedConfigurable {
-    init {
-        val instance = KtxEditorOptions.getInstance()
-        checkBox("Convert pasted XML code to Kotlin KTX",
-            { instance.enableXmlToKtxConversion }, { instance.enableXmlToKtxConversion = it }
-        )
-        checkBox("Don't show XML to Kotlin KTX conversion dialog on paste",
-            { instance.donTShowKtxConversionDialog },
-            { instance.donTShowKtxConversionDialog = it })
-        checkBox("Automatically add @Composable annotation and import androidx.compose.* when " +
-            "converting XML to KTX code",
-            {
-                instance.enableAddComposableAnnotation &&
-                        instance.donTShowAddComposableAnnotationDialog
-            },
-            { shouldAutomaticallyAddAnnotation ->
-                if (shouldAutomaticallyAddAnnotation) {
-                    instance.enableAddComposableAnnotation = true
-                    instance.donTShowAddComposableAnnotationDialog = true
-                } else {
-                    // Unchecking the box means that on next paste, the dialog will be shown and the user will be able to cancel it and
-                    // check "Don't show this dialog next time".
-                    instance.enableAddComposableAnnotation = true
-                    instance.donTShowAddComposableAnnotationDialog = false
-                }
-            }
-        )
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEnterHandler.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEnterHandler.kt
deleted file mode 100644
index ff28491..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxEnterHandler.kt
+++ /dev/null
@@ -1,289 +0,0 @@
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.codeInsight.AutoPopupController
-import com.intellij.codeInsight.CodeInsightSettings
-import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate
-import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter
-import com.intellij.openapi.actionSystem.DataContext
-import com.intellij.openapi.diagnostic.Logger
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.editor.EditorModificationUtil
-import com.intellij.openapi.editor.actionSystem.EditorActionHandler
-import com.intellij.openapi.util.Ref
-import com.intellij.openapi.util.TextRange
-import com.intellij.psi.PsiBlockStatement
-import com.intellij.psi.PsiComment
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiFile
-import com.intellij.psi.PsiWhiteSpace
-import com.intellij.psi.codeStyle.CodeStyleManager
-import com.intellij.util.IncorrectOperationException
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.KtxLambdaExpression
-import org.jetbrains.kotlin.psi.psiUtil.children
-import org.jetbrains.kotlin.psi.psiUtil.endOffset
-import org.jetbrains.kotlin.psi.psiUtil.leaves
-import org.jetbrains.kotlin.psi.psiUtil.startOffset
-import androidx.compose.plugins.idea.getNextLeafIgnoringWhitespace
-import androidx.compose.plugins.idea.getPrevLeafIgnoringWhitespace
-import androidx.compose.plugins.idea.parentOfType
-
-class KtxEnterHandler : EnterHandlerDelegateAdapter() {
-    companion object {
-        private val LOG = Logger.getInstance(KtxEnterHandler::class.java)
-    }
-
-    override fun preprocessEnter(
-        file: PsiFile,
-        editor: Editor,
-        caretOffsetRef: Ref<Int>,
-        caretAdvance: Ref<Int>,
-        dataContext: DataContext,
-        originalHandler: EditorActionHandler?
-    ): EnterHandlerDelegate.Result? {
-
-        val (
-            smartIndent,
-            insertClosingTag,
-            indentClosingTag,
-            element
-        ) = getIndentMeta(file, editor, caretOffsetRef)
-            ?: return EnterHandlerDelegate.Result.Continue
-
-        if (insertClosingTag) {
-            element?.let { ktxTag ->
-                val openTag = ktxTag.simpleTagName ?: ktxTag.qualifiedTagName
-                    ?: error("malformed tag")
-                val tagText = editor.document.charsSequence.subSequence(
-                    openTag.startOffset,
-                    openTag.endOffset
-                )
-                EditorModificationUtil.insertStringAtCaret(
-                    editor,
-                    "</$tagText>",
-                    true,
-                    false
-                )
-            }
-        }
-
-        if (indentClosingTag) {
-            element?.let { ktxTag ->
-                val closingTag =
-                    ktxTag.node.children().lastOrNull {
-                            child -> child.elementType == KtTokens.LT
-                    } ?: error("expected to find")
-                editor.document.insertString(
-                    closingTag.startOffset,
-                    "\n"
-                )
-                PsiDocumentManager.getInstance(file.project).commitDocument(editor.document)
-                try {
-                    CodeStyleManager.getInstance(file.project)!!.adjustLineIndent(
-                        file,
-                        closingTag.startOffset
-                    )
-                } catch (e: IncorrectOperationException) {
-                }
-            }
-        }
-
-        if (smartIndent) {
-            originalHandler?.execute(editor, editor.caretModel.currentCaret, dataContext)
-            PsiDocumentManager.getInstance(file.project).commitDocument(editor.document)
-            try {
-                CodeStyleManager.getInstance(
-                    file.project
-                )!!.adjustLineIndent(file, editor.caretModel.offset)
-            } catch (e: IncorrectOperationException) {
-                LOG.error(e)
-            }
-        }
-
-        val autocomplete = shouldPopupAutocomplete(file, caretOffsetRef)
-
-        if (autocomplete) {
-            AutoPopupController.getInstance(editor.project)?.scheduleAutoPopup(editor)
-        }
-
-        return if (smartIndent) EnterHandlerDelegate.Result.DefaultForceIndent
-            else EnterHandlerDelegate.Result.Continue
-    }
-
-    private data class Meta(
-        var smartIndent: Boolean = false,
-        var insertClosingTag: Boolean = false,
-        var indentClosingTag: Boolean = false,
-        var element: KtxElement? = null
-    )
-
-    /**
-     * We want to do a few "smart" enter handlers for KTX-specific edits.
-     *
-     * 1. Last attribute:
-     *
-     *          <Foo{{CURSOR}}></Foo>
-     *
-     *      should transform into:
-     *
-     *          <Foo
-     *              {{CURSOR}}
-     *          ></Foo>
-     *
-     *      Note that we can also do this transformation when it is a self-closing tag
-     *
-     * 2. Between Open/Closing:
-     *
-     *          <Foo>{{CURSOR}}</Foo>
-     *
-     *      should transform into:
-     *
-     *          <Foo>
-     *              {{CURSOR}}
-     *          </Foo>
-     *
-     *      Note that in this transformation, we can also have a parameter list to the left side of the cursor.
-     */
-    private fun getIndentMeta(
-        file: PsiFile,
-        editor: Editor,
-        caretOffsetRef: Ref<Int>
-    ): Meta? {
-        if (file !is KtFile) return null
-
-        // honor normal kotlin settings for smart enter
-        if (!CodeInsightSettings.getInstance()!!.SMART_INDENT_ON_ENTER) return null
-
-        val document = editor.document
-        val text = document.charsSequence
-        val caretOffset = caretOffsetRef.get()!!.toInt()
-
-        if (caretOffset !in 0..text.length) return null
-
-        val elementAt = file.findElementAt(caretOffset) ?: return null
-
-        val elementBefore = elementAt.getPrevLeafIgnoringWhitespace(includeSelf = false)
-            ?: return null
-        val elementAfter = elementAt.getNextLeafIgnoringWhitespace(includeSelf = true)
-            ?: return null
-        if (elementBefore.endOffset > caretOffset) return null
-        if (caretOffset > elementAfter.startOffset) return null
-
-        val returnsBetweenLeftAndCaret =
-            document.getText(TextRange(elementBefore.endOffset, caretOffset)).contains('\n')
-        val returnsBetweenRightAndCaret =
-            document.getText(TextRange(caretOffset, elementAfter.startOffset)).contains('\n')
-
-        val beforeParent = elementBefore.parent
-        val afterParent = elementAfter.parent
-
-        val isAfterGt = elementBefore.node?.elementType == KtTokens.GT
-        val isAfterArrow = elementBefore.node?.elementType == KtTokens.ARROW
-        val isBeforeGt = elementAfter.node?.elementType == KtTokens.GT
-        val isBeforeDivAndGt =
-            elementAfter.node?.elementType == KtTokens.DIV &&
-                    elementAfter.nextSibling?.node?.elementType == KtTokens.GT
-        val isBeforeLtAndDiv =
-            elementAfter.node?.elementType == KtTokens.LT &&
-                    elementAfter.nextSibling?.node?.elementType == KtTokens.DIV
-        val afterIsSameKtxTag = afterParent is KtxElement &&
-                beforeParent?.parentOfType<KtxElement>() == afterParent
-
-        val ktxElement = if (beforeParent is KtxElement)
-            beforeParent
-        else if (isAfterArrow && beforeParent?.parent is KtxLambdaExpression)
-            beforeParent.parent.parent as? KtxElement
-        else null
-
-        val isUnclosed = ktxElement?.let {
-            it.node.children().none { child -> child.elementType == KtTokens.DIV }
-        } ?: false
-        val isSelfClosing = !isUnclosed && ktxElement?.let {
-            it.simpleClosingTagName ?: it.qualifiedClosingTagName
-        } == null
-        val isBetweenOpenAndCloseOfKtxElement = ktxElement?.let {
-            it.simpleClosingTagName ?: it.qualifiedClosingTagName
-        }?.let {
-            val closeTagStart = it.startOffset - 2
-            caretOffset <= closeTagStart
-        } ?: false
-
-        val closingTagLt = ktxElement?.let {
-            it.node.children().lastOrNull { child -> child.elementType == KtTokens.LT }
-        }
-        val newLineExistsBeforeClosingTag = closingTagLt?.let { lt ->
-            lt
-                .leaves(forward = false)
-                .takeWhile { leaf ->
-                    when (leaf) {
-                        is PsiWhiteSpace -> true
-                        is PsiComment -> true
-                        is PsiBlockStatement -> true
-                        else -> false
-                    }
-                }
-                .any { it.textContains('\n') }
-        } ?: false
-
-        return Meta(
-            smartIndent = when {
-                returnsBetweenLeftAndCaret || (returnsBetweenRightAndCaret && afterIsSameKtxTag) ->
-                    false
-                isBeforeGt && afterIsSameKtxTag -> true // // <Foo{{CURSOR}}></Foo>
-                isBeforeDivAndGt && afterIsSameKtxTag -> true // <Foo{{CURSOR}}/>
-                isAfterGt && isBeforeLtAndDiv && afterIsSameKtxTag ->
-                    true // <Foo>{{CURSOR}}</Foo>
-                isAfterArrow && isBeforeLtAndDiv && afterIsSameKtxTag ->
-                    true // <Foo> x ->{{CURSOR}}</Foo>
-
-                // <Foo>{{CURSOR}}<Bar /></Foo>
-                (isAfterGt || isAfterArrow) && !isUnclosed && !afterIsSameKtxTag &&
-                        !isSelfClosing && isBetweenOpenAndCloseOfKtxElement &&
-                        !returnsBetweenRightAndCaret -> true
-                // <Foo>{{CURSOR}}<Bar />
-                (isAfterGt || isAfterArrow) && isUnclosed -> true
-                else -> false
-            },
-            insertClosingTag = when {
-                isSelfClosing -> false
-                (isAfterGt || isAfterArrow) && isUnclosed -> true
-                else -> false
-            },
-            indentClosingTag = when {
-                isSelfClosing -> false
-                !isUnclosed && !newLineExistsBeforeClosingTag &&
-                        !afterIsSameKtxTag && isBetweenOpenAndCloseOfKtxElement -> true
-                else -> false
-            },
-            element = ktxElement
-        )
-    }
-
-    private fun shouldPopupAutocomplete(
-        file: PsiFile,
-        caretOffsetRef: Ref<Int>
-    ): Boolean {
-        if (file !is KtFile) return false
-        val caretOffset = caretOffsetRef.get()!!.toInt()
-
-        val cursorEl = file.findElementAt(caretOffset) as? PsiWhiteSpace ?: return false
-
-        val ktxElement = cursorEl.parent as? KtxElement ?: return false
-
-        val firstDiv = ktxElement.node.findChildByType(KtTokens.DIV)
-        val firstGt = ktxElement.node.findChildByType(KtTokens.GT)
-
-        if (firstDiv == null && firstGt == null) return false
-
-        val endOfOpenTag = Math.min(firstDiv?.startOffset ?: Int.MAX_VALUE, firstGt?.startOffset
-            ?: Int.MAX_VALUE)
-
-        if (caretOffset > endOfOpenTag) return false
-
-        // TODO(lmr): if element to the right is not white space, false???
-
-        return true
-    }
-}
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxReferenceContributor.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxReferenceContributor.kt
deleted file mode 100644
index e843e79..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxReferenceContributor.kt
+++ /dev/null
@@ -1,322 +0,0 @@
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.openapi.util.TextRange
-import com.intellij.patterns.PlatformPatterns
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiReference
-import com.intellij.psi.PsiReferenceProvider
-import com.intellij.psi.PsiReferenceRegistrar
-import com.intellij.util.ProcessingContext
-import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.idea.references.KtMultiReference
-import org.jetbrains.kotlin.idea.references.KtSimpleReference
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
-import org.jetbrains.kotlin.psi.KtElement
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtSimpleNameExpression
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.kotlin.KtxNameConventions
-import androidx.compose.plugins.kotlin.ComposeUtils
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import androidx.compose.plugins.kotlin.EmitCallNode
-import androidx.compose.plugins.kotlin.EmitOrCallNode
-import androidx.compose.plugins.kotlin.ErrorNode
-import androidx.compose.plugins.kotlin.MemoizedCallNode
-import androidx.compose.plugins.kotlin.NonMemoizedCallNode
-import com.intellij.psi.PsiReferenceContributor
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
-import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
-import org.jetbrains.kotlin.util.OperatorNameConventions
-
-class KtxReferenceContributor : PsiReferenceContributor() {
-    override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
-        // We want to search for references on the closest ancestor of the element itself that we are putting a
-        // reference on. This ends up being KtSimpleNameExpression for most things, which this provider deals with.
-        // The reason we need to do it this way is because the reference handling is pretty broken in Kotlin, and the
-        // "element" that the IDE ends up using to do the highlighting and surfacing of the references is always the
-        // *last* element that the algorithm finds as it traverses up the spine of the tree. The way we are
-        registrar.registerReferenceProvider(
-            PlatformPatterns.psiElement(KtSimpleNameExpression::class.java),
-            KtxReferenceProvider
-        )
-        // We are hanging references on the LT bracket of the KTX element itself. To do this, we need to target the
-        // KTX element overall, though I think this would work even better if we could target the token directly, but I
-        // can't figure out how to do that and it doesn't look like that's done anywhere else.
-        registrar.registerReferenceProvider(
-            PlatformPatterns.psiElement(KtxElement::class.java),
-            KtxSyntaxReferenceProvider
-        )
-    }
-}
-
-object KtxSyntaxReferenceProvider : PsiReferenceProvider() {
-    override fun getReferencesByElement(
-        element: PsiElement,
-        context: ProcessingContext
-    ): Array<out PsiReference> {
-        return when (element) {
-            is KtxElement -> arrayOf(KtxSyntaxReference(element))
-            else -> PsiReference.EMPTY_ARRAY
-        }
-    }
-}
-
-/**
- * Because we are targeting SimpleNameExpression instead of KtxElement (because things will conflict otherwise), we have to run a
- * bit of logic to ensure that the simple name expression we have is one that we want to target in the KTX tag.
- *
- * The reason we have to do this runaround logic is because the way references currently work is that it calls `getReferencesByElement()`
- * as it travels up the spine of the tree from the leaf element that the cursor is on top of. When it is done, the IDE will highlight
- * and surface the references on the element that is shown by the *last* reference in the list that it finds as it traverses. This means
- * that using the `KtxElement` as the root is too high because it will be the "last" element for everything that gets run below it,
- * including nested KTX tags where this ends up getting really bad.  As a result, our strategy is to have `getReferencesByElement` run
- * on as small of a node as practical, even if it needs to look at it's parents and has the `ref.element` of the  reference it returns
- * be on a bigger element.
- *
- * This combination of things seems to work, but overall the reference system in IntelliJ/Kotlin is *really* fragile, so be really
- * careful when modifying this code.
- */
-object KtxReferenceProvider : PsiReferenceProvider() {
-    override fun getReferencesByElement(
-        element: PsiElement,
-        context: ProcessingContext
-    ): Array<out PsiReference> {
-        if (element !is KtSimpleNameExpression) return PsiReference.EMPTY_ARRAY
-        val parent = element.parent
-        when (parent) {
-            is KtxElement -> {
-                if (element == parent.simpleTagName) {
-                    // it is a simple open tag. include the syntax reference
-                    return arrayOf<PsiReference>(
-                        KtxSyntaxReferenceForImports(parent),
-                        KtxReference(parent, element)
-                    )
-                } else if (element == parent.simpleClosingTagName) {
-                    // it is a simple closing tag
-                    return arrayOf<PsiReference>(
-                        KtxReference(
-                            parent,
-                            element
-                        )
-                    )
-                }
-            }
-            is KtxAttribute -> {
-                if (parent.key == element) {
-                    // attribute key
-                    return arrayOf<PsiReference>(
-                        AttributeReference(
-                            parent
-                        )
-                    )
-                }
-            }
-            is KtDotQualifiedExpression -> {
-                val superparent = parent.parent
-                if (superparent is KtxElement) {
-                    val openFirstPart =
-                        firstNameForElement(superparent)
-                    if (openFirstPart == element) {
-                        // the first part of the open tag. we add a syntax reference here since it needs to have no receiver
-                        // in order to get used in the "unused imports" algorithm
-                        return arrayOf<PsiReference>(
-                            KtxSyntaxReferenceForImports(
-                                superparent
-                            )
-                        )
-                    } else {
-                        val openLastPart =
-                            lastNameForElement(superparent)
-                        val closingLastPart =
-                            superparent.qualifiedClosingTagName?.lastSimpleNameExpression()
-                        if (closingLastPart == element || openLastPart == element) {
-                            // if it's the last part of a dot qualified expression, on either the closing or open tag,
-                            // we go ahead and add our ktx reference
-                            return arrayOf<PsiReference>(
-                                KtxReference(
-                                    superparent,
-                                    element
-                                )
-                            )
-                        }
-                    }
-                }
-            }
-        }
-        return PsiReference.EMPTY_ARRAY
-    }
-}
-
-open class KtxSyntaxReference(
-    val ktxElement: KtxElement
-) : KtMultiReference<KtElement>(ktxElement) {
-
-    override fun getRangeInElement() = TextRange(0, 1)
-
-    override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
-        val resolvedElementCall = context[ComposeWritableSlices.RESOLVED_KTX_CALL, ktxElement]
-            ?: return emptyList()
-
-        val results = mutableListOf<DeclarationDescriptor>()
-
-        resolvedElementCall.getComposerCall?.resultingDescriptor?.let { results.add(it) }
-
-        var node: EmitOrCallNode? = resolvedElementCall.emitOrCall
-
-        while (node != null) {
-            node = when (node) {
-                is EmitCallNode -> {
-                    node.memoize.composerCall?.resultingDescriptor?.let { results.add(it) }
-                    null
-                }
-                is MemoizedCallNode -> {
-                    node.memoize.composerCall?.resultingDescriptor?.let { results.add(it) }
-                    node.call
-                }
-                is NonMemoizedCallNode -> node.nextCall
-                is ErrorNode -> null
-            }
-        }
-
-        return results
-    }
-
-    override val resolvesByNames: Collection<Name>
-        get() = COMPOSER_NAMES
-}
-
-class KtxSyntaxReferenceForImports(ktxElement: KtxElement) : KtxSyntaxReference(ktxElement) {
-    // NOTE(lmr): It's important that this return a KtNameReferenceElement or else this reference will not get used in the
-    // Unused Import detection! Moreover, we want it to return a name expression that does *not* have a receiver to the left of
-    // it, or else it will also get excluded. In this case we just return the left-most SimpleNameExpression of the KtxElement.
-    override fun getElement() = firstNameForElement(ktxElement)
-
-    override fun getRangeInElement() = TextRange.EMPTY_RANGE
-}
-
-/**
- * This is needed because sometimes attributes of KTX tags target a setter function with a different name than
- * the "attribute" name, which means that the extension setter won't show up as properly "used". This fixes that.
- *
- * In the long-term, I think we should not need this, since we should probably just target properties in kotlin and not setters
- */
-class AttributeReference(
-    private var attribute: KtxAttribute
-) : KtSimpleReference<KtSimpleNameExpression>(attribute.key) {
-
-    override fun getRangeInElement() = TextRange(0, attribute.key.textLength)
-
-    override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
-        return context[ComposeWritableSlices.ATTRIBUTE_KEY_REFERENCE_TARGET, attribute.key]
-            ?: listOfNotNull(context[BindingContext.REFERENCE_TARGET, attribute.key])
-    }
-
-    override val resolvesByNames: Collection<Name>
-        get() = attribute.key.getReferencedNameAsName().let {
-            listOf(
-                it,
-                Name.identifier(ComposeUtils.setterMethodFromPropertyName(it.identifier))
-            )
-        }
-}
-
-class KtxReference(
-    val ktxElement: KtxElement,
-    val nameElement: KtSimpleNameExpression
-) : KtMultiReference<KtElement>(nameElement) {
-
-    override fun getRangeInElement() = TextRange(0, nameElement.textLength)
-
-    private fun primaryTargetOf(resolvedCall: ResolvedCall<*>?): List<DeclarationDescriptor> {
-        return when (resolvedCall) {
-            is VariableAsFunctionResolvedCall ->
-                listOf(resolvedCall.variableCall.resultingDescriptor)
-            null -> emptyList()
-            else -> listOf(resolvedCall.resultingDescriptor)
-        }
-    }
-
-    private fun primaryTargetsOf(node: EmitOrCallNode?): List<DeclarationDescriptor> {
-        return when (node) {
-            is EmitCallNode -> primaryTargetOf(node.memoize.ctorCall)
-            is MemoizedCallNode ->
-                primaryTargetOf(node.memoize.ctorCall) + primaryTargetsOf(node.call)
-            is NonMemoizedCallNode ->
-                primaryTargetOf(node.resolvedCall) + primaryTargetsOf(node.nextCall)
-            is ErrorNode -> emptyList()
-            null -> emptyList()
-        }
-    }
-
-    private fun filterResultsIfInSameContainer(
-        targets: List<DeclarationDescriptor>
-    ): List<DeclarationDescriptor> {
-        if (targets.size <= 1) return targets
-        var node = targets.first()
-        val results = mutableListOf(node)
-        for (target in targets.drop(1)) {
-            val prev = node
-            node = target
-
-            val container = target.containingDeclaration
-            if (container == prev) continue
-            if (prev is ClassConstructorDescriptor && prev.containingDeclaration == container)
-                continue
-
-            results.add(target)
-        }
-        return results
-    }
-
-    override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
-        val resolvedElementCall = context[ComposeWritableSlices.RESOLVED_KTX_CALL, ktxElement]
-            ?: return emptyList()
-        val results = primaryTargetsOf(resolvedElementCall.emitOrCall)
-
-        return filterResultsIfInSameContainer(results)
-    }
-
-    override val resolvesByNames: Collection<Name>
-        get() = listOf(
-            nameElement.getReferencedNameAsName(),
-            OperatorNameConventions.INVOKE
-        )
-}
-
-private val COMPOSER_NAMES = listOf(
-    KtxNameConventions.COMPOSER,
-    KtxNameConventions.EMIT,
-    KtxNameConventions.CALL
-)
-
-private fun firstNameForElement(element: KtxElement): KtSimpleNameExpression {
-    return element.simpleTagName
-        ?: element.qualifiedTagName?.firstSimpleNameExpression()
-        ?: error("Expected a simple name expression")
-}
-
-private fun KtExpression.firstSimpleNameExpression(): KtSimpleNameExpression? = when (this) {
-    is KtSimpleNameExpression -> this
-    is KtDotQualifiedExpression ->
-        receiverExpression.firstSimpleNameExpression()
-            ?: selectorExpression?.firstSimpleNameExpression()
-    else -> null
-}
-
-private fun lastNameForElement(element: KtxElement): KtSimpleNameExpression {
-    return element.simpleTagName
-        ?: element.qualifiedTagName?.lastSimpleNameExpression()
-        ?: error("Expected a simple name expression")
-}
-
-private fun KtExpression.lastSimpleNameExpression(): KtSimpleNameExpression? = when (this) {
-    is KtSimpleNameExpression -> this
-    is KtDotQualifiedExpression ->
-        selectorExpression?.lastSimpleNameExpression()
-            ?: receiverExpression.lastSimpleNameExpression()
-    else -> null
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxTagNameSynchronizer.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxTagNameSynchronizer.kt
deleted file mode 100644
index 4da2cff..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxTagNameSynchronizer.kt
+++ /dev/null
@@ -1,334 +0,0 @@
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.codeInsight.editorActions.XmlTagNameSynchronizer
-import com.intellij.codeInsight.lookup.LookupManager
-import com.intellij.codeInsight.lookup.impl.LookupImpl
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.command.CommandEvent
-import com.intellij.openapi.command.CommandListener
-import com.intellij.openapi.command.CommandProcessor
-import com.intellij.openapi.command.undo.UndoManager
-import com.intellij.openapi.diagnostic.Attachment
-import com.intellij.openapi.diagnostic.Logger
-import com.intellij.openapi.editor.Caret
-import com.intellij.openapi.editor.Document
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.editor.EditorFactory
-import com.intellij.openapi.editor.RangeMarker
-import com.intellij.openapi.editor.event.DocumentEvent
-import com.intellij.openapi.editor.event.DocumentListener
-import com.intellij.openapi.editor.event.EditorFactoryEvent
-import com.intellij.openapi.editor.event.EditorFactoryListener
-import com.intellij.openapi.editor.ex.DocumentEx
-import com.intellij.openapi.editor.impl.EditorImpl
-import com.intellij.openapi.fileEditor.FileDocumentManager
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.Couple
-import com.intellij.openapi.util.Key
-import com.intellij.openapi.util.TextRange
-import com.intellij.pom.core.impl.PomModelImpl
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiFile
-import com.intellij.psi.PsiManager
-import com.intellij.psi.impl.PsiDocumentManagerBase
-import com.intellij.util.SmartList
-import org.jetbrains.kotlin.idea.KotlinLanguage
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.psiUtil.endOffset
-import org.jetbrains.kotlin.psi.psiUtil.startOffset
-import androidx.compose.plugins.idea.parentOfType
-
-private val LOG = Logger.getInstance(XmlTagNameSynchronizer::class.java)
-private val SYNCHRONIZER_KEY = Key.create<TagNameSynchronizer>("ktx.tag_name_synchronizer")
-private val Document.synchronizers get() =
-    EditorFactory.getInstance().getEditors(this).mapNotNull {
-        it.getUserData(SYNCHRONIZER_KEY)
-    }
-
-/**
- * Much of this file was modeled after the XML tag name synchronizer, which can be found here:
- *
- * https://github.com/JetBrains/intellij-community/blob/6eee222d1cda938673813a809ee5a8550baed005/xml/impl/src/com/intellij/codeInsight/editorActions/XmlTagNameSynchronizer.java
- */
-class KtxTagNameSynchronizer(
-    editorFactory: EditorFactory,
-    private val manager: FileDocumentManager
-) : CommandListener {
-
-    init {
-        editorFactory.addEditorFactoryListener(object : EditorFactoryListener {
-            override fun editorReleased(e: EditorFactoryEvent) = uninstall(e.editor)
-            override fun editorCreated(e: EditorFactoryEvent) = install(e.editor)
-        }, ApplicationManager.getApplication())
-
-        @Suppress("DEPRECATION")
-        CommandProcessor.getInstance().addCommandListener(this)
-    }
-
-    private fun install(editor: Editor) {
-        val project = editor.project ?: return
-
-        val document = editor.document
-        val file = manager.getFile(document) ?: return
-        if (!file.isValid) return
-        val psiFile = PsiManager.getInstance(project).findFile(file) ?: return
-
-        if (psiFile.language == KotlinLanguage.INSTANCE) {
-            TagNameSynchronizer(editor, project)
-        }
-    }
-
-    private fun uninstall(@Suppress("UNUSED_PARAMETER") editor: Editor) {
-        // Nothing to do here since we pass in itself as the disposable
-    }
-
-    override fun beforeCommandFinished(event: CommandEvent) {
-        event.document?.synchronizers?.forEach { it.beforeCommandFinished() }
-    }
-}
-
-private class TagNameSynchronizer(val editor: Editor, val project: Project) : DocumentListener {
-
-    companion object {
-        private fun Char.isValidTagNameChar() =
-            isLetter() || isDigit() || this == '.' || this == '_'
-    }
-
-    private enum class State {
-        INITIAL,
-        TRACKING,
-        APPLYING
-    }
-
-    private var manager = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
-    private var state = State.INITIAL
-    private val markers = SmartList<Couple<RangeMarker>>()
-
-    init {
-        editor.document.addDocumentListener(this, (editor as EditorImpl).disposable)
-        editor.putUserData(SYNCHRONIZER_KEY, this)
-    }
-
-    override fun beforeDocumentChange(event: DocumentEvent) {
-
-        val document = event.document
-        if (
-            state == State.APPLYING ||
-            UndoManager.getInstance(editor.project!!).isUndoInProgress ||
-            !PomModelImpl.isAllowPsiModification() ||
-            (document as DocumentEx).isInBulkUpdate
-        ) {
-            return
-        }
-
-        val offset = event.offset
-        val oldLength = event.oldLength
-        val fragment = event.newFragment
-        val newLength = event.newLength
-
-        for (i in 0 until newLength) {
-            if (!fragment[i].isValidTagNameChar()) {
-                clearMarkers()
-                return
-            }
-        }
-
-        if (state == State.INITIAL) {
-            val file = manager.getPsiFile(document)
-            if (file == null || manager.synchronizer.isInSynchronization(document)) return
-
-            val leaders = SmartList<RangeMarker>()
-            for (caret in editor.caretModel.allCarets) {
-                val leader = createTagNameMarker(caret)
-                if (leader == null) {
-                    for (marker in leaders) {
-                        marker.dispose()
-                    }
-                    return
-                }
-                leader.isGreedyToLeft = true
-                leader.isGreedyToRight = true
-                leaders.add(leader)
-            }
-            if (leaders.isEmpty()) return
-
-            if (manager.isUncommited(document)) {
-                manager.commitDocument(document)
-            }
-
-            for (leader in leaders) {
-                val support = findSupport(leader, file, document)
-                if (support == null) {
-                    clearMarkers()
-                    return
-                }
-                support.isGreedyToLeft = true
-                support.isGreedyToRight = true
-                markers.add(Couple.of(leader, support))
-            }
-
-            if (!fitsInMarker(offset, oldLength)) {
-                clearMarkers()
-                return
-            }
-
-            state = State.TRACKING
-        }
-
-        if (markers.isEmpty()) return
-
-        val fitsInMarker = fitsInMarker(offset, oldLength)
-        if (!fitsInMarker || markers.size != editor.caretModel.caretCount) {
-            clearMarkers()
-            beforeDocumentChange(event)
-        }
-    }
-
-    fun beforeCommandFinished() {
-        if (markers.isEmpty()) return
-
-        state = State.APPLYING
-
-        val document = editor.document
-        val apply = Runnable {
-            for (couple in markers) {
-                val leader = couple.first
-                val support = couple.second
-                if (document.textLength < leader.endOffset) {
-                    return@Runnable
-                }
-                val name = document.getText(TextRange(leader.startOffset, leader.endOffset))
-                if (document.textLength >= support.endOffset && name != document.getText(
-                        TextRange(
-                            support.startOffset,
-                            support.endOffset
-                        )
-                    )
-                ) {
-                    document.replaceString(support.startOffset, support.endOffset, name)
-                }
-            }
-        }
-        ApplicationManager.getApplication().runWriteAction {
-            val lookup = LookupManager.getActiveLookup(editor) as? LookupImpl
-            if (lookup != null) {
-                lookup.performGuardedChange(apply)
-            } else {
-                apply.run()
-            }
-        }
-
-        state = State.TRACKING
-    }
-
-    fun fitsInMarker(offset: Int, oldLength: Int): Boolean {
-        var fitsInMarker = false
-        for (leaderAndSupport in markers) {
-            val leader = leaderAndSupport.first
-            if (!leader.isValid) {
-                fitsInMarker = false
-                break
-            }
-            fitsInMarker = fitsInMarker or
-                    (offset >= leader.startOffset && offset + oldLength <= leader.endOffset)
-        }
-        return fitsInMarker
-    }
-
-    fun clearMarkers() {
-        for (leaderAndSupport in markers) {
-            leaderAndSupport.first.dispose()
-            leaderAndSupport.second.dispose()
-        }
-        markers.clear()
-        state = State.INITIAL
-    }
-
-    private fun createTagNameMarker(caret: Caret): RangeMarker? {
-        val offset = caret.offset
-        val document = editor.document
-        val sequence = document.charsSequence
-        var start = -1
-        var end = -1
-        for (i in offset - 1 downTo Math.max(0, offset - 50)) {
-            try {
-                val c = sequence[i]
-                if (c == '<' || c == '/' && i > 0 && sequence[i - 1] == '<') {
-                    start = i + 1
-                    break
-                }
-                if (!c.isValidTagNameChar()) break
-            } catch (e: IndexOutOfBoundsException) {
-                LOG.error(
-                    "incorrect offset:$i, initial: $offset",
-                    Attachment("document.txt", sequence.toString())
-                )
-                return null
-            }
-        }
-        if (start < 0) return null
-        for (i in offset until Math.min(document.textLength, offset + 50)) {
-            val c = sequence[i]
-            if (!c.isValidTagNameChar()) {
-                end = i
-                break
-            }
-        }
-        return if (end < 0 || start > end) null else document.createRangeMarker(start, end, true)
-    }
-
-    private fun findSupport(leader: RangeMarker, file: PsiFile, document: Document): RangeMarker? {
-        val offset = leader.startOffset
-        val element: PsiElement? = file.findElementAt(offset)
-        val support: PsiElement? = findSupportElement(element)
-
-        @Suppress("FoldInitializerAndIfToElvis")
-        if (support == null) return findSupportForTagList(leader, element, document)
-
-        val range = support.textRange
-        return document.createRangeMarker(range.startOffset, range.endOffset, true)
-    }
-
-    private fun findSupportForTagList(
-        leader: RangeMarker,
-        element: PsiElement?,
-        document: Document
-    ): RangeMarker? {
-        if (leader.startOffset != leader.endOffset || element == null) return null
-
-        var support: PsiElement? = null
-        if ("<>" == element.text) {
-            val last = element.parent.lastChild
-            if ("</>" == last.text) {
-                support = last
-            }
-        }
-        if ("</>" == element.text) {
-            val first = element.parent.firstChild
-            if ("<>" == first.text) {
-                support = first
-            }
-        }
-        if (support != null) {
-            val range = support.textRange
-            return document.createRangeMarker(range.endOffset - 1, range.endOffset - 1, true)
-        }
-        return null
-    }
-
-    private fun findSupportElement(el: PsiElement?): PsiElement? {
-        if (el == null) return null
-        val ktxEl = el.parentOfType<KtxElement>() ?: return null
-        val start = ktxEl.simpleTagName ?: ktxEl.qualifiedTagName ?: return null
-        val end = ktxEl.simpleClosingTagName ?: ktxEl.qualifiedClosingTagName
-        return if (start.startOffset <= el.startOffset && start.endOffset >= el.endOffset) {
-            // el is start tag, support is end tag
-            end
-        } else if (end != null && end.startOffset <= el.startOffset &&
-            end.endOffset >= el.endOffset) {
-            // el is the end tag, support is the start tag
-            start
-        } else null
-    }
-}
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxTypedHandler.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxTypedHandler.kt
deleted file mode 100644
index d1ffb7b..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/editor/KtxTypedHandler.kt
+++ /dev/null
@@ -1,245 +0,0 @@
-package androidx.compose.plugins.idea.editor
-
-import com.intellij.codeInsight.editorActions.TypedHandlerDelegate
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.editor.EditorModificationUtil
-import com.intellij.openapi.editor.ex.EditorEx
-import com.intellij.openapi.fileTypes.FileType
-import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiErrorElement
-import com.intellij.psi.PsiFile
-import com.intellij.psi.codeStyle.CodeStyleManager
-import com.intellij.psi.tree.IElementType
-import com.intellij.util.IncorrectOperationException
-import org.jetbrains.kotlin.KtNodeTypes
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.psiUtil.endOffset
-import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespace
-import org.jetbrains.kotlin.psi.psiUtil.startOffset
-import androidx.compose.plugins.idea.getNextLeafIgnoringWhitespace
-import androidx.compose.plugins.idea.parentOfType
-
-class KtxTypedHandler : TypedHandlerDelegate() {
-
-    override fun beforeCharTyped(
-        c: Char,
-        project: Project,
-        editor: Editor,
-        file: PsiFile,
-        fileType: FileType
-    ): Result {
-        when (c) {
-            '>' -> {
-                if (shouldOverwrite(KtTokens.GT, editor, file)) {
-                    EditorModificationUtil.moveCaretRelatively(editor, 1)
-                    return Result.STOP
-                }
-            }
-            '/' -> {
-                if (shouldOverwrite(KtTokens.DIV, editor, file)) {
-                    EditorModificationUtil.moveCaretRelatively(editor, 1)
-                    return Result.STOP
-                }
-            }
-            '{' -> {
-                // if '{' is typed at the start of an attribute value expression and right before a '>' or a '/', the '}' won't get
-                // inserted by kotlin, so we do it for you...
-                if (betweenEqOfAttributeAndCloseTag(editor, file)) {
-                    EditorModificationUtil.insertStringAtCaret(
-                        editor,
-                        "{}",
-                        true,
-                        false
-                    )
-                    EditorModificationUtil.moveCaretRelatively(editor, 1)
-                    return Result.STOP
-                }
-            }
-        }
-        return Result.CONTINUE
-    }
-
-    private fun betweenEqOfAttributeAndCloseTag(editor: Editor, file: PsiFile): Boolean {
-        val el = file.findElementAt(editor.caretModel.offset) ?: return false
-        if (el.node.elementType == KtTokens.DOUBLE_ARROW) {
-            // this is a special case where <Foo x=> will end in a double arrow, but is really just a user in the middle of typing
-            // an attribute value. If they type `{` after the `=` we want to do the right thing here
-            if (editor.caretModel.offset != el.startOffset + 1) return false
-            if (el.parent?.parent !is KtxElement) return false
-            if (el.parent?.getPrevSiblingIgnoringWhitespace(withItself = false) !is KtxAttribute)
-                return false
-            return true
-        }
-        val next = el.nextSibling
-        if (next == null) {
-            return false
-        }
-        if (next.node.elementType != KtTokens.DIV && next.node.elementType != KtTokens.GT)
-            return false
-        if (el.getPrevSiblingIgnoringWhitespace(withItself = false) !is KtxAttribute) return false
-
-        return true
-    }
-
-    private fun shouldOverwrite(token: IElementType, editor: Editor, file: PsiFile): Boolean {
-        val el = file.findElementAt(editor.caretModel.offset) ?: return false
-        if (el.node?.elementType != token) return false
-        if (el.parent?.node?.elementType != KtNodeTypes.KTX_ELEMENT) return false
-        return true
-    }
-
-    override fun charTyped(
-        c: Char,
-        project: Project,
-        editor: Editor,
-        file: PsiFile
-    ): Result {
-        @Suppress("NAME_SHADOWING") val editor = editor as EditorEx
-        when (c) {
-            '/' -> {
-                // if `</` is typed, we can complete the closing tag...
-                if (justTypedTheDivOfAClosingTag(editor)) {
-                    PsiDocumentManager.getInstance(project).commitDocument(editor.document)
-                    val div = file.findElementAt(editor.caretModel.offset - 1)
-                        ?: return Result.CONTINUE
-                    assert(div.node.elementType == KtTokens.DIV)
-                    val errorKtxElement = div.parent as? PsiErrorElement ?: return Result.CONTINUE
-                    // when the closing tag isn't fully formed, we actually parse it as an error tag in the body of the unclosed
-                    // parent tag. Thus, to find the tag we want to close, we find the first parent ktx element
-                    val el = errorKtxElement.parentOfType<KtxElement>()
-                        ?: return Result.CONTINUE
-                    val openTag = el.qualifiedTagName ?: el.simpleTagName
-                        ?: return Result.CONTINUE
-                    val tagText = editor.document.charsSequence.subSequence(
-                        openTag.startOffset,
-                        openTag.endOffset
-                    )
-                    EditorModificationUtil.insertStringAtCaret(
-                        editor,
-                        "$tagText>",
-                        false,
-                        true
-                    )
-                    PsiDocumentManager.getInstance(file.project).commitDocument(editor.document)
-                    try {
-                        CodeStyleManager.getInstance(file.project)!!.adjustLineIndent(
-                            file,
-                            openTag.endOffset + 1
-                        )
-                    } catch (e: IncorrectOperationException) {
-                    }
-                    return Result.STOP
-                }
-                // if `/` is typed before a tag is closed, we can add `>` to complete the self-closing tag
-                if (maybeJustTypedTheDivOfASelfClosingTag(editor)) {
-                    // the above check can have false positives, so to be sure that we are in a KTX element, we commit the document,
-                    // and then perform an additional check to ensure that the parent of the div is a ktx element
-                    PsiDocumentManager.getInstance(project).commitDocument(editor.document)
-                    if (justTypedTheDivOfASelfClosingTagAfterCommit(editor, file)) {
-                        // now we can for sure check add the closing bracket
-                        EditorModificationUtil.insertStringAtCaret(
-                            editor,
-                            ">",
-                            true,
-                            false)
-                        return Result.STOP
-                    }
-                }
-            }
-            '>' -> {
-                // if `>` is typed on an open tag with no closing tag, we can insert the full close tag here...
-                if (justTypedTheClosingBracketOfOpenTag(editor)) {
-                    PsiDocumentManager.getInstance(project).commitDocument(editor.document)
-
-                    val gt = file.findElementAt(editor.caretModel.offset - 1)
-                        ?: return Result.CONTINUE
-                    assert(gt.node.elementType == KtTokens.GT)
-
-                    val el = gt.parent as? KtxElement ?: return Result.CONTINUE
-                    val openTag = el.qualifiedTagName ?: el.simpleTagName ?: return Result.CONTINUE
-                    val closeTag = el.qualifiedClosingTagName ?: el.simpleClosingTagName
-                    if (closeTag != null) {
-                        // this element already has a closing tag, so we don't want to add another one... but we do want
-                        // to go ahead and ensure that the indent of the body of this tag is correct
-                        try {
-                            CodeStyleManager.getInstance(file.project)!!
-                                .adjustLineIndent(file, openTag.endOffset + 1)
-                        } catch (e: IncorrectOperationException) {
-                        }
-                        return Result.CONTINUE
-                    } else {
-                        val next = gt.getNextLeafIgnoringWhitespace()
-                        if (next == null || next.node.elementType == KtTokens.RBRACE) {
-                            // the next token is a close brace or empty, so we assume that the user's intent is not to wrap
-                            // content below with this tag. as a result, we automatically insert the closing tag
-                            val tagText = editor.document.charsSequence.subSequence(
-                                openTag.startOffset,
-                                openTag.endOffset
-                            )
-                            EditorModificationUtil.insertStringAtCaret(
-                                editor,
-                                "</$tagText>",
-                                true,
-                                false)
-                            return Result.STOP
-                        } else {
-                            // since there is content below the tag they are typing, we aren't going to auto-insert the close tag.
-                            return Result.CONTINUE
-                        }
-                    }
-                }
-            }
-        }
-        return Result.CONTINUE
-    }
-
-    private fun justTypedTheClosingBracketOfOpenTag(editor: EditorEx): Boolean {
-        val iterator = editor.highlighter.createIterator(editor.caretModel.offset)
-        with(iterator) {
-            retreat()
-            if (tokenType != KtTokens.GT) return false
-
-            retreat()
-            // if it's a DIV then the tag was self-closing and there's nothing we need to do
-            if (tokenType == KtTokens.DIV) return false
-        }
-        return true
-    }
-
-    private fun justTypedTheDivOfAClosingTag(editor: EditorEx): Boolean {
-        val iterator = editor.highlighter.createIterator(editor.caretModel.offset)
-        with(iterator) {
-            retreat()
-            if (tokenType != KtTokens.DIV) return false
-            retreat()
-
-            if (tokenType != KtTokens.LT) return false // we aren't in a ktx closing tag
-        }
-        return true
-    }
-
-    private fun maybeJustTypedTheDivOfASelfClosingTag(editor: EditorEx): Boolean {
-        val iterator = editor.highlighter.createIterator(editor.caretModel.offset)
-        with(iterator) {
-            retreat()
-            if (tokenType != KtTokens.DIV) return false
-            retreat()
-
-            if (tokenType == KtTokens.LT) return false // we aren't in a ktx closing tag
-        }
-        return true
-    }
-
-    private fun justTypedTheDivOfASelfClosingTagAfterCommit(
-        editor: EditorEx,
-        file: PsiFile
-    ): Boolean {
-        val ktxEl = file.findElementAt(editor.caretModel.offset - 1)?.parent ?: return false
-        if (ktxEl.node.elementType != KtNodeTypes.KTX_ELEMENT ||
-            ktxEl.lastChild.node.elementType != KtTokens.DIV) return false
-        return true
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AbstractKtxQuickFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AbstractKtxQuickFix.kt
deleted file mode 100644
index 47a2c0b..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AbstractKtxQuickFix.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.intention.IntentionAction
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import org.jetbrains.kotlin.diagnostics.Diagnostic
-import org.jetbrains.kotlin.idea.core.ShortenReferences
-import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
-import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
-import org.jetbrains.kotlin.psi.KtElement
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
-
-abstract class AbstractKtxQuickFix<T : KtElement>(element: T) : KotlinQuickFixAction<T>(element) {
-    protected companion object {
-        fun <T : KtElement> T.shortenReferences() = ShortenReferences.DEFAULT.process(this)
-    }
-
-    override fun getFamilyName() = "KTX"
-
-    abstract fun invoke(ktPsiFactory: KtPsiFactory, element: T)
-
-    final override fun invoke(project: Project, editor: Editor?, file: KtFile) {
-        val clazz = element ?: return
-        val ktPsiFactory = KtPsiFactory(project, markGenerated = true)
-        invoke(ktPsiFactory, clazz)
-    }
-
-    abstract class AbstractFactory(
-        private val f: Diagnostic.() -> IntentionAction?
-    ) : KotlinSingleIntentionActionFactory() {
-        companion object {
-            inline fun <reified T : KtElement> Diagnostic.findElement() =
-                psiElement.getNonStrictParentOfType<T>()
-        }
-
-        override fun createAction(diagnostic: Diagnostic) = f(diagnostic)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateTargetWithComposableQuickFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateTargetWithComposableQuickFix.kt
deleted file mode 100644
index a1e390f..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateTargetWithComposableQuickFix.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.intention.IntentionAction
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import org.jetbrains.kotlin.diagnostics.Diagnostic
-import org.jetbrains.kotlin.diagnostics.Errors
-import org.jetbrains.kotlin.idea.core.ShortenReferences
-import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
-import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
-import org.jetbrains.kotlin.idea.util.addAnnotation
-import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtElement
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtLambdaExpression
-import org.jetbrains.kotlin.psi.KtNamedFunction
-import org.jetbrains.kotlin.psi.KtParameter
-import org.jetbrains.kotlin.psi.KtProperty
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import androidx.compose.plugins.kotlin.ComposeFqNames
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
-
-class AnnotateTargetWithComposableQuickFix(
-    private val expression: KtElement
-) : KotlinQuickFixAction<KtElement>(expression) {
-    companion object MyFactory : KotlinSingleIntentionActionFactory() {
-        override fun createAction(diagnostic: Diagnostic): IntentionAction? {
-            val target = ComposeErrors.NON_COMPOSABLE_INVOCATION.cast(
-                Errors.PLUGIN_WARNING.cast(diagnostic).a.diagnostic
-            ).b
-            val foundPsiElement = target.findPsi() as? KtElement ?: return null
-
-            return AnnotateTargetWithComposableQuickFix(
-                foundPsiElement
-            )
-        }
-    }
-
-    override fun getFamilyName() = "KTX"
-
-    // TODO(lmr): we should pass in the name and use it here
-    override fun getText() = "Annotate with ''@Composable''"
-
-    override fun invoke(project: Project, editor: Editor?, file: KtFile) {
-//        val ktPsiFactory = KtPsiFactory(project, markGenerated = true)
-
-        when (expression) {
-            is KtProperty -> {
-                val typeRef = expression.typeReference
-                val defaultValue = expression.initializer
-                if (typeRef != null) {
-                    typeRef.addAnnotation(ComposeFqNames.Composable, "")
-                } else if (defaultValue != null && defaultValue is KtLambdaExpression) {
-                    // do it to default value...
-                    defaultValue.addAnnotation(ComposeFqNames.Composable)
-                } else {
-                    expression.addAnnotation(ComposeFqNames.Composable)
-                }
-            }
-            is KtParameter -> {
-                // if there's a type reference, add it to that
-                // if not, try adding it to the expression...?
-                val typeRef = expression.typeReference
-                val defaultValue = expression.defaultValue
-                if (typeRef != null) {
-                    typeRef.addAnnotation(ComposeFqNames.Composable, "")
-                } else if (defaultValue != null && defaultValue is KtLambdaExpression) {
-                    // do it to default value...
-                    defaultValue.addAnnotation(ComposeFqNames.Composable)
-                } else {
-                    expression.addAnnotation(ComposeFqNames.Composable)
-                }
-            }
-            is KtNamedFunction -> expression.addAnnotation(ComposeFqNames.Composable)
-            else -> error("Unknown element type: ${expression.node.elementType}")
-        }
-    }
-}
-
-private fun KtLambdaExpression.addAnnotation(
-    annotationFqName: FqName,
-    annotationInnerText: String? = null
-): Boolean {
-    val annotationText = when (annotationInnerText) {
-        null -> "@${annotationFqName.asString()}"
-        else -> "@${annotationFqName.asString()}($annotationInnerText)"
-    }
-
-    val psiFactory = KtPsiFactory(this)
-    val annotatedExpression = psiFactory.createExpression("$annotationText $text")
-    val parent = parent as? KtElement
-    replace(annotatedExpression)
-    parent?.let { ShortenReferences.DEFAULT.process(it) }
-
-    return true
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateWithComposableQuickFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateWithComposableQuickFix.kt
deleted file mode 100644
index 4ab38ba..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/AnnotateWithComposableQuickFix.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.idea.quickfix
-
-import org.jetbrains.kotlin.idea.core.ShortenReferences
-import org.jetbrains.kotlin.idea.util.addAnnotation
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtElement
-import org.jetbrains.kotlin.psi.KtFunction
-import org.jetbrains.kotlin.psi.KtLambdaExpression
-import org.jetbrains.kotlin.psi.KtModifierListOwner
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import androidx.compose.plugins.kotlin.ComposeFqNames
-
-class AnnotateWithComposableQuickFix(fn: KtElement) : AbstractKtxQuickFix<KtElement>(fn) {
-    companion object MyFactory : AbstractFactory(
-        {
-            val element = psiElement
-            if (element.node.elementType == KtTokens.IDENTIFIER) {
-                // if it is an identifier, it is because it is a named function declaration that
-                // needs to be annotated as @Composable. Here we find the function itself, and pass
-                // it to the quickfix
-                val targetFn: KtElement? = findElement<KtFunction>()
-                targetFn?.let {
-                    AnnotateWithComposableQuickFix(
-                        it
-                    )
-                }
-            } else when (element) {
-                // if it is a lambda expression, then we should annotate the expression itself
-                is KtLambdaExpression -> AnnotateWithComposableQuickFix(
-                    element
-                )
-                else -> null
-            }
-        }
-    )
-
-    override fun getText() = "Annotate with ''@Composable''"
-
-    override fun invoke(ktPsiFactory: KtPsiFactory, element: KtElement) {
-        when (element) {
-            // add it to the list of modifiers
-            is KtModifierListOwner -> element.addAnnotation(ComposeFqNames.Composable)
-            // annotate the expression itself
-            is KtLambdaExpression -> element.addAnnotation(ComposeFqNames.Composable)
-            else -> error("Expected a KtModifierListOwner or KtLambdaExpression. Found ${
-                element.node.elementType
-            }")
-        }
-    }
-}
-
-private fun KtLambdaExpression.addAnnotation(
-    annotationFqName: FqName,
-    annotationInnerText: String? = null
-): Boolean {
-    val annotationText = when (annotationInnerText) {
-        null -> "@${annotationFqName.asString()}"
-        else -> "@${annotationFqName.asString()}($annotationInnerText)"
-    }
-
-    val psiFactory = KtPsiFactory(this)
-    val annotatedExpression = psiFactory.createExpression("$annotationText $text")
-    val parent = parent as? KtElement
-    replace(annotatedExpression)
-    parent?.let { ShortenReferences.DEFAULT.process(it) }
-
-    return true
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeAddImportAction.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeAddImportAction.kt
deleted file mode 100644
index 30fe5d9..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeAddImportAction.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.daemon.impl.ShowAutoImportPass
-import com.intellij.codeInsight.hint.HintManager
-import com.intellij.codeInsight.hint.QuestionAction
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.command.CommandProcessor
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.ui.popup.JBPopupFactory
-import com.intellij.openapi.ui.popup.PopupStep
-import com.intellij.openapi.ui.popup.util.BaseListPopupStep
-import com.intellij.psi.PsiDocumentManager
-import org.jetbrains.kotlin.idea.util.ImportInsertHelper
-import org.jetbrains.kotlin.psi.KtElement
-import androidx.compose.plugins.idea.ComposeBundle
-
-class ComposeAddImportAction(
-    private val project: Project,
-    private val editor: Editor,
-    private val element: KtElement,
-    private val variants: List<ImportVariant>
-) : QuestionAction {
-    override fun execute(): Boolean {
-        PsiDocumentManager.getInstance(project).commitAllDocuments()
-        if (!element.isValid) return false
-        if (variants.isEmpty()) return false
-
-        if (variants.size == 1 || ApplicationManager.getApplication().isUnitTestMode) {
-            addImport(variants.first())
-            return true
-        }
-
-        JBPopupFactory.getInstance().createListPopup(
-            getVariantSelectionPopup()
-        ).showInBestPositionFor(editor)
-        return true
-    }
-
-    fun showHint(): Boolean {
-        if (variants.isEmpty()) return false
-
-        val hintText = ShowAutoImportPass.getMessage(variants.size > 1, variants.first().hint)
-        HintManager.getInstance()
-            .showQuestionHint(
-                editor,
-                hintText,
-                element.textOffset,
-                element.textRange!!.endOffset,
-                this
-            )
-
-        return true
-    }
-
-    private fun getVariantSelectionPopup(): BaseListPopupStep<ImportVariant> {
-        return object : BaseListPopupStep<ImportVariant>(
-            ComposeBundle.message("imports.chooser.title"),
-            variants
-        ) {
-            override fun isAutoSelectionEnabled() = false
-
-            override fun isSpeedSearchEnabled() = true
-
-            override fun onChosen(
-                selectedValue: ImportVariant?,
-                finalChoice: Boolean
-            ): PopupStep<String>? {
-                if (selectedValue == null || project.isDisposed) return null
-                addImport(selectedValue)
-                return null
-            }
-
-            override fun hasSubstep(selectedValue: ImportVariant?) = false
-            override fun getTextFor(value: ImportVariant) = value.hint
-        }
-    }
-
-    private fun addImport(variant: ImportVariant) {
-        PsiDocumentManager.getInstance(project).commitAllDocuments()
-
-        CommandProcessor.getInstance().executeCommand(project, {
-            ApplicationManager.getApplication().runWriteAction {
-                ImportInsertHelper.getInstance(project)
-                    .importDescriptor(element.containingKtFile, variant.descriptor)
-            }
-        }, ComposeBundle.message("add.import"), null)
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeImportFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeImportFix.kt
deleted file mode 100644
index 8b0cb22..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeImportFix.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.hint.HintManager
-import com.intellij.codeInsight.intention.HighPriorityAction
-import com.intellij.codeInspection.HintAction
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.command.CommandProcessor
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.psi.util.PsiModificationTracker
-import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtFile
-import androidx.compose.plugins.idea.ComposeBundle
-
-abstract class ComposeImportFix(
-    protected var expression: KtExpression
-) : KotlinQuickFixAction<KtExpression>(expression), HighPriorityAction, HintAction {
-    private val project = expression.project
-
-    private val modificationCountOnCreate =
-        PsiModificationTracker.SERVICE.getInstance(project).modificationCount
-
-    private lateinit var suggestions: Collection<ImportVariant>
-
-    override fun invoke(project: Project, editor: Editor?, file: KtFile) {
-        CommandProcessor.getInstance().runUndoTransparentAction {
-            createAction(project, editor!!).execute()
-        }
-    }
-
-    override fun getFamilyName(): String = ComposeBundle.message("import.fix")
-
-    override fun getText(): String = ComposeBundle.message("import.fix")
-
-    override fun startInWriteAction() = true
-
-    override fun isAvailable(
-        project: Project,
-        editor: Editor?,
-        file: KtFile
-    ) = element != null && suggestions.isNotEmpty()
-
-    fun isOutdated() =
-        modificationCountOnCreate !=
-                PsiModificationTracker.SERVICE.getInstance(project).modificationCount
-
-    override fun showHint(editor: Editor): Boolean {
-        if (!expression.isValid || isOutdated()) return false
-
-        if (
-            ApplicationManager.getApplication().isUnitTestMode &&
-            HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)
-        ) return false
-
-        if (suggestions.isEmpty()) return false
-
-        return createAction(project, editor).showHint()
-    }
-
-    fun collectSuggestions() {
-        suggestions = computeSuggestions()
-    }
-
-    abstract fun computeSuggestions(): List<ImportVariant>
-
-    private fun createAction(project: Project, editor: Editor): ComposeAddImportAction {
-        return ComposeAddImportAction(
-            project,
-            editor,
-            expression,
-            suggestions.toList()
-        )
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeQuickFixRegistry.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeQuickFixRegistry.kt
deleted file mode 100644
index 40e0e43..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ComposeQuickFixRegistry.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import org.jetbrains.kotlin.diagnostics.Errors
-import org.jetbrains.kotlin.idea.quickfix.QuickFixContributor
-import org.jetbrains.kotlin.idea.quickfix.QuickFixes
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
-
-class ComposeQuickFixRegistry : QuickFixContributor {
-    override fun registerQuickFixes(quickFixes: QuickFixes) {
-
-        // Provide fixes to annotate things that need to be @Composable when they aren't
-        quickFixes.register(
-            ComposeErrors.KTX_IN_NON_COMPOSABLE,
-            AnnotateWithComposableQuickFix
-        )
-        quickFixes.register(
-            ComposeErrors.NON_COMPOSABLE_INVOCATION,
-            AnnotateTargetWithComposableQuickFix
-        )
-
-        // Provide fixes for calling composable with a normal call
-        quickFixes.register(
-            ComposeErrors.SVC_INVOCATION,
-            ConvertCallToKtxQuickFix
-        )
-
-        // "Add Import" quick fixes for unresolved attributes that have valid extension attributes
-        quickFixes.register(
-            ComposeErrors.MISMATCHED_ATTRIBUTE_TYPE,
-            ImportAttributeFix
-        )
-        quickFixes.register(Errors.UNRESOLVED_REFERENCE,
-            ImportAttributeFix
-        )
-        quickFixes.register(
-            ComposeErrors.UNRESOLVED_ATTRIBUTE_KEY,
-            ImportAttributeFix
-        )
-        quickFixes.register(
-            ComposeErrors.UNRESOLVED_ATTRIBUTE_KEY_UNKNOWN_TYPE,
-            ImportAttributeFix
-        )
-
-        // "Add Import" for unresolved tags on KTX elements. The normal "Unresolved Reference" quick fix
-        // doesn't work in this case because if the KTX element has an open and closing tag, only one of
-        // them gets changes, and then the tag becomes invalid, and then only the one tag changes. We
-        // wrote our own custom add import quick fix that handles it correctly, but it must use the
-        // UNRESOLVED_TAG diagnostic in order to not compete with the built-in one. If JetBrains adds
-        // a better prioritization system for quick fixes, we could use `UNRESOLVED_TAG` only if we
-        // wanted.
-        quickFixes.register(Errors.UNRESOLVED_REFERENCE,
-            ImportComponentFix
-        )
-        quickFixes.register(
-            ComposeErrors.UNRESOLVED_TAG,
-            ImportComponentFix
-        )
-
-        // when a composer isn't in scope, this proovides a quickfix to import one
-        quickFixes.register(
-            ComposeErrors.NO_COMPOSER_FOUND,
-            ImportComposerFix
-        )
-    }
-}
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ConvertCallToKtxQuickFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ConvertCallToKtxQuickFix.kt
deleted file mode 100644
index 21702b9..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ConvertCallToKtxQuickFix.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.intention.IntentionAction
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiElement
-import org.jetbrains.kotlin.diagnostics.Diagnostic
-import org.jetbrains.kotlin.diagnostics.Errors
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
-import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
-import org.jetbrains.kotlin.psi.KtCallExpression
-import org.jetbrains.kotlin.psi.KtElement
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.psi.KtxElement
-import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
-import androidx.compose.plugins.kotlin.analysis.ComposeErrors
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-
-class ConvertCallToKtxQuickFix(
-    private val expression: KtCallExpression
-) : KotlinQuickFixAction<KtElement>(expression) {
-    companion object MyFactory : KotlinSingleIntentionActionFactory() {
-        override fun createAction(diagnostic: Diagnostic): IntentionAction? {
-            val target = ComposeErrors.SVC_INVOCATION.cast(
-                Errors.PLUGIN_ERROR.cast(diagnostic).a.diagnostic
-            ).psiElement
-            val foundPsiElement = target.containingCallExpression() ?: return null
-
-            return ConvertCallToKtxQuickFix(foundPsiElement)
-        }
-    }
-
-    override fun getFamilyName() = "KTX"
-
-    override fun getText() = "Convert to a tag"
-
-    override fun invoke(project: Project, editor: Editor?, file: KtFile) {
-        val bindingContext = expression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
-        val call = bindingContext.get(BindingContext.CALL, expression.calleeExpression)
-        val resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, call) ?: return
-
-        val factory = KtPsiFactory(expression)
-
-        // Create a KTX_ELEMENT node with dummy values for the arguments
-        val ktxElement = factory.createBlock(
-            "<Test ${
-            resolvedCall.valueArguments.map { "${it.key.name}=1" }.joinToString(" ")
-            } />"
-        ).statements.first() as? KtxElement ?: return
-
-        // Replace the dummy arguments with the existing expressions
-        var index = 0
-        resolvedCall.valueArguments.forEach { _, resolvedValueArgument ->
-            val ktxAttribute = ktxElement.attributes[index++]
-            val originalReference = resolvedValueArgument.arguments.first() as? PsiElement
-            val originalValue = originalReference?.getChildOfType<KtExpression>() as? PsiElement
-            originalValue?.let { ktxAttribute.value?.replace(it) }
-        }
-
-        expression.replace(ktxElement)
-    }
-}
-
-fun KtElement.containingCallExpression(): KtCallExpression? =
-    this as? KtCallExpression ?: (this.parent as? KtElement)?.containingCallExpression()
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportAttributeFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportAttributeFix.kt
deleted file mode 100644
index b87567b..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportAttributeFix.kt
+++ /dev/null
@@ -1,186 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.ImportFilter
-import com.intellij.codeInsight.intention.IntentionAction
-import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.diagnostics.Diagnostic
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
-import org.jetbrains.kotlin.idea.caches.resolve.util.getResolveScope
-import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
-import org.jetbrains.kotlin.idea.core.isVisible
-import org.jetbrains.kotlin.idea.imports.importableFqName
-import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
-import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
-import org.jetbrains.kotlin.idea.util.getFileResolutionScope
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtSimpleNameExpression
-import org.jetbrains.kotlin.psi.KtxAttribute
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.kotlin.ComposeUtils
-import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-import org.jetbrains.kotlin.resolve.scopes.LexicalScope
-import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
-import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
-import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
-import org.jetbrains.kotlin.types.typeUtil.isUnit
-
-class ImportAttributeFix(expression: KtSimpleNameExpression) : ComposeImportFix(expression) {
-    private val ktxAttribute = expression.parent as KtxAttribute
-
-    private fun getReceiverTypes(
-        bindingContext: BindingContext,
-        element: KtxElement
-    ): List<KotlinType>? {
-        val ktxCall = bindingContext[ComposeWritableSlices.RESOLVED_KTX_CALL, element]
-            ?: return null
-        return ktxCall.emitOrCall.resolvedCalls().mapNotNull { it.resultingDescriptor.returnType }
-    }
-
-    override fun computeSuggestions(): List<ImportVariant> {
-        val ktxElement = ktxAttribute.parent as? KtxElement ?: return emptyList()
-        if (!ktxAttribute.isValid) return emptyList()
-        if (ktxAttribute.containingFile !is KtFile) return emptyList()
-
-        val file = ktxAttribute.containingKtFile
-
-        val name = ktxAttribute.name ?: return emptyList()
-
-        val bindingContext = ktxAttribute.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
-
-        val receiverTypes = getReceiverTypes(bindingContext, ktxElement) ?: return emptyList()
-        val expectedTypeInfo = bindingContext[
-                BindingContext.EXPRESSION_TYPE_INFO,
-                ktxAttribute.value ?: ktxAttribute.key
-        ]
-
-        val searchScope = getResolveScope(file)
-
-        val resolutionFacade = file.getResolutionFacade()
-
-        val topLevelScope = resolutionFacade.getFileResolutionScope(file)
-
-        val callTypeAndReceiver = CallTypeAndReceiver.DOT(ktxElement)
-
-        fun isVisible(descriptor: DeclarationDescriptor): Boolean {
-            if (descriptor is DeclarationDescriptorWithVisibility) {
-                return descriptor.isVisible(
-                    ktxAttribute,
-                    callTypeAndReceiver.receiver as? KtExpression,
-                    bindingContext,
-                    resolutionFacade
-                )
-            }
-
-            return true
-        }
-
-        fun isValid(descriptor: DeclarationDescriptor): Boolean {
-            return when (descriptor) {
-                is FunctionDescriptor -> when {
-                    descriptor.valueParameters.size != 1 -> false
-                    descriptor.returnType?.isUnit() != true -> false
-                    ComposeUtils.propertyNameFromSetterMethod(descriptor.name.asString()) ==
-                            name -> true
-                    else -> false
-                }
-                else -> false
-            }
-        }
-
-        val type = expectedTypeInfo?.type
-
-        fun isCorrectType(descriptor: DeclarationDescriptor): Boolean {
-            if (type == null) return true
-            return when (descriptor) {
-                is FunctionDescriptor -> type.isSubtypeOf(descriptor.valueParameters.first().type)
-                else -> false
-            }
-        }
-
-        fun shouldShow(descriptor: DeclarationDescriptor): Boolean {
-            if (!ImportFilter.shouldImport(file, descriptor.fqNameSafe.asString())) return false
-
-            if (isAlreadyImported(descriptor, topLevelScope, descriptor.fqNameSafe)) return false
-
-            return true
-        }
-
-        val indicesHelper = KotlinIndicesHelper(
-            resolutionFacade,
-            searchScope,
-            ::isVisible,
-            file = file
-        )
-
-        val candidates = indicesHelper.getCallableTopLevelExtensions(
-            callTypeAndReceiver = callTypeAndReceiver,
-            receiverTypes = receiverTypes,
-            nameFilter = { true },
-            declarationFilter = { true }
-        )
-            .asSequence()
-            .filter { isValid(it) }
-            .filter { isVisible(it) }
-            .filter { shouldShow(it) }
-            .toList()
-
-        val filteredByTypeCandidates = candidates.filter { isCorrectType(it) }
-
-        val finalCandidates =
-            if (filteredByTypeCandidates.isNotEmpty()) filteredByTypeCandidates else candidates
-
-        return finalCandidates.map {
-            ImportVariant.forAttribute(
-                it
-            )
-        }
-    }
-
-    private fun isAlreadyImported(
-        target: DeclarationDescriptor,
-        topLevelScope: LexicalScope,
-        targetFqName: FqName
-    ): Boolean {
-        val name = target.name
-        return when (target) {
-            is ClassifierDescriptorWithTypeParameters -> {
-                val classifier = topLevelScope.findClassifier(name, NoLookupLocation.FROM_IDE)
-                classifier?.importableFqName == targetFqName
-            }
-
-            is FunctionDescriptor ->
-                topLevelScope.findFunction(name, NoLookupLocation.FROM_IDE) {
-                    it.importableFqName == targetFqName
-                } != null
-
-            is PropertyDescriptor ->
-                topLevelScope.findVariable(name, NoLookupLocation.FROM_IDE) {
-                    it.importableFqName == targetFqName
-                } != null
-
-            else -> false
-        }
-    }
-
-    companion object MyFactory : KotlinSingleIntentionActionFactory() {
-        override fun createAction(diagnostic: Diagnostic): IntentionAction? {
-            val element = diagnostic.psiElement as? KtSimpleNameExpression ?: return null
-            val attribute = element.parent as? KtxAttribute ?: return null
-            if (element != attribute.key) return null
-            return ImportAttributeFix(element).apply { collectSuggestions() }
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportComponentFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportComponentFix.kt
deleted file mode 100644
index 5ff7276..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportComponentFix.kt
+++ /dev/null
@@ -1,161 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.ImportFilter
-import com.intellij.codeInsight.intention.IntentionAction
-import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.diagnostics.Diagnostic
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
-import org.jetbrains.kotlin.idea.caches.resolve.util.getResolveScope
-import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
-import org.jetbrains.kotlin.idea.core.isVisible
-import org.jetbrains.kotlin.idea.imports.importableFqName
-import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
-import org.jetbrains.kotlin.idea.util.getFileResolutionScope
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtSimpleNameExpression
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.idea.parentOfType
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-import org.jetbrains.kotlin.resolve.scopes.LexicalScope
-import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
-import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
-import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
-
-class ImportComponentFix(
-    element: KtSimpleNameExpression,
-    private val ktxElement: KtxElement
-) : ComposeImportFix(element) {
-
-    private val name = element.getReferencedName()
-
-    override fun computeSuggestions(): List<ImportVariant> {
-        if (!ktxElement.isValid) return emptyList()
-
-        if (ktxElement.containingFile !is KtFile) return emptyList()
-
-        val file = ktxElement.containingKtFile
-
-        val bindingContext = ktxElement.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
-
-        val searchScope = getResolveScope(file)
-
-        val resolutionFacade = file.getResolutionFacade()
-
-        val topLevelScope = resolutionFacade.getFileResolutionScope(file)
-
-        fun isVisible(descriptor: DeclarationDescriptor): Boolean {
-            if (descriptor is DeclarationDescriptorWithVisibility) {
-                return descriptor.isVisible(
-                    ktxElement,
-                    null,
-                    bindingContext,
-                    resolutionFacade
-                )
-            }
-
-            return true
-        }
-
-        fun shouldShow(descriptor: DeclarationDescriptor): Boolean {
-            if (!ImportFilter.shouldImport(file, descriptor.fqNameSafe.asString())) return false
-
-            if (isAlreadyImported(descriptor, topLevelScope, descriptor.fqNameSafe)) return false
-
-            return true
-        }
-
-        val candidates = mutableListOf<ImportVariant>()
-
-        val indicesHelper = KotlinIndicesHelper(
-            resolutionFacade,
-            searchScope,
-            ::isVisible,
-            file = file
-        )
-
-        indicesHelper.processTopLevelCallables({ it == name }) loop@{ descriptor ->
-            if (!isVisible(descriptor)) return@loop
-            if (!shouldShow(descriptor)) return@loop
-            // NOTE(lmr): we could restrict some options here, but it might be best to include everything and then let
-            // the next level of error resolution tell the user how to fix. For instance, if we checked for @Composable, we might
-            // miss out on a freshly created component function that the user wants to use, but hasn't annotated properly
-            // yet. In that case we might still want to include it in this list, since duplicate names will be rare.
-            candidates.add(
-                ImportVariant.forComponent(
-                    descriptor
-                )
-            )
-        }
-
-        indicesHelper.getJvmClassesByName(name).forEach { descriptor ->
-            if (!isVisible(descriptor)) return@forEach
-            if (!shouldShow(descriptor)) return@forEach
-            candidates.add(
-                ImportVariant.forComponent(
-                    descriptor
-                )
-            )
-        }
-
-        return candidates
-    }
-
-    private fun isAlreadyImported(
-        target: DeclarationDescriptor,
-        topLevelScope: LexicalScope,
-        targetFqName: FqName
-    ): Boolean {
-        val name = target.name
-        return when (target) {
-            is ClassifierDescriptorWithTypeParameters -> {
-                val classifier = topLevelScope.findClassifier(name, NoLookupLocation.FROM_IDE)
-                classifier?.importableFqName == targetFqName
-            }
-
-            is FunctionDescriptor ->
-                topLevelScope.findFunction(name, NoLookupLocation.FROM_IDE) {
-                    it.importableFqName == targetFqName
-                } != null
-
-            is PropertyDescriptor ->
-                topLevelScope.findVariable(name, NoLookupLocation.FROM_IDE) {
-                    it.importableFqName == targetFqName
-                } != null
-
-            else -> false
-        }
-    }
-
-    companion object MyFactory : KotlinSingleIntentionActionFactory() {
-        override fun createAction(diagnostic: Diagnostic): IntentionAction? {
-            val element = diagnostic.psiElement as? KtSimpleNameExpression ?: return null
-            val ktxElement = element.parentOfType<KtxElement>() ?: return null
-            val tagOpen = ktxElement.simpleTagName /* ?: ktxElement.qualifiedTagName */
-                ?: return null
-            if (tagOpen.textRange.contains(element.textRange)) {
-                return ImportComponentFix(
-                    element,
-                    ktxElement
-                ).apply { collectSuggestions() }
-            }
-            val tagClose =
-                ktxElement.simpleClosingTagName /* ?: ktxElement.qualifiedClosingTagName */
-                    ?: return null
-            if (tagClose.textRange.contains(element.textRange)) {
-                return ImportComponentFix(
-                    element,
-                    ktxElement
-                ).apply { collectSuggestions() }
-            }
-            return null
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportComposerFix.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportComposerFix.kt
deleted file mode 100644
index 875c1c8..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportComposerFix.kt
+++ /dev/null
@@ -1,132 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import com.intellij.codeInsight.ImportFilter
-import com.intellij.codeInsight.intention.IntentionAction
-import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.diagnostics.Diagnostic
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
-import org.jetbrains.kotlin.idea.caches.resolve.util.getResolveScope
-import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
-import org.jetbrains.kotlin.idea.core.isVisible
-import org.jetbrains.kotlin.idea.imports.importableFqName
-import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
-import org.jetbrains.kotlin.idea.util.getFileResolutionScope
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.psi.KtxElement
-import androidx.compose.plugins.kotlin.KtxNameConventions
-import androidx.compose.plugins.idea.parentOfType
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-import org.jetbrains.kotlin.resolve.scopes.LexicalScope
-import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
-import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
-import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
-
-class ImportComposerFix(
-    element: KtExpression,
-    private val ktxElement: KtxElement
-) : ComposeImportFix(element) {
-
-    override fun computeSuggestions(): List<ImportVariant> {
-        if (!ktxElement.isValid) return emptyList()
-
-        if (ktxElement.containingFile !is KtFile) return emptyList()
-
-        val file = ktxElement.containingKtFile
-
-        val bindingContext = ktxElement.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
-
-        val searchScope = getResolveScope(file)
-
-        val resolutionFacade = file.getResolutionFacade()
-
-        val topLevelScope = resolutionFacade.getFileResolutionScope(file)
-
-        fun isVisible(descriptor: DeclarationDescriptor): Boolean {
-            if (descriptor is DeclarationDescriptorWithVisibility) {
-                return descriptor.isVisible(
-                    ktxElement,
-                    null,
-                    bindingContext,
-                    resolutionFacade
-                )
-            }
-
-            return true
-        }
-
-        fun shouldShow(descriptor: DeclarationDescriptor): Boolean {
-            if (!ImportFilter.shouldImport(file, descriptor.fqNameSafe.asString())) return false
-
-            if (isAlreadyImported(descriptor, topLevelScope, descriptor.fqNameSafe)) return false
-
-            return true
-        }
-
-        val candidates = mutableListOf<ImportVariant>()
-
-        val indicesHelper = KotlinIndicesHelper(
-            resolutionFacade,
-            searchScope,
-            ::isVisible,
-            file = file
-        )
-
-        val composerName = KtxNameConventions.COMPOSER.identifier
-
-        indicesHelper.processTopLevelCallables({ it == composerName }) loop@{ descriptor ->
-            if (descriptor.name != KtxNameConventions.COMPOSER) return@loop
-            if (!isVisible(descriptor)) return@loop
-            if (!shouldShow(descriptor)) return@loop
-            candidates.add(
-                ImportVariant.forComponent(
-                    descriptor
-                )
-            )
-        }
-
-        return candidates
-    }
-
-    private fun isAlreadyImported(
-        target: DeclarationDescriptor,
-        topLevelScope: LexicalScope,
-        targetFqName: FqName
-    ): Boolean {
-        val name = target.name
-        return when (target) {
-            is ClassifierDescriptorWithTypeParameters -> {
-                val classifier = topLevelScope.findClassifier(name, NoLookupLocation.FROM_IDE)
-                classifier?.importableFqName == targetFqName
-            }
-
-            is FunctionDescriptor ->
-                topLevelScope.findFunction(name, NoLookupLocation.FROM_IDE) {
-                    it.importableFqName == targetFqName
-                } != null
-
-            is PropertyDescriptor ->
-                topLevelScope.findVariable(name, NoLookupLocation.FROM_IDE) {
-                    it.importableFqName == targetFqName
-                } != null
-
-            else -> false
-        }
-    }
-
-    companion object MyFactory : KotlinSingleIntentionActionFactory() {
-        override fun createAction(diagnostic: Diagnostic): IntentionAction? {
-            val element = diagnostic.psiElement as? KtExpression ?: return null
-            val ktxElement = element.parentOfType<KtxElement>() ?: return null
-            return ImportComposerFix(element, ktxElement).apply { collectSuggestions() }
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportVariant.kt b/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportVariant.kt
deleted file mode 100644
index 49dad57..0000000
--- a/compose/compose-ide-plugin/src/main/java/androidx/compose/plugins/idea/quickfix/ImportVariant.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package androidx.compose.plugins.idea.quickfix
-
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.name.FqName
-import androidx.compose.plugins.kotlin.ComposeUtils
-import org.jetbrains.kotlin.renderer.DescriptorRenderer
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-
-data class ImportVariant(
-    val descriptor: DeclarationDescriptor,
-    val hint: String,
-    val fqName: FqName
-) {
-    companion object {
-        private val RENDERER = DescriptorRenderer.SHORT_NAMES_IN_TYPES.withOptions {
-            parameterNamesInFunctionalTypes = false
-        }
-
-        fun forAttribute(descriptor: DeclarationDescriptor): ImportVariant {
-            val fqName = descriptor.fqNameSafe
-            val type = when (descriptor) {
-                is FunctionDescriptor -> descriptor.valueParameters.first().type
-                else -> null
-            }
-            val attrName = when (descriptor) {
-                is FunctionDescriptor -> ComposeUtils.propertyNameFromSetterMethod(
-                    descriptor.name.asString()
-                )
-                else -> descriptor.name.asString()
-            }
-            val hint = "$attrName=(${type?.let { RENDERER.renderType(it) }}) (from ${
-                descriptor.containingDeclaration?.fqNameSafe
-            })"
-
-            return ImportVariant(descriptor, hint, fqName)
-        }
-
-        fun forComponent(descriptor: DeclarationDescriptor): ImportVariant {
-            return ImportVariant(
-                descriptor,
-                descriptor.fqNameSafe.asString(),
-                descriptor.fqNameSafe
-            )
-        }
-    }
-}
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/resources/META-INF/plugin.xml b/compose/compose-ide-plugin/src/main/resources/META-INF/plugin.xml
index 3e5bfc9..aa18ef3 100644
--- a/compose/compose-ide-plugin/src/main/resources/META-INF/plugin.xml
+++ b/compose/compose-ide-plugin/src/main/resources/META-INF/plugin.xml
@@ -26,31 +26,11 @@
     <idea-version since-build="191.5109.14" until-build="192.*"/>
     <depends>org.jetbrains.kotlin</depends>
 
-    <extensions defaultExtensionNs="com.intellij">
-        <completion.contributor language="kotlin" implementationClass="androidx.compose.plugins.idea.completion.ComposeCompletionContributor" />
-        <typedHandler implementation="androidx.compose.plugins.idea.editor.KtxTypedHandler" />
-        <typedHandler implementation="androidx.compose.plugins.idea.editor.KtxAttributeAutoParensHandler" />
-        <enterHandlerDelegate implementation="androidx.compose.plugins.idea.editor.KtxEnterHandler" />
-        <annotator language="kotlin" implementationClass="androidx.compose.plugins.idea.editor.ComposeUnresolvedTagAnnotator" />
-        <psi.referenceContributor language="kotlin" implementation="androidx.compose.plugins.idea.editor.KtxReferenceContributor"/>
-    </extensions>
     <extensions defaultExtensionNs="org.jetbrains.kotlin">
-        <ktxParsingExtension implementation="androidx.compose.plugins.kotlin.ComposeKtxParsingExtension" />
-        <storageComponentContainerContributor implementation="androidx.compose.plugins.kotlin.ComponentsClosedDeclarationChecker" />
         <storageComponentContainerContributor implementation="androidx.compose.plugins.kotlin.ComposableAnnotationChecker" />
         <storageComponentContainerContributor implementation="androidx.compose.plugins.kotlin.UnionAnnotationCheckerProvider" />
-        <ktxTypeResolutionExtension implementation="androidx.compose.plugins.kotlin.ComposeKtxTypeResolutionExtension"/>
         <callResolutionInterceptorExtension implementation="androidx.compose.plugins.kotlin.ComposeCallResolutionInterceptorExtension"/>
-        <ktxControlFlowExtension implementation="androidx.compose.plugins.kotlin.ComposeKtxControlFlowExtension"/>
         <typeResolutionInterceptorExtension implementation="androidx.compose.plugins.kotlin.ComposeTypeResolutionInterceptorExtension"/>
-        <completionExtension implementation="androidx.compose.plugins.idea.completion.ComposeCompletionExtension"/>
         <diagnosticSuppressor implementation="androidx.compose.plugins.kotlin.ComposeDiagnosticSuppressor"/>
-        <quickFixContributor implementation="androidx.compose.plugins.idea.quickfix.ComposeQuickFixRegistry" />
     </extensions>
-
-    <application-components>
-        <component>
-            <implementation-class>androidx.compose.plugins.idea.editor.KtxTagNameSynchronizer</implementation-class>
-        </component>
-    </application-components>
 </idea-plugin>
\ No newline at end of file
diff --git a/compose/compose-ide-plugin/src/main/resources/androidx/compose/plugins/idea/ComposeBundle.properties b/compose/compose-ide-plugin/src/main/resources/androidx/compose/plugins/idea/ComposeBundle.properties
deleted file mode 100644
index 75d537a..0000000
--- a/compose/compose-ide-plugin/src/main/resources/androidx/compose/plugins/idea/ComposeBundle.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#quick fix messages
-import.fix=Import
-add.import=Add Import
-imports.chooser.title=Imports
\ No newline at end of file
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt
index 876da5f..3bed268 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.benchmark.dbmonster
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Model
 import androidx.compose.composer
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/deeptree/DeepTree.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/deeptree/DeepTree.kt
index c77cfd8..43f6cd1 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/deeptree/DeepTree.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/deeptree/DeepTree.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.benchmark.deeptree
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.core.dp
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/siblings/SiblingManagement.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/siblings/SiblingManagement.kt
index 9d420ae..1169bad 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/siblings/SiblingManagement.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/siblings/SiblingManagement.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.benchmark.siblings
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.Key
 import androidx.compose.composer
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Children.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Children.kt
deleted file mode 100644
index c4584d3..0000000
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Children.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose
-
-/**
- * [Children] can be applied to one parameter of a composable function, to indicate that this
- * parameter represents the composable's children.  The general expectation is that the parameter
- * this annotates is used to describe the composable's sub-nodes within the composable's view
- * hierarchy.  The type of the parameter that [Children] annotates is expected to be a function of
- * some type, and it is assumed to be [Composable] unless otherwise specified with the [composable]
- * parameter. One does not need to use both [Composable] and [Children] in conjunction with one
- * another.
- *
- * NOTE: It is expected that this annotation will eventually go away and function parameters at the
- * end of a parameter list will be treated as Children parameters, just like postfix lambda
- * arguments in normal Kotlin.
- *
- * @param composable If false, the type of the argument will be compiled as a function that is _not_
- *  [Composable]. Defaults to true.
- *
- * @see Composable
- */
-@MustBeDocumented
-@Target(
-    // Parameters of [Composable] functions
-    AnnotationTarget.VALUE_PARAMETER,
-    // Properties of [Component] classes
-    AnnotationTarget.PROPERTY,
-    // Setter functions of [Component] classes
-    AnnotationTarget.FUNCTION
-)
-annotation class Children(val composable: Boolean = true)
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt
index 0327da2..c073d0e 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Component.kt
@@ -51,7 +51,6 @@
  *
  * @see Composable
  */
-@Stateful
 @Suppress("PLUGIN_ERROR")
 abstract class Component {
     @HiddenAttribute
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
index 82f9c4d..9203840 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
@@ -1836,3 +1836,9 @@
         else break
     }
 }
+
+object NullCompitionScope {
+    val composer = Unit
+}
+
+inline fun <T> escapeCompose(block: NullCompitionScope.() -> T) = NullCompitionScope.block()
diff --git a/ui/ui-android-view/src/main/java/androidx/ui/androidview/WebComponentActivity.kt b/ui/ui-android-view/src/main/java/androidx/ui/androidview/WebComponentActivity.kt
index 94de6b7..a137403 100644
--- a/ui/ui-android-view/src/main/java/androidx/ui/androidview/WebComponentActivity.kt
+++ b/ui/ui-android-view/src/main/java/androidx/ui/androidview/WebComponentActivity.kt
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package androidx.ui.androidview
 
 import android.app.Activity
diff --git a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DraggableSamples.kt b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DraggableSamples.kt
index 6043816..9894036 100644
--- a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DraggableSamples.kt
+++ b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DraggableSamples.kt
@@ -23,6 +23,7 @@
 import androidx.compose.unaryPlus
 import androidx.ui.animation.animatedFloat
 import androidx.ui.core.Alignment
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.dp
 import androidx.ui.core.withDensity
 import androidx.ui.foundation.ColoredRect
@@ -42,12 +43,12 @@
     // Composable that users can drag over 300 dp.
     val max = 300.dp
     val min = 0.dp
-    val (minPx, maxPx) = +withDensity {
+    val (minPx, maxPx) = withDensity(+ambientDensity()) {
         min.toPx().value to max.toPx().value
     }
     Draggable(DragDirection.Horizontal, minPx, maxPx) { dragValue ->
         // dragValue is the current value in progress of dragging
-        val draggedDp = +withDensity {
+        val draggedDp = withDensity(+ambientDensity()) {
             dragValue.toDp()
         }
         val squareSize = 50.dp
@@ -70,7 +71,7 @@
     // and the value will gravitate to 0, 150 or 300 dp
     val max = 300.dp
     val min = 0.dp
-    val (minPx, maxPx) = +withDensity {
+    val (minPx, maxPx) = withDensity(+ambientDensity()) {
         min.toPx().value to max.toPx().value
     }
     // define anchors and related animation controller
@@ -86,7 +87,7 @@
     ) { dragValue ->
         // dragValue is the current value in progress
         // of dragging or animation
-        val draggedDp = +withDensity {
+        val draggedDp = withDensity(+ambientDensity()) {
             dragValue.toDp()
         }
         val squareSize = 50.dp
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Popup.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Popup.kt
index 4448586..f41f664 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Popup.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Popup.kt
@@ -32,6 +32,7 @@
 import androidx.compose.ambient
 import androidx.compose.composer
 import androidx.compose.disposeComposition
+import androidx.compose.escapeCompose
 import androidx.compose.memo
 import androidx.compose.onCommit
 import androidx.compose.onDispose
@@ -136,14 +137,14 @@
     val providedTestTag = +ambient(TestTagAmbient)
 
     val popupLayout = +memo(popupProperties) {
-        PopupLayout(
+        escapeCompose { PopupLayout(
             context = context,
             composeView = composeView,
             popupProperties = popupProperties,
             popupPositionProperties = popupPositionProperties,
             calculatePopupPosition = calculatePopupPosition,
             testTag = providedTestTag
-        )
+        ) }
     }
     popupLayout.calculatePopupPosition = calculatePopupPosition
 
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
index 9850ba5..c93722d 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
@@ -20,7 +20,6 @@
 import androidx.animation.AnimationEndReason
 import androidx.animation.ExponentialDecay
 import androidx.animation.ValueHolder
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.Model
@@ -148,7 +147,7 @@
         scrollerPosition.value = position
     },
     isScrollable: Boolean = true,
-    @Children child: @Composable() () -> Unit
+    child: @Composable() () -> Unit
 ) {
     Scroller(scrollerPosition, onScrollPositionChanged, true, isScrollable, child)
 }
@@ -181,7 +180,7 @@
         scrollerPosition.value = position
     },
     isScrollable: Boolean = true,
-    @Children child: @Composable() () -> Unit
+    child: @Composable() () -> Unit
 ) {
     Scroller(scrollerPosition, onScrollPositionChanged, false, isScrollable, child)
 }
@@ -192,7 +191,7 @@
     onScrollPositionChanged: (position: Px, maxPosition: Px) -> Unit,
     isVertical: Boolean,
     isScrollable: Boolean,
-    @Children child: @Composable() () -> Unit
+    child: @Composable() () -> Unit
 ) {
     val maxPosition = +state { Px.Infinity }
     val direction = if (isVertical) DragDirection.Vertical else DragDirection.Horizontal
diff --git a/ui/ui-framework/api/0.1.0-dev02.txt b/ui/ui-framework/api/0.1.0-dev02.txt
index ac9847d..0f68ae1 100644
--- a/ui/ui-framework/api/0.1.0-dev02.txt
+++ b/ui/ui-framework/api/0.1.0-dev02.txt
@@ -143,7 +143,6 @@
     method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityScope,? extends R> block);
   }
 
 }
diff --git a/ui/ui-framework/api/current.txt b/ui/ui-framework/api/current.txt
index ac9847d..0f68ae1 100644
--- a/ui/ui-framework/api/current.txt
+++ b/ui/ui-framework/api/current.txt
@@ -143,7 +143,6 @@
     method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityScope,? extends R> block);
   }
 
 }
diff --git a/ui/ui-framework/api/public_plus_experimental_0.1.0-dev02.txt b/ui/ui-framework/api/public_plus_experimental_0.1.0-dev02.txt
index ac9847d..0f68ae1 100644
--- a/ui/ui-framework/api/public_plus_experimental_0.1.0-dev02.txt
+++ b/ui/ui-framework/api/public_plus_experimental_0.1.0-dev02.txt
@@ -143,7 +143,6 @@
     method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityScope,? extends R> block);
   }
 
 }
diff --git a/ui/ui-framework/api/public_plus_experimental_current.txt b/ui/ui-framework/api/public_plus_experimental_current.txt
index ac9847d..0f68ae1 100644
--- a/ui/ui-framework/api/public_plus_experimental_current.txt
+++ b/ui/ui-framework/api/public_plus_experimental_current.txt
@@ -143,7 +143,6 @@
     method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityScope,? extends R> block);
   }
 
 }
diff --git a/ui/ui-framework/api/restricted_0.1.0-dev02.txt b/ui/ui-framework/api/restricted_0.1.0-dev02.txt
index ac9847d..0f68ae1 100644
--- a/ui/ui-framework/api/restricted_0.1.0-dev02.txt
+++ b/ui/ui-framework/api/restricted_0.1.0-dev02.txt
@@ -143,7 +143,6 @@
     method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityScope,? extends R> block);
   }
 
 }
diff --git a/ui/ui-framework/api/restricted_current.txt b/ui/ui-framework/api/restricted_current.txt
index ac9847d..0f68ae1 100644
--- a/ui/ui-framework/api/restricted_current.txt
+++ b/ui/ui-framework/api/restricted_current.txt
@@ -143,7 +143,6 @@
     method public static androidx.compose.Ambient<androidx.ui.core.LayoutDirection> getLayoutDirectionAmbient();
     method public static androidx.compose.CompositionContext? setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.CompositionContext? setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @CheckResult(suggest="+") public static <R> androidx.compose.Effect<R> withDensity(kotlin.jvm.functions.Function1<? super androidx.ui.core.DensityScope,? extends R> block);
   }
 
 }
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL1.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL1.kt
index 9ca9993..974f4f0 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL1.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL1.kt
@@ -30,7 +30,6 @@
 import androidx.ui.material.Button
 import androidx.ui.material.MaterialTheme
 import androidx.ui.material.themeTextStyle
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.state
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL2.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL2.kt
index 031632f..d9f4116 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL2.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL2.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.framework.demos
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL3.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL3.kt
index 565ab99..d0cf6ad 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL3.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/SemanticsL3.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.framework.demos
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt
index b1aa6b6..bc078c9 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/VectorGraphicsActivity.kt
@@ -18,7 +18,6 @@
 
 import android.app.Activity
 import android.os.Bundle
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.unaryPlus
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/autofill/ExplicitAutofillTypesActivity.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/autofill/ExplicitAutofillTypesActivity.kt
index c141109..b1c76ac 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/autofill/ExplicitAutofillTypesActivity.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/autofill/ExplicitAutofillTypesActivity.kt
@@ -19,7 +19,6 @@
 import android.app.Activity
 import android.graphics.Rect
 import android.os.Bundle
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.ambient
 import androidx.compose.composer
@@ -102,7 +101,7 @@
 fun Autofill(
     autofillTypes: List<AutofillType>,
     onFill: ((String) -> Unit),
-    @Children children: @Composable() (AutofillNode) -> Unit
+    children: @Composable() (AutofillNode) -> Unit
 ) {
     val autofillNode = AutofillNode( autofillTypes = autofillTypes)
 
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
index c5e852a..e114e50 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
@@ -18,7 +18,6 @@
 
 import android.app.Activity
 import android.os.Bundle
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.state
 import androidx.compose.unaryPlus
@@ -66,7 +65,7 @@
     paddingTop: Dp? = null,
     paddingRight: Dp? = null,
     paddingBottom: Dp? = null,
-    @Children children: (@Composable() () -> Unit)
+    children: (@Composable() () -> Unit)
 ) {
     val defaultColor = DefaultBackgroundColor
     val pressedColor = PressedColor
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt
index c63b0d6..c830a8a 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.core
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.ui.engine.geometry.Shape
@@ -28,7 +27,7 @@
  */
 @Composable
 inline fun Clip(shape: Shape, crossinline children: @Composable() () -> Unit) {
-    <RepaintBoundaryNode name=null shape=shape clipToShape=true>
+    RepaintBoundaryNode(name=null, shape=shape, clipToShape=true) {
         children()
-    </RepaintBoundaryNode>
+    }
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt
index daf526c..e9c3d4b 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Draw.kt
@@ -39,11 +39,11 @@
 ) {
     // Hide the internals of DrawNode
     if (+ambient(InspectionMode)) {
-        <RepaintBoundaryNode name=null>
-            <DrawNode >
-        </RepaintBoundaryNode>
+        RepaintBoundaryNode(name=null) {
+            DrawNode(>
+        }
     } else {
-        <DrawNode >
+        DrawNode(>
     }
 }
 
@@ -63,14 +63,14 @@
 ) {
     // Hide the internals of DrawNode
     if (+ambient(InspectionMode)) {
-        <RepaintBoundaryNode name=null>
-            <DrawNode >
+        RepaintBoundaryNode(name=null) {
+            DrawNode( {
                 children()
-            </DrawNode>
-        </RepaintBoundaryNode>
+            }
+        }
     } else {
-        <DrawNode >
+        DrawNode( {
             children()
-        </DrawNode>
+        }
     }
 }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt b/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
index 05f436c..39e7a05 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
@@ -34,5 +34,5 @@
 @Composable
 @Suppress("NOTHING_TO_INLINE")
 inline fun DrawShadow(shape: Shape, elevation: Dp) {
-    <RepaintBoundaryNode name=null shape=shape elevation=elevation/>
+    RepaintBoundaryNode(name=null, shape=shape, elevation=elevation)
 }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
index 73d8b53..bc8a00e 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
@@ -134,9 +134,9 @@
     measureBlocks: LayoutNode.MeasureBlocks,
     modifier: Modifier
 ) {
-    <LayoutNode modifier=modifier measureBlocks=measureBlocks>
+    LayoutNode(modifier=modifier, measureBlocks=measureBlocks) {
         children()
-    </LayoutNode>
+    }
 }
 
 /**
@@ -415,9 +415,9 @@
     } else {
         @Composable {
             childrenArray.forEach { childrenComposable ->
-                <DataNode key=ChildGroupKey value=childrenComposable>
+                DataNode(key=ChildGroupKey, value=childrenComposable) {
                     childrenComposable()
-                </DataNode>
+                }
             }
         }
     }
@@ -518,11 +518,11 @@
         ) = error("Intrinsic measurements not supported for WithConstraints")
     }
 
-    <LayoutNode
-        ref=layoutNodeRef
-        modifier=Modifier.None
+    LayoutNode(
+        ref=layoutNodeRef,
+        modifier=Modifier.None,
         measureBlocks=measureBlocks
-    />
+    )
 }
 
 /**
@@ -545,7 +545,7 @@
 inline fun OnPositioned(
     noinline onPositioned: (coordinates: LayoutCoordinates) -> Unit
 ) {
-    <DataNode key=OnPositionedKey value=onPositioned/>
+    DataNode(key=OnPositionedKey, value=onPositioned)
 }
 
 /**
@@ -567,7 +567,7 @@
     noinline onPositioned: (coordinates: LayoutCoordinates) -> Unit,
     crossinline children: @Composable() () -> Unit
 ) {
-    <DataNode key=OnChildPositionedKey value=onPositioned>
+    DataNode(key=OnChildPositionedKey, value=onPositioned) {
         children()
-    </DataNode>
+    }
 }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt
index e8debcd..3f81bee 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt
@@ -17,7 +17,6 @@
 package androidx.ui.core
 
 import androidx.annotation.FloatRange
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
@@ -35,7 +34,7 @@
     @FloatRange(from = 0.0, to = 1.0) opacity: Float,
     crossinline children: @Composable() () -> Unit
 ) {
-    <RepaintBoundaryNode name=null opacity=opacity>
+    RepaintBoundaryNode(name=null, opacity=opacity) {
         children()
-    </RepaintBoundaryNode>
+    }
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/ParentData.kt b/ui/ui-framework/src/main/java/androidx/ui/core/ParentData.kt
index b13ecb9e..42eb651 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/ParentData.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/ParentData.kt
@@ -15,7 +15,6 @@
  */
 package androidx.ui.core
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
@@ -54,7 +53,7 @@
  */
 @Composable
 inline fun ParentData(data: Any, crossinline children: @Composable() () -> Unit) {
-    <DataNode key=ParentDataKey value=data>
+    DataNode(key=ParentDataKey, value=data) {
         children()
-    </DataNode>
+    }
 }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/PointerInputWrapper.kt b/ui/ui-framework/src/main/java/androidx/ui/core/PointerInputWrapper.kt
index bbd3fc5..845a9ff 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/PointerInputWrapper.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/PointerInputWrapper.kt
@@ -13,10 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package androidx.ui.core
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
@@ -27,7 +25,7 @@
     crossinline children: @Composable() () -> Unit
 ) {
     // Hide the internals of PointerInputNode
-    <PointerInputNode pointerInputHandler>
+    PointerInputNode(pointerInputHandler=pointerInputHandler) {
         children()
-    </PointerInputNode>
+    }
 }
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/RepaintBoundary.kt b/ui/ui-framework/src/main/java/androidx/ui/core/RepaintBoundary.kt
index cbf1760..5d4b9b2 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/RepaintBoundary.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/RepaintBoundary.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.core
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
@@ -32,7 +31,7 @@
  */
 @Composable
 fun RepaintBoundary(name: String? = null, children: @Composable() () -> Unit) {
-    <RepaintBoundaryNode name=name>
-        <children/>
-    </RepaintBoundaryNode>
+    RepaintBoundaryNode(name=name) {
+        children()
+    }
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/TestTagProvider.kt b/ui/ui-framework/src/main/java/androidx/ui/core/TestTagProvider.kt
index a75a022..ca9b79f 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/TestTagProvider.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/TestTagProvider.kt
@@ -17,7 +17,6 @@
 package androidx.ui.core
 
 import androidx.compose.Ambient
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/TextSpanCompose.kt b/ui/ui-framework/src/main/java/androidx/ui/core/TextSpanCompose.kt
index bae2121..f733208 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/TextSpanCompose.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/TextSpanCompose.kt
@@ -18,7 +18,6 @@
 
 import androidx.compose.Applier
 import androidx.compose.ApplyAdapter
-import androidx.compose.Children
 import androidx.compose.Component
 import androidx.compose.Composable
 import androidx.compose.Composer
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
index 025c8ae..ae051a7 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
@@ -54,7 +54,7 @@
 fun ComposeView(children: @Composable() () -> Unit) {
     val rootRef = +memo { Ref<AndroidComposeView>() }
 
-    <AndroidComposeView ref=rootRef>
+    AndroidComposeView(ref=rootRef) {
         var reference: CompositionReference? = null
         var cc: CompositionContext? = null
 
@@ -89,12 +89,13 @@
         // If this value is inlined where it is used, an error that includes 'Precise Reference:
         // kotlinx.coroutines.Dispatchers' not instance of 'Precise Reference: androidx.compose.Ambient'.
         val coroutineContext = Dispatchers.Main
-        cc = Compose.composeInto(container = rootLayoutNode, context = context, parent = reference) {
-            WrapWithAmbients(rootRef.value!!, context, coroutineContext) {
-                children()
+        cc =
+            Compose.composeInto(container = rootLayoutNode, context = context, parent = reference) {
+                WrapWithAmbients(rootRef.value!!, context, coroutineContext) {
+                    children()
+                }
             }
-        }
-    </AndroidComposeView>
+    }
 }
 
 /**
@@ -259,29 +260,6 @@
     effectOf<Density> { +ambient(DensityAmbient) }
 
 /**
- * An effect to be able to convert dimensions between each other.
- * A [Density] object will be taken from an ambient.
- *
- * Usage examples:
- *
- *     +withDensity() {
- *        val pxHeight = DpHeight.toPx()
- *     }
- *
- * or
- *
- *     val pxHeight = +withDensity(density) { DpHeight.toPx() }
- *
- */
-@CheckResult(suggest = "+")
-// can't make this inline as tests are failing with "DensityKt.$jacocoInit()' is inaccessible"
-/*inline*/ fun <R> withDensity(/*crossinline*/ block: DensityScope.() -> R) =
-    effectOf<R> {
-        @Suppress("USELESS_CAST")
-        withDensity(+ambientDensity(), block as DensityScope.() -> R)
-    }
-
-/**
  * A component to be able to convert dimensions between each other.
  * A [Density] object will be take from an ambient.
  *
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressGestureDetector.kt
index e91a1e34..459b88a 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressGestureDetector.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/PressGestureDetector.kt
@@ -17,7 +17,6 @@
 package androidx.ui.core.gesture
 
 import androidx.ui.core.PxPosition
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopDragGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopDragGestureDetector.kt
index 636c602..bd7297a 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopDragGestureDetector.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopDragGestureDetector.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.Composable
 import androidx.compose.memo
+import androidx.compose.composer
 import androidx.compose.unaryPlus
 import androidx.ui.core.Direction
 import androidx.ui.core.PxPosition
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetector.kt b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetector.kt
index f490466..4b1307a 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetector.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/gesture/TouchSlopExceededGestureDetector.kt
@@ -29,6 +29,7 @@
 import androidx.ui.core.PointerInputWrapper
 import androidx.compose.composer
 import androidx.ui.core.IntPx
+import androidx.ui.core.ambientDensity
 
 // TODO(shepshapard): Convert to functional component with effects once effects are ready.
 /**
@@ -48,7 +49,7 @@
     canDrag: ((Direction) -> Boolean)? = null,
     children: @Composable() () -> Unit
 ) {
-    val touchSlop = +withDensity { TouchSlop.toIntPx() }
+    val touchSlop = withDensity(+ambientDensity()) { TouchSlop.toIntPx() }
     val recognizer = +memo { TouchSlopExceededGestureRecognizer(touchSlop) }
 
     recognizer.canDrag = canDrag
diff --git a/ui/ui-framework/src/main/java/androidx/ui/graphics/vector/VectorCompose.kt b/ui/ui-framework/src/main/java/androidx/ui/graphics/vector/VectorCompose.kt
index 9fb9fdf..9fd6448 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/graphics/vector/VectorCompose.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/graphics/vector/VectorCompose.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.graphics.vector
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.compositionReference
@@ -26,6 +25,7 @@
 import androidx.ui.core.Dp
 import androidx.ui.core.Draw
 import androidx.ui.core.Px
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.withDensity
 import androidx.ui.graphics.Brush
 import androidx.ui.graphics.StrokeCap
@@ -52,10 +52,10 @@
     viewportWidth: Float = unset,
     viewportHeight: Float = unset,
     name: String = "",
-    @Children children: @Composable() VectorScope.(viewportWidth: Float, viewportHeight: Float) -> Unit
+    children: @Composable() VectorScope.(viewportWidth: Float, viewportHeight: Float) -> Unit
 ) {
-    val widthPx = +withDensity { defaultWidth.toPx() }
-    val heightPx = +withDensity { defaultHeight.toPx() }
+    val widthPx = withDensity(+ambientDensity()) { defaultWidth.toPx() }
+    val heightPx = withDensity(+ambientDensity()) { defaultHeight.toPx() }
 
     val vpWidth = if (viewportWidth == unset) widthPx.value else viewportWidth
     val vpHeight = if (viewportHeight == unset) heightPx.value else viewportHeight
@@ -78,7 +78,7 @@
     viewportWidth: Float = defaultWidth.value,
     viewportHeight: Float = defaultHeight.value,
     name: String = "",
-    @Children children: @Composable() VectorScope.(viewportWidth: Float, viewportHeight: Float) -> Unit
+    children: @Composable() VectorScope.(viewportWidth: Float, viewportHeight: Float) -> Unit
 ) {
     val vector =
         +memo(name, viewportWidth, viewportHeight) {
@@ -117,19 +117,19 @@
     clipPathData: Array<PathNode> = EmptyPath,
     children: @Composable() VectorScope.() -> Unit
 ) {
-    <GroupComponent
-        name = name
-        rotation = rotation
-        pivotX = pivotX
-        pivotY = pivotY
-        scaleX = scaleX
-        scaleY = scaleY
-        translationX = translationX
-        translationY = translationY
+    GroupComponent(
+        name = name,
+        rotation = rotation,
+        pivotX = pivotX,
+        pivotY = pivotY,
+        scaleX = scaleX,
+        scaleY = scaleY,
+        translationX = translationX,
+        translationY = translationY,
         clipPathData = clipPathData
-    >
+    ) {
         children()
-    </GroupComponent>
+    }
 }
 
 @Composable
@@ -145,16 +145,16 @@
     strokeLineJoin: StrokeJoin = DefaultStrokeLineJoin,
     strokeLineMiter: Float = DefaultStrokeLineMiter
 ) {
-    <PathComponent
-        name
-        pathData
-        fill
-        fillAlpha
-        stroke
-        strokeAlpha
-        strokeLineWidth
-        strokeLineJoin
-        strokeLineCap
-        strokeLineMiter
-    />
+    PathComponent(
+        name=name,
+        pathData=pathData,
+        fill=fill,
+        fillAlpha=fillAlpha,
+        stroke=stroke,
+        strokeAlpha=strokeAlpha,
+        strokeLineWidth=strokeLineWidth,
+        strokeLineJoin=strokeLineJoin,
+        strokeLineCap=strokeLineCap,
+        strokeLineMiter=strokeLineMiter
+    )
 }
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/semantics/Semantics.kt b/ui/ui-framework/src/main/java/androidx/ui/semantics/Semantics.kt
index e3ba12c..4b1161d 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/semantics/Semantics.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/semantics/Semantics.kt
@@ -15,7 +15,6 @@
  */
 package androidx.ui.semantics
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.ambient
 import androidx.compose.composer
@@ -64,11 +63,13 @@
         it.testTag = it.getOrNull(SemanticsProperties.TestTag) ?: providedTestTag
     }
 
-    <SemanticsComponentNode
-        container
-        explicitChildNodes
-        semanticsConfiguration> TestTag(tag = DefaultTestTag) {
-        children()
+    SemanticsComponentNode(
+        container=container,
+        explicitChildNodes=explicitChildNodes,
+        semanticsConfiguration=semanticsConfiguration
+    ) {
+        TestTag(tag = DefaultTestTag) {
+            children()
+        }
     }
-    </SemanticsComponentNode>
 }
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioModifierTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioModifierTest.kt
index d7a3575..cacd9d9 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioModifierTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioModifierTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.ui.layout.test
 
-import androidx.compose.Children
+import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.test.filters.SmallTest
 import androidx.ui.core.Constraints
@@ -43,7 +43,7 @@
 class AspectRatioModifierTest : LayoutTest() {
     @Test
     fun testAspectRatioModifier_intrinsicDimensions() = withDensity(density) {
-        testIntrinsics(@Children {
+        testIntrinsics(@Composable {
             Container(modifier = AspectRatio(2f), width = 30.dp, height = 40.dp) { }
         }) { minIntrinsicWidth, minIntrinsicHeight, maxIntrinsicWidth, maxIntrinsicHeight ->
             assertEquals(40.ipx, minIntrinsicWidth(20.ipx))
@@ -99,7 +99,7 @@
         val size = Ref<PxSize>()
         val position = Ref<PxPosition>()
         show {
-            Layout(@Children {
+            Layout(@Composable {
                 Container(AspectRatio(aspectRatio)) {
                     SaveLayoutInfo(size, position, positionedLatch)
                 }
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioTest.kt
index c06806f2..544e3dd 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AspectRatioTest.kt
@@ -19,7 +19,7 @@
 
 package androidx.ui.layout.test
 
-import androidx.compose.Children
+import androidx.compose.Composable
 import androidx.test.filters.SmallTest
 import androidx.ui.core.Layout
 import androidx.ui.core.OnChildPositioned
@@ -137,7 +137,7 @@
 
     @Test
     fun testAspectRatio_intrinsicDimensions() = withDensity(density) {
-        testIntrinsics(@Children {
+        testIntrinsics(@Composable {
             AspectRatio(2f) {
                 Container(width = 30.dp, height = 40.dp) { }
             }
@@ -159,7 +159,7 @@
         val size = Ref<PxSize>()
         show {
             Align(alignment = Alignment.TopLeft) {
-                val children = @Children {
+                val children = @Composable {
                     AspectRatio(aspectRatio) {
                         SaveLayoutInfo(size, Ref<PxPosition>(), positionedLatch)
                     }
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ExpandedModifierTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ExpandedModifierTest.kt
index 1c3e365..a91eef7 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ExpandedModifierTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ExpandedModifierTest.kt
@@ -17,7 +17,6 @@
 package androidx.ui.layout.test
 
 import android.content.res.Resources
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.test.filters.SmallTest
@@ -89,7 +88,7 @@
         val size = Ref<PxSize>()
         val position = Ref<PxPosition>()
         show {
-            Layout(@Children {
+            Layout(@Composable {
                 Align(alignment = Alignment.TopLeft) {
                     Container(modifier = modifier) {
                         Container(width = Width, height = Height) { }
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
index 1c76244..b9ce811 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
@@ -67,7 +67,7 @@
     }
 
     fun inflexible(children: @Composable() () -> Unit) {
-        childrenList += {
+        childrenList += @Composable {
             ParentData(data = FlexInfo(flex = 0f, fit = FlexFit.Loose), children = children)
         }
     }
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt
index 3784df0..070c338 100644
--- a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/TabSamples.kt
@@ -28,6 +28,7 @@
 import androidx.ui.animation.Transition
 import androidx.ui.core.Alignment
 import androidx.ui.core.Text
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.dp
 import androidx.ui.core.toPx
 import androidx.ui.core.withDensity
@@ -343,8 +344,10 @@
     // Padding to set the 'offset'
     Container(expanded = true, alignment = Alignment.BottomLeft) {
         Transition(transitionDefinition, selectedIndex) { state ->
-            val offset = +withDensity { state[indicatorStart].toDp() }
-            val width = +withDensity { (state[indicatorEnd] - state[indicatorStart]).toDp() }
+            val offset = withDensity(+ambientDensity()) { state[indicatorStart].toDp() }
+            val width = withDensity(+ambientDensity()) {
+                (state[indicatorEnd] - state[indicatorStart]).toDp()
+            }
             Padding(left = offset) {
                 Container(width = width) {
                     // Pass the current color to the indicator
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt b/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
index 6a76a4a..9bb106b 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
@@ -31,6 +31,7 @@
 import androidx.ui.core.PxPosition
 import androidx.ui.core.PxSize
 import androidx.ui.core.Text
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.dp
 import androidx.ui.core.sp
 import androidx.ui.core.withDensity
@@ -172,7 +173,7 @@
                 Align(Alignment.BottomLeft) {
                     AlignmentLineOffset(
                         alignmentLine = LastBaseline,
-                        after = +withDensity { AppBarTitleBaselineOffset.toDp() }
+                        after = withDensity(+ambientDensity()) { AppBarTitleBaselineOffset.toDp() }
                     ) {
                         // TODO: AlignmentLineOffset requires a child, so in case title() is
                         // empty we just add an empty wrap here - should be fixed when we move to
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
index 68b1041..f415c8a 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
@@ -32,6 +32,7 @@
 import androidx.ui.core.Layout
 import androidx.ui.core.Px
 import androidx.ui.core.RepaintBoundary
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.dp
 import androidx.ui.core.hasBoundedHeight
 import androidx.ui.core.hasBoundedWidth
@@ -129,7 +130,7 @@
             if (!pxConstraints.hasBoundedWidth) {
                 throw IllegalStateException("Drawer shouldn't have infinite width")
             }
-            val constraints = +withDensity {
+            val constraints = withDensity(+ambientDensity()) {
                 DpConstraints(pxConstraints)
             }
             val minValue = -pxConstraints.maxWidth.value.toFloat()
@@ -199,7 +200,7 @@
             if (!pxConstraints.hasBoundedHeight) {
                 throw IllegalStateException("Drawer shouldn't have infinite height")
             }
-            val constraints = +withDensity {
+            val constraints = withDensity(+ambientDensity()) {
                 DpConstraints(pxConstraints)
             }
             val minValue = 0f
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt b/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
index ee3d757..2c5e31f 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/MaterialTheme.kt
@@ -25,6 +25,7 @@
 import androidx.compose.memo
 import androidx.compose.unaryPlus
 import androidx.ui.core.CurrentTextStyleProvider
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.dp
 import androidx.ui.core.sp
 import androidx.ui.core.withDensity
@@ -308,7 +309,7 @@
  */
 @Composable
 fun MaterialShapeTheme(children: @Composable() () -> Unit) {
-    val value = +withDensity {
+    val value = withDensity(+ambientDensity()) {
         Shapes(
             button = RoundedCornerShape(4.dp),
             card = RectangleShape
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
index 075938d..03dd8e2 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
@@ -24,7 +24,6 @@
 import androidx.animation.transitionDefinition
 import androidx.annotation.CheckResult
 import androidx.annotation.FloatRange
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.compose.effectOf
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt b/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt
index 8abd451..77ec45b 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt
@@ -24,6 +24,7 @@
 import androidx.ui.core.DensityScope
 import androidx.ui.core.Draw
 import androidx.ui.core.PxSize
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.dp
 import androidx.ui.core.px
 import androidx.ui.core.withDensity
@@ -73,7 +74,7 @@
 @Composable
 private fun SwitchImpl(checked: Boolean, onCheckedChange: ((Boolean) -> Unit)?, color: Color) {
     val minBound = 0f
-    val maxBound = +withDensity { ThumbPathLength.toPx().value }
+    val maxBound = withDensity(+ambientDensity()) { ThumbPathLength.toPx().value }
     StateDraggable(
         state = checked,
          ?: {},
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
index 8771dda..c997c3f 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
@@ -33,6 +33,7 @@
 import androidx.ui.core.Placeable
 import androidx.ui.core.Px
 import androidx.ui.core.Text
+import androidx.ui.core.ambientDensity
 import androidx.ui.core.coerceIn
 import androidx.ui.core.dp
 import androidx.ui.core.toPx
@@ -191,7 +192,7 @@
     divider: @Composable() () -> Unit,
     indicatorContainer: @Composable() (tabPositions: List<TabPosition>) -> Unit
 ) {
-    val edgeOffset = +withDensity { ScrollableTabRowEdgeOffset.toIntPx() }
+    val edgeOffset = withDensity(+ambientDensity()) { ScrollableTabRowEdgeOffset.toIntPx() }
 
     // TODO: unfortunate 1f lag as we need to first calculate tab positions before drawing the
     // indicator container
@@ -361,11 +362,13 @@
     ) {
         // TODO: should we animate the width of the indicator as it moves between tabs of different
         // sizes inside a scrollable tab row?
-        val currentTabWidth = +withDensity { tabPositions[selectedIndex].width.toDp() }
+        val currentTabWidth = withDensity(+ambientDensity()) {
+            tabPositions[selectedIndex].width.toDp()
+        }
 
         Container(expanded = true, alignment = Alignment.BottomLeft) {
             IndicatorTransition(tabPositions, selectedIndex) { indicatorOffset ->
-                Padding(left = +withDensity { indicatorOffset.toDp() }) {
+                Padding(left = withDensity(+ambientDensity()) { indicatorOffset.toDp() }) {
                     Container(width = currentTabWidth) {
                         indicator()
                     }
@@ -618,7 +621,7 @@
 
 // TabRow specifications
 private val IndicatorHeight = 2.dp
-private const val DividerOpacity = 0.12f
+private val DividerOpacity = 0.12f
 // How far from the start and end of a scrollable TabRow should the first Tab be displayed
 private val ScrollableTabRowEdgeOffset = 52.dp
 private val ScrollableTabRowMinimumTabWidth = 90.dp
@@ -626,13 +629,13 @@
 // Tab specifications
 private val SmallTabHeight = 48.dp
 private val LargeTabHeight = 72.dp
-private const val InactiveTabOpacity = 0.74f
-private const val MaxTitleLineCount = 2
+private val InactiveTabOpacity = 0.74f
+private val MaxTitleLineCount = 2
 
 // Tab transition specifications
-private const val TabFadeInAnimationDuration = 150
-private const val TabFadeInAnimationDelay = 100
-private const val TabFadeOutAnimationDuration = 100
+private val TabFadeInAnimationDuration = 150
+private val TabFadeInAnimationDelay = 100
+private val TabFadeOutAnimationDuration = 100
 
 // The horizontal padding on the left and right of text
 private val HorizontalTextPadding = 16.dp
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/ToolingTest.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/ToolingTest.kt
index e2d67c5..6470b72 100644
--- a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/ToolingTest.kt
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/ToolingTest.kt
@@ -17,7 +17,6 @@
 package androidx.ui.tooling
 
 import android.os.Handler
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.composer
 import androidx.test.rule.ActivityTestRule
@@ -50,7 +49,7 @@
         OnPositioned( positionedLatch.countDown() })
     }
 
-    internal fun show(@Children composable: @Composable() () -> Unit) {
+    internal fun show(composable: @Composable() () -> Unit) {
         positionedLatch = CountDownLatch(1)
         activityTestRule.onUiThread {
             activity.setContent {
diff --git a/ui/ui-tooling/src/main/java/androidx/ui/tooling/Inspectable.kt b/ui/ui-tooling/src/main/java/androidx/ui/tooling/Inspectable.kt
index 6ee1947..9cbca8a 100644
--- a/ui/ui-tooling/src/main/java/androidx/ui/tooling/Inspectable.kt
+++ b/ui/ui-tooling/src/main/java/androidx/ui/tooling/Inspectable.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.tooling
 
-import androidx.compose.Children
 import androidx.compose.Composable
 import androidx.compose.SlotTable
 import androidx.compose.ambient
@@ -30,7 +29,7 @@
  * is in inspection mode.
  */
 @Composable
-fun Inspectable(@Children children: @Composable() () -> Unit) {
+fun Inspectable(children: @Composable() () -> Unit) {
     composer.composer.collectKeySourceInformation()
     tables.add(composer.composer.slotTable)
     InspectionMode.Provider(true) {
@@ -45,7 +44,7 @@
  * in the composition when the composition is in inspection mode.
  */
 @Composable
-fun InInspectionModeOnly(@Children children: @Composable() () -> Unit) {
+fun InInspectionModeOnly(children: @Composable() () -> Unit) {
     if (+ambient(InspectionMode)) {
         children()
     }