WIP
diff --git a/compiler/testData/codegen/boxJvm/reflection/annotations/subclassOptInRequired.kt b/compiler/testData/codegen/boxJvm/reflection/annotations/subclassOptInRequired.kt
index 2585084..3d66b01 100644
--- a/compiler/testData/codegen/boxJvm/reflection/annotations/subclassOptInRequired.kt
+++ b/compiler/testData/codegen/boxJvm/reflection/annotations/subclassOptInRequired.kt
@@ -30,11 +30,11 @@
     // @SubclassOptInRequired should be findable via findAnnotation
     val ann = ExperimentalBase::class.findAnnotation<SubclassOptInRequired>()
     assertNotNull(ann, "@SubclassOptInRequired not found on ExperimentalBase")
-    assertEquals(ExperimentalFeature::class, ann.markerClass)
+    assertEquals<Any>(ExperimentalFeature::class, ann.markerClass) // TODO: Interesting. Type inference fails here without <Any> but FE shows that it is redundant
 
     val ann2 = AnotherBase::class.findAnnotation<SubclassOptInRequired>()
     assertNotNull(ann2)
-    assertEquals(AnotherExperimentalApi::class, ann2.markerClass)
+    assertEquals<Any>(AnotherExperimentalApi::class, ann2.markerClass)
 
     // hasAnnotation should return true
     assertTrue(ExperimentalBase::class.hasAnnotation<SubclassOptInRequired>())
@@ -48,7 +48,7 @@
     val annotations = ExperimentalBase::class.annotations
     val found = annotations.filterIsInstance<SubclassOptInRequired>()
     assertEquals(1, found.size)
-    assertEquals(ExperimentalFeature::class, found.single().markerClass)
+    assertEquals<Any>(ExperimentalFeature::class, found.single().markerClass)
 
     // Class modifiers are unaffected by the annotation
     assertTrue(ExperimentalBase::class.isAbstract)
diff --git a/compiler/testData/codegen/boxJvm/reflection/builtins/arrayMemberPropertiesAndFunctions.kt b/compiler/testData/codegen/boxJvm/reflection/builtins/arrayMemberPropertiesAndFunctions.kt
new file mode 100644
index 0000000..3da5e9a
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/builtins/arrayMemberPropertiesAndFunctions.kt
@@ -0,0 +1,30 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that array types expose their 'size' memberProperty and inherited
+// Object methods via memberFunctions.
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    val arrayClasses = listOf(
+        Array::class, IntArray::class, LongArray::class, ShortArray::class,
+        ByteArray::class, FloatArray::class, DoubleArray::class,
+        BooleanArray::class, CharArray::class
+    )
+
+    for (klass in arrayClasses) {
+        // memberProperties must include 'size'
+        assertTrue(klass.memberProperties.any { it.name == "size" },
+            "${klass.simpleName}::class.memberProperties must include 'size'")
+
+        // memberFunctions must include the inherited Object methods
+        val fnNames = klass.memberFunctions.map { it.name }.toSet()
+        for (name in listOf("equals", "hashCode", "toString")) {
+            assertTrue(name in fnNames,
+                "${klass.simpleName}::class.memberFunctions must include '$name'")
+        }
+    }
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/builtins/primitiveAndBooleanMemberFunctions.kt b/compiler/testData/codegen/boxJvm/reflection/builtins/primitiveAndBooleanMemberFunctions.kt
new file mode 100644
index 0000000..721ef22
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/builtins/primitiveAndBooleanMemberFunctions.kt
@@ -0,0 +1,30 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that Boolean and Char expose their full set of member functions via reflection.
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    // Boolean has compareTo, and, or, xor, not, toInt, equals, hashCode, toString
+    val boolFns = Boolean::class.memberFunctions.map { it.name }.toSet()
+    assertTrue("compareTo" in boolFns, "Boolean must have compareTo()")
+    assertTrue("and"       in boolFns, "Boolean must have and()")
+    assertTrue("or"        in boolFns, "Boolean must have or()")
+    assertTrue("not"       in boolFns, "Boolean must have not()")
+
+    // Char has compareTo, plus(Int), minus(Char/Int), toInt/toLong/etc., and range operators
+    val charFns = Char::class.memberFunctions.map { it.name }.toSet()
+    assertTrue("compareTo" in charFns, "Char must have compareTo()")
+    assertTrue("plus"      in charFns, "Char must have plus()")
+    assertTrue("minus"     in charFns, "Char must have minus()")
+
+    // Both must include Object methods
+    for ((klass, fns) in listOf(Boolean::class to boolFns, Char::class to charFns)) {
+        assertTrue("equals"   in fns, "${klass.simpleName} must have equals()")
+        assertTrue("hashCode" in fns, "${klass.simpleName} must have hashCode()")
+        assertTrue("toString" in fns, "${klass.simpleName} must have toString()")
+    }
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/builtins/primitiveConstructorAnnotations.kt b/compiler/testData/codegen/boxJvm/reflection/builtins/primitiveConstructorAnnotations.kt
new file mode 100644
index 0000000..6e30079
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/builtins/primitiveConstructorAnnotations.kt
@@ -0,0 +1,18 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that annotations on primitive-type constructors are accessible and empty.
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    for (klass in listOf(
+        Int::class, Long::class, Short::class, Byte::class,
+        Float::class, Double::class, Boolean::class, Char::class
+    )) {
+        val ctor = klass.constructors.single()
+        assertEquals(emptyList(), ctor.annotations,
+            "${klass.simpleName} constructor should have no annotations")
+    }
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/call/javaAnnotationElementCallability.kt b/compiler/testData/codegen/boxJvm/reflection/call/javaAnnotationElementCallability.kt
new file mode 100644
index 0000000..2530e8a
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/call/javaAnnotationElementCallability.kt
@@ -0,0 +1,58 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: CallableAnnotation.java
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface CallableAnnotation {
+    String name()    default "default-name";
+    int    version() default 1;
+    boolean enabled() default true;
+}
+
+// FILE: box.kt
+// Tests that Java annotation element accessor properties are callable via reflection,
+// including via KProperty0.getter.call() and KProperty0.call().
+
+import kotlin.reflect.*
+import kotlin.reflect.full.*
+import kotlin.reflect.jvm.*
+import kotlin.test.*
+
+fun box(): String {
+    val annClass = CallableAnnotation::class
+
+    // Static properties represent annotation elements
+    val staticProps = annClass.staticProperties
+    assertTrue(staticProps.isNotEmpty(),
+        "CallableAnnotation must have staticProperties for its elements, got: ${staticProps.map { it.name }}")
+
+    val nameProp   = staticProps.firstOrNull { it.name == "name" }
+    val versionProp = staticProps.firstOrNull { it.name == "version" }
+    val enabledProp = staticProps.firstOrNull { it.name == "enabled" }
+
+    // Check the properties exist
+    assertNotNull(nameProp,    "CallableAnnotation must have 'name' static property")
+    assertNotNull(versionProp, "CallableAnnotation must have 'version' static property")
+    assertNotNull(enabledProp, "CallableAnnotation must have 'enabled' static property")
+
+    // Call the default value accessors — they must not throw
+    val nameDefault    = runCatching { nameProp.call() }
+        .getOrElse { return "Fail: calling 'name' threw ${it::class.simpleName}: ${it.message}" }
+    val versionDefault = runCatching { versionProp.call() }
+        .getOrElse { return "Fail: calling 'version' threw ${it::class.simpleName}: ${it.message}" }
+    val enabledDefault = runCatching { enabledProp.call() }
+        .getOrElse { return "Fail: calling 'enabled' threw ${it::class.simpleName}: ${it.message}" }
+
+    assertEquals("default-name", nameDefault,    "name default should be 'default-name'")
+    assertEquals(1,               versionDefault, "version default should be 1")
+    assertEquals(true,            enabledDefault, "enabled default should be true")
+
+    // Also verify via getter.call()
+    val nameViaGetter = runCatching { nameProp.getter.call() }
+        .getOrElse { return "Fail: name getter.call() threw ${it::class.simpleName}: ${it.message}" }
+    assertEquals("default-name", nameViaGetter)
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/constructors/multipleConstructorsPrimaryOrder.kt b/compiler/testData/codegen/boxJvm/reflection/constructors/multipleConstructorsPrimaryOrder.kt
new file mode 100644
index 0000000..db7661d
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/constructors/multipleConstructorsPrimaryOrder.kt
@@ -0,0 +1,61 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that when a class has multiple constructors, primaryConstructor correctly
+// identifies the source-declared primary constructor (not some arbitrary secondary one).
+
+import kotlin.reflect.*
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+class MultiCtorClass(val x: Int, val y: String) {
+    constructor(x: Int)          : this(x, "")
+    constructor()                : this(0, "")
+    constructor(y: String)       : this(0, y)
+    constructor(x: Int, y: String, extra: Boolean) : this(x, if (extra) y.uppercase() else y)
+}
+
+class SingleCtorClass(val id: Int)
+
+class NoArgClass {
+    val value = 42
+}
+
+fun box(): String {
+    // The primary constructor of MultiCtorClass is (Int, String)
+    val primary = MultiCtorClass::class.primaryConstructor
+        ?: return "Fail: MultiCtorClass has no primaryConstructor"
+
+    val primaryParamNames = primary.parameters.map { it.name }
+    assertEquals(listOf("x", "y"), primaryParamNames,
+        "primaryConstructor should be (x: Int, y: String), got params: $primaryParamNames")
+
+    // The primary constructor should be findable in the constructors list
+    val ctors = MultiCtorClass::class.constructors.toList()
+    assertEquals(5, ctors.size, "Expected 5 constructors")
+    assertTrue(primary in ctors, "primaryConstructor must be in constructors list")
+
+    // Calling the primary constructor via reflection should work
+    val instance = primary.call(7, "hello")
+    assertEquals(7, instance.x)
+    assertEquals("hello", instance.y)
+
+    // callBy with only the required params (no defaults here) also works
+    val instance2 = primary.callBy(mapOf(
+        primary.parameters[0] to 3,
+        primary.parameters[1] to "world"
+    ))
+    assertEquals(3, instance2.x)
+    assertEquals("world", instance2.y)
+
+    // SingleCtorClass: only one constructor, which is the primary
+    val singlePrimary = SingleCtorClass::class.primaryConstructor
+        ?: return "Fail: SingleCtorClass has no primaryConstructor"
+    assertEquals(listOf("id"), singlePrimary.parameters.map { it.name })
+
+    // NoArgClass: primary constructor has zero parameters
+    val noArgPrimary = NoArgClass::class.primaryConstructor
+        ?: return "Fail: NoArgClass has no primaryConstructor"
+    assertEquals(0, noArgPrimary.parameters.size)
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/companionExtensionStaticVisibility.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/companionExtensionStaticVisibility.kt
new file mode 100644
index 0000000..ba3d6ce
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/mapping/companionExtensionStaticVisibility.kt
@@ -0,0 +1,50 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// LANGUAGE: +CompanionBlocksAndExtensions
+// Tests that companion extensions declared at top-level are visible as static members
+// of the file facade class via reflection.
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+class Widget(val id: Int) {
+    companion {
+        val defaultId: Int = 0
+        fun create(): Widget = Widget(defaultId)
+    }
+}
+
+companion val Widget.label: String get() = "widget-${Widget.defaultId}"
+companion fun Widget.describe(): String = "Widget[default=${Widget.defaultId}]"
+companion fun Widget.withId(n: Int): Widget = Widget(n)
+
+fun box(): String {
+    // Companion BLOCK members are on Widget::class as staticFunctions/staticProperties
+    val widgetStatic = Widget::class.staticFunctions.map { it.name }.toSet()
+    assertTrue("create" in widgetStatic, "create should be in Widget::class.staticFunctions")
+
+    // Companion EXTENSIONS are on the file facade class
+    val facadeKlass = Class.forName("CompanionExtensionStaticVisibilityKt").kotlin
+
+    val facadeStaticFns = facadeKlass.staticFunctions.map { it.name }.toSet()
+    assertTrue(facadeStaticFns.isNotEmpty(),
+        "File facade must have static functions for companion extensions, got: $facadeStaticFns")
+    assertTrue("describe" in facadeStaticFns,
+        "describe() companion extension must be in facade staticFunctions, got: $facadeStaticFns")
+    assertTrue("withId" in facadeStaticFns,
+        "withId() companion extension must be in facade staticFunctions, got: $facadeStaticFns")
+
+    val facadeStaticProps = facadeKlass.staticProperties.map { it.name }.toSet()
+    assertTrue("label" in facadeStaticProps,
+        "label companion extension property must be in facade staticProperties, got: $facadeStaticProps")
+
+    // Companion extensions are callable via the facade
+    val describeFn = facadeKlass.staticFunctions.first { it.name == "describe" }
+    assertEquals("Widget[default=0]", describeFn.call())
+
+    val withIdFn = facadeKlass.staticFunctions.first { it.name == "withId" }
+    val w = withIdFn.call(42) as Widget
+    assertEquals(42, w.id)
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/genericJavaClassJavaType.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/genericJavaClassJavaType.kt
new file mode 100644
index 0000000..f971d15
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/mapping/genericJavaClassJavaType.kt
@@ -0,0 +1,49 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: GenericJavaHolder.java
+public class GenericJavaHolder {
+    public static class Box<T> {
+        public T get() { return null; }
+        public void set(T value) {}
+    }
+    public static class Pair<A, B> {
+        public A first() { return null; }
+        public B second() { return null; }
+    }
+}
+
+// FILE: box.kt
+// Tests that KType.javaType correctly includes type parameters for generic Java classes.
+
+import kotlin.reflect.jvm.javaType
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    // Box<T>.get() → return type T; represented as a TypeVariable "T"
+    val getMethod = GenericJavaHolder.Box::class.memberFunctions.first { it.name == "get" }
+    val getJavaType = getMethod.returnType.javaType.typeName
+    assertEquals("T", getJavaType,
+        "Box.get() return javaType should be 'T', got: $getJavaType")
+
+    // Box<T>.set(T) → parameter type T
+    val setMethod = GenericJavaHolder.Box::class.memberFunctions.first { it.name == "set" }
+    val setParamType = setMethod.valueParameters.first().type.javaType.typeName
+    assertEquals("T", setParamType,
+        "Box.set() parameter javaType should be 'T', got: $setParamType")
+
+    // Pair<A, B>.first() → A, second() → B (distinct type variables)
+    val firstMethod = GenericJavaHolder.Pair::class.memberFunctions.first { it.name == "first" }
+    assertEquals("A", firstMethod.returnType.javaType.typeName,
+        "Pair.first() return javaType should be 'A'")
+
+    val secondMethod = GenericJavaHolder.Pair::class.memberFunctions.first { it.name == "second" }
+    assertEquals("B", secondMethod.returnType.javaType.typeName,
+        "Pair.second() return javaType should be 'B'")
+
+    // For the class itself as a type argument, javaType should include the parameter
+    val boxSupertype = GenericJavaHolder.Box::class.supertypes.firstOrNull()
+    // supertypes just shows Any here, but declaring class via members is tested above
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/javaAnnotationElementJavaType.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/javaAnnotationElementJavaType.kt
new file mode 100644
index 0000000..89fb813
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/mapping/javaAnnotationElementJavaType.kt
@@ -0,0 +1,50 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: SampleAnnotation.java
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface SampleAnnotation {
+    String  text()    default "";
+    int     count()   default 0;
+    Class<?> type()  default Object.class;
+    String[] tags()  default {};
+    boolean flag()   default false;
+}
+
+// FILE: box.kt
+// Tests that KType.javaType on Java annotation element parameter types is accessible
+// and returns the correct Java types.
+
+import kotlin.reflect.jvm.javaType
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    val ctor = SampleAnnotation::class.constructors.single()
+
+    val paramsByName = ctor.parameters.associateBy { it.name }
+
+    // Each element type must be accessible via javaType without throwing
+    val expectedJavaTypes = mapOf(
+        "text"  to "java.lang.String",
+        "count" to "int",
+        "type"  to "java.lang.Class",   // Class<?> erases to Class
+        "tags"  to "[Ljava.lang.String;",
+        "flag"  to "boolean"
+    )
+
+    for ((name, expectedType) in expectedJavaTypes) {
+        val param = paramsByName[name]
+            ?: return "Fail: annotation element '$name' not found in constructor parameters"
+
+        val javaType = runCatching { param.type.javaType.typeName }
+            .getOrElse { return "Fail: javaType for '$name' threw ${it::class.simpleName}: ${it.message}" }
+
+        assertTrue(javaType.startsWith(expectedType) || javaType == expectedType,
+            "Annotation element '$name': expected javaType starting with '$expectedType', got: $javaType")
+    }
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/javaEnumConstructorParameterNames.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/javaEnumConstructorParameterNames.kt
new file mode 100644
index 0000000..5b9935b
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/mapping/javaEnumConstructorParameterNames.kt
@@ -0,0 +1,43 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: ColorEnum.java
+public enum ColorEnum {
+    RED(255, 0, 0),
+    GREEN(0, 255, 0),
+    BLUE(0, 0, 255);
+
+    private final int r, g, b;
+    ColorEnum(int r, int g, int b) { this.r = r; this.g = g; this.b = b; }
+    public int getR() { return r; }
+    public int getG() { return g; }
+    public int getB() { return b; }
+}
+
+// FILE: box.kt
+// Tests that Java enum constructor parameters are reflected with their original
+// field names, not generic positional names like arg0, arg1, arg2.
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    val ctor = ColorEnum::class.constructors.single()
+    val paramNames = ctor.parameters.map { it.name }
+
+    assertEquals(3, paramNames.size,
+        "ColorEnum constructor should have 3 parameters, got: $paramNames")
+
+    // The parameter names must be the actual field names, not arg0/arg1/arg2
+    for (name in paramNames) {
+        assertFalse(name?.startsWith("arg") == true,
+            "Expected field name, got positional placeholder: paramNames=$paramNames")
+        assertNotNull(name,
+            "Constructor parameter name must not be null: paramNames=$paramNames")
+    }
+
+    // Must be the field names in declaration order
+    assertEquals(listOf("r", "g", "b"), paramNames,
+        "Constructor parameter names should match field names r, g, b")
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/javaFunctionInterfaceImplementorTypes.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/javaFunctionInterfaceImplementorTypes.kt
new file mode 100644
index 0000000..7ef8474
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/mapping/javaFunctionInterfaceImplementorTypes.kt
@@ -0,0 +1,50 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: KotlinFunctionImplementor.java
+import kotlin.jvm.functions.Function1;
+import kotlin.jvm.functions.Function2;
+
+public class KotlinFunctionImplementor {
+    public static class IntToString implements Function1<Integer, String> {
+        @Override public String invoke(Integer value) { return value.toString(); }
+    }
+    public static class StringAndIntToBoolean implements Function2<String, Integer, Boolean> {
+        @Override public Boolean invoke(String s, Integer n) { return s.length() == n; }
+    }
+}
+
+// FILE: box.kt
+// Tests that a Java class implementing a Kotlin functional interface has its invoke
+// parameter and return types reflected as proper Kotlin types (non-nullable, not platform).
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    // Function1<Integer, String> implementor: invoke(Integer) → String
+    val invoke1 = KotlinFunctionImplementor.IntToString::class
+        .memberFunctions.first { it.name == "invoke" && !it.isAbstract }
+
+    val paramType = invoke1.valueParameters.first().type.toString()
+    assertFalse(paramType.endsWith("!"),
+        "invoke parameter type should not be a platform type, got: $paramType")
+    assertEquals("kotlin.Int", paramType,
+        "invoke parameter should be kotlin.Int (not kotlin.Int! or java.lang.Integer)")
+
+    val returnType = invoke1.returnType.toString()
+    assertFalse(returnType.endsWith("!"),
+        "invoke return type should not be a platform type, got: $returnType")
+    assertEquals("kotlin.String", returnType,
+        "invoke return should be kotlin.String (not kotlin.String!)")
+
+    // Function2<String, Integer, Boolean> implementor
+    val invoke2 = KotlinFunctionImplementor.StringAndIntToBoolean::class
+        .memberFunctions.first { it.name == "invoke" && !it.isAbstract }
+
+    assertEquals(2, invoke2.valueParameters.size)
+    assertEquals("kotlin.String", invoke2.valueParameters[0].type.toString())
+    assertEquals("kotlin.Int",    invoke2.valueParameters[1].type.toString())
+    assertEquals("kotlin.Boolean", invoke2.returnType.toString())
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/javaFunctionInterfaceInvokeFakeOverride.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/javaFunctionInterfaceInvokeFakeOverride.kt
new file mode 100644
index 0000000..3aacfe7
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/mapping/javaFunctionInterfaceInvokeFakeOverride.kt
@@ -0,0 +1,35 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: SingleInvokeImpl.java
+import kotlin.jvm.functions.Function1;
+
+public class SingleInvokeImpl implements Function1<String, Integer> {
+    @Override
+    public Integer invoke(String value) { return value.length(); }
+}
+
+// FILE: box.kt
+// Tests that a Java class implementing a Kotlin Function1 has exactly one non-abstract
+// 'invoke' in memberFunctions, and that its parameter has a name (not null).
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun box(): String {
+    val invokeFns = SingleInvokeImpl::class.memberFunctions.filter { it.name == "invoke" }
+
+    // There should be exactly one concrete (non-abstract) invoke
+    val concreteInvokes = invokeFns.filter { !it.isAbstract }
+    assertEquals(1, concreteInvokes.size,
+        "Expected exactly 1 concrete invoke, got: ${concreteInvokes.map { "${it.name} abstract=${it.isAbstract} params=${it.parameters.map { p -> p.name }}" }}")
+
+    val invoke = concreteInvokes.single()
+    // The VALUE parameter must have a non-null name
+    val valueParam = invoke.valueParameters.singleOrNull()
+        ?: return "Fail: invoke should have exactly 1 value parameter"
+
+    assertNotNull(valueParam.name,
+        "invoke value parameter name must not be null, got: ${valueParam.name}")
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/jvmExposeBoxed.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/jvmExposeBoxed.kt
index c954228..b011488 100644
--- a/compiler/testData/codegen/boxJvm/reflection/mapping/jvmExposeBoxed.kt
+++ b/compiler/testData/codegen/boxJvm/reflection/mapping/jvmExposeBoxed.kt
@@ -1,6 +1,7 @@
 // TARGET_BACKEND: JVM
 // WITH_REFLECT
 // WITH_STDLIB
+@file:OptIn(ExperimentalStdlibApi::class)
 
 import kotlin.jvm.JvmExposeBoxed
 import kotlin.reflect.*
diff --git a/compiler/testData/codegen/boxJvm/reflection/mapping/jvmStaticInCompanionBlock.kt b/compiler/testData/codegen/boxJvm/reflection/mapping/jvmStaticInCompanionBlock.kt
deleted file mode 100644
index 28104e9..0000000
--- a/compiler/testData/codegen/boxJvm/reflection/mapping/jvmStaticInCompanionBlock.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-// TARGET_BACKEND: JVM
-// WITH_REFLECT
-// LANGUAGE: +CompanionBlocksAndExtensions
-
-import kotlin.reflect.*
-import kotlin.reflect.full.*
-import kotlin.reflect.jvm.*
-import kotlin.test.*
-
-class WithJvmStaticInCompanionBlock {
-    companion {
-        // @JvmStatic has no effect inside companion blocks (members are already static),
-        // but the annotation should still be reflected on the callable.
-        @JvmStatic
-        fun alreadyStatic(): String = "static"
-
-        // Without @JvmStatic for comparison
-        fun plainStatic(): String = "plain"
-
-        @JvmStatic
-        val staticProp: Int = 42
-    }
-}
-
-class WithJvmStaticInCompanionObject(val x: Int) {
-    companion object {
-        @JvmStatic
-        fun fromObject(): String = "from-object"
-
-        fun notJvmStatic(): String = "not-static"
-    }
-}
-
-fun box(): String {
-    // Companion block: both @JvmStatic and plain functions appear in staticFunctions
-    val blockFns = WithJvmStaticInCompanionBlock::class.staticFunctions.associateBy { it.name }
-    assertNotNull(blockFns["alreadyStatic"], "alreadyStatic should be in staticFunctions")
-    assertNotNull(blockFns["plainStatic"], "plainStatic should be in staticFunctions")
-
-    // @JvmStatic annotation is reflected on the callable
-    val annotated = blockFns["alreadyStatic"]!!
-    val jvmStaticAnn = annotated.annotations.firstOrNull { it.annotationClass.simpleName == "JvmStatic" }
-    assertNotNull(jvmStaticAnn, "@JvmStatic should appear in annotations of the function")
-
-    // Plain companion block function has no @JvmStatic annotation
-    val plain = blockFns["plainStatic"]!!
-    val plainJvmStatic = plain.annotations.firstOrNull { it.annotationClass.simpleName == "JvmStatic" }
-    assertNull(plainJvmStatic, "plainStatic should not have @JvmStatic annotation")
-
-    // Both are callable without an instance (static — no INSTANCE parameter)
-    assertEquals(emptyList(), annotated.parameters.filter { it.kind == KParameter.Kind.INSTANCE })
-    assertEquals(emptyList(), plain.parameters.filter { it.kind == KParameter.Kind.INSTANCE })
-    assertEquals("static", annotated.call())
-    assertEquals("plain", plain.call())
-
-    // @JvmStatic property in companion block
-    val staticProp = WithJvmStaticInCompanionBlock::class.staticProperties.firstOrNull { it.name == "staticProp" }
-    assertNotNull(staticProp, "staticProp should be in staticProperties")
-    assertEquals(42, staticProp.call())
-    val propJvmStatic = staticProp.annotations.firstOrNull { it.annotationClass.simpleName == "JvmStatic" }
-    assertNotNull(propJvmStatic, "@JvmStatic should appear in property annotations")
-
-    // Companion OBJECT with @JvmStatic: function appears both as static and as member of companion
-    // The @JvmStatic function is in staticFunctions of the outer class
-    val objStaticFns = WithJvmStaticInCompanionObject::class.staticFunctions.map { it.name }.toSet()
-    assertTrue("fromObject" in objStaticFns,
-        "@JvmStatic in companion object should appear in outer class staticFunctions: $objStaticFns")
-    assertFalse("notJvmStatic" in objStaticFns,
-        "Non-@JvmStatic companion function should NOT appear in outer class staticFunctions: $objStaticFns")
-
-    // Verify javaMethod is accessible for the @JvmStatic companion block function
-    val javaMethod = annotated.javaMethod
-    assertNotNull(javaMethod, "javaMethod should be accessible for @JvmStatic companion block function")
-    assertEquals("alreadyStatic", javaMethod.name)
-
-    return "OK"
-}
diff --git a/compiler/testData/codegen/boxJvm/reflection/modifiers/inlineModifiers.kt b/compiler/testData/codegen/boxJvm/reflection/modifiers/inlineModifiers.kt
index d7470c6..e902fff 100644
--- a/compiler/testData/codegen/boxJvm/reflection/modifiers/inlineModifiers.kt
+++ b/compiler/testData/codegen/boxJvm/reflection/modifiers/inlineModifiers.kt
@@ -12,7 +12,7 @@
     inline fun <reified T> reifiedInline(): String = T::class.simpleName ?: "?"
     inline fun <reified T, reified R : T> multiReifiedInline(x: T): R? = x as? R
     inline fun withBothModifiers(crossinline cross: () -> String, noinline noin: () -> Int): String = cross() + noin()
-    noinline fun notInline(x: Int): Int = x
+    fun notInline(x: Int): Int = x
 
     infix fun infixFun(other: Int): Int = other
     operator fun plus(other: InlineSubject): InlineSubject = this
diff --git a/compiler/testData/codegen/boxJvm/reflection/modifiers/sealedInterfaceWithValueClasses.kt b/compiler/testData/codegen/boxJvm/reflection/modifiers/sealedInterfaceWithValueClasses.kt
index 67c59d7..bf83ed7 100644
--- a/compiler/testData/codegen/boxJvm/reflection/modifiers/sealedInterfaceWithValueClasses.kt
+++ b/compiler/testData/codegen/boxJvm/reflection/modifiers/sealedInterfaceWithValueClasses.kt
@@ -28,7 +28,7 @@
     // sealedSubclasses contains all 5 variants
     val subclasses = Measurement::class.sealedSubclasses
     assertEquals(5, subclasses.size)
-    val names = subclasses.map { it.simpleName }.sorted()
+    val names = subclasses.map { it.simpleName.orEmpty() }.sorted()
     assertEquals(listOf("Combined", "Distance", "Duration", "Empty", "Weight"), names)
 
     // Value class variants: isValue=true, isData=false
diff --git a/compiler/testData/codegen/boxJvm/reflection/properties/kotlinEnumEntriesProperty.kt b/compiler/testData/codegen/boxJvm/reflection/properties/kotlinEnumEntriesProperty.kt
index c735b28..db02bbc4 100644
--- a/compiler/testData/codegen/boxJvm/reflection/properties/kotlinEnumEntriesProperty.kt
+++ b/compiler/testData/codegen/boxJvm/reflection/properties/kotlinEnumEntriesProperty.kt
@@ -17,7 +17,7 @@
 
 enum class Singleton { ONLY }
 
-private fun <E : Enum<E>> checkEntriesProperty(enumClass: KClass<E>, expectedCount: Int) {
+private inline fun <reified E : Enum<E>> checkEntriesProperty(enumClass: KClass<E>, expectedCount: Int) {
     val prop = enumClass.members.single { it.name == "entries" }
         .also { assertTrue(it is KProperty0<*>, "entries should be KProperty0") } as KProperty0<*>
 
diff --git a/compiler/testData/codegen/boxJvm/reflection/supertypes/genericSealedHierarchy.kt b/compiler/testData/codegen/boxJvm/reflection/supertypes/genericSealedHierarchy.kt
index 49266ee..ae4b1fa 100644
--- a/compiler/testData/codegen/boxJvm/reflection/supertypes/genericSealedHierarchy.kt
+++ b/compiler/testData/codegen/boxJvm/reflection/supertypes/genericSealedHierarchy.kt
@@ -29,7 +29,7 @@
     // sealedSubclasses
     val eitherSubs = Either::class.sealedSubclasses
     assertEquals(3, eitherSubs.size)
-    val names = eitherSubs.map { it.simpleName }.sorted()
+    val names = eitherSubs.map { it.simpleName.orEmpty() }.sorted()
     assertEquals(listOf("Empty", "Left", "Right"), names)
 
     // Left implements Either<L, Nothing> — type arguments in supertype
diff --git a/compiler/testData/codegen/boxJvm/reflection/supertypes/javaCollectionSupertypesNoDuplicates.kt b/compiler/testData/codegen/boxJvm/reflection/supertypes/javaCollectionSupertypesNoDuplicates.kt
new file mode 100644
index 0000000..fceee15
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/supertypes/javaCollectionSupertypesNoDuplicates.kt
@@ -0,0 +1,41 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that Java collection class supertypes do not contain duplicate entries.
+// Each Kotlin-mapped supertype (MutableList, MutableSet, etc.) must appear at most once.
+
+import kotlin.reflect.*
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun checkNoDuplicates(klass: kotlin.reflect.KClass<*>) {
+    val supertypes = klass.supertypes
+    val typeStrings = supertypes.map { it.toString() }
+    val duplicates = typeStrings.groupBy { it }.filter { it.value.size > 1 }.keys
+    assertTrue(duplicates.isEmpty(),
+        "${klass.simpleName}::class.supertypes contains duplicates: $duplicates\nAll supertypes: $typeStrings")
+}
+
+fun box(): String {
+    // LinkedList implements List + Deque; must not have MutableList twice
+    checkNoDuplicates(java.util.LinkedList::class)
+
+    // ArrayList also maps to MutableList
+    checkNoDuplicates(java.util.ArrayList::class)
+
+    // HashSet maps to MutableSet
+    checkNoDuplicates(java.util.HashSet::class)
+
+    // TreeSet maps to MutableSet + NavigableSet etc.
+    checkNoDuplicates(java.util.TreeSet::class)
+
+    // HashMap maps to MutableMap
+    checkNoDuplicates(java.util.HashMap::class)
+
+    // Verify the specific LinkedList count: MutableList must appear exactly once
+    val linkedListSupertypes = java.util.LinkedList::class.supertypes.map { it.toString() }
+    val mutableListCount = linkedListSupertypes.count { it.contains("MutableList") }
+    assertEquals(1, mutableListCount,
+        "LinkedList supertypes must contain MutableList exactly once, got: $linkedListSupertypes")
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/supertypes/sealedInterfaceSupertypes.kt b/compiler/testData/codegen/boxJvm/reflection/supertypes/sealedInterfaceSupertypes.kt
index c29e917..8e622cb 100644
--- a/compiler/testData/codegen/boxJvm/reflection/supertypes/sealedInterfaceSupertypes.kt
+++ b/compiler/testData/codegen/boxJvm/reflection/supertypes/sealedInterfaceSupertypes.kt
@@ -57,7 +57,7 @@
     // sealedSubclasses of JsonElement
     val subs = JsonElement::class.sealedSubclasses
     assertEquals(4, subs.size)
-    val subNames = subs.map { it.simpleName }.sorted()
+    val subNames = subs.map { it.simpleName.orEmpty() }.sorted()
     assertEquals(listOf("JsonArray", "JsonNull", "JsonNumber", "JsonString"), subNames)
 
     // superclasses (KClass not KType form)
diff --git a/compiler/testData/codegen/boxJvm/reflection/supertypes/suspendFunctionalInterfaceMemberFunctions.kt b/compiler/testData/codegen/boxJvm/reflection/supertypes/suspendFunctionalInterfaceMemberFunctions.kt
new file mode 100644
index 0000000..c73c911
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/supertypes/suspendFunctionalInterfaceMemberFunctions.kt
@@ -0,0 +1,45 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that classes implementing suspend functional interfaces expose their inherited
+// member functions (invoke, equals, hashCode, toString) via memberFunctions.
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+class SuspendUnit : suspend () -> Unit {
+    override suspend fun invoke() {}
+}
+
+class SuspendStringProducer : suspend () -> String {
+    override suspend fun invoke(): String = "hello"
+}
+
+class SuspendMapper : suspend (Int) -> String {
+    override suspend fun invoke(p: Int): String = p.toString()
+}
+
+fun checkMemberFunctions(klass: kotlin.reflect.KClass<*>, label: String) {
+    val fns = klass.memberFunctions.map { it.name }.toSet()
+
+    // Must have invoke
+    assertTrue("invoke" in fns,
+        "$label: memberFunctions must include 'invoke', got: $fns")
+
+    // Must have the standard Object methods
+    for (name in listOf("equals", "hashCode", "toString")) {
+        assertTrue(name in fns,
+            "$label: memberFunctions must include '$name', got: $fns")
+    }
+}
+
+fun box(): String {
+    checkMemberFunctions(SuspendUnit::class,           "SuspendUnit")
+    checkMemberFunctions(SuspendStringProducer::class, "SuspendStringProducer")
+    checkMemberFunctions(SuspendMapper::class,         "SuspendMapper")
+
+    // Verify invoke is callable
+    val invoker = SuspendStringProducer::class.memberFunctions.first { it.name == "invoke" }
+    assertTrue(invoker.isSuspend)
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/supertypes/throwablePrintStackTraceFakeOverride.kt b/compiler/testData/codegen/boxJvm/reflection/supertypes/throwablePrintStackTraceFakeOverride.kt
new file mode 100644
index 0000000..1466f86
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/supertypes/throwablePrintStackTraceFakeOverride.kt
@@ -0,0 +1,37 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that Throwable, Exception, and Error expose printStackTrace(PrintStream)
+// as a properly-typed member function via reflection.
+
+import kotlin.reflect.full.*
+import kotlin.test.*
+
+fun checkPrintStackTrace(klass: kotlin.reflect.KClass<*>, label: String) {
+    val fns = klass.memberFunctions.filter { it.name == "printStackTrace" }
+
+    // Must have at least one printStackTrace overload
+    assertTrue(fns.isNotEmpty(),
+        "$label must have at least one printStackTrace() in memberFunctions")
+
+    // Must have a no-arg overload
+    assertTrue(fns.any { it.valueParameters.isEmpty() },
+        "$label must have printStackTrace() with no parameters")
+
+    // Must have a PrintStream overload
+    val withParam = fns.firstOrNull { it.valueParameters.size == 1 }
+    assertNotNull(withParam,
+        "$label must have printStackTrace(PrintStream) overload, found: ${fns.map { it.parameters.map { p -> p.type } }}")
+
+    // The PrintStream overload's parameter must be typed as PrintStream, not generic Any
+    val paramType = withParam.valueParameters.single().type.toString()
+    assertTrue(paramType.contains("PrintStream"),
+        "$label.printStackTrace(PrintStream) parameter type must contain 'PrintStream', got: $paramType")
+}
+
+fun box(): String {
+    checkPrintStackTrace(Throwable::class,          "Throwable")
+    checkPrintStackTrace(Exception::class,           "Exception")
+    checkPrintStackTrace(java.lang.Error::class,    "Error")
+    checkPrintStackTrace(RuntimeException::class,   "RuntimeException")
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/typeParameters/enumFakeOverrideTypeSubstitution.kt b/compiler/testData/codegen/boxJvm/reflection/typeParameters/enumFakeOverrideTypeSubstitution.kt
new file mode 100644
index 0000000..2ac0189
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/typeParameters/enumFakeOverrideTypeSubstitution.kt
@@ -0,0 +1,45 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// Tests that fake override methods inherited from Enum<E> have their type parameter E
+// correctly substituted with the concrete enum type in javaType.
+
+import kotlin.reflect.full.*
+import kotlin.reflect.jvm.javaType
+import kotlin.test.*
+
+enum class Season { SPRING, SUMMER, AUTUMN, WINTER }
+enum class Weekday(val abbreviation: String) {
+    MON("Mon"), TUE("Tue"), WED("Wed"), THU("Thu"), FRI("Fri")
+}
+
+fun checkEnumFakeOverrides(enumClass: kotlin.reflect.KClass<out Enum<*>>, simpleName: String) {
+    val fns = enumClass.memberFunctions.associateBy { it.name }
+
+    // getDeclaringClass() is inherited from Enum<E>; return type should be Class<EnumType>
+    val getDeclaringClass = fns["getDeclaringClass"]
+    if (getDeclaringClass != null) {
+        val jt = getDeclaringClass.returnType.javaType.typeName
+        assertTrue(
+            jt.contains(simpleName) || jt == "java.lang.Class<${enumClass.java.name}>",
+            "$simpleName.getDeclaringClass() return javaType should reference $simpleName, got: $jt"
+        )
+        assertFalse(jt == "java.lang.Class<E>" || jt.endsWith("<E>"),
+            "$simpleName.getDeclaringClass() must not use raw type variable E, got: $jt")
+    }
+
+    // compareTo(E other) — parameter should be the concrete enum type, not E
+    val compareTo = fns["compareTo"]
+    if (compareTo != null) {
+        val paramType = compareTo.valueParameters.firstOrNull()?.type?.javaType?.typeName
+        if (paramType != null) {
+            assertFalse(paramType == "E",
+                "$simpleName.compareTo() parameter must not be raw 'E', got: $paramType")
+        }
+    }
+}
+
+fun box(): String {
+    checkEnumFakeOverrides(Season::class,  "Season")
+    checkEnumFakeOverrides(Weekday::class, "Weekday")
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/typeParameters/javaSubclassFakeOverrideTypeSubstitution.kt b/compiler/testData/codegen/boxJvm/reflection/typeParameters/javaSubclassFakeOverrideTypeSubstitution.kt
new file mode 100644
index 0000000..a1a1d47
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/typeParameters/javaSubclassFakeOverrideTypeSubstitution.kt
@@ -0,0 +1,51 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: TypedJavaBase.java
+public class TypedJavaBase<T> {
+    public T value() { return null; }
+    public void setValue(T t) {}
+    public java.util.List<T> getList() { return null; }
+}
+
+// FILE: box.kt
+// Tests that a Kotlin class extending a generic Java class has its inherited fake override
+// methods with type parameters correctly substituted with the concrete bound type.
+
+import kotlin.reflect.full.*
+import kotlin.reflect.jvm.javaType
+import kotlin.test.*
+
+class KotlinExtendsTyped : TypedJavaBase<String>()
+class KotlinExtendsTypedInt : TypedJavaBase<Int>()
+
+fun box(): String {
+    // value() return type should be String, not T
+    val valueFn = KotlinExtendsTyped::class.memberFunctions.firstOrNull { it.name == "value" }
+        ?: return "Fail: 'value' not found in KotlinExtendsTyped.memberFunctions"
+
+    val returnJavaType = valueFn.returnType.javaType.typeName
+    assertFalse(returnJavaType == "T",
+        "KotlinExtendsTyped.value() return javaType must not be raw 'T', got: $returnJavaType")
+    assertEquals("java.lang.String", returnJavaType,
+        "KotlinExtendsTyped.value() return javaType should be java.lang.String")
+
+    // setValue(T) parameter type should be String
+    val setValueFn = KotlinExtendsTyped::class.memberFunctions.firstOrNull { it.name == "setValue" }
+    if (setValueFn != null) {
+        val paramType = setValueFn.valueParameters.firstOrNull()?.type?.javaType?.typeName
+        if (paramType != null) {
+            assertFalse(paramType == "T",
+                "KotlinExtendsTyped.setValue() param must not be 'T', got: $paramType")
+        }
+    }
+
+    // For Int bound: value() should return int/Integer
+    val intValueFn = KotlinExtendsTypedInt::class.memberFunctions.firstOrNull { it.name == "value" }
+    if (intValueFn != null) {
+        val intReturnType = intValueFn.returnType.javaType.typeName
+        assertFalse(intReturnType == "T",
+            "KotlinExtendsTypedInt.value() return must not be raw 'T', got: $intReturnType")
+    }
+
+    return "OK"
+}
diff --git a/compiler/testData/codegen/boxJvm/reflection/types/javaWildcardTypeStructure.kt b/compiler/testData/codegen/boxJvm/reflection/types/javaWildcardTypeStructure.kt
new file mode 100644
index 0000000..e762f05
--- /dev/null
+++ b/compiler/testData/codegen/boxJvm/reflection/types/javaWildcardTypeStructure.kt
@@ -0,0 +1,74 @@
+// TARGET_BACKEND: JVM
+// WITH_REFLECT
+// FILE: WildcardMethods.java
+import java.util.*;
+
+public class WildcardMethods {
+    public static List<? extends Number>     boundedOut()    { return null; }
+    public static List<? super Integer>      boundedIn()     { return null; }
+    public static List<?>                    unbounded()     { return null; }
+    public static Map<String, ? extends Number> mapBounded(){ return null; }
+}
+
+// FILE: box.kt
+// Tests structural properties of reflected types for Java wildcard-typed methods:
+// correct classifier, argument count, and variance projections.
+
+import kotlin.reflect.*
+import kotlin.reflect.full.*
+import kotlin.reflect.jvm.javaType
+import kotlin.test.*
+
+fun box(): String {
+    val fns = WildcardMethods::class.staticFunctions.associateBy { it.name }
+
+    // boundedOut(): List<? extends Number>
+    // → classifier should be some List type, with 1 argument of OUT variance
+    val boundedOut = fns["boundedOut"] ?: return "Fail: boundedOut not found"
+    val boundedOutType = boundedOut.returnType
+    val boundedOutClassifier = boundedOutType.classifier as? KClass<*>
+    assertNotNull(boundedOutClassifier, "boundedOut return type must have a KClass classifier")
+    assertTrue(boundedOutClassifier.qualifiedName?.contains("List") == true,
+        "boundedOut return type classifier must be a List, got: ${boundedOutClassifier.qualifiedName}")
+    assertEquals(1, boundedOutType.arguments.size,
+        "boundedOut return type must have 1 type argument")
+    val boundedOutArg = boundedOutType.arguments.single()
+    assertEquals(KVariance.OUT, boundedOutArg.variance,
+        "boundedOut type argument must be OUT (covariant)")
+    val boundedOutArgType = boundedOutArg.type
+    assertNotNull(boundedOutArgType, "boundedOut type argument must not be star")
+    assertTrue(boundedOutArgType.toString().contains("Number"),
+        "boundedOut type argument must be Number, got: $boundedOutArgType")
+
+    // boundedIn(): List<? super Integer>
+    // → 1 argument of IN variance
+    val boundedIn = fns["boundedIn"] ?: return "Fail: boundedIn not found"
+    val boundedInType = boundedIn.returnType
+    assertEquals(1, boundedInType.arguments.size)
+    val boundedInArg = boundedInType.arguments.single()
+    assertEquals(KVariance.IN, boundedInArg.variance,
+        "boundedIn type argument must be IN (contravariant)")
+    assertTrue(boundedInArg.type?.toString()?.contains("Int") == true,
+        "boundedIn type argument must contain Int, got: ${boundedInArg.type}")
+
+    // unbounded(): List<?>
+    // → 1 star-projection argument
+    val unbounded = fns["unbounded"] ?: return "Fail: unbounded not found"
+    val unboundedType = unbounded.returnType
+    assertEquals(1, unboundedType.arguments.size)
+    val unboundedArg = unboundedType.arguments.single()
+    assertNull(unboundedArg.variance, "unbounded type argument must be a star projection (null variance)")
+    assertNull(unboundedArg.type,     "unbounded type argument must be a star projection (null type)")
+
+    // mapBounded(): Map<String, ? extends Number>
+    // → 2 arguments; second is OUT
+    val mapBounded = fns["mapBounded"] ?: return "Fail: mapBounded not found"
+    val mapBoundedType = mapBounded.returnType
+    assertEquals(2, mapBoundedType.arguments.size,
+        "mapBounded return type must have 2 type arguments")
+    val mapSecondArg = mapBoundedType.arguments[1]
+    assertEquals(KVariance.OUT, mapSecondArg.variance,
+        "mapBounded second type argument must be OUT")
+
+    return "OK"
+}