diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/AbstractSerialGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/AbstractSerialGenerator.kt
index b9fab87..ea5ee96 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/AbstractSerialGenerator.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/AbstractSerialGenerator.kt
@@ -5,19 +5,9 @@
 
 package org.jetbrains.kotlinx.serialization.compiler.backend.common
 
-import org.jetbrains.kotlin.backend.jvm.ir.fileParent
 import org.jetbrains.kotlin.descriptors.ClassDescriptor
 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.ir.declarations.IrClass
-import org.jetbrains.kotlin.ir.expressions.IrClassReference
-import org.jetbrains.kotlin.ir.expressions.IrVararg
-import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
-import org.jetbrains.kotlin.ir.types.IrSimpleType
-import org.jetbrains.kotlin.ir.types.classOrNull
-import org.jetbrains.kotlin.ir.types.isNullable
-import org.jetbrains.kotlin.ir.types.typeOrNull
-import org.jetbrains.kotlin.ir.util.findAnnotation
 import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
 import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.name.Name
@@ -31,46 +21,15 @@
 import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
 import org.jetbrains.kotlinx.serialization.compiler.resolve.isKSerializer
 import org.jetbrains.kotlinx.serialization.compiler.resolve.toClassDescriptor
-abstract class AbstractIrGenerator(private val currentClass: IrClass) {
-    private fun getClassListFromFileAnnotation(annotationFqName: FqName): List<IrClassSymbol> {
-        val annotation = currentClass.fileParent.annotations.findAnnotation(annotationFqName) ?: return emptyList()
-        val vararg = annotation.getValueArgument(0) as? IrVararg ?: return emptyList()
-        return vararg.elements
-            .mapNotNull { (it as? IrClassReference)?.symbol as? IrClassSymbol}
-    }
-
-    val contextualKClassListInCurrentFile: Set<IrClassSymbol> by lazy {
-        getClassListFromFileAnnotation(
-            SerializationAnnotations.contextualFqName,
-        ).plus(
-            getClassListFromFileAnnotation(
-                SerializationAnnotations.contextualOnFileFqName,
-            )
-        ).toSet()
-    }
-
-    val additionalSerializersInScopeOfCurrentFile: Map<Pair<IrClassSymbol, Boolean>, IrClassSymbol> by lazy {
-        getClassListFromFileAnnotation(SerializationAnnotations.additionalSerializersFqName,)
-            .associateBy(
-                { serializerSymbol ->
-                    val kotlinType = (serializerSymbol.owner.superTypes.find(::isKSerializer) as? IrSimpleType)?.arguments?.firstOrNull()?.typeOrNull
-                    val classSymbol = kotlinType?.classOrNull
-                        ?: throw AssertionError("Argument for ${SerializationAnnotations.additionalSerializersFqName} does not implement KSerializer or does not provide serializer for concrete type")
-                    classSymbol to kotlinType.isNullable()
-                },
-                { it }
-            )
-    }
-}
 
 abstract class AbstractSerialGenerator(val bindingContext: BindingContext?, val currentDeclaration: ClassDescriptor) {
-
     private fun getKClassListFromFileAnnotation(annotationFqName: FqName, declarationInFile: DeclarationDescriptor): List<KotlinType> {
-        if (bindingContext == null) return emptyList() // TODO: support @UseSerializers in FIR
+        if (bindingContext == null) return emptyList()
         val annotation = AnnotationsUtils
             .getContainingFileAnnotations(bindingContext, declarationInFile)
             .find { it.fqName == annotationFqName }
             ?: return emptyList()
+
         @Suppress("UNCHECKED_CAST")
         val typeList: List<KClassValue> = annotation.firstArgument()?.value as? List<KClassValue> ?: return emptyList()
         return typeList.map { it.getArgumentType(declarationInFile.module) }
@@ -102,5 +61,6 @@
     }
 
     protected fun ClassDescriptor.getFuncDesc(funcName: String): Sequence<FunctionDescriptor> =
-        unsubstitutedMemberScope.getDescriptorsFiltered { it == Name.identifier(funcName) }.asSequence().filterIsInstance<FunctionDescriptor>()
+        unsubstitutedMemberScope.getDescriptorsFiltered { it == Name.identifier(funcName) }.asSequence()
+            .filterIsInstance<FunctionDescriptor>()
 }
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt
index f0cf7c7..14fa565 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt
@@ -8,7 +8,6 @@
 import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
 import org.jetbrains.kotlin.descriptors.ClassDescriptor
 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
 import org.jetbrains.kotlin.incremental.components.NoLookupLocation
 import org.jetbrains.kotlin.resolve.BindingContext
 import org.jetbrains.kotlinx.serialization.compiler.resolve.*
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt
index 9de53f7..e10fb3e 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt
@@ -10,11 +10,6 @@
 import org.jetbrains.kotlin.codegen.CompilationException
 import org.jetbrains.kotlin.descriptors.*
 import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.ir.declarations.IrProperty
-import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
-import org.jetbrains.kotlin.ir.types.*
-import org.jetbrains.kotlin.ir.util.hasAnnotation
-import org.jetbrains.kotlin.ir.util.isTypeParameter
 import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
 import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
 import org.jetbrains.kotlin.name.ClassId
@@ -26,32 +21,17 @@
 import org.jetbrains.kotlin.resolve.BindingContext
 import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
 import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.model.KotlinTypeMarker
 import org.jetbrains.kotlin.types.typeUtil.*
 import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.enumSerializerId
 import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.referenceArraySerializerId
-import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
 import org.jetbrains.kotlinx.serialization.compiler.resolve.*
 import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages.internalPackageFqName
 
-interface ISerialTypeInfo<C, D, T : KotlinTypeMarker, S : ISerializableProperty<D, T>> {
-    val property: S
-    val elementMethodPrefix: String
-    val serializer: C?
-}
-
 open class SerialTypeInfo(
-    override val property: SerializableProperty,
-    override val elementMethodPrefix: String,
-    override val serializer: ClassDescriptor? = null
-) : ISerialTypeInfo<ClassDescriptor, PropertyDescriptor, KotlinType, SerializableProperty>
-
-class IrSerialTypeInfo(
-    override val property: IrSerializableProperty,
-    override val elementMethodPrefix: String,
-    override val serializer: IrClassSymbol? = null
-) : ISerialTypeInfo<IrClassSymbol, IrProperty, IrSimpleType, IrSerializableProperty>
-
+    val property: SerializableProperty,
+    val elementMethodPrefix: String,
+    val serializer: ClassDescriptor? = null
+)
 
 fun AbstractSerialGenerator.findAddOnSerializer(propertyType: KotlinType, module: ModuleDescriptor): ClassDescriptor? {
     additionalSerializersInScopeOfCurrentFile[propertyType.toClassDescriptor to propertyType.isMarkedNullable]?.let { return it }
@@ -63,48 +43,9 @@
     return null
 }
 
-fun AbstractIrGenerator.findAddOnSerializer(propertyType: IrType, ctx: SerializationPluginContext): IrClassSymbol? {
-    val classSymbol = propertyType.classOrNull ?: return null
-    additionalSerializersInScopeOfCurrentFile[classSymbol to propertyType.isNullable()]?.let { return it }
-    if (classSymbol in contextualKClassListInCurrentFile)
-        return ctx.getClassFromRuntime(SpecialBuiltins.contextSerializer)
-    if (classSymbol.owner.annotations.hasAnnotation(SerializationAnnotations.polymorphicFqName))
-        return ctx.getClassFromRuntime(SpecialBuiltins.polymorphicSerializer)
-    if (propertyType.isNullable()) return findAddOnSerializer(propertyType.makeNotNull(), ctx)
-    return null
-}
-
-
 fun KotlinType.isGeneratedSerializableObject() =
     toClassDescriptor?.run { kind == ClassKind.OBJECT && hasSerializableOrMetaAnnotationWithoutArgs } == true
 
-fun AbstractIrGenerator.getIrSerialTypeInfo(property: IrSerializableProperty, ctx: SerializationPluginContext): IrSerialTypeInfo {
-    fun SerializableInfo(serializer: IrClassSymbol?) =
-        IrSerialTypeInfo(property, if (property.type.isNullable()) "Nullable" else "", serializer)
-
-    val T = property.type
-    property.serializableWith(ctx)?.let { return SerializableInfo(it) }
-    findAddOnSerializer(T, ctx)?.let { return SerializableInfo(it) }
-    T.overridenSerializer?.let { return SerializableInfo(it) }
-    return when {
-        T.isTypeParameter() -> IrSerialTypeInfo(property, if (property.type.isMarkedNullable()) "Nullable" else "", null)
-        T.isPrimitiveType() -> IrSerialTypeInfo(
-            property,
-            T.classFqName!!.asString().removePrefix("kotlin.")
-        )
-        T.isString() -> IrSerialTypeInfo(property, "String")
-        T.isArray() -> {
-            val serializer = property.serializableWith(ctx) ?: ctx.getClassFromInternalSerializationPackage(SpecialBuiltins.referenceArraySerializer)
-            SerializableInfo(serializer)
-        }
-        else -> {
-            val serializer =
-                findTypeSerializerOrContext(ctx, property.type)
-            SerializableInfo(serializer)
-        }
-    }
-}
-
 @Suppress("FunctionName", "LocalVariableName")
 fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty): SerialTypeInfo {
     fun SerializableInfo(serializer: ClassDescriptor?) =
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtilIr.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtilIr.kt
deleted file mode 100644
index a10c7c0..0000000
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtilIr.kt
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
- * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
- */
-
-package org.jetbrains.kotlinx.serialization.compiler.backend.common
-
-import org.jetbrains.kotlin.backend.jvm.ir.getStringConstArgument
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.descriptors.Modality
-import org.jetbrains.kotlin.ir.declarations.*
-import org.jetbrains.kotlin.ir.expressions.IrClassReference
-import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
-import org.jetbrains.kotlin.ir.expressions.IrExpression
-import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
-import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
-import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
-import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
-import org.jetbrains.kotlin.ir.types.*
-import org.jetbrains.kotlin.ir.util.*
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
-import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
-import org.jetbrains.kotlinx.serialization.compiler.fir.SerializationPluginKey
-import org.jetbrains.kotlinx.serialization.compiler.resolve.*
-
-fun AbstractIrGenerator.findTypeSerializerOrContextUnchecked(
-    context: SerializationPluginContext, kType: IrType
-): IrClassSymbol? {
-    val annotations = kType.annotations
-    if (kType.isTypeParameter()) return null
-    annotations.serializableWith()?.let { return it }
-    additionalSerializersInScopeOfCurrentFile[kType.classOrNull!! to kType.isNullable()]?.let {
-        return it
-    }
-    if (kType.isMarkedNullable()) return findTypeSerializerOrContextUnchecked(context, kType.makeNotNull())
-    if (kType.classOrNull in contextualKClassListInCurrentFile) return context.referenceClass(contextSerializerId)
-    return analyzeSpecialSerializers(context, annotations) ?: findTypeSerializer(context, kType)
-}
-
-fun analyzeSpecialSerializers(
-    context: SerializationPluginContext,
-    annotations: List<IrConstructorCall>
-): IrClassSymbol? = when {
-    annotations.hasAnnotation(SerializationAnnotations.contextualFqName) || annotations.hasAnnotation(SerializationAnnotations.contextualOnPropertyFqName) ->
-        context.referenceClass(contextSerializerId)
-    // can be annotation on type usage, e.g. List<@Polymorphic Any>
-    annotations.hasAnnotation(SerializationAnnotations.polymorphicFqName) ->
-        context.referenceClass(polymorphicSerializerId)
-    else -> null
-}
-
-fun AbstractIrGenerator.findTypeSerializerOrContext(
-    context: SerializationPluginContext, kType: IrType
-): IrClassSymbol? {
-    if (kType.isTypeParameter()) return null
-    return findTypeSerializerOrContextUnchecked(context, kType) ?: error("Serializer for element of type ${kType.render()} has not been found")
-}
-
-fun findTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
-    type.overridenSerializer?.let { return it }
-    if (type.isTypeParameter()) return null
-    if (type.isArray()) return context.referenceClass(referenceArraySerializerId)
-    if (type.isGeneratedSerializableObject()) return context.referenceClass(objectSerializerId)
-    val stdSer = findStandardKotlinTypeSerializer(context, type) // see if there is a standard serializer
-        ?: findEnumTypeSerializer(context, type)
-    if (stdSer != null) return stdSer
-    if (type.isInterface() && type.classOrNull?.owner?.isSealedSerializableInterface == false) return context.referenceClass(
-        polymorphicSerializerId
-    )
-    return type.classOrNull?.owner.classSerializer(context) // check for serializer defined on the type
-}
-
-internal fun IrClass?.classSerializer(context: SerializationPluginContext): IrClassSymbol? = this?.let {
-    // serializer annotation on class?
-    serializableWith?.let { return it }
-    // companion object serializer?
-    if (hasCompanionObjectAsSerializer) return companionObject()?.symbol
-    // can infer @Poly?
-    polymorphicSerializerIfApplicableAutomatically(context)?.let { return it }
-    // default serializable?
-    if (shouldHaveGeneratedSerializer) {
-        // $serializer nested class
-        return this.declarations
-            .filterIsInstance<IrClass>()
-            .singleOrNull { it.name == SerialEntityNames.SERIALIZER_CLASS_NAME }?.symbol
-    }
-    return null
-}
-
-private val IrClass.isSerialInfoAnnotation: Boolean
-    get() = annotations.hasAnnotation(SerializationAnnotations.serialInfoFqName)
-            || annotations.hasAnnotation(SerializationAnnotations.inheritableSerialInfoFqName)
-            || annotations.hasAnnotation(SerializationAnnotations.metaSerializableAnnotationFqName)
-
-internal val IrClass.shouldHaveGeneratedSerializer: Boolean
-    get() = (isInternalSerializable && (modality == Modality.FINAL || modality == Modality.OPEN))
-            || isEnumWithLegacyGeneratedSerializer()
-
-internal fun IrClass.polymorphicSerializerIfApplicableAutomatically(context: SerializationPluginContext): IrClassSymbol? {
-    val serializer = when {
-        kind == ClassKind.INTERFACE && modality == Modality.SEALED -> SpecialBuiltins.sealedSerializer
-        kind == ClassKind.INTERFACE -> SpecialBuiltins.polymorphicSerializer
-        isInternalSerializable && modality == Modality.ABSTRACT -> SpecialBuiltins.polymorphicSerializer
-        isInternalSerializable && modality == Modality.SEALED -> SpecialBuiltins.sealedSerializer
-        else -> null
-    }
-    return serializer?.let {
-        context.getClassFromRuntimeOrNull(
-            it,
-            SerializationPackages.packageFqName,
-            SerializationPackages.internalPackageFqName
-        )
-    }
-}
-
-internal val IrClass.isInternalSerializable: Boolean
-    get() {
-        if (kind != ClassKind.CLASS) return false
-        return hasSerializableOrMetaAnnotationWithoutArgs()
-    }
-
-internal val IrClass.isAbstractOrSealedSerializableClass: Boolean get() = isInternalSerializable && (modality == Modality.ABSTRACT || modality == Modality.SEALED)
-
-internal val IrClass.isStaticSerializable: Boolean get() = this.typeParameters.isEmpty()
-
-
-internal val IrClass.hasCompanionObjectAsSerializer: Boolean
-    get() = isInternallySerializableObject || companionObject()?.serializerForClass == this.symbol
-
-internal val IrClass.isInternallySerializableObject: Boolean
-    get() = kind == ClassKind.OBJECT && hasSerializableOrMetaAnnotationWithoutArgs()
-
-internal val IrClass.serializerForClass: IrClassSymbol?
-    get() = (annotations.findAnnotation(SerializationAnnotations.serializerAnnotationFqName)
-        ?.getValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol
-
-fun findEnumTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
-    val classSymbol = type.classOrNull?.owner ?: return null
-    return if (classSymbol.kind == ClassKind.ENUM_CLASS && !classSymbol.isEnumWithLegacyGeneratedSerializer())
-        context.referenceClass(enumSerializerId)
-    else null
-}
-
-internal fun IrClass.isEnumWithLegacyGeneratedSerializer(): Boolean = isInternallySerializableEnum() && useGeneratedEnumSerializer
-
-internal val IrClass.useGeneratedEnumSerializer: Boolean
-    get() = true // FIXME This would break if we try to use this new IR compiler with pre-1.4.1 serialization versions. I think we just need to raise min runtime version.
-
-internal val IrClass.isSealedSerializableInterface: Boolean
-    get() = kind == ClassKind.INTERFACE && modality == Modality.SEALED && hasSerializableOrMetaAnnotation()
-
-internal fun IrClass.isInternallySerializableEnum(): Boolean =
-    kind == ClassKind.ENUM_CLASS && hasSerializableOrMetaAnnotationWithoutArgs()
-
-fun findStandardKotlinTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
-    val typeName = type.classFqName?.toString()
-    val name = when (typeName) {
-        "Z" -> if (type.isBoolean()) "BooleanSerializer" else null
-        "B" -> if (type.isByte()) "ByteSerializer" else null
-        "S" -> if (type.isShort()) "ShortSerializer" else null
-        "I" -> if (type.isInt()) "IntSerializer" else null
-        "J" -> if (type.isLong()) "LongSerializer" else null
-        "F" -> if (type.isFloat()) "FloatSerializer" else null
-        "D" -> if (type.isDouble()) "DoubleSerializer" else null
-        "C" -> if (type.isChar()) "CharSerializer" else null
-        null -> null
-        else -> findStandardKotlinTypeSerializer(typeName)
-    } ?: return null
-    return context.getClassFromRuntimeOrNull(name, SerializationPackages.internalPackageFqName, SerializationPackages.packageFqName)
-}
-
-fun IrType.isGeneratedSerializableObject(): Boolean {
-    return classOrNull?.run { owner.kind == ClassKind.OBJECT && owner.hasSerializableOrMetaAnnotationWithoutArgs() } == true
-}
-
-internal val IrClass.isSerializableObject: Boolean
-    get() = kind == ClassKind.OBJECT && hasSerializableOrMetaAnnotation()
-
-// todo: optimize & unify with hasSerializableOrMeta
-internal fun IrClass.hasSerializableOrMetaAnnotationWithoutArgs(): Boolean {
-    val annot = getAnnotation(SerializationAnnotations.serializableAnnotationFqName)
-    if (annot != null) {
-        for (i in 0 until annot.valueArgumentsCount) {
-            if (annot.getValueArgument(i) != null) return false
-        }
-        return true
-    }
-    val metaAnnotation = annotations
-        .flatMap { it.symbol.owner.constructedClass.annotations }
-        .find { it.isAnnotation(SerializationAnnotations.metaSerializableAnnotationFqName) }
-    return metaAnnotation != null
-}
-
-fun SerializationPluginContext.getClassFromRuntimeOrNull(className: String, vararg packages: FqName): IrClassSymbol? {
-    val listToSearch = if (packages.isEmpty()) SerializationPackages.allPublicPackages else packages.toList()
-    for (pkg in listToSearch) {
-        referenceClass(ClassId(pkg, Name.identifier(className)))?.let { return it }
-    }
-    return null
-}
-
-fun SerializationPluginContext.getClassFromRuntime(className: String, vararg packages: FqName): IrClassSymbol {
-    return getClassFromRuntimeOrNull(className, *packages) ?: error(
-        "Class $className wasn't found in ${packages.toList().ifEmpty { SerializationPackages.allPublicPackages }}. " +
-                "Check that you have correct version of serialization runtime in classpath."
-    )
-}
-
-fun SerializationPluginContext.getClassFromInternalSerializationPackage(className: String): IrClassSymbol =
-    getClassFromRuntimeOrNull(className, SerializationPackages.internalPackageFqName)
-        ?: error("Class $className wasn't found in ${SerializationPackages.internalPackageFqName}. Check that you have correct version of serialization runtime in classpath.")
-
-
-internal val IrType.overridenSerializer: IrClassSymbol?
-    get() {
-        val desc = this.classOrNull ?: return null
-        desc.owner.serializableWith?.let { return it }
-        return null
-    }
-
-internal val IrClass.serializableWith: IrClassSymbol?
-    get() = annotations.serializableWith()
-
-
-// @Serializable(X::class) -> X
-internal fun List<IrConstructorCall>.serializableWith(): IrClassSymbol? {
-    val annotation = findAnnotation(SerializationAnnotations.serializableAnnotationFqName) ?: return null
-    val arg = annotation.getValueArgument(0) as? IrClassReference ?: return null
-    return arg.symbol as? IrClassSymbol
-}
-
-internal fun getSerializableClassByCompanion(companionClass: IrClass): IrClass? {
-    if (companionClass.isSerializableObject) return companionClass
-    if (!companionClass.isCompanion) return null
-    val classDescriptor = (companionClass.parent as? IrClass) ?: return null
-    if (!classDescriptor.shouldHaveGeneratedMethodsInCompanion) return null
-    return classDescriptor
-}
-
-internal val IrClass.shouldHaveGeneratedMethodsInCompanion: Boolean
-    get() = this.isSerializableObject || this.isSerializableEnum() || (this.kind == ClassKind.CLASS && hasSerializableOrMetaAnnotation()) || this.isSealedSerializableInterface
-
-internal fun IrClass.isSerializableEnum(): Boolean = kind == ClassKind.ENUM_CLASS && hasSerializableOrMetaAnnotation()
-
-fun IrClass.hasSerializableOrMetaAnnotation() = descriptor.hasSerializableOrMetaAnnotation // TODO
-
-internal val IrType.genericIndex: Int?
-    get() = (this.classifierOrNull as? IrTypeParameterSymbol)?.owner?.index
-
-fun IrType.serialName(): String = this.classOrNull!!.owner.serialName()
-fun IrClass.serialName(): String {
-    return annotations.serialNameValue ?: fqNameWhenAvailable?.asString() ?: error("${this.render()} does not have fqName")
-}
-
-fun AbstractIrGenerator.allSealedSerializableSubclassesFor(
-    irClass: IrClass,
-    context: SerializationPluginContext
-): Pair<List<IrSimpleType>, List<IrClassSymbol>> {
-    assert(irClass.modality == Modality.SEALED)
-    fun recursiveSealed(klass: IrClass): Collection<IrClass> {
-        return klass.sealedSubclasses.map { it.owner }.flatMap { if (it.modality == Modality.SEALED) recursiveSealed(it) else setOf(it) }
-    }
-
-    val serializableSubtypes = recursiveSealed(irClass).map { it.defaultType }
-    return serializableSubtypes.mapNotNull { subtype ->
-        findTypeSerializerOrContextUnchecked(context, subtype)?.let { Pair(subtype, it) }
-    }.unzip()
-}
-
-fun IrClass.findEnumValuesMethod() = this.functions.singleOrNull { f ->
-    f.name == Name.identifier("values") && f.valueParameters.isEmpty() && f.extensionReceiverParameter == null
-} ?: throw AssertionError("Enum class does not have single .values() function")
-
-internal fun IrClass.enumEntries(): List<IrEnumEntry> {
-    check(this.kind == ClassKind.ENUM_CLASS)
-    return declarations.filterIsInstance<IrEnumEntry>().toList()
-}
-
-internal fun IrClass.isEnumWithSerialInfoAnnotation(): Boolean {
-    if (kind != ClassKind.ENUM_CLASS) return false
-    if (annotations.hasAnySerialAnnotation) return true
-    return enumEntries().any { (it.annotations.hasAnySerialAnnotation) }
-}
-
-internal val List<IrConstructorCall>.hasAnySerialAnnotation: Boolean
-    get() = serialNameValue != null || any { it.annotationClass.isSerialInfoAnnotation == true }
-
-internal val List<IrConstructorCall>.serialNameValue: String?
-    get() = findAnnotation(SerializationAnnotations.serialNameAnnotationFqName)?.getStringConstArgument(0) // @SerialName("foo")
-
-internal fun getSerializableClassDescriptorBySerializer(serializer: IrClass): IrClass? {
-    val serializerForClass = serializer.serializerForClass
-    if (serializerForClass != null) return serializerForClass.owner
-    if (serializer.name !in setOf(
-            SerialEntityNames.SERIALIZER_CLASS_NAME,
-            SerialEntityNames.GENERATED_SERIALIZER_CLASS
-        )
-    ) return null
-    val classDescriptor = (serializer.parent as? IrClass) ?: return null
-    if (!classDescriptor.shouldHaveGeneratedSerializer) return null
-    return classDescriptor
-}
-
-internal fun isKSerializer(type: IrType): Boolean {
-    val simpleType = type as? IrSimpleType ?: return false
-    val classifier = simpleType.classifier as? IrClassSymbol ?: return false
-    val fqName = classifier.owner.fqNameWhenAvailable
-    return fqName == SerialEntityNames.KSERIALIZER_NAME_FQ || fqName == SerialEntityNames.GENERATED_SERIALIZER_FQ
-}
-
-internal fun IrClass.findPluginGeneratedMethod(name: String): IrSimpleFunction? {
-    return this.functions.find {
-        it.name.asString() == name && it.isFromPlugin()
-    }
-}
-
-internal fun IrDeclaration.isFromPlugin(): Boolean =
-    this.origin == IrDeclarationOrigin.GeneratedByPlugin(SerializationPluginKey) || (this.descriptor as? CallableMemberDescriptor)?.kind == CallableMemberDescriptor.Kind.SYNTHESIZED // old FE doesn't specify origin
-
-internal fun IrConstructor.isSerializationCtor(): Boolean {
-    /*kind == CallableMemberDescriptor.Kind.SYNTHESIZED does not work because DeserializedClassConstructorDescriptor loses its kind*/
-    return valueParameters.lastOrNull()?.run {
-        name == SerialEntityNames.dummyParamName && type.classFqName == SerializationPackages.internalPackageFqName.child(
-            SerialEntityNames.SERIAL_CTOR_MARKER_NAME
-        )
-    } == true
-}
-
-internal fun IrExpression.isInitializePropertyFromParameter(): Boolean =
-    this is IrGetValueImpl && this.origin == IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
-
-internal val IrConstructorCall.annotationClass
-    get() = this.symbol.owner.constructedClass
\ No newline at end of file
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/BaseIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/BaseIrGenerator.kt
new file mode 100644
index 0000000..0a6c9f1
--- /dev/null
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/BaseIrGenerator.kt
@@ -0,0 +1,578 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlinx.serialization.compiler.backend.ir
+
+import org.jetbrains.kotlin.backend.common.lower.irIfThen
+import org.jetbrains.kotlin.backend.jvm.functionByName
+import org.jetbrains.kotlin.backend.jvm.ir.fileParent
+import org.jetbrains.kotlin.backend.jvm.ir.representativeUpperBound
+import org.jetbrains.kotlin.descriptors.ClassKind
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.descriptors.isSealed
+import org.jetbrains.kotlin.ir.builders.*
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.deepCopyWithVariables
+import org.jetbrains.kotlin.ir.expressions.IrClassReference
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
+import org.jetbrains.kotlin.ir.expressions.IrVararg
+import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
+import org.jetbrains.kotlin.ir.types.*
+import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
+import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
+import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.name.CallableId
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.types.Variance
+import org.jetbrains.kotlin.util.OperatorNameConventions
+import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
+import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
+import org.jetbrains.kotlinx.serialization.compiler.resolve.*
+
+abstract class BaseIrGenerator(private val currentClass: IrClass, final override val compilerContext: SerializationPluginContext): IrBuilderWithPluginContext {
+
+    private val throwMissedFieldExceptionFunc
+        = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.SINGLE_MASK_FIELD_MISSING_FUNC_NAME)).singleOrNull()
+
+    private val throwMissedFieldExceptionArrayFunc
+        = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.ARRAY_MASK_FIELD_MISSING_FUNC_NAME)).singleOrNull()
+
+    private val enumSerializerFactoryFunc
+        = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.ENUM_SERIALIZER_FACTORY_FUNC_NAME)).singleOrNull()
+
+    private val markedEnumSerializerFactoryFunc
+        = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.MARKED_ENUM_SERIALIZER_FACTORY_FUNC_NAME)).singleOrNull()
+
+    fun useFieldMissingOptimization(): Boolean {
+        return throwMissedFieldExceptionFunc != null && throwMissedFieldExceptionArrayFunc != null
+    }
+
+    private fun getClassListFromFileAnnotation(annotationFqName: FqName): List<IrClassSymbol> {
+        val annotation = currentClass.fileParent.annotations.findAnnotation(annotationFqName) ?: return emptyList()
+        val vararg = annotation.getValueArgument(0) as? IrVararg ?: return emptyList()
+        return vararg.elements
+            .mapNotNull { (it as? IrClassReference)?.symbol as? IrClassSymbol }
+    }
+
+    val contextualKClassListInCurrentFile: Set<IrClassSymbol> by lazy {
+        getClassListFromFileAnnotation(
+            SerializationAnnotations.contextualFqName,
+        ).plus(
+            getClassListFromFileAnnotation(
+                SerializationAnnotations.contextualOnFileFqName,
+            )
+        ).toSet()
+    }
+
+    val additionalSerializersInScopeOfCurrentFile: Map<Pair<IrClassSymbol, Boolean>, IrClassSymbol> by lazy {
+        getClassListFromFileAnnotation(SerializationAnnotations.additionalSerializersFqName,)
+            .associateBy(
+                { serializerSymbol ->
+                    val kotlinType = (serializerSymbol.owner.superTypes.find(IrType::isKSerializer) as? IrSimpleType)?.arguments?.firstOrNull()?.typeOrNull
+                    val classSymbol = kotlinType?.classOrNull
+                        ?: throw AssertionError("Argument for ${SerializationAnnotations.additionalSerializersFqName} does not implement KSerializer or does not provide serializer for concrete type")
+                    classSymbol to kotlinType.isNullable()
+                },
+                { it }
+            )
+    }
+
+    fun IrBlockBodyBuilder.generateGoldenMaskCheck(
+        seenVars: List<IrValueDeclaration>,
+        properties: IrSerializableProperties,
+        serialDescriptor: IrExpression
+    ) {
+        val fieldsMissedTest: IrExpression
+        val throwErrorExpr: IrExpression
+
+        val maskSlotCount = seenVars.size
+        if (maskSlotCount == 1) {
+            val goldenMask = properties.goldenMask
+
+
+            throwErrorExpr = irInvoke(
+                null,
+                throwMissedFieldExceptionFunc!!,
+                irGet(seenVars[0]),
+                irInt(goldenMask),
+                serialDescriptor,
+                typeHint = compilerContext.irBuiltIns.unitType
+            )
+
+            fieldsMissedTest = irNotEquals(
+                irInt(goldenMask),
+                irBinOp(
+                    OperatorNameConventions.AND,
+                    irInt(goldenMask),
+                    irGet(seenVars[0])
+                )
+            )
+        } else {
+            val goldenMaskList = properties.goldenMaskList
+
+            var compositeExpression: IrExpression? = null
+            for (i in goldenMaskList.indices) {
+                val singleCheckExpr = irNotEquals(
+                    irInt(goldenMaskList[i]),
+                    irBinOp(
+                        OperatorNameConventions.AND,
+                        irInt(goldenMaskList[i]),
+                        irGet(seenVars[i])
+                    )
+                )
+
+                compositeExpression = if (compositeExpression == null) {
+                    singleCheckExpr
+                } else {
+                    irBinOp(
+                        OperatorNameConventions.OR,
+                        compositeExpression,
+                        singleCheckExpr
+                    )
+                }
+            }
+
+            fieldsMissedTest = compositeExpression!!
+
+            throwErrorExpr = irBlock {
+                +irInvoke(
+                    null,
+                    throwMissedFieldExceptionArrayFunc!!,
+                    createPrimitiveArrayOfExpression(compilerContext.irBuiltIns.intType, goldenMaskList.indices.map { irGet(seenVars[it]) }),
+                    createPrimitiveArrayOfExpression(compilerContext.irBuiltIns.intType, goldenMaskList.map { irInt(it) }),
+                    serialDescriptor,
+                    typeHint = compilerContext.irBuiltIns.unitType
+                )
+            }
+        }
+
+        +irIfThen(compilerContext.irBuiltIns.unitType, fieldsMissedTest, throwErrorExpr)
+    }
+
+    fun IrBlockBodyBuilder.serializeAllProperties(
+        serializableProperties: List<IrSerializableProperty>,
+        objectToSerialize: IrValueDeclaration,
+        localOutput: IrValueDeclaration,
+        localSerialDesc: IrValueDeclaration,
+        kOutputClass: IrClassSymbol,
+        ignoreIndexTo: Int,
+        initializerAdapter: (IrExpressionBody) -> IrExpression,
+        genericGetter: ((Int, IrType) -> IrExpression)?
+    ) {
+
+        fun IrSerializableProperty.irGet(): IrExpression {
+            val ownerType = objectToSerialize.symbol.owner.type
+            return getProperty(
+                irGet(
+                    type = ownerType,
+                    variable = objectToSerialize.symbol
+                ), ir
+            )
+        }
+
+        for ((index, property) in serializableProperties.withIndex()) {
+            if (index < ignoreIndexTo) continue
+            // output.writeXxxElementValue(classDesc, index, value)
+            val elementCall = formEncodeDecodePropertyCall(
+                irGet(localOutput),
+                property, { innerSerial, sti ->
+                    val f =
+                        kOutputClass.functionByName("${CallingConventions.encode}${sti.elementMethodPrefix}Serializable${CallingConventions.elementPostfix}")
+                    f to listOf(
+                        irGet(localSerialDesc),
+                        irInt(index),
+                        innerSerial,
+                        property.irGet()
+                    )
+                }, {
+                    val f =
+                        kOutputClass.functionByName("${CallingConventions.encode}${it.elementMethodPrefix}${CallingConventions.elementPostfix}")
+                    val args: MutableList<IrExpression> = mutableListOf(irGet(localSerialDesc), irInt(index))
+                    if (it.elementMethodPrefix != "Unit") args.add(property.irGet())
+                    f to args
+                },
+                genericGetter
+            )
+
+            // check for call to .shouldEncodeElementDefault
+            val encodeDefaults = property.ir.getEncodeDefaultAnnotationValue()
+            val field =
+                property.ir.backingField // Nullable when property from another module; can't compare it with default value on JS or Native
+            if (!property.optional || encodeDefaults == true || field == null) {
+                // emit call right away
+                +elementCall
+            } else {
+                val partB = irNotEquals(property.irGet(), initializerAdapter(field.initializer!!))
+
+                val condition = if (encodeDefaults == false) {
+                    // drop default without call to .shouldEncodeElementDefault
+                    partB
+                } else {
+                    // emit check:
+                    // if (if (output.shouldEncodeElementDefault(this.descriptor, i)) true else {obj.prop != DEFAULT_VALUE} ) {
+                    //    output.encodeIntElement(this.descriptor, i, obj.prop)// block {obj.prop != DEFAULT_VALUE} may contain several statements
+                    val shouldEncodeFunc = kOutputClass.functionByName(CallingConventions.shouldEncodeDefault)
+                    val partA = irInvoke(irGet(localOutput), shouldEncodeFunc, irGet(localSerialDesc), irInt(index))
+                    // Ir infrastructure does not have dedicated symbol for ||, so
+                    //  `a || b == if (a) true else b`, see org.jetbrains.kotlin.ir.builders.PrimitivesKt.oror
+                    irIfThenElse(compilerContext.irBuiltIns.booleanType, partA, irTrue(), partB)
+                }
+                +irIfThen(condition, elementCall)
+            }
+        }
+    }
+
+
+    fun IrBlockBodyBuilder.formEncodeDecodePropertyCall(
+        encoder: IrExpression,
+        property: IrSerializableProperty,
+        whenHaveSerializer: (serializer: IrExpression, sti: IrSerialTypeInfo) -> FunctionWithArgs,
+        whenDoNot: (sti: IrSerialTypeInfo) -> FunctionWithArgs,
+        genericGetter: ((Int, IrType) -> IrExpression)? = null,
+        returnTypeHint: IrType? = null
+    ): IrExpression {
+        val sti = getIrSerialTypeInfo(property, compilerContext)
+        val innerSerial = serializerInstance(
+            sti.serializer,
+            compilerContext,
+            property.type,
+            property.genericIndex,
+            genericGetter
+        )
+        val (functionToCall, args: List<IrExpression>) = if (innerSerial != null) whenHaveSerializer(innerSerial, sti) else whenDoNot(sti)
+        val typeArgs = if (functionToCall.descriptor.typeParameters.isNotEmpty()) listOf(property.type) else listOf()
+        return irInvoke(encoder, functionToCall, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnTypeHint)
+    }
+
+    fun IrBuilderWithScope.callSerializerFromCompanion(
+        thisIrType: IrType,
+        typeArgs: List<IrType>,
+        args: List<IrExpression>
+    ): IrExpression? {
+        val baseClass = thisIrType.getClass() ?: return null
+        val companionClass = baseClass.companionObject() ?: return null
+        val serializerProviderFunction = companionClass.declarations.singleOrNull {
+            it is IrFunction && it.name == SerialEntityNames.SERIALIZER_PROVIDER_NAME && it.valueParameters.size == baseClass.typeParameters.size
+        } ?: return null
+
+        val adjustedArgs: List<IrExpression> =
+            // if typeArgs.size == args.size then the serializer is custom - we need to use the actual serializers from the arguments
+            if ((typeArgs.size != args.size) && (baseClass.descriptor.isSealed() || baseClass.descriptor.modality == Modality.ABSTRACT)) {
+                val serializer = findStandardKotlinTypeSerializer(compilerContext, context.irBuiltIns.unitType)!!
+                // workaround for sealed and abstract classes - the `serializer` function expects non-null serializers, but does not use them, so serializers of any type can be passed
+                List(baseClass.typeParameters.size) { irGetObject(serializer) }
+            } else {
+                args
+            }
+
+        with(serializerProviderFunction as IrFunction) {
+            // Note that [typeArgs] may be unused if we short-cut to e.g. SealedClassSerializer
+            return irInvoke(
+                irGetObject(companionClass),
+                symbol,
+                typeArgs.takeIf { it.size == typeParameters.size }.orEmpty(),
+                adjustedArgs.takeIf { it.size == valueParameters.size }.orEmpty()
+            )
+        }
+    }
+
+    // Does not use sti and therefore does not perform encoder calls optimization
+    fun IrBuilderWithScope.serializerTower(
+        generator: SerializerIrGenerator,
+        dispatchReceiverParameter: IrValueParameter,
+        property: IrSerializableProperty
+    ): IrExpression? {
+        val nullableSerClass = compilerContext.referenceProperties(SerialEntityNames.wrapIntoNullableCallableId).single()
+        val serializer =
+            property.serializableWith(compilerContext)
+                ?: if (!property.type.isTypeParameter()) generator.findTypeSerializerOrContext(
+                    compilerContext,
+                    property.type
+                ) else null
+        return serializerInstance(
+            serializer,
+            compilerContext,
+            property.type,
+            genericIndex = property.genericIndex
+        ) { it, _ ->
+            val (_, ir) = generator.localSerializersFieldsDescriptors[it]
+            irGetField(irGet(dispatchReceiverParameter), ir.backingField!!)
+        }?.let { expr -> wrapWithNullableSerializerIfNeeded(property.type, expr, nullableSerClass) }
+    }
+
+    private fun IrBuilderWithScope.wrapWithNullableSerializerIfNeeded(
+        type: IrType,
+        expression: IrExpression,
+        nullableProp: IrPropertySymbol
+    ): IrExpression = if (type.isMarkedNullable()) {
+        val resultType = type.makeNotNull()
+        val typeArguments = listOf(resultType)
+        val callee = nullableProp.owner.getter!!
+
+        val returnType = callee.returnType.substitute(callee.typeParameters, typeArguments)
+
+        irInvoke(
+            callee = callee.symbol,
+            typeArguments = typeArguments,
+            valueArguments = emptyList(),
+            returnTypeHint = returnType
+        ).apply { extensionReceiver = expression }
+    } else {
+        expression
+    }
+
+    fun wrapIrTypeIntoKSerializerIrType(
+        type: IrType,
+        variance: Variance = Variance.INVARIANT
+    ): IrType {
+        val kSerClass = compilerContext.referenceClass(ClassId(SerializationPackages.packageFqName, SerialEntityNames.KSERIALIZER_NAME))
+            ?: error("Couldn't find class ${SerialEntityNames.KSERIALIZER_NAME}")
+        return IrSimpleTypeImpl(
+            kSerClass, hasQuestionMark = false, arguments = listOf(
+                makeTypeProjection(type, variance)
+            ), annotations = emptyList()
+        )
+    }
+
+    fun IrBuilderWithScope.serializerInstance(
+        serializerClassOriginal: IrClassSymbol?,
+        pluginContext: SerializationPluginContext,
+        kType: IrType,
+        genericIndex: Int? = null,
+        genericGetter: ((Int, IrType) -> IrExpression)? = null
+    ): IrExpression? {
+        val nullableSerClass = compilerContext.referenceProperties(SerialEntityNames.wrapIntoNullableCallableId).single()
+        if (serializerClassOriginal == null) {
+            if (genericIndex == null) return null
+            return genericGetter?.invoke(genericIndex, kType)
+        }
+        if (serializerClassOriginal.owner.kind == ClassKind.OBJECT) {
+            return irGetObject(serializerClassOriginal)
+        }
+        fun instantiate(serializer: IrClassSymbol?, type: IrType): IrExpression? {
+            val expr = serializerInstance(
+                serializer,
+                pluginContext,
+                type,
+                type.genericIndex,
+                genericGetter
+            ) ?: return null
+            return wrapWithNullableSerializerIfNeeded(type, expr, nullableSerClass)
+        }
+
+        var serializerClass = serializerClassOriginal
+        var args: List<IrExpression>
+        var typeArgs: List<IrType>
+        val thisIrType = (kType as? IrSimpleType) ?: error("Don't know how to work with type ${kType::class}")
+        var needToCopyAnnotations = false
+
+        when (serializerClassOriginal.owner.classId) {
+            polymorphicSerializerId -> {
+                needToCopyAnnotations = true
+                args = listOf(classReference(kType))
+                typeArgs = listOf(thisIrType)
+            }
+            contextSerializerId -> {
+                args = listOf(classReference(kType))
+                typeArgs = listOf(thisIrType)
+
+                val hasNewCtxSerCtor = compilerContext.referenceConstructors(contextSerializerId).any { it.owner.valueParameters.size == 3 }
+
+                if (hasNewCtxSerCtor) {
+                    // new signature of context serializer
+                    args = args + mutableListOf<IrExpression>().apply {
+                        val fallbackDefaultSerializer = findTypeSerializer(pluginContext, kType)
+                        add(instantiate(fallbackDefaultSerializer, kType) ?: irNull())
+                        add(
+                            createArrayOfExpression(
+                                wrapIrTypeIntoKSerializerIrType(
+                                    thisIrType,
+                                    variance = Variance.OUT_VARIANCE
+                                ),
+                                thisIrType.arguments.map {
+                                    val argSer = findTypeSerializerOrContext(
+                                        compilerContext,
+                                        it.typeOrNull!! //todo: handle star projections here?
+                                    )
+                                    instantiate(argSer, it.typeOrNull!!)!!
+                                })
+                        )
+                    }
+                }
+            }
+            objectSerializerId -> {
+                needToCopyAnnotations = true
+                args = listOf(irString(kType.serialName()), irGetObject(kType.classOrNull!!))
+                typeArgs = listOf(thisIrType)
+            }
+            sealedSerializerId -> {
+                needToCopyAnnotations = true
+                args = mutableListOf<IrExpression>().apply {
+                    add(irString(kType.serialName()))
+                    add(classReference(kType))
+                    val (subclasses, subSerializers) = allSealedSerializableSubclassesFor(
+                        kType.classOrNull!!.owner,
+                        pluginContext
+                    )
+                    val projectedOutCurrentKClass =
+                        compilerContext.irBuiltIns.kClassClass.typeWithArguments(
+                            listOf(makeTypeProjection(thisIrType, Variance.OUT_VARIANCE))
+                        )
+                    add(
+                        createArrayOfExpression(
+                            projectedOutCurrentKClass,
+                            subclasses.map { classReference(it) }
+                        )
+                    )
+                    add(
+                        createArrayOfExpression(
+                            wrapIrTypeIntoKSerializerIrType(thisIrType, variance = Variance.OUT_VARIANCE),
+                            subSerializers.mapIndexed { i, serializer ->
+                                val type = subclasses[i]
+                                val expr = serializerInstance(
+                                    serializer,
+                                    pluginContext,
+                                    type,
+                                    type.genericIndex
+                                ) { _, genericType ->
+                                    serializerInstance(
+                                        pluginContext.referenceClass(polymorphicSerializerId),
+                                        pluginContext,
+                                        (genericType.classifierOrNull as IrTypeParameterSymbol).owner.representativeUpperBound
+                                    )!!
+                                }!!
+                                wrapWithNullableSerializerIfNeeded(type, expr, nullableSerClass)
+                            }
+                        )
+                    )
+                }
+                typeArgs = listOf(thisIrType)
+            }
+            enumSerializerId -> {
+                serializerClass = pluginContext.referenceClass(enumSerializerId)
+                val enumDescriptor = kType.classOrNull!!
+                typeArgs = listOf(thisIrType)
+                // instantiate serializer only inside enum Companion
+                if (this@BaseIrGenerator !is SerializableCompanionIrGenerator) {
+                    // otherwise call Companion.serializer()
+                    callSerializerFromCompanion(thisIrType, typeArgs, emptyList())?.let { return it }
+                }
+
+                val enumArgs = mutableListOf(
+                    irString(thisIrType.serialName()),
+                    irCall(enumDescriptor.owner.findEnumValuesMethod()),
+                )
+
+                val enumSerializerFactoryFunc = enumSerializerFactoryFunc
+                val markedEnumSerializerFactoryFunc = markedEnumSerializerFactoryFunc
+                if (enumSerializerFactoryFunc != null && markedEnumSerializerFactoryFunc != null) {
+                    // runtime contains enum serializer factory functions
+                    val factoryFunc: IrSimpleFunctionSymbol = if (enumDescriptor.owner.isEnumWithSerialInfoAnnotation()) {
+                        // need to store SerialInfo annotation in descriptor
+                        val enumEntries = enumDescriptor.owner.enumEntries()
+                        val entriesNames = enumEntries.map { it.annotations.serialNameValue?.let { n -> irString(n) } ?: irNull() }
+                        val entriesAnnotations = enumEntries.map {
+                            val annotationConstructors = it.annotations.map { a ->
+                                a.deepCopyWithVariables()
+                            }
+                            val annotationsConstructors = copyAnnotationsFrom(annotationConstructors)
+                            if (annotationsConstructors.isEmpty()) {
+                                irNull()
+                            } else {
+                                createArrayOfExpression(compilerContext.irBuiltIns.annotationType, annotationsConstructors)
+                            }
+                        }
+                        val annotationArrayType =
+                            compilerContext.irBuiltIns.arrayClass.typeWith(compilerContext.irBuiltIns.annotationType.makeNullable())
+
+                        enumArgs += createArrayOfExpression(compilerContext.irBuiltIns.stringType.makeNullable(), entriesNames)
+                        enumArgs += createArrayOfExpression(annotationArrayType, entriesAnnotations)
+
+                        markedEnumSerializerFactoryFunc
+                    } else {
+                        enumSerializerFactoryFunc
+                    }
+
+                    val factoryReturnType = factoryFunc.owner.returnType.substitute(factoryFunc.owner.typeParameters, typeArgs)
+                    return irInvoke(null, factoryFunc, typeArgs, enumArgs, factoryReturnType)
+                } else {
+                    // support legacy serializer instantiation by constructor for old runtimes
+                    args = enumArgs
+                }
+            }
+            else -> {
+                args = kType.arguments.map {
+                    val argSer = findTypeSerializerOrContext(
+                        pluginContext,
+                        it.typeOrNull!! // todo: stars?
+                    )
+                    instantiate(argSer, it.typeOrNull!!) ?: return null
+                }
+                typeArgs = kType.arguments.map { it.typeOrNull!! }
+            }
+
+        }
+        if (serializerClassOriginal.owner.classId == referenceArraySerializerId) {
+            args = listOf(wrapperClassReference(kType.arguments.single().typeOrNull!!)) + args
+            typeArgs = listOf(typeArgs[0].makeNotNull()) + typeArgs
+        }
+
+        // If KType is interface, .classSerializer always yields PolymorphicSerializer, which may be unavailable for interfaces from other modules
+        if (!kType.isInterface() && serializerClassOriginal == kType.classOrNull!!.owner.classSerializer(pluginContext) && this@BaseIrGenerator !is SerializableCompanionIrGenerator) {
+            // This is default type serializer, we can shortcut through Companion.serializer()
+            // BUT not during generation of this method itself
+            callSerializerFromCompanion(thisIrType, typeArgs, args)?.let { return it }
+        }
+
+
+        val serializable = serializerClass?.owner?.let { getSerializableClassDescriptorBySerializer(it) }
+        requireNotNull(serializerClass)
+        val ctor = if (serializable?.typeParameters?.isNotEmpty() == true) {
+            requireNotNull(
+                findSerializerConstructorForTypeArgumentsSerializers(serializerClass.owner)
+            ) { "Generated serializer does not have constructor with required number of arguments" }
+        } else {
+            val constructors = serializerClass.constructors
+            // search for new signature of polymorphic/sealed/contextual serializer
+            if (!needToCopyAnnotations) {
+                constructors.single { it.owner.isPrimary }
+            } else {
+                constructors.find { it.owner.lastArgumentIsAnnotationArray() } ?: run {
+                    // not found - we are using old serialization runtime without this feature
+                    // todo: optimize allocating an empty array when no annotations defined, maybe use old constructor?
+                    needToCopyAnnotations = false
+                    constructors.single { it.owner.isPrimary }
+                }
+            }
+        }
+        // Return type should be correctly substituted
+        assert(ctor.isBound)
+        val ctorDecl = ctor.owner
+        if (needToCopyAnnotations) {
+            val classAnnotations = copyAnnotationsFrom(thisIrType.getClass()?.let { collectSerialInfoAnnotations(it) }.orEmpty())
+            args = args + createArrayOfExpression(compilerContext.irBuiltIns.annotationType, classAnnotations)
+        }
+
+        val typeParameters = ctorDecl.parentAsClass.typeParameters
+        val substitutedReturnType = ctorDecl.returnType.substitute(typeParameters, typeArgs)
+        return irInvoke(
+            null,
+            ctor,
+            // User may declare serializer with fixed type arguments, e.g. class SomeSerializer : KSerializer<ClosedRange<Float>>
+            typeArguments = typeArgs.takeIf { it.size == ctorDecl.typeParameters.size }.orEmpty(),
+            valueArguments = args.takeIf { it.size == ctorDecl.valueParameters.size }.orEmpty(),
+            returnTypeHint = substitutedReturnType
+        )
+    }
+
+}
\ No newline at end of file
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/DefaultValuesUtils.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/DefaultValuesUtils.kt
new file mode 100644
index 0000000..43c07c6
--- /dev/null
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/DefaultValuesUtils.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlinx.serialization.compiler.backend.ir
+
+import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
+import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
+import org.jetbrains.kotlin.ir.builders.irGet
+import org.jetbrains.kotlin.ir.builders.irGetField
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrProperty
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.deepCopyWithVariables
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
+import org.jetbrains.kotlin.ir.expressions.IrGetValue
+import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
+import org.jetbrains.kotlin.ir.util.constructors
+import org.jetbrains.kotlin.ir.util.properties
+import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
+
+fun IrBuilderWithScope.getProperty(receiver: IrExpression, property: IrProperty): IrExpression {
+    return if (property.getter != null)
+        irGet(property.getter!!.returnType, receiver, property.getter!!.symbol)
+    else
+        irGetField(receiver, property.backingField!!)
+}
+
+/*
+  Create a function that creates `get property value expressions` for given corresponded constructor's param
+    (constructor_params) -> get_property_value_expression
+ */
+fun IrBuilderWithScope.createPropertyByParamReplacer(
+    irClass: IrClass,
+    serialProperties: List<IrSerializableProperty>,
+    instance: IrValueParameter
+): (ValueParameterDescriptor) -> IrExpression? {
+    fun IrSerializableProperty.irGet(): IrExpression {
+        val ownerType = instance.symbol.owner.type
+        return getProperty(
+            irGet(
+                type = ownerType,
+                variable = instance.symbol
+            ), ir
+        )
+    }
+
+    val serialPropertiesMap = serialProperties.associateBy { it.ir }
+
+    val transientPropertiesSet =
+        irClass.declarations.asSequence()
+            .filterIsInstance<IrProperty>()
+            .filter { it.backingField != null }
+            .filter { !serialPropertiesMap.containsKey(it) }
+            .toSet()
+
+    return { vpd ->
+        val propertyDescriptor = irClass.properties.find { it.name == vpd.name }
+        if (propertyDescriptor != null) {
+            val value = serialPropertiesMap[propertyDescriptor]
+            value?.irGet() ?: run {
+                if (propertyDescriptor in transientPropertiesSet)
+                    getProperty(
+                        irGet(instance),
+                        propertyDescriptor
+                    )
+                else null
+            }
+        } else {
+            null
+        }
+    }
+}
+
+/*
+    Creates an initializer adapter function that can replace IR expressions of getting constructor parameter value by some other expression.
+    Also adapter may replace IR expression of getting `this` value by another expression.
+     */
+fun createInitializerAdapter(
+    irClass: IrClass,
+    paramGetReplacer: (ValueParameterDescriptor) -> IrExpression?,
+    thisGetReplacer: Pair<IrValueSymbol, () -> IrExpression>? = null
+): (IrExpressionBody) -> IrExpression {
+    val initializerTransformer = object : IrElementTransformerVoid() {
+        // try to replace `get some value` expression
+        override fun visitGetValue(expression: IrGetValue): IrExpression {
+            val symbol = expression.symbol
+            if (thisGetReplacer != null && thisGetReplacer.first == symbol) {
+                // replace `get this value` expression
+                return thisGetReplacer.second()
+            }
+
+            val descriptor = symbol.descriptor
+            if (descriptor is ValueParameterDescriptor) {
+                // replace `get parameter value` expression
+                paramGetReplacer(descriptor)?.let { return it }
+            }
+
+            // otherwise leave expression as it is
+            return super.visitGetValue(expression)
+        }
+    }
+    val defaultsMap = extractDefaultValuesFromConstructor(irClass)
+    return fun(initializer: IrExpressionBody): IrExpression {
+        val rawExpression = initializer.expression
+        val expression =
+            if (rawExpression.isInitializePropertyFromParameter()) {
+                // this is a primary constructor property, use corresponding default of value parameter
+                defaultsMap.getValue((rawExpression as IrGetValue).symbol)!!
+            } else {
+                rawExpression
+            }
+        return expression.deepCopyWithVariables().transform(initializerTransformer, null)
+    }
+}
+
+private fun extractDefaultValuesFromConstructor(irClass: IrClass?): Map<IrValueSymbol, IrExpression?> {
+    if (irClass == null) return emptyMap()
+    val original = irClass.constructors.singleOrNull { it.isPrimary }
+    // default arguments of original constructor
+    val defaultsMap: Map<IrValueSymbol, IrExpression?> =
+        original?.valueParameters?.associate { it.symbol to it.defaultValue?.expression } ?: emptyMap()
+    return defaultsMap + extractDefaultValuesFromConstructor(irClass.getSuperClassNotAny())
+}
\ No newline at end of file
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt
deleted file mode 100644
index 9f6861a..0000000
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt
+++ /dev/null
@@ -1,1367 +0,0 @@
-/*
- * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
- * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
- */
-
-package org.jetbrains.kotlinx.serialization.compiler.backend.ir
-
-import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI
-import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
-import org.jetbrains.kotlin.backend.common.lower.irIfThen
-import org.jetbrains.kotlin.backend.jvm.functionByName
-import org.jetbrains.kotlin.backend.jvm.ir.representativeUpperBound
-import org.jetbrains.kotlin.builtins.KotlinBuiltIns
-import org.jetbrains.kotlin.builtins.StandardNames
-import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.ir.builders.*
-import org.jetbrains.kotlin.ir.builders.declarations.buildFun
-import org.jetbrains.kotlin.ir.declarations.*
-import org.jetbrains.kotlin.ir.deepCopyWithVariables
-import org.jetbrains.kotlin.ir.expressions.*
-import org.jetbrains.kotlin.ir.expressions.impl.*
-import org.jetbrains.kotlin.ir.symbols.*
-import org.jetbrains.kotlin.ir.symbols.impl.*
-import org.jetbrains.kotlin.ir.types.*
-import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
-import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
-import org.jetbrains.kotlin.ir.util.*
-import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
-import org.jetbrains.kotlin.name.CallableId
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.platform.jvm.isJvm
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
-import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.TypeProjectionImpl
-import org.jetbrains.kotlin.types.Variance
-import org.jetbrains.kotlin.types.replace
-import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
-import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
-import org.jetbrains.kotlin.util.OperatorNameConventions
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
-import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
-import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
-import org.jetbrains.kotlinx.serialization.compiler.resolve.*
-import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_FQ
-import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_MODE_FQ
-import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_PUBLICATION_MODE_NAME
-
-interface IrBuilderExtension {
-    val compilerContext: SerializationPluginContext
-
-    private val throwMissedFieldExceptionFunc
-        get() = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.SINGLE_MASK_FIELD_MISSING_FUNC_NAME)).singleOrNull()
-
-    private val throwMissedFieldExceptionArrayFunc
-        get() = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.ARRAY_MASK_FIELD_MISSING_FUNC_NAME)).singleOrNull()
-
-    private val enumSerializerFactoryFunc
-        get() = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.ENUM_SERIALIZER_FACTORY_FUNC_NAME)).singleOrNull()
-
-    private val markedEnumSerializerFactoryFunc
-        get() = compilerContext.referenceFunctions(CallableId(SerializationPackages.internalPackageFqName, SerialEntityNames.MARKED_ENUM_SERIALIZER_FACTORY_FUNC_NAME)).singleOrNull()
-
-    private inline fun <reified T : IrDeclaration> IrClass.searchForDeclaration(descriptor: DeclarationDescriptor): T? {
-        return declarations.singleOrNull { it.descriptor == descriptor } as? T
-    }
-
-    fun useFieldMissingOptimization(): Boolean {
-        return throwMissedFieldExceptionFunc != null && throwMissedFieldExceptionArrayFunc != null
-    }
-
-    fun <F: IrFunction> addFunctionBody(function: F, bodyGen: IrBlockBodyBuilder.(F) -> Unit) {
-        val parentClass = function.parent
-        val startOffset = function.startOffset.takeIf { it >= 0 } ?: parentClass.startOffset
-        val endOffset = function.endOffset.takeIf { it >= 0 } ?: parentClass.endOffset
-        function.body = DeclarationIrBuilder(compilerContext, function.symbol, startOffset, endOffset).irBlockBody(
-            startOffset,
-            endOffset
-        ) { bodyGen(function) }
-    }
-
-    fun IrClass.contributeFunction(descriptor: FunctionDescriptor, ignoreWhenMissing: Boolean = false, bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit) {
-        val f: IrSimpleFunction = searchForDeclaration(descriptor)
-            ?: (if (ignoreWhenMissing) return else compilerContext.symbolTable.referenceSimpleFunction(descriptor).owner)
-        f.body = DeclarationIrBuilder(compilerContext, f.symbol, this.startOffset, this.endOffset).irBlockBody(
-            this.startOffset,
-            this.endOffset
-        ) { bodyGen(f) }
-    }
-
-    fun IrClass.contributeConstructor(
-        descriptor: ClassConstructorDescriptor,
-        declareNew: Boolean = true,
-        overwriteValueParameters: Boolean = false,
-        bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
-    ) {
-        val c: IrConstructor = searchForDeclaration(descriptor) ?: compilerContext.symbolTable.referenceConstructor(descriptor).owner
-        c.body = DeclarationIrBuilder(compilerContext, c.symbol, this.startOffset, this.endOffset).irBlockBody(
-            this.startOffset,
-            this.endOffset
-        ) { bodyGen(c) }
-    }
-
-    fun IrClass.createLambdaExpression(
-        type: IrType,
-        bodyGen: IrBlockBodyBuilder.() -> Unit
-    ): IrFunctionExpression {
-        val function = compilerContext.irFactory.buildFun {
-            this.startOffset = this@createLambdaExpression.startOffset
-            this.endOffset = this@createLambdaExpression.endOffset
-            this.returnType = type
-            name = Name.identifier("<anonymous>")
-            visibility = DescriptorVisibilities.LOCAL
-            origin = SERIALIZABLE_PLUGIN_ORIGIN
-        }
-        function.body =
-            DeclarationIrBuilder(compilerContext, function.symbol, startOffset, endOffset).irBlockBody(startOffset, endOffset, bodyGen)
-        function.parent = this
-
-        val f0Type = compilerContext.irBuiltIns.functionN(0)
-        val f0ParamSymbol = f0Type.typeParameters[0].symbol
-        val f0IrType = f0Type.defaultType.substitute(mapOf(f0ParamSymbol to type))
-
-        return IrFunctionExpressionImpl(
-            startOffset,
-            endOffset,
-            f0IrType,
-            function,
-            IrStatementOrigin.LAMBDA
-        )
-    }
-
-    fun createLazyProperty(
-        containingClass: IrClass,
-        targetIrType: IrType,
-        name: Name,
-        initializerBuilder: IrBlockBodyBuilder.() -> Unit
-    ): IrProperty {
-        val lazySafeModeClassDescriptor = compilerContext.referenceClass(ClassId.topLevel(LAZY_MODE_FQ))!!.owner
-        val lazyFunctionSymbol = compilerContext.referenceFunctions(CallableId(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("lazy"))).single {
-            it.owner.valueParameters.size == 2 && it.owner.valueParameters[0].type == lazySafeModeClassDescriptor.defaultType
-        }
-        val publicationEntryDescriptor = lazySafeModeClassDescriptor.enumEntries().single { it.name == LAZY_PUBLICATION_MODE_NAME }
-
-        val lazyIrClass = compilerContext.referenceClass(ClassId.topLevel(LAZY_FQ))!!.owner
-        val lazyIrType = lazyIrClass.defaultType.substitute(mapOf(lazyIrClass.typeParameters[0].symbol to targetIrType))
-
-        val propertyDescriptor =
-            KSerializerDescriptorResolver.createValPropertyDescriptor(
-                Name.identifier(name.asString() + "\$delegate"),
-                containingClass.descriptor,
-                lazyIrType.toKotlinType(),
-                createGetter = true
-            )
-
-        return generateSimplePropertyWithBackingField(propertyDescriptor, containingClass).apply {
-            val builder = DeclarationIrBuilder(compilerContext, containingClass.symbol, startOffset, endOffset)
-            val initializerBody = builder.run {
-                val enumElement = IrGetEnumValueImpl(
-                    startOffset,
-                    endOffset,
-                    lazySafeModeClassDescriptor.defaultType,
-                    publicationEntryDescriptor.symbol
-                )
-
-                val lambdaExpression = containingClass.createLambdaExpression(targetIrType, initializerBuilder)
-
-                irExprBody(
-                    irInvoke(null, lazyFunctionSymbol, listOf(targetIrType), listOf(enumElement, lambdaExpression), lazyIrType)
-                )
-            }
-            backingField!!.initializer = initializerBody
-        }
-    }
-
-    fun createCompanionValProperty(
-        companionClass: IrClass,
-        type: IrType,
-        name: Name,
-        initializerBuilder: IrBlockBodyBuilder.() -> Unit
-    ): IrProperty {
-        val targetKotlinType = type.toKotlinType()
-        val propertyDescriptor =
-            KSerializerDescriptorResolver.createValPropertyDescriptor(name, companionClass.descriptor, targetKotlinType)
-
-        return generateSimplePropertyWithBackingField(propertyDescriptor, companionClass, name).apply {
-            companionClass.contributeAnonymousInitializer {
-                val irBlockBody = irBlockBody(startOffset, endOffset, initializerBuilder)
-                irBlockBody.statements.dropLast(1).forEach { +it }
-                val expression = irBlockBody.statements.last() as? IrExpression
-                    ?: throw AssertionError("Last statement in property initializer builder is not an a expression")
-                +irSetField(irGetObject(companionClass), backingField!!, expression)
-            }
-        }
-    }
-
-    fun IrClass.contributeAnonymousInitializer(bodyGen: IrBlockBodyBuilder.() -> Unit) {
-        val symbol = IrAnonymousInitializerSymbolImpl(descriptor)
-        factory.createAnonymousInitializer(startOffset, endOffset, SERIALIZABLE_PLUGIN_ORIGIN, symbol).also {
-            it.parent = this
-            declarations.add(it)
-            it.body = DeclarationIrBuilder(compilerContext, symbol, startOffset, endOffset).irBlockBody(startOffset, endOffset, bodyGen)
-        }
-    }
-
-    fun IrBlockBodyBuilder.getLazyValueExpression(thisParam: IrValueParameter, property: IrProperty, type: IrType): IrExpression {
-        val lazyIrClass = compilerContext.referenceClass(ClassId.topLevel(LAZY_FQ))!!.owner
-        val valueGetter = lazyIrClass.getPropertyGetter("value")!!
-
-        val propertyGetter = property.getter!!
-
-        return irInvoke(
-            irGet(propertyGetter.returnType, irGet(thisParam), propertyGetter.symbol),
-            valueGetter,
-            typeHint = type
-        )
-    }
-
-    fun IrBuilderWithScope.irInvoke(
-        dispatchReceiver: IrExpression? = null,
-        callee: IrFunctionSymbol,
-        vararg args: IrExpression,
-        typeHint: IrType? = null
-    ): IrMemberAccessExpression<*> {
-        assert(callee.isBound) { "Symbol $callee expected to be bound" }
-        val returnType = typeHint ?: callee.owner.returnType
-        val call = irCall(callee, type = returnType)
-        call.dispatchReceiver = dispatchReceiver
-        args.forEachIndexed(call::putValueArgument)
-        return call
-    }
-
-    fun IrBuilderWithScope.irInvoke(
-        dispatchReceiver: IrExpression? = null,
-        callee: IrFunctionSymbol,
-        typeArguments: List<IrType?>,
-        valueArguments: List<IrExpression>,
-        returnTypeHint: IrType? = null
-    ): IrMemberAccessExpression<*> =
-        irInvoke(
-            dispatchReceiver,
-            callee,
-            *valueArguments.toTypedArray(),
-            typeHint = returnTypeHint
-        ).also { call -> typeArguments.forEachIndexed(call::putTypeArgument) }
-
-    fun IrBuilderWithScope.createArrayOfExpression(
-        arrayElementType: IrType,
-        arrayElements: List<IrExpression>
-    ): IrExpression {
-
-        val arrayType = compilerContext.irBuiltIns.arrayClass.typeWith(arrayElementType)
-        val arg0 = IrVarargImpl(startOffset, endOffset, arrayType, arrayElementType, arrayElements)
-        val typeArguments = listOf(arrayElementType)
-
-        return irCall(compilerContext.irBuiltIns.arrayOf, arrayType, typeArguments = typeArguments).apply {
-            putValueArgument(0, arg0)
-        }
-    }
-
-    fun IrBuilderWithScope.createPrimitiveArrayOfExpression(
-        elementPrimitiveType: IrType,
-        arrayElements: List<IrExpression>
-    ): IrExpression {
-        val arrayType = compilerContext.irBuiltIns.primitiveArrayForType.getValue(elementPrimitiveType).defaultType
-        val arg0 = IrVarargImpl(startOffset, endOffset, arrayType, elementPrimitiveType, arrayElements)
-        val typeArguments = listOf(elementPrimitiveType)
-
-        return irCall(compilerContext.irBuiltIns.arrayOf, arrayType, typeArguments = typeArguments).apply {
-            putValueArgument(0, arg0)
-        }
-    }
-
-    fun IrBuilderWithScope.irBinOp(name: Name, lhs: IrExpression, rhs: IrExpression): IrExpression {
-        val classFqName = (lhs.type as IrSimpleType).classOrNull!!.owner.fqNameWhenAvailable!!
-        val symbol = compilerContext.referenceFunctions(CallableId(ClassId.topLevel(classFqName), name)).single()
-        return irInvoke(lhs, symbol, rhs)
-    }
-
-    fun IrBuilderWithScope.irGetObject(irObject: IrClass) =
-        IrGetObjectValueImpl(
-            startOffset,
-            endOffset,
-            irObject.defaultType,
-            irObject.symbol
-        )
-
-    fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
-        also { irDeclaration ->
-            compilerContext.symbolTable.withReferenceScope(irDeclaration) {
-                builder(irDeclaration)
-            }
-        }
-
-    class BranchBuilder(
-        val irWhen: IrWhen,
-        context: IrGeneratorContext,
-        scope: Scope,
-        startOffset: Int,
-        endOffset: Int
-    ) : IrBuilderWithScope(context, scope, startOffset, endOffset) {
-        operator fun IrBranch.unaryPlus() {
-            irWhen.branches.add(this)
-        }
-    }
-
-    fun IrBuilderWithScope.irWhen(typeHint: IrType? = null, block: BranchBuilder.() -> Unit): IrWhen {
-        val whenExpr = IrWhenImpl(startOffset, endOffset, typeHint ?: compilerContext.irBuiltIns.unitType)
-        val builder = BranchBuilder(whenExpr, context, scope, startOffset, endOffset)
-        builder.block()
-        return whenExpr
-    }
-
-    fun BranchBuilder.elseBranch(result: IrExpression): IrElseBranch =
-        IrElseBranchImpl(
-            IrConstImpl.boolean(result.startOffset, result.endOffset, compilerContext.irBuiltIns.booleanType, true),
-            result
-        )
-
-    @FirIncompatiblePluginAPI
-    fun KotlinType.toIrType() = compilerContext.typeTranslator.translateType(this)
-
-    // note: this method should be used only for properties from current module. Fields from other modules are private and inaccessible.
-    val IrSerializableProperty.irField: IrField?
-        get() = this.descriptor.backingField
-
-
-
-
-    /*
-      Create a function that creates `get property value expressions` for given corresponded constructor's param
-        (constructor_params) -> get_property_value_expression
-     */
-    fun IrBuilderWithScope.createPropertyByParamReplacer(
-        irClass: IrClass,
-        serialProperties: List<IrSerializableProperty>,
-        instance: IrValueParameter
-    ): (ValueParameterDescriptor) -> IrExpression? {
-        fun IrSerializableProperty.irGet(): IrExpression {
-            val ownerType = instance.symbol.owner.type
-            return getProperty(
-                irGet(
-                    type = ownerType,
-                    variable = instance.symbol
-                ), descriptor
-            )
-        }
-
-        val serialPropertiesMap = serialProperties.associateBy { it.descriptor }
-
-        val transientPropertiesSet =
-            irClass.declarations.asSequence()
-                .filterIsInstance<IrProperty>()
-                .filter { it.backingField != null }
-                .filter { !serialPropertiesMap.containsKey(it) }
-                .toSet()
-
-        return { vpd ->
-            val propertyDescriptor = irClass.properties.find { it.name == vpd.name }
-            if (propertyDescriptor != null) {
-                val value = serialPropertiesMap[propertyDescriptor]
-                value?.irGet() ?: run {
-                    if (propertyDescriptor in transientPropertiesSet)
-                        getProperty(
-                            irGet(instance),
-                            propertyDescriptor
-                        )
-                    else null
-                }
-            } else {
-                null
-            }
-        }
-    }
-
-    fun IrBuilderWithScope.getProperty(receiver: IrExpression, property: IrProperty): IrExpression {
-        return if (property.getter != null)
-            irGet(property.getter!!.returnType, receiver, property.getter!!.symbol)
-        else
-            irGetField(receiver, property.backingField!!)
-    }
-
-    fun IrBuilderWithScope.setProperty(receiver: IrExpression, property: IrProperty, value: IrExpression): IrExpression {
-        return if (property.setter != null)
-            irSet(property.setter!!.returnType, receiver, property.setter!!.symbol, value)
-        else
-            irSetField(receiver, property.backingField!!, value)
-    }
-
-    /*
-     The rest of the file is mainly copied from FunctionGenerator.
-     However, I can't use it's directly because all generateSomething methods require KtProperty (psi element)
-     Also, FunctionGenerator itself has DeclarationGenerator as ctor param, which is a part of psi2ir
-     (it can be instantiated here, but I don't know how good is that idea)
-     */
-
-    fun IrBuilderWithScope.generateAnySuperConstructorCall(toBuilder: IrBlockBodyBuilder) {
-        val anyConstructor = compilerContext.irBuiltIns.anyClass.owner.declarations.single { it is IrConstructor } as IrConstructor
-        with(toBuilder) {
-            +IrDelegatingConstructorCallImpl.fromSymbolDescriptor(
-                startOffset, endOffset,
-                compilerContext.irBuiltIns.unitType,
-                anyConstructor.symbol
-            )
-        }
-    }
-
-    fun IrBlockBodyBuilder.generateGoldenMaskCheck(
-        seenVars: List<IrValueDeclaration>,
-        properties: IrSerializableProperties,
-        serialDescriptor: IrExpression
-    ) {
-        val fieldsMissedTest: IrExpression
-        val throwErrorExpr: IrExpression
-
-        val maskSlotCount = seenVars.size
-        if (maskSlotCount == 1) {
-            val goldenMask = properties.goldenMask
-
-
-            throwErrorExpr = irInvoke(
-                null,
-                throwMissedFieldExceptionFunc!!,
-                irGet(seenVars[0]),
-                irInt(goldenMask),
-                serialDescriptor,
-                typeHint = compilerContext.irBuiltIns.unitType
-            )
-
-            fieldsMissedTest = irNotEquals(
-                irInt(goldenMask),
-                irBinOp(
-                    OperatorNameConventions.AND,
-                    irInt(goldenMask),
-                    irGet(seenVars[0])
-                )
-            )
-        } else {
-            val goldenMaskList = properties.goldenMaskList
-
-            var compositeExpression: IrExpression? = null
-            for (i in goldenMaskList.indices) {
-                val singleCheckExpr = irNotEquals(
-                    irInt(goldenMaskList[i]),
-                    irBinOp(
-                        OperatorNameConventions.AND,
-                        irInt(goldenMaskList[i]),
-                        irGet(seenVars[i])
-                    )
-                )
-
-                compositeExpression = if (compositeExpression == null) {
-                    singleCheckExpr
-                } else {
-                    irBinOp(
-                        OperatorNameConventions.OR,
-                        compositeExpression,
-                        singleCheckExpr
-                    )
-                }
-            }
-
-            fieldsMissedTest = compositeExpression!!
-
-            throwErrorExpr = irBlock {
-                +irInvoke(
-                    null,
-                    throwMissedFieldExceptionArrayFunc!!,
-                    createPrimitiveArrayOfExpression(compilerContext.irBuiltIns.intType, goldenMaskList.indices.map { irGet(seenVars[it]) }),
-                    createPrimitiveArrayOfExpression(compilerContext.irBuiltIns.intType, goldenMaskList.map { irInt(it) }),
-                    serialDescriptor,
-                    typeHint = compilerContext.irBuiltIns.unitType
-                )
-            }
-        }
-
-        +irIfThen(compilerContext.irBuiltIns.unitType, fieldsMissedTest, throwErrorExpr)
-    }
-
-    fun generateSimplePropertyWithBackingField(
-        propertyDescriptor: PropertyDescriptor,
-        propertyParent: IrClass,
-        fieldName: Name = propertyDescriptor.name,
-    ): IrProperty {
-        val irProperty = propertyParent.searchForDeclaration(propertyDescriptor) ?: run {
-            with(propertyDescriptor) {
-                propertyParent.factory.createProperty(
-                    propertyParent.startOffset, propertyParent.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrPropertySymbolImpl(propertyDescriptor),
-                    name, visibility, modality, isVar, isConst, isLateInit, isDelegated, isExternal
-                ).also {
-                    it.parent = propertyParent
-                    propertyParent.addMember(it)
-                }
-            }
-        }
-
-        propertyParent.generatePropertyBackingFieldIfNeeded(propertyDescriptor, irProperty, fieldName)
-        val fieldSymbol = irProperty.backingField!!.symbol
-        irProperty.getter = propertyDescriptor.getter?.let {
-            propertyParent.generatePropertyAccessor(propertyDescriptor, irProperty, it, fieldSymbol, isGetter = true)
-        }?.apply { parent = propertyParent }
-        irProperty.setter = propertyDescriptor.setter?.let {
-            propertyParent.generatePropertyAccessor(propertyDescriptor, irProperty, it, fieldSymbol, isGetter = false)
-        }?.apply { parent = propertyParent }
-        return irProperty
-    }
-
-    fun IrType.kClassToJClassIfNeeded(): IrType = this
-
-    fun kClassExprToJClassIfNeeded(startOffset: Int, endOffset: Int, irExpression: IrExpression): IrExpression = irExpression
-
-    private fun IrClass.generatePropertyBackingFieldIfNeeded(
-        propertyDescriptor: PropertyDescriptor,
-        originProperty: IrProperty,
-        name: Name,
-    ) {
-        if (originProperty.backingField != null) return
-
-        val field = with(propertyDescriptor) {
-            // TODO: type parameters
-            @OptIn(FirIncompatiblePluginAPI::class)// should be called only with old FE
-            originProperty.factory.createField(
-                originProperty.startOffset, originProperty.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrFieldSymbolImpl(propertyDescriptor), name, type.toIrType(),
-                visibility, !isVar, isEffectivelyExternal(), dispatchReceiverParameter == null
-            )
-        }
-        field.apply {
-            parent = this@generatePropertyBackingFieldIfNeeded
-            correspondingPropertySymbol = originProperty.symbol
-        }
-
-        originProperty.backingField = field
-    }
-
-    private fun IrClass.generatePropertyAccessor(
-        propertyDescriptor: PropertyDescriptor,
-        property: IrProperty,
-        descriptor: PropertyAccessorDescriptor,
-        fieldSymbol: IrFieldSymbol,
-        isGetter: Boolean,
-    ): IrSimpleFunction {
-        val irAccessor: IrSimpleFunction = when (isGetter) {
-            true -> searchForDeclaration<IrProperty>(propertyDescriptor)?.getter
-            false -> searchForDeclaration<IrProperty>(propertyDescriptor)?.setter
-        } ?: run {
-            with(descriptor) {
-                @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
-                property.factory.createFunction(
-                    fieldSymbol.owner.startOffset, fieldSymbol.owner.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrSimpleFunctionSymbolImpl(descriptor),
-                    name, visibility, modality, returnType!!.toIrType(),
-                    isInline, isEffectivelyExternal(), isTailrec, isSuspend, isOperator, isInfix, isExpect
-                )
-            }.also { f ->
-                generateOverriddenFunctionSymbols(f, compilerContext.symbolTable)
-                f.createParameterDeclarations(descriptor)
-                @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
-                f.returnType = descriptor.returnType!!.toIrType()
-                f.correspondingPropertySymbol = fieldSymbol.owner.correspondingPropertySymbol
-            }
-        }
-
-        irAccessor.body = when (isGetter) {
-            true -> generateDefaultGetterBody(descriptor as PropertyGetterDescriptor, irAccessor)
-            false -> generateDefaultSetterBody(descriptor as PropertySetterDescriptor, irAccessor)
-        }
-
-        return irAccessor
-    }
-
-    private fun generateDefaultGetterBody(
-        getter: PropertyGetterDescriptor,
-        irAccessor: IrSimpleFunction
-    ): IrBlockBody {
-        val property = getter.correspondingProperty
-        val irProperty = irAccessor.correspondingPropertySymbol?.owner ?: error("Expected property for $getter")
-
-        val startOffset = irAccessor.startOffset
-        val endOffset = irAccessor.endOffset
-        val irBody = irAccessor.factory.createBlockBody(startOffset, endOffset)
-
-        val receiver = generateReceiverExpressionForFieldAccess(irAccessor.dispatchReceiverParameter!!.symbol, property)
-
-        val propertyIrType = irAccessor.returnType
-        irBody.statements.add(
-            IrReturnImpl(
-                startOffset, endOffset, compilerContext.irBuiltIns.nothingType,
-                irAccessor.symbol,
-                IrGetFieldImpl(
-                    startOffset, endOffset,
-                    irProperty.backingField?.symbol ?: error("Property expected to have backing field"),
-                    propertyIrType,
-                    receiver
-                ).let {
-                    if (propertyIrType.isKClass()) {
-                        irAccessor.returnType = irAccessor.returnType.kClassToJClassIfNeeded()
-                        kClassExprToJClassIfNeeded(startOffset, endOffset, it)
-                    } else it
-                }
-            )
-        )
-        return irBody
-    }
-
-    private fun generateDefaultSetterBody(
-        setter: PropertySetterDescriptor,
-        irAccessor: IrSimpleFunction
-    ): IrBlockBody {
-        val property = setter.correspondingProperty
-        val irProperty = irAccessor.correspondingPropertySymbol?.owner ?: error("Expected corresponding property for accessor $setter")
-        val startOffset = irAccessor.startOffset
-        val endOffset = irAccessor.endOffset
-        val irBody = irAccessor.factory.createBlockBody(startOffset, endOffset)
-
-        val receiver = generateReceiverExpressionForFieldAccess(irAccessor.dispatchReceiverParameter!!.symbol, property)
-
-        val irValueParameter = irAccessor.valueParameters.single()
-        irBody.statements.add(
-            IrSetFieldImpl(
-                startOffset, endOffset,
-                irProperty.backingField?.symbol ?: error("Property $property expected to have backing field"),
-                receiver,
-                IrGetValueImpl(startOffset, endOffset, irValueParameter.type, irValueParameter.symbol),
-                compilerContext.irBuiltIns.unitType
-            )
-        )
-        return irBody
-    }
-
-    fun generateReceiverExpressionForFieldAccess( // todo: remove this
-        ownerSymbol: IrValueSymbol,
-        property: PropertyDescriptor
-    ): IrExpression {
-        val containingDeclaration = property.containingDeclaration
-        return when (containingDeclaration) {
-            is ClassDescriptor ->
-                IrGetValueImpl(
-                    ownerSymbol.owner.startOffset, ownerSymbol.owner.endOffset,
-                    ownerSymbol
-                )
-            else -> throw AssertionError("Property must be in class")
-        }
-    }
-
-    fun IrFunction.createParameterDeclarations(
-        descriptor: FunctionDescriptor,
-        overwriteValueParameters: Boolean = false,
-        copyTypeParameters: Boolean = true
-    ) {
-        val function = this
-        fun irValueParameter(descriptor: ParameterDescriptor): IrValueParameter = with(descriptor) {
-            @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
-            factory.createValueParameter(
-                function.startOffset, function.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrValueParameterSymbolImpl(this),
-                name, indexOrMinusOne, type.toIrType(), varargElementType?.toIrType(), isCrossinline, isNoinline,
-                isHidden = false, isAssignable = false
-            ).also {
-                it.parent = function
-            }
-        }
-
-        if (copyTypeParameters) {
-            assert(typeParameters.isEmpty())
-            copyTypeParamsFromDescriptor(descriptor)
-        }
-
-        dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let { irValueParameter(it) }
-        extensionReceiverParameter = descriptor.extensionReceiverParameter?.let { irValueParameter(it) }
-
-        if (!overwriteValueParameters)
-            assert(valueParameters.isEmpty())
-
-        valueParameters = descriptor.valueParameters.map { irValueParameter(it) }
-    }
-
-    fun IrFunction.copyTypeParamsFromDescriptor(descriptor: FunctionDescriptor) {
-        val newTypeParameters = descriptor.typeParameters.map {
-            factory.createTypeParameter(
-                startOffset, endOffset,
-                SERIALIZABLE_PLUGIN_ORIGIN,
-                IrTypeParameterSymbolImpl(it),
-                it.name, it.index, it.isReified, it.variance
-            ).also { typeParameter ->
-                typeParameter.parent = this
-            }
-        }
-        @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
-        newTypeParameters.forEach { typeParameter ->
-            typeParameter.superTypes = typeParameter.descriptor.upperBounds.map { it.toIrType() }
-        }
-
-        typeParameters = newTypeParameters
-    }
-
-    fun createClassReference(classType: IrType, startOffset: Int, endOffset: Int): IrClassReference {
-        return IrClassReferenceImpl(
-            startOffset,
-            endOffset,
-            compilerContext.irBuiltIns.kClassClass.starProjectedType,
-            classType.classifierOrFail,
-            classType
-        )
-    }
-
-    // It is impossible to use star projections right away, because Array<Int>::class differ from Array<String>::class :
-    // detailed information about type arguments required for class references on jvm
-    private val KotlinType.approximateJvmErasure: KotlinType
-        get() = when (val classifier = constructor.declarationDescriptor) {
-            is TypeParameterDescriptor -> {
-                // Note that if the upper bound is Array, the argument type will be replaced with star here, which is probably incorrect.
-                classifier.classBound.defaultType.replaceArgumentsWithStarProjections()
-            }
-            is ClassDescriptor -> if (KotlinBuiltIns.isArray(this)) {
-                replace(arguments.map { TypeProjectionImpl(Variance.INVARIANT, it.type.approximateJvmErasure) })
-            } else {
-                replaceArgumentsWithStarProjections()
-            }
-            else -> error("Unsupported classifier: $this")
-        }
-
-    private val TypeParameterDescriptor.classBound: ClassDescriptor
-        get() = when (val bound = representativeUpperBound.constructor.declarationDescriptor) {
-            is ClassDescriptor -> bound
-            is TypeParameterDescriptor -> bound.classBound
-            else -> error("Unsupported classifier: $this")
-        }
-
-
-    fun IrBuilderWithScope.classReference(classSymbol: IrType): IrClassReference =
-        createClassReference(classSymbol, startOffset, endOffset)
-
-    private fun extractDefaultValuesFromConstructor(irClass: IrClass?): Map<IrValueSymbol, IrExpression?> {
-        if (irClass == null) return emptyMap()
-        val original = irClass.constructors.singleOrNull { it.isPrimary }
-        // default arguments of original constructor
-        val defaultsMap: Map<IrValueSymbol, IrExpression?> =
-            original?.valueParameters?.associate { it.symbol to it.defaultValue?.expression } ?: emptyMap()
-        return defaultsMap + extractDefaultValuesFromConstructor(irClass.getSuperClassNotAny())
-    }
-
-    /*
-    Creates an initializer adapter function that can replace IR expressions of getting constructor parameter value by some other expression.
-    Also adapter may replace IR expression of getting `this` value by another expression.
-     */
-    fun createInitializerAdapter(
-        irClass: IrClass,
-        paramGetReplacer: (ValueParameterDescriptor) -> IrExpression?,
-        thisGetReplacer: Pair<IrValueSymbol, () -> IrExpression>? = null
-    ): (IrExpressionBody) -> IrExpression {
-        val initializerTransformer = object : IrElementTransformerVoid() {
-            // try to replace `get some value` expression
-            override fun visitGetValue(expression: IrGetValue): IrExpression {
-                val symbol = expression.symbol
-                if (thisGetReplacer != null && thisGetReplacer.first == symbol) {
-                    // replace `get this value` expression
-                    return thisGetReplacer.second()
-                }
-
-                val descriptor = symbol.descriptor
-                if (descriptor is ValueParameterDescriptor) {
-                    // replace `get parameter value` expression
-                    paramGetReplacer(descriptor)?.let { return it }
-                }
-
-                // otherwise leave expression as it is
-                return super.visitGetValue(expression)
-            }
-        }
-        val defaultsMap = extractDefaultValuesFromConstructor(irClass)
-        return fun(initializer: IrExpressionBody): IrExpression {
-            val rawExpression = initializer.expression
-            val expression =
-                if (rawExpression.isInitializePropertyFromParameter()) {
-                    // this is a primary constructor property, use corresponding default of value parameter
-                     defaultsMap.getValue((rawExpression as IrGetValue).symbol)!!
-                } else {
-                    rawExpression
-                }
-            return expression.deepCopyWithVariables().transform(initializerTransformer, null)
-        }
-    }
-
-    private fun getEnumMembersNames(enumClass: ClassDescriptor): Sequence<String> {
-        assert(enumClass.kind == ClassKind.ENUM_CLASS)
-        return enumClass.unsubstitutedMemberScope.getContributedDescriptors().asSequence()
-            .filterIsInstance<ClassDescriptor>()
-            .filter { it.kind == ClassKind.ENUM_ENTRY }
-            .map { it.name.toString() }
-    }
-
-    fun IrBuilderWithScope.copyAnnotationsFrom(annotations: List<IrConstructorCall>): List<IrExpression> =
-        annotations.mapNotNull { annotationCall ->
-            val annotationClass = annotationCall.symbol.owner.parentAsClass
-            if (!annotationClass.descriptor.isSerialInfoAnnotation) return@mapNotNull null
-
-            if (compilerContext.platform.isJvm()) {
-                val implClass = compilerContext.serialInfoImplJvmIrGenerator.getImplClass(annotationClass)
-                val ctor = implClass.constructors.singleOrNull { it.valueParameters.size == annotationCall.valueArgumentsCount }
-                    ?: error("No constructor args found for SerialInfo annotation Impl class: ${implClass.render()}")
-                irCall(ctor).apply {
-                    for (i in 0 until annotationCall.valueArgumentsCount) {
-                        val argument = annotationCall.getValueArgument(i)
-                            ?: annotationClass.primaryConstructor!!.valueParameters[i].defaultValue?.expression
-                        putValueArgument(i, argument!!.deepCopyWithVariables())
-                    }
-                }
-            } else {
-                annotationCall.deepCopyWithVariables()
-            }
-        }
-
-    // Does not use sti and therefore does not perform encoder calls optimization
-    fun IrBuilderWithScope.serializerTower(
-        generator: SerializerIrGenerator,
-        dispatchReceiverParameter: IrValueParameter,
-        property: IrSerializableProperty
-    ): IrExpression? {
-        val nullableSerClass = compilerContext.referenceProperties(SerialEntityNames.wrapIntoNullableCallableId).single()
-        val serializer =
-            property.serializableWith(compilerContext)
-                ?: if (!property.type.isTypeParameter()) generator.findTypeSerializerOrContext(
-                    compilerContext,
-                    property.type
-                ) else null
-        return serializerInstance(
-            generator,
-            dispatchReceiverParameter,
-            serializer,
-            compilerContext,
-            property.type,
-            genericIndex = property.genericIndex
-        )
-            ?.let { expr -> wrapWithNullableSerializerIfNeeded(property.type, expr, nullableSerClass) }
-    }
-
-    private fun IrBuilderWithScope.wrapWithNullableSerializerIfNeeded(
-        type: IrType,
-        expression: IrExpression,
-        nullableProp: IrPropertySymbol
-    ): IrExpression = if (type.isMarkedNullable()) {
-        val resultType = type.makeNotNull()
-        val typeArguments = listOf(resultType)
-        val callee = nullableProp.owner.getter!!
-
-        val returnType = callee.returnType.substitute(callee.typeParameters, typeArguments)
-
-        irInvoke(
-            callee = callee.symbol,
-            typeArguments = typeArguments,
-            valueArguments = emptyList(),
-            returnTypeHint = returnType
-        ).apply { extensionReceiver = expression }
-    } else {
-        expression
-    }
-
-    fun wrapIrTypeIntoKSerializerIrType(
-        type: IrType,
-        variance: Variance = Variance.INVARIANT
-    ): IrType {
-        val kSerClass = compilerContext.referenceClass(ClassId(SerializationPackages.packageFqName, SerialEntityNames.KSERIALIZER_NAME))
-            ?: error("Couldn't find class ${SerialEntityNames.KSERIALIZER_NAME}")
-        return IrSimpleTypeImpl(
-            kSerClass, hasQuestionMark = false, arguments = listOf(
-                makeTypeProjection(type, variance)
-            ), annotations = emptyList()
-        )
-    }
-
-    fun IrBuilderWithScope.serializerInstance(
-        enclosingGenerator: SerializerIrGenerator,
-        dispatchReceiverParameter: IrValueParameter,
-        serializerClassOriginal: IrClassSymbol?,
-        pluginContext: SerializationPluginContext,
-        kType: IrType,
-        genericIndex: Int? = null
-    ): IrExpression? = serializerInstance(
-        enclosingGenerator,
-        serializerClassOriginal,
-        pluginContext,
-        kType,
-        genericIndex
-    ) { it, _ ->
-        val (_, ir) = enclosingGenerator.localSerializersFieldsDescriptors[it]
-        irGetField(irGet(dispatchReceiverParameter), ir.backingField!!)
-    }
-
-    fun IrBuilderWithScope.serializerInstance(
-        enclosingGenerator: AbstractIrGenerator,
-        serializerClassOriginal: ClassDescriptor?,
-        module: ModuleDescriptor,
-        kType: IrType,
-        genericIndex: Int? = null,
-        genericGetter: ((Int) -> IrExpression)? = null
-    ): IrExpression? {
-        return serializerInstance(
-            enclosingGenerator,
-            serializerClassOriginal?.let { compilerContext.symbolTable.referenceClass(it) },
-            compilerContext,
-            kType,
-            genericIndex,
-            if (genericGetter != null) { i, _ -> genericGetter(i) } else null
-        )
-    }
-
-    fun IrBuilderWithScope.serializerInstance(
-        enclosingGenerator: AbstractIrGenerator,
-        serializerClassOriginal: IrClassSymbol?,
-        pluginContext: SerializationPluginContext,
-        kType: IrType,
-        genericIndex: Int? = null,
-        genericGetter: ((Int, IrType) -> IrExpression)? = null
-    ): IrExpression? {
-        val nullableSerClass = compilerContext.referenceProperties(SerialEntityNames.wrapIntoNullableCallableId).single()
-        if (serializerClassOriginal == null) {
-            if (genericIndex == null) return null
-            return genericGetter?.invoke(genericIndex, kType)
-        }
-        if (serializerClassOriginal.owner.kind == ClassKind.OBJECT) {
-            return irGetObject(serializerClassOriginal)
-        }
-        fun instantiate(serializer: IrClassSymbol?, type: IrType): IrExpression? {
-            val expr = serializerInstance(
-                enclosingGenerator,
-                serializer,
-                pluginContext,
-                type,
-                type.genericIndex,
-                genericGetter
-            ) ?: return null
-            return wrapWithNullableSerializerIfNeeded(type, expr, nullableSerClass)
-        }
-
-        var serializerClass = serializerClassOriginal
-        var args: List<IrExpression>
-        var typeArgs: List<IrType>
-        val thisIrType = (kType as? IrSimpleType) ?: error("Don't know how to work with type ${kType::class}")
-        var needToCopyAnnotations = false
-
-        when (serializerClassOriginal.owner.classId) {
-            polymorphicSerializerId -> {
-                needToCopyAnnotations = true
-                args = listOf(classReference(kType))
-                typeArgs = listOf(thisIrType)
-            }
-            contextSerializerId -> {
-                args = listOf(classReference(kType))
-                typeArgs = listOf(thisIrType)
-
-                val hasNewCtxSerCtor = compilerContext.referenceConstructors(contextSerializerId).any { it.owner.valueParameters.size == 3 }
-
-                if (hasNewCtxSerCtor) {
-                    // new signature of context serializer
-                    args = args + mutableListOf<IrExpression>().apply {
-                        val fallbackDefaultSerializer = findTypeSerializer(pluginContext, kType)
-                        add(instantiate(fallbackDefaultSerializer, kType) ?: irNull())
-                        add(
-                            createArrayOfExpression(
-                                wrapIrTypeIntoKSerializerIrType(
-                                    thisIrType,
-                                    variance = Variance.OUT_VARIANCE
-                                ),
-                                thisIrType.arguments.map {
-                                    val argSer = enclosingGenerator.findTypeSerializerOrContext(
-                                        compilerContext,
-                                        it.typeOrNull!! //todo: handle star projections here?
-                                    )
-                                    instantiate(argSer, it.typeOrNull!!)!!
-                                })
-                        )
-                    }
-                }
-            }
-            objectSerializerId -> {
-                needToCopyAnnotations = true
-                args = listOf(irString(kType.serialName()), irGetObject(kType.classOrNull!!))
-                typeArgs = listOf(thisIrType)
-            }
-            sealedSerializerId -> {
-                needToCopyAnnotations = true
-                args = mutableListOf<IrExpression>().apply {
-                    add(irString(kType.serialName()))
-                    add(classReference(kType))
-                    val (subclasses, subSerializers) = enclosingGenerator.allSealedSerializableSubclassesFor(
-                        kType.classOrNull!!.owner,
-                        pluginContext
-                    )
-                    val projectedOutCurrentKClass =
-                        compilerContext.irBuiltIns.kClassClass.typeWithArguments(
-                            listOf(makeTypeProjection(thisIrType, Variance.OUT_VARIANCE))
-                        )
-                    add(
-                        createArrayOfExpression(
-                            projectedOutCurrentKClass,
-                            subclasses.map { classReference(it) }
-                        )
-                    )
-                    add(
-                        createArrayOfExpression(
-                            wrapIrTypeIntoKSerializerIrType(thisIrType, variance = Variance.OUT_VARIANCE),
-                            subSerializers.mapIndexed { i, serializer ->
-                                val type = subclasses[i]
-                                val expr = serializerInstance(
-                                    enclosingGenerator,
-                                    serializer,
-                                    pluginContext,
-                                    type,
-                                    type.genericIndex
-                                ) { _, genericType ->
-                                    serializerInstance(
-                                        enclosingGenerator,
-                                        pluginContext.referenceClass(polymorphicSerializerId),
-                                        pluginContext,
-                                        (genericType.classifierOrNull as IrTypeParameterSymbol).owner.representativeUpperBound
-                                    )!!
-                                }!!
-                                wrapWithNullableSerializerIfNeeded(type, expr, nullableSerClass)
-                            }
-                        )
-                    )
-                }
-                typeArgs = listOf(thisIrType)
-            }
-            enumSerializerId -> {
-                serializerClass = pluginContext.referenceClass(enumSerializerId)
-                val enumDescriptor = kType.classOrNull!!
-                typeArgs = listOf(thisIrType)
-                // instantiate serializer only inside enum Companion
-                if (enclosingGenerator !is SerializableCompanionIrGenerator) {
-                    // otherwise call Companion.serializer()
-                    callSerializerFromCompanion(thisIrType, typeArgs, emptyList())?.let { return it }
-                }
-
-                val enumArgs = mutableListOf(
-                    irString(thisIrType.serialName()),
-                    irCall(enumDescriptor.owner.findEnumValuesMethod()),
-                )
-
-                val enumSerializerFactoryFunc = enumSerializerFactoryFunc
-                val markedEnumSerializerFactoryFunc = markedEnumSerializerFactoryFunc
-                if (enumSerializerFactoryFunc != null && markedEnumSerializerFactoryFunc != null) {
-                    // runtime contains enum serializer factory functions
-                    val factoryFunc: IrSimpleFunctionSymbol = if (enumDescriptor.owner.isEnumWithSerialInfoAnnotation()) {
-                        // need to store SerialInfo annotation in descriptor
-                        val enumEntries = enumDescriptor.owner.enumEntries()
-                        val entriesNames = enumEntries.map { it.annotations.serialNameValue?.let { n -> irString(n) } ?: irNull() }
-                        val entriesAnnotations = enumEntries.map {
-                            val annotationConstructors = it.annotations.map { a ->
-//                                compilerContext.typeTranslator.constantValueGenerator.generateAnnotationConstructorCall(a)
-                                a.deepCopyWithVariables()
-                            }
-                            val annotationsConstructors = copyAnnotationsFrom(annotationConstructors)
-                            if (annotationsConstructors.isEmpty()) {
-                                irNull()
-                            } else {
-                                createArrayOfExpression(compilerContext.irBuiltIns.annotationType, annotationsConstructors)
-                            }
-                        }
-                        val annotationArrayType =
-                            compilerContext.irBuiltIns.arrayClass.typeWith(compilerContext.irBuiltIns.annotationType.makeNullable())
-
-                        enumArgs += createArrayOfExpression(compilerContext.irBuiltIns.stringType.makeNullable(), entriesNames)
-                        enumArgs += createArrayOfExpression(annotationArrayType, entriesAnnotations)
-
-                        markedEnumSerializerFactoryFunc
-                    } else {
-                        enumSerializerFactoryFunc
-                    }
-
-                    val factoryReturnType = factoryFunc.owner.returnType.substitute(factoryFunc.owner.typeParameters, typeArgs)
-                    return irInvoke(null, factoryFunc, typeArgs, enumArgs, factoryReturnType)
-                } else {
-                    // support legacy serializer instantiation by constructor for old runtimes
-                    args = enumArgs
-                }
-            }
-            else -> {
-                args = kType.arguments.map {
-                    val argSer = enclosingGenerator.findTypeSerializerOrContext(
-                        pluginContext,
-                        it.typeOrNull!! // todo: stars?
-                    )
-                    instantiate(argSer, it.typeOrNull!!) ?: return null
-                }
-                typeArgs = kType.arguments.map { it.typeOrNull!! }
-            }
-
-        }
-        if (serializerClassOriginal.owner.classId == referenceArraySerializerId) {
-            args = listOf(wrapperClassReference(kType.arguments.single().typeOrNull!!)) + args
-            typeArgs = listOf(typeArgs[0].makeNotNull()) + typeArgs
-        }
-
-        // If KType is interface, .classSerializer always yields PolymorphicSerializer, which may be unavailable for interfaces from other modules
-        if (!kType.isInterface() && serializerClassOriginal == kType.classOrNull!!.owner.classSerializer(pluginContext) && enclosingGenerator !is SerializableCompanionIrGenerator) {
-            // This is default type serializer, we can shortcut through Companion.serializer()
-            // BUT not during generation of this method itself
-            callSerializerFromCompanion(thisIrType, typeArgs, args)?.let { return it }
-        }
-
-
-        val serializable = serializerClass?.owner?.let { getSerializableClassDescriptorBySerializer(it) }
-        requireNotNull(serializerClass)
-        val ctor = if (serializable?.typeParameters?.isNotEmpty() == true) {
-            requireNotNull(
-                findSerializerConstructorForTypeArgumentsSerializers(serializerClass.owner)
-            ) { "Generated serializer does not have constructor with required number of arguments" }
-        } else {
-            val constructors = serializerClass.constructors
-            // search for new signature of polymorphic/sealed/contextual serializer
-            if (!needToCopyAnnotations) {
-                constructors.single { it.owner.isPrimary }
-            } else {
-                constructors.find { it.owner.lastArgumentIsAnnotationArray() } ?: run {
-                    // not found - we are using old serialization runtime without this feature
-                    // todo: optimize allocating an empty array when no annotations defined, maybe use old constructor?
-                    needToCopyAnnotations = false
-                    constructors.single { it.owner.isPrimary }
-                }
-            }
-        }
-        // Return type should be correctly substituted
-        assert(ctor.isBound)
-        val ctorDecl = ctor.owner
-        if (needToCopyAnnotations) {
-            val classAnnotations = copyAnnotationsFrom(thisIrType.getClass()?.let { collectSerialInfoAnnotations(it) }.orEmpty())
-            args = args + createArrayOfExpression(compilerContext.irBuiltIns.annotationType, classAnnotations)
-        }
-
-        val typeParameters = ctorDecl.parentAsClass.typeParameters
-        val substitutedReturnType = ctorDecl.returnType.substitute(typeParameters, typeArgs)
-        return irInvoke(
-            null,
-            ctor,
-            // User may declare serializer with fixed type arguments, e.g. class SomeSerializer : KSerializer<ClosedRange<Float>>
-            typeArguments = typeArgs.takeIf { it.size == ctorDecl.typeParameters.size }.orEmpty(),
-            valueArguments = args.takeIf { it.size == ctorDecl.valueParameters.size }.orEmpty(),
-            returnTypeHint = substitutedReturnType
-        )
-    }
-
-    fun collectSerialInfoAnnotations(irClass: IrClass): List<IrConstructorCall> {
-        if (!(irClass.isInterface || irClass.descriptor.hasSerializableOrMetaAnnotation)) return emptyList()
-        val annotationByFq: MutableMap<FqName, IrConstructorCall> =
-            irClass.annotations.associateBy { it.symbol.owner.parentAsClass.descriptor.fqNameSafe }.toMutableMap()
-        for (clazz in irClass.getAllSuperclasses()) {
-            val annotations = clazz.annotations
-                .mapNotNull {
-                    val descriptor = it.symbol.owner.parentAsClass.descriptor
-                    if (descriptor.isInheritableSerialInfoAnnotation) descriptor.fqNameSafe to it else null
-                }
-            annotations.forEach { (fqname, call) ->
-                if (fqname !in annotationByFq) {
-                    annotationByFq[fqname] = call
-                } else {
-                    // SerializationPluginDeclarationChecker already reported inconsistency
-                }
-            }
-        }
-        return annotationByFq.values.toList()
-    }
-
-    fun IrBuilderWithScope.callSerializerFromCompanion(
-        thisIrType: IrType,
-        typeArgs: List<IrType>,
-        args: List<IrExpression>
-    ): IrExpression? {
-        val baseClass = thisIrType.getClass() ?: return null
-        val companionClass = baseClass.companionObject() ?: return null
-        val serializerProviderFunction = companionClass.declarations.singleOrNull {
-            it is IrFunction && it.name == SerialEntityNames.SERIALIZER_PROVIDER_NAME && it.valueParameters.size == baseClass.typeParameters.size
-        } ?: return null
-
-        val adjustedArgs: List<IrExpression> =
-            // if typeArgs.size == args.size then the serializer is custom - we need to use the actual serializers from the arguments
-            if ((typeArgs.size != args.size) && (baseClass.descriptor.isSealed() || baseClass.descriptor.modality == Modality.ABSTRACT)) {
-                val serializer = findStandardKotlinTypeSerializer(compilerContext, context.irBuiltIns.unitType)!!
-                // workaround for sealed and abstract classes - the `serializer` function expects non-null serializers, but does not use them, so serializers of any type can be passed
-                List(baseClass.typeParameters.size) { irGetObject(serializer) }
-            } else {
-                args
-            }
-
-        with(serializerProviderFunction as IrFunction) {
-            // Note that [typeArgs] may be unused if we short-cut to e.g. SealedClassSerializer
-            return irInvoke(
-                irGetObject(companionClass),
-                symbol,
-                typeArgs.takeIf { it.size == typeParameters.size }.orEmpty(),
-                adjustedArgs.takeIf { it.size == valueParameters.size }.orEmpty()
-            )
-        }
-    }
-
-    private fun IrConstructor.lastArgumentIsAnnotationArray(): Boolean {
-        val lastArgType = valueParameters.lastOrNull()?.type
-        if (lastArgType == null || !lastArgType.isArray()) return false
-        return ((lastArgType as? IrSimpleType)?.arguments?.firstOrNull()?.typeOrNull?.classFqName?.toString() == "kotlin.Annotation")
-    }
-
-    private fun IrBuilderWithScope.wrapperClassReference(classType: IrType): IrClassReference {
-        if (compilerContext.platform.isJvm()) {
-            // "Byte::class" -> "java.lang.Byte::class"
-//          TODO: get rid of descriptor
-            val wrapperFqName = KotlinBuiltIns.getPrimitiveType(classType.classOrNull!!.descriptor)?.let(JvmPrimitiveType::get)?.wrapperFqName
-            if (wrapperFqName != null) {
-                val wrapperClass = compilerContext.referenceClass(ClassId.topLevel(wrapperFqName))
-                    ?: error("Primitive wrapper class for $classType not found: $wrapperFqName")
-                return classReference(wrapperClass.defaultType)
-            }
-        }
-        return classReference(classType)
-    }
-
-    fun findSerializerConstructorForTypeArgumentsSerializers(serializer: IrClass): IrConstructorSymbol? {
-
-        val typeParamsCount = ((serializer.superTypes.find { isKSerializer(it) } as IrSimpleType).arguments.first().typeOrNull!! as IrSimpleType).arguments.size
-        if (typeParamsCount == 0) return null //don't need it
-
-        return serializer.constructors.singleOrNull {
-            it.valueParameters.let { vps -> vps.size == typeParamsCount && vps.all { vp -> isKSerializer(vp.type) } }
-        }?.symbol
-    }
-
-    private fun IrConstructor.isSerializationCtor(): Boolean {
-        val serialMarker =
-            compilerContext.referenceClass(ClassId.topLevel(SerializationPackages.internalPackageFqName.child(SerialEntityNames.SERIAL_CTOR_MARKER_NAME)))
-
-        return valueParameters.lastOrNull()?.run {
-            name == SerialEntityNames.dummyParamName && type.classifierOrNull == serialMarker
-        } == true
-    }
-
-    fun serializableSyntheticConstructor(forClass: IrClass): IrConstructorSymbol? { // todo: remove this W/A when FIR plugin will add proper ctor
-        return forClass.declarations.filterIsInstance<IrConstructor>().singleOrNull { it.isSerializationCtor() }?.symbol
-    }
-
-    fun IrClass.getSuperClassOrAny(): IrClass = getSuperClassNotAny() ?: compilerContext.irBuiltIns.anyClass.owner
-
-    fun IrClass.getSuperClassNotAny(): IrClass? {
-        val superClasses = superTypes.mapNotNull { it.classOrNull }.map { it.owner }
-
-        return superClasses.singleOrNull { it.kind == ClassKind.CLASS }
-    }
-
-    fun IrClass.findWriteSelfMethod(): IrSimpleFunction? =
-        declarations.singleOrNull { it is IrSimpleFunction && it.name == SerialEntityNames.WRITE_SELF_NAME && !it.isFakeOverride } as IrSimpleFunction?
-
-    fun IrBlockBodyBuilder.serializeAllProperties(
-        generator: AbstractIrGenerator,
-        serializableIrClass: IrClass,
-        serializableProperties: List<IrSerializableProperty>,
-        objectToSerialize: IrValueDeclaration,
-        localOutput: IrValueDeclaration,
-        localSerialDesc: IrValueDeclaration,
-        kOutputClass: IrClassSymbol,
-        ignoreIndexTo: Int,
-        initializerAdapter: (IrExpressionBody) -> IrExpression,
-        genericGetter: ((Int, IrType) -> IrExpression)?
-    ) {
-
-        fun IrSerializableProperty.irGet(): IrExpression {
-            val ownerType = objectToSerialize.symbol.owner.type
-            return getProperty(
-                irGet(
-                    type = ownerType,
-                    variable = objectToSerialize.symbol
-                ), descriptor
-            )
-        }
-
-        for ((index, property) in serializableProperties.withIndex()) {
-            if (index < ignoreIndexTo) continue
-            // output.writeXxxElementValue(classDesc, index, value)
-            val elementCall = formEncodeDecodePropertyCall(
-                generator,
-                irGet(localOutput),
-                property, { innerSerial, sti ->
-                    val f =
-                        kOutputClass.functionByName("${CallingConventions.encode}${sti.elementMethodPrefix}Serializable${CallingConventions.elementPostfix}")
-                    f to listOf(
-                        irGet(localSerialDesc),
-                        irInt(index),
-                        innerSerial,
-                        property.irGet()
-                    )
-                }, {
-                    val f =
-                        kOutputClass.functionByName("${CallingConventions.encode}${it.elementMethodPrefix}${CallingConventions.elementPostfix}")
-                    val args: MutableList<IrExpression> = mutableListOf(irGet(localSerialDesc), irInt(index))
-                    if (it.elementMethodPrefix != "Unit") args.add(property.irGet())
-                    f to args
-                },
-                genericGetter
-            )
-
-            // check for call to .shouldEncodeElementDefault
-            val encodeDefaults = property.descriptor.getEncodeDefaultAnnotationValue()
-            val field = property.irField // Nullable when property from another module; can't compare it with default value on JS or Native
-            if (!property.optional || encodeDefaults == true || field == null) {
-                // emit call right away
-                +elementCall
-            } else {
-                val partB = irNotEquals(property.irGet(), initializerAdapter(field.initializer!!))
-
-                val condition = if (encodeDefaults == false) {
-                    // drop default without call to .shouldEncodeElementDefault
-                    partB
-                } else {
-                    // emit check:
-                    // if (if (output.shouldEncodeElementDefault(this.descriptor, i)) true else {obj.prop != DEFAULT_VALUE} ) {
-                    //    output.encodeIntElement(this.descriptor, i, obj.prop)// block {obj.prop != DEFAULT_VALUE} may contain several statements
-                    val shouldEncodeFunc = kOutputClass.functionByName(CallingConventions.shouldEncodeDefault)
-                    val partA = irInvoke(irGet(localOutput), shouldEncodeFunc, irGet(localSerialDesc), irInt(index))
-                    // Ir infrastructure does not have dedicated symbol for ||, so
-                    //  `a || b == if (a) true else b`, see org.jetbrains.kotlin.ir.builders.PrimitivesKt.oror
-                    irIfThenElse(compilerContext.irBuiltIns.booleanType, partA, irTrue(), partB)
-                }
-                +irIfThen(condition, elementCall)
-            }
-        }
-    }
-
-    /**
-     * True — ALWAYS
-     * False — NEVER
-     * null — not specified
-     */
-    fun IrProperty.getEncodeDefaultAnnotationValue(): Boolean? {
-        val call = annotations.findAnnotation(SerializationAnnotations.encodeDefaultFqName) ?: return null
-        val arg = call.getValueArgument(0) ?: return true // ALWAYS by default
-        val argValue = (arg as? IrGetEnumValue
-            ?: error("Argument of enum constructor expected to implement IrGetEnumValue, got $arg")).symbol.owner.name.toString()
-        return when (argValue) {
-            "ALWAYS" -> true
-            "NEVER" -> false
-            else -> error("Unknown EncodeDefaultMode enum value: $argValue")
-        }
-    }
-
-
-    fun IrBlockBodyBuilder.formEncodeDecodePropertyCall(
-        enclosingGenerator: AbstractIrGenerator,
-        encoder: IrExpression,
-        property: IrSerializableProperty,
-        whenHaveSerializer: (serializer: IrExpression, sti: IrSerialTypeInfo) -> FunctionWithArgs,
-        whenDoNot: (sti: IrSerialTypeInfo) -> FunctionWithArgs,
-        genericGetter: ((Int, IrType) -> IrExpression)? = null,
-        returnTypeHint: IrType? = null
-    ): IrExpression {
-        val sti = enclosingGenerator.getIrSerialTypeInfo(property, compilerContext)
-        val innerSerial = serializerInstance(
-            enclosingGenerator,
-            sti.serializer,
-            compilerContext,
-            property.type,
-            property.genericIndex,
-            genericGetter
-        )
-        val (functionToCall, args: List<IrExpression>) = if (innerSerial != null) whenHaveSerializer(innerSerial, sti) else whenDoNot(sti)
-        val typeArgs = if (functionToCall.descriptor.typeParameters.isNotEmpty()) listOf(property.type) else listOf()
-        return irInvoke(encoder, functionToCall, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnTypeHint)
-    }
-
-}
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrBuilderWithPluginContext.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrBuilderWithPluginContext.kt
new file mode 100644
index 0000000..e39488b
--- /dev/null
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrBuilderWithPluginContext.kt
@@ -0,0 +1,582 @@
+/*
+ * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlinx.serialization.compiler.backend.ir
+
+import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI
+import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.builtins.StandardNames
+import org.jetbrains.kotlin.descriptors.*
+import org.jetbrains.kotlin.ir.builders.*
+import org.jetbrains.kotlin.ir.builders.declarations.buildFun
+import org.jetbrains.kotlin.ir.declarations.*
+import org.jetbrains.kotlin.ir.deepCopyWithVariables
+import org.jetbrains.kotlin.ir.expressions.*
+import org.jetbrains.kotlin.ir.expressions.impl.*
+import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
+import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
+import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
+import org.jetbrains.kotlin.ir.symbols.impl.*
+import org.jetbrains.kotlin.ir.types.*
+import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.name.CallableId
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.platform.jvm.isJvm
+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
+import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
+import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
+import org.jetbrains.kotlin.types.KotlinType
+import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
+import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_FQ
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_MODE_FQ
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_PUBLICATION_MODE_NAME
+import org.jetbrains.kotlinx.serialization.compiler.resolve.hasSerializableOrMetaAnnotation
+import org.jetbrains.kotlinx.serialization.compiler.resolve.isInheritableSerialInfoAnnotation
+import org.jetbrains.kotlinx.serialization.compiler.resolve.isSerialInfoAnnotation
+
+
+interface IrBuilderWithPluginContext {
+    val compilerContext: SerializationPluginContext
+
+    fun <F: IrFunction> addFunctionBody(function: F, bodyGen: IrBlockBodyBuilder.(F) -> Unit) {
+        val parentClass = function.parent
+        val startOffset = function.startOffset.takeIf { it >= 0 } ?: parentClass.startOffset
+        val endOffset = function.endOffset.takeIf { it >= 0 } ?: parentClass.endOffset
+        function.body = DeclarationIrBuilder(compilerContext, function.symbol, startOffset, endOffset).irBlockBody(
+            startOffset,
+            endOffset
+        ) { bodyGen(function) }
+    }
+
+    fun IrClass.createLambdaExpression(
+        type: IrType,
+        bodyGen: IrBlockBodyBuilder.() -> Unit
+    ): IrFunctionExpression {
+        val function = compilerContext.irFactory.buildFun {
+            this.startOffset = this@createLambdaExpression.startOffset
+            this.endOffset = this@createLambdaExpression.endOffset
+            this.returnType = type
+            name = Name.identifier("<anonymous>")
+            visibility = DescriptorVisibilities.LOCAL
+            origin = SERIALIZABLE_PLUGIN_ORIGIN
+        }
+        function.body =
+            DeclarationIrBuilder(compilerContext, function.symbol, startOffset, endOffset).irBlockBody(startOffset, endOffset, bodyGen)
+        function.parent = this
+
+        val f0Type = compilerContext.irBuiltIns.functionN(0)
+        val f0ParamSymbol = f0Type.typeParameters[0].symbol
+        val f0IrType = f0Type.defaultType.substitute(mapOf(f0ParamSymbol to type))
+
+        return IrFunctionExpressionImpl(
+            startOffset,
+            endOffset,
+            f0IrType,
+            function,
+            IrStatementOrigin.LAMBDA
+        )
+    }
+
+    fun createLazyProperty(
+        containingClass: IrClass,
+        targetIrType: IrType,
+        name: Name,
+        initializerBuilder: IrBlockBodyBuilder.() -> Unit
+    ): IrProperty {
+        val lazySafeModeClassDescriptor = compilerContext.referenceClass(ClassId.topLevel(LAZY_MODE_FQ))!!.owner
+        val lazyFunctionSymbol = compilerContext.referenceFunctions(CallableId(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("lazy"))).single {
+            it.owner.valueParameters.size == 2 && it.owner.valueParameters[0].type == lazySafeModeClassDescriptor.defaultType
+        }
+        val publicationEntryDescriptor = lazySafeModeClassDescriptor.enumEntries().single { it.name == LAZY_PUBLICATION_MODE_NAME }
+
+        val lazyIrClass = compilerContext.referenceClass(ClassId.topLevel(LAZY_FQ))!!.owner
+        val lazyIrType = lazyIrClass.defaultType.substitute(mapOf(lazyIrClass.typeParameters[0].symbol to targetIrType))
+
+        val propertyDescriptor =
+            KSerializerDescriptorResolver.createValPropertyDescriptor(
+                Name.identifier(name.asString() + "\$delegate"),
+                containingClass.descriptor,
+                lazyIrType.toKotlinType(),
+                createGetter = true
+            )
+
+        return generateSimplePropertyWithBackingField(propertyDescriptor, containingClass).apply {
+            val builder = DeclarationIrBuilder(compilerContext, containingClass.symbol, startOffset, endOffset)
+            val initializerBody = builder.run {
+                val enumElement = IrGetEnumValueImpl(
+                    startOffset,
+                    endOffset,
+                    lazySafeModeClassDescriptor.defaultType,
+                    publicationEntryDescriptor.symbol
+                )
+
+                val lambdaExpression = containingClass.createLambdaExpression(targetIrType, initializerBuilder)
+
+                irExprBody(
+                    irInvoke(null, lazyFunctionSymbol, listOf(targetIrType), listOf(enumElement, lambdaExpression), lazyIrType)
+                )
+            }
+            backingField!!.initializer = initializerBody
+        }
+    }
+
+    fun createCompanionValProperty(
+        companionClass: IrClass,
+        type: IrType,
+        name: Name,
+        initializerBuilder: IrBlockBodyBuilder.() -> Unit
+    ): IrProperty {
+        val targetKotlinType = type.toKotlinType()
+        val propertyDescriptor =
+            KSerializerDescriptorResolver.createValPropertyDescriptor(name, companionClass.descriptor, targetKotlinType)
+
+        return generateSimplePropertyWithBackingField(propertyDescriptor, companionClass, name).apply {
+            companionClass.contributeAnonymousInitializer {
+                val irBlockBody = irBlockBody(startOffset, endOffset, initializerBuilder)
+                irBlockBody.statements.dropLast(1).forEach { +it }
+                val expression = irBlockBody.statements.last() as? IrExpression
+                    ?: throw AssertionError("Last statement in property initializer builder is not an a expression")
+                +irSetField(irGetObject(companionClass), backingField!!, expression)
+            }
+        }
+    }
+
+    fun IrClass.contributeAnonymousInitializer(bodyGen: IrBlockBodyBuilder.() -> Unit) {
+        val symbol = IrAnonymousInitializerSymbolImpl(descriptor)
+        factory.createAnonymousInitializer(startOffset, endOffset, SERIALIZABLE_PLUGIN_ORIGIN, symbol).also {
+            it.parent = this
+            declarations.add(it)
+            it.body = DeclarationIrBuilder(compilerContext, symbol, startOffset, endOffset).irBlockBody(startOffset, endOffset, bodyGen)
+        }
+    }
+
+    fun IrBlockBodyBuilder.getLazyValueExpression(thisParam: IrValueParameter, property: IrProperty, type: IrType): IrExpression {
+        val lazyIrClass = compilerContext.referenceClass(ClassId.topLevel(LAZY_FQ))!!.owner
+        val valueGetter = lazyIrClass.getPropertyGetter("value")!!
+
+        val propertyGetter = property.getter!!
+
+        return irInvoke(
+            irGet(propertyGetter.returnType, irGet(thisParam), propertyGetter.symbol),
+            valueGetter,
+            typeHint = type
+        )
+    }
+
+    fun IrBuilderWithScope.irInvoke(
+        dispatchReceiver: IrExpression? = null,
+        callee: IrFunctionSymbol,
+        vararg args: IrExpression,
+        typeHint: IrType? = null
+    ): IrMemberAccessExpression<*> {
+        assert(callee.isBound) { "Symbol $callee expected to be bound" }
+        val returnType = typeHint ?: callee.owner.returnType
+        val call = irCall(callee, type = returnType)
+        call.dispatchReceiver = dispatchReceiver
+        args.forEachIndexed(call::putValueArgument)
+        return call
+    }
+
+    fun IrBuilderWithScope.irInvoke(
+        dispatchReceiver: IrExpression? = null,
+        callee: IrFunctionSymbol,
+        typeArguments: List<IrType?>,
+        valueArguments: List<IrExpression>,
+        returnTypeHint: IrType? = null
+    ): IrMemberAccessExpression<*> =
+        irInvoke(
+            dispatchReceiver,
+            callee,
+            *valueArguments.toTypedArray(),
+            typeHint = returnTypeHint
+        ).also { call -> typeArguments.forEachIndexed(call::putTypeArgument) }
+
+    fun IrBuilderWithScope.createArrayOfExpression(
+        arrayElementType: IrType,
+        arrayElements: List<IrExpression>
+    ): IrExpression {
+
+        val arrayType = compilerContext.irBuiltIns.arrayClass.typeWith(arrayElementType)
+        val arg0 = IrVarargImpl(startOffset, endOffset, arrayType, arrayElementType, arrayElements)
+        val typeArguments = listOf(arrayElementType)
+
+        return irCall(compilerContext.irBuiltIns.arrayOf, arrayType, typeArguments = typeArguments).apply {
+            putValueArgument(0, arg0)
+        }
+    }
+
+    fun IrBuilderWithScope.createPrimitiveArrayOfExpression(
+        elementPrimitiveType: IrType,
+        arrayElements: List<IrExpression>
+    ): IrExpression {
+        val arrayType = compilerContext.irBuiltIns.primitiveArrayForType.getValue(elementPrimitiveType).defaultType
+        val arg0 = IrVarargImpl(startOffset, endOffset, arrayType, elementPrimitiveType, arrayElements)
+        val typeArguments = listOf(elementPrimitiveType)
+
+        return irCall(compilerContext.irBuiltIns.arrayOf, arrayType, typeArguments = typeArguments).apply {
+            putValueArgument(0, arg0)
+        }
+    }
+
+    fun IrBuilderWithScope.irBinOp(name: Name, lhs: IrExpression, rhs: IrExpression): IrExpression {
+        val classFqName = (lhs.type as IrSimpleType).classOrNull!!.owner.fqNameWhenAvailable!!
+        val symbol = compilerContext.referenceFunctions(CallableId(ClassId.topLevel(classFqName), name)).single()
+        return irInvoke(lhs, symbol, rhs)
+    }
+
+    fun IrBuilderWithScope.irGetObject(irObject: IrClass) =
+        IrGetObjectValueImpl(
+            startOffset,
+            endOffset,
+            irObject.defaultType,
+            irObject.symbol
+        )
+
+    fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
+        also { irDeclaration ->
+            compilerContext.symbolTable.withReferenceScope(irDeclaration) {
+                builder(irDeclaration)
+            }
+        }
+
+    class BranchBuilder(
+        val irWhen: IrWhen,
+        context: IrGeneratorContext,
+        scope: Scope,
+        startOffset: Int,
+        endOffset: Int
+    ) : IrBuilderWithScope(context, scope, startOffset, endOffset) {
+        operator fun IrBranch.unaryPlus() {
+            irWhen.branches.add(this)
+        }
+    }
+
+    fun IrBuilderWithScope.irWhen(typeHint: IrType? = null, block: BranchBuilder.() -> Unit): IrWhen {
+        val whenExpr = IrWhenImpl(startOffset, endOffset, typeHint ?: compilerContext.irBuiltIns.unitType)
+        val builder = BranchBuilder(whenExpr, context, scope, startOffset, endOffset)
+        builder.block()
+        return whenExpr
+    }
+
+    fun BranchBuilder.elseBranch(result: IrExpression): IrElseBranch =
+        IrElseBranchImpl(
+            IrConstImpl.boolean(result.startOffset, result.endOffset, compilerContext.irBuiltIns.booleanType, true),
+            result
+        )
+
+    @FirIncompatiblePluginAPI
+    fun KotlinType.toIrType() = compilerContext.typeTranslator.translateType(this)
+
+    fun IrBuilderWithScope.setProperty(receiver: IrExpression, property: IrProperty, value: IrExpression): IrExpression {
+        return if (property.setter != null)
+            irSet(property.setter!!.returnType, receiver, property.setter!!.symbol, value)
+        else
+            irSetField(receiver, property.backingField!!, value)
+    }
+
+    fun IrBuilderWithScope.generateAnySuperConstructorCall(toBuilder: IrBlockBodyBuilder) {
+        val anyConstructor = compilerContext.irBuiltIns.anyClass.owner.declarations.single { it is IrConstructor } as IrConstructor
+        with(toBuilder) {
+            +IrDelegatingConstructorCallImpl.fromSymbolDescriptor(
+                startOffset, endOffset,
+                compilerContext.irBuiltIns.unitType,
+                anyConstructor.symbol
+            )
+        }
+    }
+
+    private inline fun <reified T : IrDeclaration> IrClass.searchForDeclaration(descriptor: DeclarationDescriptor): T? {
+        return declarations.singleOrNull { it.descriptor == descriptor } as? T
+    }
+
+    fun generateSimplePropertyWithBackingField(
+        propertyDescriptor: PropertyDescriptor,
+        propertyParent: IrClass,
+        fieldName: Name = propertyDescriptor.name,
+    ): IrProperty {
+        val irProperty = propertyParent.searchForDeclaration(propertyDescriptor) ?: run {
+            with(propertyDescriptor) {
+                propertyParent.factory.createProperty(
+                    propertyParent.startOffset, propertyParent.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrPropertySymbolImpl(propertyDescriptor),
+                    name, visibility, modality, isVar, isConst, isLateInit, isDelegated, isExternal
+                ).also {
+                    it.parent = propertyParent
+                    propertyParent.addMember(it)
+                }
+            }
+        }
+
+        propertyParent.generatePropertyBackingFieldIfNeeded(propertyDescriptor, irProperty, fieldName)
+        val fieldSymbol = irProperty.backingField!!.symbol
+        irProperty.getter = propertyDescriptor.getter?.let {
+            propertyParent.generatePropertyAccessor(propertyDescriptor, irProperty, it, fieldSymbol, isGetter = true)
+        }?.apply { parent = propertyParent }
+        irProperty.setter = propertyDescriptor.setter?.let {
+            propertyParent.generatePropertyAccessor(propertyDescriptor, irProperty, it, fieldSymbol, isGetter = false)
+        }?.apply { parent = propertyParent }
+        return irProperty
+    }
+
+    fun IrType.kClassToJClassIfNeeded(): IrType = this
+
+    fun kClassExprToJClassIfNeeded(startOffset: Int, endOffset: Int, irExpression: IrExpression): IrExpression = irExpression
+
+    private fun IrClass.generatePropertyBackingFieldIfNeeded(
+        propertyDescriptor: PropertyDescriptor,
+        originProperty: IrProperty,
+        name: Name,
+    ) {
+        if (originProperty.backingField != null) return
+
+        val field = with(propertyDescriptor) {
+            // TODO: type parameters
+            @OptIn(FirIncompatiblePluginAPI::class)// should be called only with old FE
+            originProperty.factory.createField(
+                originProperty.startOffset, originProperty.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrFieldSymbolImpl(propertyDescriptor), name, type.toIrType(),
+                visibility, !isVar, isEffectivelyExternal(), dispatchReceiverParameter == null
+            )
+        }
+        field.apply {
+            parent = this@generatePropertyBackingFieldIfNeeded
+            correspondingPropertySymbol = originProperty.symbol
+        }
+
+        originProperty.backingField = field
+    }
+
+    private fun IrClass.generatePropertyAccessor(
+        propertyDescriptor: PropertyDescriptor,
+        property: IrProperty,
+        descriptor: PropertyAccessorDescriptor,
+        fieldSymbol: IrFieldSymbol,
+        isGetter: Boolean,
+    ): IrSimpleFunction {
+        val irAccessor: IrSimpleFunction = when (isGetter) {
+            true -> searchForDeclaration<IrProperty>(propertyDescriptor)?.getter
+            false -> searchForDeclaration<IrProperty>(propertyDescriptor)?.setter
+        } ?: run {
+            with(descriptor) {
+                @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
+                property.factory.createFunction(
+                    fieldSymbol.owner.startOffset, fieldSymbol.owner.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrSimpleFunctionSymbolImpl(descriptor),
+                    name, visibility, modality, returnType!!.toIrType(),
+                    isInline, isEffectivelyExternal(), isTailrec, isSuspend, isOperator, isInfix, isExpect
+                )
+            }.also { f ->
+                generateOverriddenFunctionSymbols(f, compilerContext.symbolTable)
+                f.createParameterDeclarations(descriptor)
+                @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
+                f.returnType = descriptor.returnType!!.toIrType()
+                f.correspondingPropertySymbol = fieldSymbol.owner.correspondingPropertySymbol
+            }
+        }
+
+        irAccessor.body = when (isGetter) {
+            true -> generateDefaultGetterBody(descriptor as PropertyGetterDescriptor, irAccessor)
+            false -> generateDefaultSetterBody(descriptor as PropertySetterDescriptor, irAccessor)
+        }
+
+        return irAccessor
+    }
+
+    private fun generateDefaultGetterBody(
+        getter: PropertyGetterDescriptor,
+        irAccessor: IrSimpleFunction
+    ): IrBlockBody {
+        val property = getter.correspondingProperty
+        val irProperty = irAccessor.correspondingPropertySymbol?.owner ?: error("Expected property for $getter")
+
+        val startOffset = irAccessor.startOffset
+        val endOffset = irAccessor.endOffset
+        val irBody = irAccessor.factory.createBlockBody(startOffset, endOffset)
+
+        val receiver = generateReceiverExpressionForFieldAccess(irAccessor.dispatchReceiverParameter!!.symbol, property)
+
+        val propertyIrType = irAccessor.returnType
+        irBody.statements.add(
+            IrReturnImpl(
+                startOffset, endOffset, compilerContext.irBuiltIns.nothingType,
+                irAccessor.symbol,
+                IrGetFieldImpl(
+                    startOffset, endOffset,
+                    irProperty.backingField?.symbol ?: error("Property expected to have backing field"),
+                    propertyIrType,
+                    receiver
+                ).let {
+                    if (propertyIrType.isKClass()) {
+                        irAccessor.returnType = irAccessor.returnType.kClassToJClassIfNeeded()
+                        kClassExprToJClassIfNeeded(startOffset, endOffset, it)
+                    } else it
+                }
+            )
+        )
+        return irBody
+    }
+
+    private fun generateDefaultSetterBody(
+        setter: PropertySetterDescriptor,
+        irAccessor: IrSimpleFunction
+    ): IrBlockBody {
+        val property = setter.correspondingProperty
+        val irProperty = irAccessor.correspondingPropertySymbol?.owner ?: error("Expected corresponding property for accessor $setter")
+        val startOffset = irAccessor.startOffset
+        val endOffset = irAccessor.endOffset
+        val irBody = irAccessor.factory.createBlockBody(startOffset, endOffset)
+
+        val receiver = generateReceiverExpressionForFieldAccess(irAccessor.dispatchReceiverParameter!!.symbol, property)
+
+        val irValueParameter = irAccessor.valueParameters.single()
+        irBody.statements.add(
+            IrSetFieldImpl(
+                startOffset, endOffset,
+                irProperty.backingField?.symbol ?: error("Property $property expected to have backing field"),
+                receiver,
+                IrGetValueImpl(startOffset, endOffset, irValueParameter.type, irValueParameter.symbol),
+                compilerContext.irBuiltIns.unitType
+            )
+        )
+        return irBody
+    }
+
+    fun generateReceiverExpressionForFieldAccess( // todo: remove this
+        ownerSymbol: IrValueSymbol,
+        property: PropertyDescriptor
+    ): IrExpression {
+        val containingDeclaration = property.containingDeclaration
+        return when (containingDeclaration) {
+            is ClassDescriptor ->
+                IrGetValueImpl(
+                    ownerSymbol.owner.startOffset, ownerSymbol.owner.endOffset,
+                    ownerSymbol
+                )
+            else -> throw AssertionError("Property must be in class")
+        }
+    }
+
+    fun IrFunction.createParameterDeclarations(
+        descriptor: FunctionDescriptor,
+        overwriteValueParameters: Boolean = false,
+        copyTypeParameters: Boolean = true
+    ) {
+        val function = this
+        fun irValueParameter(descriptor: ParameterDescriptor): IrValueParameter = with(descriptor) {
+            @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
+            factory.createValueParameter(
+                function.startOffset, function.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, IrValueParameterSymbolImpl(this),
+                name, indexOrMinusOne, type.toIrType(), varargElementType?.toIrType(), isCrossinline, isNoinline,
+                isHidden = false, isAssignable = false
+            ).also {
+                it.parent = function
+            }
+        }
+
+        if (copyTypeParameters) {
+            assert(typeParameters.isEmpty())
+            copyTypeParamsFromDescriptor(descriptor)
+        }
+
+        dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let { irValueParameter(it) }
+        extensionReceiverParameter = descriptor.extensionReceiverParameter?.let { irValueParameter(it) }
+
+        if (!overwriteValueParameters)
+            assert(valueParameters.isEmpty())
+
+        valueParameters = descriptor.valueParameters.map { irValueParameter(it) }
+    }
+
+    fun IrFunction.copyTypeParamsFromDescriptor(descriptor: FunctionDescriptor) {
+        val newTypeParameters = descriptor.typeParameters.map {
+            factory.createTypeParameter(
+                startOffset, endOffset,
+                SERIALIZABLE_PLUGIN_ORIGIN,
+                IrTypeParameterSymbolImpl(it),
+                it.name, it.index, it.isReified, it.variance
+            ).also { typeParameter ->
+                typeParameter.parent = this
+            }
+        }
+        @OptIn(FirIncompatiblePluginAPI::class) // should never be called after FIR frontend
+        newTypeParameters.forEach { typeParameter ->
+            typeParameter.superTypes = typeParameter.descriptor.upperBounds.map { it.toIrType() }
+        }
+
+        typeParameters = newTypeParameters
+    }
+
+    fun createClassReference(classType: IrType, startOffset: Int, endOffset: Int): IrClassReference {
+        return IrClassReferenceImpl(
+            startOffset,
+            endOffset,
+            compilerContext.irBuiltIns.kClassClass.starProjectedType,
+            classType.classifierOrFail,
+            classType
+        )
+    }
+
+    fun IrBuilderWithScope.classReference(classSymbol: IrType): IrClassReference =
+        createClassReference(classSymbol, startOffset, endOffset)
+
+    fun collectSerialInfoAnnotations(irClass: IrClass): List<IrConstructorCall> {
+        if (!(irClass.isInterface || irClass.descriptor.hasSerializableOrMetaAnnotation)) return emptyList()
+        val annotationByFq: MutableMap<FqName, IrConstructorCall> =
+            irClass.annotations.associateBy { it.symbol.owner.parentAsClass.descriptor.fqNameSafe }.toMutableMap()
+        for (clazz in irClass.getAllSuperclasses()) {
+            val annotations = clazz.annotations
+                .mapNotNull {
+                    val descriptor = it.symbol.owner.parentAsClass.descriptor
+                    if (descriptor.isInheritableSerialInfoAnnotation) descriptor.fqNameSafe to it else null
+                }
+            annotations.forEach { (fqname, call) ->
+                if (fqname !in annotationByFq) {
+                    annotationByFq[fqname] = call
+                } else {
+                    // SerializationPluginDeclarationChecker already reported inconsistency
+                }
+            }
+        }
+        return annotationByFq.values.toList()
+    }
+
+    fun IrBuilderWithScope.copyAnnotationsFrom(annotations: List<IrConstructorCall>): List<IrExpression> =
+        annotations.mapNotNull { annotationCall ->
+            val annotationClass = annotationCall.symbol.owner.parentAsClass
+            if (!annotationClass.descriptor.isSerialInfoAnnotation) return@mapNotNull null
+
+            if (compilerContext.platform.isJvm()) {
+                val implClass = compilerContext.serialInfoImplJvmIrGenerator.getImplClass(annotationClass)
+                val ctor = implClass.constructors.singleOrNull { it.valueParameters.size == annotationCall.valueArgumentsCount }
+                    ?: error("No constructor args found for SerialInfo annotation Impl class: ${implClass.render()}")
+                irCall(ctor).apply {
+                    for (i in 0 until annotationCall.valueArgumentsCount) {
+                        val argument = annotationCall.getValueArgument(i)
+                            ?: annotationClass.primaryConstructor!!.valueParameters[i].defaultValue?.expression
+                        putValueArgument(i, argument!!.deepCopyWithVariables())
+                    }
+                }
+            } else {
+                annotationCall.deepCopyWithVariables()
+            }
+        }
+
+    fun IrBuilderWithScope.wrapperClassReference(classType: IrType): IrClassReference {
+        if (compilerContext.platform.isJvm()) {
+            // "Byte::class" -> "java.lang.Byte::class"
+//          TODO: get rid of descriptor
+            val wrapperFqName = KotlinBuiltIns.getPrimitiveType(classType.classOrNull!!.descriptor)?.let(JvmPrimitiveType::get)?.wrapperFqName
+            if (wrapperFqName != null) {
+                val wrapperClass = compilerContext.referenceClass(ClassId.topLevel(wrapperFqName))
+                    ?: error("Primitive wrapper class for $classType not found: $wrapperFqName")
+                return classReference(wrapperClass.defaultType)
+            }
+        }
+        return classReference(classType)
+    }
+
+    fun IrClass.getSuperClassOrAny(): IrClass = getSuperClassNotAny() ?: compilerContext.irBuiltIns.anyClass.owner
+}
\ No newline at end of file
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrPredicates.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrPredicates.kt
new file mode 100644
index 0000000..de87f71
--- /dev/null
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrPredicates.kt
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlinx.serialization.compiler.backend.ir
+
+import org.jetbrains.kotlin.backend.jvm.ir.getStringConstArgument
+import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
+import org.jetbrains.kotlin.descriptors.ClassKind
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.declarations.*
+import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
+import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
+import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
+import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
+import org.jetbrains.kotlin.ir.types.*
+import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlinx.serialization.compiler.fir.SerializationPluginKey
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages
+import org.jetbrains.kotlinx.serialization.compiler.resolve.hasSerializableOrMetaAnnotation
+
+internal fun IrType.isKSerializer(): Boolean {
+    val simpleType = this as? IrSimpleType ?: return false
+    val classifier = simpleType.classifier as? IrClassSymbol ?: return false
+    val fqName = classifier.owner.fqNameWhenAvailable
+    return fqName == SerialEntityNames.KSERIALIZER_NAME_FQ || fqName == SerialEntityNames.GENERATED_SERIALIZER_FQ
+}
+
+internal val IrClass.isInternalSerializable: Boolean
+    get() {
+        if (kind != ClassKind.CLASS) return false
+        return hasSerializableOrMetaAnnotationWithoutArgs()
+    }
+
+internal val IrClass.isAbstractOrSealedSerializableClass: Boolean get() = isInternalSerializable && (modality == Modality.ABSTRACT || modality == Modality.SEALED)
+
+internal val IrClass.isStaticSerializable: Boolean get() = this.typeParameters.isEmpty()
+
+
+internal val IrClass.hasCompanionObjectAsSerializer: Boolean
+    get() = isInternallySerializableObject || companionObject()?.serializerForClass == this.symbol
+
+internal val IrClass.isInternallySerializableObject: Boolean
+    get() = kind == ClassKind.OBJECT && hasSerializableOrMetaAnnotationWithoutArgs()
+
+
+internal fun IrClass.findPluginGeneratedMethod(name: String): IrSimpleFunction? {
+    return this.functions.find {
+        it.name.asString() == name && it.isFromPlugin()
+    }
+}
+
+internal fun IrClass.isEnumWithLegacyGeneratedSerializer(): Boolean = isInternallySerializableEnum() && useGeneratedEnumSerializer
+
+internal val IrClass.useGeneratedEnumSerializer: Boolean
+    get() = true // FIXME This would break if we try to use this new IR compiler with pre-1.4.1 serialization versions. I think we just need to raise min runtime version.
+
+internal val IrClass.isSealedSerializableInterface: Boolean
+    get() = kind == ClassKind.INTERFACE && modality == Modality.SEALED && hasSerializableOrMetaAnnotation()
+
+internal fun IrClass.isInternallySerializableEnum(): Boolean =
+    kind == ClassKind.ENUM_CLASS && hasSerializableOrMetaAnnotationWithoutArgs()
+
+fun IrType.isGeneratedSerializableObject(): Boolean {
+    return classOrNull?.run { owner.kind == ClassKind.OBJECT && owner.hasSerializableOrMetaAnnotationWithoutArgs() } == true
+}
+
+internal val IrClass.isSerializableObject: Boolean
+    get() = kind == ClassKind.OBJECT && hasSerializableOrMetaAnnotation()
+
+// todo: optimize & unify with hasSerializableOrMeta
+internal fun IrClass.hasSerializableOrMetaAnnotationWithoutArgs(): Boolean {
+    val annot = getAnnotation(SerializationAnnotations.serializableAnnotationFqName)
+    if (annot != null) {
+        for (i in 0 until annot.valueArgumentsCount) {
+            if (annot.getValueArgument(i) != null) return false
+        }
+        return true
+    }
+    val metaAnnotation = annotations
+        .flatMap { it.symbol.owner.constructedClass.annotations }
+        .find { it.isAnnotation(SerializationAnnotations.metaSerializableAnnotationFqName) }
+    return metaAnnotation != null
+}
+
+internal val IrClass.isSerialInfoAnnotation: Boolean
+    get() = annotations.hasAnnotation(SerializationAnnotations.serialInfoFqName)
+            || annotations.hasAnnotation(SerializationAnnotations.inheritableSerialInfoFqName)
+            || annotations.hasAnnotation(SerializationAnnotations.metaSerializableAnnotationFqName)
+
+internal val IrClass.shouldHaveGeneratedSerializer: Boolean
+    get() = (isInternalSerializable && (modality == Modality.FINAL || modality == Modality.OPEN))
+            || isEnumWithLegacyGeneratedSerializer()
+
+internal val IrClass.shouldHaveGeneratedMethodsInCompanion: Boolean
+    get() = this.isSerializableObject || this.isSerializableEnum() || (this.kind == ClassKind.CLASS && hasSerializableOrMetaAnnotation()) || this.isSealedSerializableInterface
+
+internal fun IrClass.isSerializableEnum(): Boolean = kind == ClassKind.ENUM_CLASS && hasSerializableOrMetaAnnotation()
+
+fun IrClass.hasSerializableOrMetaAnnotation() = descriptor.hasSerializableOrMetaAnnotation // TODO
+
+internal val IrType.genericIndex: Int?
+    get() = (this.classifierOrNull as? IrTypeParameterSymbol)?.owner?.index
+
+fun IrType.serialName(): String = this.classOrNull!!.owner.serialName()
+
+fun IrClass.serialName(): String {
+    return annotations.serialNameValue ?: fqNameWhenAvailable?.asString() ?: error("${this.render()} does not have fqName")
+}
+
+fun IrClass.findEnumValuesMethod() = this.functions.singleOrNull { f ->
+    f.name == Name.identifier("values") && f.valueParameters.isEmpty() && f.extensionReceiverParameter == null
+} ?: throw AssertionError("Enum class does not have single .values() function")
+
+internal fun IrClass.enumEntries(): List<IrEnumEntry> {
+    check(this.kind == ClassKind.ENUM_CLASS)
+    return declarations.filterIsInstance<IrEnumEntry>().toList()
+}
+
+internal fun IrClass.isEnumWithSerialInfoAnnotation(): Boolean {
+    if (kind != ClassKind.ENUM_CLASS) return false
+    if (annotations.hasAnySerialAnnotation) return true
+    return enumEntries().any { (it.annotations.hasAnySerialAnnotation) }
+}
+
+fun IrClass.findWriteSelfMethod(): IrSimpleFunction? =
+    functions.singleOrNull { it.name == SerialEntityNames.WRITE_SELF_NAME && !it.isFakeOverride }
+
+fun IrClass.getSuperClassNotAny(): IrClass? {
+    val parentClass =
+        superTypes
+            .mapNotNull { it.classOrNull?.owner }
+            .singleOrNull { it.kind == ClassKind.CLASS || it.kind == ClassKind.ENUM_CLASS } ?: return null
+    return if (parentClass.defaultType.isAny()) null else parentClass
+}
+
+internal fun IrDeclaration.isFromPlugin(): Boolean =
+    this.origin == IrDeclarationOrigin.GeneratedByPlugin(SerializationPluginKey) || (this.descriptor as? CallableMemberDescriptor)?.kind == CallableMemberDescriptor.Kind.SYNTHESIZED // old FE doesn't specify origin
+
+internal fun IrConstructor.isSerializationCtor(): Boolean {
+    /*kind == CallableMemberDescriptor.Kind.SYNTHESIZED does not work because DeserializedClassConstructorDescriptor loses its kind*/
+    return valueParameters.lastOrNull()?.run {
+        name == SerialEntityNames.dummyParamName && type.classFqName == SerializationPackages.internalPackageFqName.child(
+            SerialEntityNames.SERIAL_CTOR_MARKER_NAME
+        )
+    } == true
+}
+
+
+internal fun IrConstructor.lastArgumentIsAnnotationArray(): Boolean {
+    val lastArgType = valueParameters.lastOrNull()?.type
+    if (lastArgType == null || !lastArgType.isArray()) return false
+    return ((lastArgType as? IrSimpleType)?.arguments?.firstOrNull()?.typeOrNull?.classFqName?.toString() == "kotlin.Annotation")
+}
+
+fun IrClass.serializableSyntheticConstructor(): IrConstructorSymbol? { // todo: remove nullability W/A when FIR plugin will add proper ctor
+    return declarations.filterIsInstance<IrConstructor>().singleOrNull { it.isSerializationCtor() }?.symbol
+}
+
+internal fun IrExpression.isInitializePropertyFromParameter(): Boolean =
+    this is IrGetValueImpl && this.origin == IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
+
+internal val IrConstructorCall.annotationClass
+    get() = this.symbol.owner.constructedClass
+
+internal val List<IrConstructorCall>.hasAnySerialAnnotation: Boolean
+    get() = serialNameValue != null || any { it.annotationClass.isSerialInfoAnnotation == true }
+
+internal val List<IrConstructorCall>.serialNameValue: String?
+    get() = findAnnotation(SerializationAnnotations.serialNameAnnotationFqName)?.getStringConstArgument(0) // @SerialName("foo")
+
+/**
+ * True — ALWAYS
+ * False — NEVER
+ * null — not specified
+ */
+fun IrProperty.getEncodeDefaultAnnotationValue(): Boolean? {
+    val call = annotations.findAnnotation(SerializationAnnotations.encodeDefaultFqName) ?: return null
+    val arg = call.getValueArgument(0) ?: return true // ALWAYS by default
+    val argValue = (arg as? IrGetEnumValue
+        ?: error("Argument of enum constructor expected to implement IrGetEnumValue, got $arg")).symbol.owner.name.toString()
+    return when (argValue) {
+        "ALWAYS" -> true
+        "NEVER" -> false
+        else -> error("Unknown EncodeDefaultMode enum value: $argValue")
+    }
+}
+
+fun findSerializerConstructorForTypeArgumentsSerializers(serializer: IrClass): IrConstructorSymbol? {
+    val typeParamsCount = ((serializer.superTypes.find { it.isKSerializer() } as IrSimpleType).arguments.first().typeOrNull!! as IrSimpleType).arguments.size
+    if (typeParamsCount == 0) return null //don't need it
+
+    return serializer.constructors.singleOrNull {
+        it.valueParameters.let { vps -> vps.size == typeParamsCount && vps.all { vp -> vp.type.isKSerializer() } }
+    }?.symbol
+}
\ No newline at end of file
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrSerializableProperties.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrSerializableProperties.kt
new file mode 100644
index 0000000..1aff0d2
--- /dev/null
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrSerializableProperties.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlinx.serialization.compiler.backend.ir
+
+import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrProperty
+import org.jetbrains.kotlin.ir.types.IrSimpleType
+import org.jetbrains.kotlin.ir.util.hasAnnotation
+import org.jetbrains.kotlin.ir.util.hasDefaultValue
+import org.jetbrains.kotlin.ir.util.primaryConstructor
+import org.jetbrains.kotlin.ir.util.properties
+import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
+import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin
+import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
+import org.jetbrains.kotlinx.serialization.compiler.resolve.ISerializableProperties
+import org.jetbrains.kotlinx.serialization.compiler.resolve.ISerializableProperty
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
+import org.jetbrains.kotlinx.serialization.compiler.resolve.declaresDefaultValue
+
+class IrSerializableProperty(
+    val ir: IrProperty,
+    override val isConstructorParameterWithDefault: Boolean,
+    hasBackingField: Boolean,
+    declaresDefaultValue: Boolean
+) : ISerializableProperty<IrSimpleType> {
+    override val name = ir.annotations.serialNameValue ?: ir.name.asString()
+    override val type = ir.getter!!.returnType as IrSimpleType
+    override val genericIndex = type.genericIndex
+    fun serializableWith(ctx: SerializationPluginContext) = ir.annotations.serializableWith() ?: analyzeSpecialSerializers(ctx, ir.annotations)
+    override val optional = !ir.annotations.hasAnnotation(SerializationAnnotations.requiredAnnotationFqName) && declaresDefaultValue
+    override val transient = ir.annotations.hasAnnotation(SerializationAnnotations.serialTransientFqName) || !hasBackingField
+}
+
+class IrSerializableProperties(
+    override val serializableProperties: List<IrSerializableProperty>,
+    override val isExternallySerializable: Boolean,
+    override val serializableConstructorProperties: List<IrSerializableProperty>,
+    override val serializableStandaloneProperties: List<IrSerializableProperty>
+) : ISerializableProperties<IrSimpleType, IrSerializableProperty>
+
+internal fun serializablePropertiesForIrBackend(
+    classDescriptor: IrClass,
+    serializationDescriptorSerializer: SerializationDescriptorSerializerPlugin? = null
+): IrSerializableProperties {
+    val properties = classDescriptor.properties.toList()
+    val primaryConstructorParams = classDescriptor.primaryConstructor?.valueParameters.orEmpty()
+    val primaryParamsAsProps = properties.associateBy { it.name }.let { namesMap ->
+        primaryConstructorParams.mapNotNull {
+            if (it.name !in namesMap) null else namesMap.getValue(it.name) to it.hasDefaultValue()
+        }.toMap()
+    }
+
+    fun isPropSerializable(it: IrProperty) =
+        if (classDescriptor.isInternalSerializable) !it.annotations.hasAnnotation(SerializationAnnotations.serialTransientFqName)
+        else !DescriptorVisibilities.isPrivate(it.visibility) && ((it.isVar && !it.annotations.hasAnnotation(SerializationAnnotations.serialTransientFqName)) || primaryParamsAsProps.contains(
+            it
+        ))
+
+    val (primaryCtorSerializableProps, bodySerializableProps) = properties
+        .asSequence()
+        .filter { !it.isFakeOverride && !it.isDelegated }
+        .filter(::isPropSerializable)
+        .map {
+            val isConstructorParameterWithDefault = primaryParamsAsProps[it] ?: false
+            // FIXME: workaround because IrLazyProperty doesn't deserialize information about backing fields. Fallback to descriptor won't work with FIR.
+            val isPropertyFromAnotherModuleDeclaresDefaultValue = it.descriptor is DeserializedPropertyDescriptor &&  it.descriptor.declaresDefaultValue()
+            val isPropertyWithBackingFieldFromAnotherModule = it.descriptor is DeserializedPropertyDescriptor && (it.descriptor.backingField != null || isPropertyFromAnotherModuleDeclaresDefaultValue)
+            IrSerializableProperty(
+                it,
+                isConstructorParameterWithDefault,
+                it.backingField != null || isPropertyWithBackingFieldFromAnotherModule,
+                it.backingField?.initializer.let { init -> init != null && !init.expression.isInitializePropertyFromParameter() } || isConstructorParameterWithDefault
+                        || isPropertyFromAnotherModuleDeclaresDefaultValue
+            )
+        }
+        .filterNot { it.transient }
+        .partition { primaryParamsAsProps.contains(it.ir) }
+
+    val serializableProps = run {
+        val supers = classDescriptor.getSuperClassNotAny()
+        if (supers == null || !supers.isInternalSerializable)
+            primaryCtorSerializableProps + bodySerializableProps
+        else
+            serializablePropertiesForIrBackend(
+                supers,
+                serializationDescriptorSerializer
+            ).serializableProperties + primaryCtorSerializableProps + bodySerializableProps
+    } // todo: implement unsorting
+
+    val isExternallySerializable =
+        classDescriptor.isInternallySerializableEnum() || primaryConstructorParams.size == primaryParamsAsProps.size
+
+    return IrSerializableProperties(serializableProps, isExternallySerializable, primaryCtorSerializableProps, bodySerializableProps)
+}
\ No newline at end of file
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerialInfoImplJvmIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerialInfoImplJvmIrGenerator.kt
index b5b61c9..ac81e44 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerialInfoImplJvmIrGenerator.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerialInfoImplJvmIrGenerator.kt
@@ -42,7 +42,7 @@
 class SerialInfoImplJvmIrGenerator(
     private val context: SerializationPluginContext,
     private val moduleFragment: IrModuleFragment,
-) : IrBuilderExtension {
+) : IrBuilderWithPluginContext {
     override val compilerContext: SerializationPluginContext
         get() = context
 
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt
index 5b57523..1614cec 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt
@@ -6,7 +6,6 @@
 package org.jetbrains.kotlinx.serialization.compiler.backend.ir
 
 import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
 import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
 import org.jetbrains.kotlin.ir.builders.irGet
 import org.jetbrains.kotlin.ir.builders.irInt
@@ -21,41 +20,37 @@
 import org.jetbrains.kotlin.name.ClassId
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.AbstractIrGenerator
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializer
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.getSerializableClassByCompanion
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.isKSerializer
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
-import org.jetbrains.kotlinx.serialization.compiler.resolve.*
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages
+import org.jetbrains.kotlinx.serialization.compiler.resolve.needSerializerFactory
 
 class SerializableCompanionIrGenerator(
     val irClass: IrClass,
     val serializableIrClass: IrClass,
-    override val compilerContext: SerializationPluginContext,
-) : AbstractIrGenerator(irClass), IrBuilderExtension {
+    compilerContext: SerializationPluginContext,
+) : BaseIrGenerator(irClass, compilerContext) {
 
-    private val serializableDescriptor = serializableIrClass.descriptor
-
-    private fun getSerializerGetterDescriptor(): FunctionDescriptor {
+    private fun getSerializerGetterFunction(): IrSimpleFunction {
         return irClass.findDeclaration<IrSimpleFunction> {
-            (it.valueParameters.size == serializableDescriptor.declaredTypeParameters.size
-                    && it.valueParameters.all { p -> isKSerializer(p.type) }) && isKSerializer(it.returnType)
-        }?.descriptor ?: throw IllegalStateException(
+            (it.valueParameters.size == serializableIrClass.typeParameters.size
+                    && it.valueParameters.all { p -> p.type.isKSerializer() }) && it.returnType.isKSerializer()
+        } ?: throw IllegalStateException(
             "Can't find synthesized 'Companion.serializer()' function to generate, " +
                     "probably clash with user-defined function has occurred"
         )
     }
 
     fun generate() {
-        val serializerGetterDescriptor = getSerializerGetterDescriptor()
+        val serializerGetterFunction = getSerializerGetterFunction()
 
-        if (serializableDescriptor.isSerializableObject
-            || serializableDescriptor.isAbstractOrSealedSerializableClass()
-            || serializableDescriptor.isSerializableEnum()
+        if (serializableIrClass.isSerializableObject
+            || serializableIrClass.isAbstractOrSealedSerializableClass
+            || serializableIrClass.isSerializableEnum()
         ) {
-            generateLazySerializerGetter(serializerGetterDescriptor)
+            generateLazySerializerGetter(serializerGetterFunction)
         } else {
-            generateSerializerGetter(serializerGetterDescriptor)
+            generateSerializerGetter(serializerGetterFunction)
         }
     }
 
@@ -64,8 +59,8 @@
             irClass: IrClass,
             context: SerializationPluginContext,
         ) {
-            val companionDescriptor = irClass.descriptor
-            val serializableClass = getSerializableClassDescriptorByCompanion(companionDescriptor) ?: return
+            val companionDescriptor = irClass
+            val serializableClass = getSerializableClassByCompanion(companionDescriptor) ?: return
             if (serializableClass.shouldHaveGeneratedMethodsInCompanion) {
                 SerializableCompanionIrGenerator(irClass, getSerializableClassByCompanion(irClass)!!, context).generate()
                 val declaration = irClass.constructors.primary // todo: move to appropriate place
@@ -110,7 +105,7 @@
         irSerializableClass.annotations += annotationCtorCall
     }
 
-    fun generateLazySerializerGetter(methodDescriptor: FunctionDescriptor) {
+    fun generateLazySerializerGetter(methodDescriptor: IrSimpleFunction) {
         val serializer = requireNotNull(
             findTypeSerializer(
                 compilerContext,
@@ -124,21 +119,20 @@
 
         val property = createLazyProperty(irClass, targetIrType, SerialEntityNames.CACHED_SERIALIZER_PROPERTY_NAME) {
             val expr = serializerInstance(
-                this@SerializableCompanionIrGenerator,
                 serializer, compilerContext, serializableIrClass.defaultType
             )
             patchSerializableClassWithMarkerAnnotation(kSerializerIrClass)
             +irReturn(requireNotNull(expr))
         }
 
-        irClass.contributeFunction(methodDescriptor) {
+        addFunctionBody(methodDescriptor) {
             +irReturn(getLazyValueExpression(it.dispatchReceiverParameter!!, property, targetIrType))
         }
         generateSerializerFactoryIfNeeded(methodDescriptor)
     }
 
-    fun generateSerializerGetter(methodDescriptor: FunctionDescriptor) {
-        irClass.contributeFunction(methodDescriptor) { getter ->
+    fun generateSerializerGetter(methodDescriptor: IrSimpleFunction) {
+        addFunctionBody(methodDescriptor) { getter ->
             val serializer = requireNotNull(
                 findTypeSerializer(
                     compilerContext,
@@ -147,7 +141,6 @@
             )
             val args: List<IrExpression> = getter.valueParameters.map { irGet(it) }
             val expr = serializerInstance(
-                this@SerializableCompanionIrGenerator,
                 serializer, compilerContext,
                 serializableIrClass.defaultType
             ) { it, _ -> args[it] }
@@ -157,25 +150,25 @@
         generateSerializerFactoryIfNeeded(methodDescriptor)
     }
 
-    private fun generateSerializerFactoryIfNeeded(getterDescriptor: FunctionDescriptor) {
+    private fun generateSerializerFactoryIfNeeded(getterDescriptor: IrSimpleFunction) {
         if (!irClass.descriptor.needSerializerFactory()) return
         val serialFactoryDescriptor = irClass.findDeclaration<IrSimpleFunction> {
             it.valueParameters.size == 1
                     && it.valueParameters.first().isVararg
-//                    && it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
-                    && isKSerializer(it.returnType)
+                    && it.returnType.isKSerializer()
+                    && it.isFromPlugin()
         } ?: return
         addFunctionBody(serialFactoryDescriptor) { factory ->
             val kSerializerStarType = factory.returnType
             val array = factory.valueParameters.first()
-            val argsSize = serializableDescriptor.declaredTypeParameters.size
+            val argsSize = serializableIrClass.typeParameters.size
             val arrayGet = compilerContext.irBuiltIns.arrayClass.owner.declarations.filterIsInstance<IrSimpleFunction>()
                 .single { it.name.asString() == "get" }
 
             val serializers: List<IrExpression> = (0 until argsSize).map {
                 irInvoke(irGet(array), arrayGet.symbol, irInt(it), typeHint = kSerializerStarType)
             }
-            val serializerCall = compilerContext.symbolTable.referenceSimpleFunction(getterDescriptor)
+            val serializerCall = getterDescriptor.symbol
             val call = irInvoke(
                 IrGetValueImpl(startOffset, endOffset, factory.dispatchReceiverParameter!!.symbol),
                 serializerCall,
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt
index b974b20..959e212 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt
@@ -24,7 +24,6 @@
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.util.OperatorNameConventions
 import org.jetbrains.kotlin.utils.getOrPutNullable
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
 import org.jetbrains.kotlinx.serialization.compiler.diagnostic.serializableAnnotationIsUseless
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
 import org.jetbrains.kotlinx.serialization.compiler.resolve.*
@@ -36,8 +35,8 @@
 
 class SerializableIrGenerator(
     val irClass: IrClass,
-    override val compilerContext: SerializationPluginContext
-) : AbstractIrGenerator(irClass), IrBuilderExtension {
+    compilerContext: SerializationPluginContext
+) : BaseIrGenerator(irClass, compilerContext) {
 
     protected val properties = serializablePropertiesForIrBackend(irClass)
 
@@ -65,7 +64,7 @@
             val thiz = irClass.thisReceiver!!
             val serializableProperties = properties.serializableProperties
 
-            val serialDescs = serializableProperties.map { it.descriptor }.toSet()
+            val serialDescs = serializableProperties.map { it.ir }.toSet()
 
             val propertyByParamReplacer: (ValueParameterDescriptor) -> IrExpression? =
                 createPropertyByParamReplacer(irClass, serializableProperties, thiz)
@@ -137,19 +136,19 @@
                 val paramRef = ctor.valueParameters[index + seenVarsOffset]
                 // Assign this.a = a in else branch
                 // Set field directly w/o setter to match behavior of old backend plugin
-                val backingFieldToAssign = prop.descriptor.backingField!!
+                val backingFieldToAssign = prop.ir.backingField!!
                 val assignParamExpr = irSetField(irGet(thiz), backingFieldToAssign, irGet(paramRef))
 
                 val ifNotSeenExpr: IrExpression = if (prop.optional) {
                     val initializerBody =
-                        requireNotNull(initializerAdapter(prop.irField?.initializer!!)) { "Optional value without an initializer" } // todo: filter abstract here
+                        requireNotNull(initializerAdapter(prop.ir.backingField?.initializer!!)) { "Optional value without an initializer" } // todo: filter abstract here
                     irSetField(irGet(thiz), backingFieldToAssign, initializerBody)
                 } else {
                     // property required
                     if (useFieldMissingOptimization()) {
                         // field definitely not empty as it's checked before - no need another IF, only assign property from param
                         +assignParamExpr
-                        statementsAfterSerializableProperty[prop.descriptor]?.forEach { +it }
+                        statementsAfterSerializableProperty[prop.ir]?.forEach { +it }
                         continue
                     } else {
                         irThrow(irInvoke(null, exceptionCtorRef, irString(prop.name), typeHint = exceptionType))
@@ -168,7 +167,7 @@
 
                 +irIfThenElse(compilerContext.irBuiltIns.unitType, propNotSeenTest, ifNotSeenExpr, assignParamExpr)
 
-                statementsAfterSerializableProperty[prop.descriptor]?.forEach { +it }
+                statementsAfterSerializableProperty[prop.ir]?.forEach { +it }
             }
 
             // Handle function-intialized interface delegates
@@ -271,7 +270,7 @@
         propertiesStart: Int
     ): Int {
         check(superClass.isInternalSerializable)
-        val superCtorRef = serializableSyntheticConstructor(superClass)!!
+        val superCtorRef = superClass.serializableSyntheticConstructor()!!
         val superProperties = serializablePropertiesForIrBackend(superClass).serializableProperties
         val superSlots = superProperties.bitMaskSlotCount()
         val arguments = allValueParameters.subList(0, superSlots) +
@@ -332,7 +331,6 @@
                         val genericIdx = irClass.defaultType.arguments.indexOf(arg).let { if (it == -1) null else it }
                         val serial = findTypeSerializerOrContext(compilerContext, arg.typeOrNull!!)
                         serializerInstance(
-                            this@SerializableIrGenerator,
                             serial,
                             compilerContext,
                             arg.typeOrNull!!,
@@ -346,9 +344,9 @@
             }
 
             serializeAllProperties(
-                this@SerializableIrGenerator, irClass, serializableProperties,
-                objectToSerialize, localOutput, localSerialDesc,
-                kOutputClass, ignoreIndexTo, initializerAdapter
+                serializableProperties, objectToSerialize,
+                localOutput, localSerialDesc, kOutputClass,
+                ignoreIndexTo, initializerAdapter
             ) { it, _ ->
                 irGet(writeSelfFunction.valueParameters[3 + it])
             }
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt
index 5110370..687bfd4 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt
@@ -7,8 +7,6 @@
 
 import org.jetbrains.kotlin.backend.jvm.functionByName
 import org.jetbrains.kotlin.builtins.StandardNames
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
 import org.jetbrains.kotlin.ir.builders.*
 import org.jetbrains.kotlin.ir.declarations.IrClass
 import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
@@ -23,14 +21,9 @@
 import org.jetbrains.kotlin.ir.util.functions
 import org.jetbrains.kotlin.ir.util.properties
 import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.enumEntries
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.getClassFromInternalSerializationPackage
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.getClassFromRuntime
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.serialNameValue
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
-import org.jetbrains.kotlinx.serialization.compiler.resolve.*
+import org.jetbrains.kotlinx.serialization.compiler.resolve.CallingConventions
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
 
 class SerializerForEnumsGenerator(
     irClass: IrClass,
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt
index a94c333..9327fc1 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt
@@ -6,8 +6,6 @@
 package org.jetbrains.kotlinx.serialization.compiler.backend.ir
 
 import org.jetbrains.kotlin.backend.jvm.functionByName
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
 import org.jetbrains.kotlin.ir.builders.*
 import org.jetbrains.kotlin.ir.declarations.IrClass
 import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
@@ -18,12 +16,9 @@
 import org.jetbrains.kotlin.ir.types.IrType
 import org.jetbrains.kotlin.ir.types.typeOrNull
 import org.jetbrains.kotlin.ir.util.constructors
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.getClassFromInternalSerializationPackage
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.getClassFromRuntime
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
-import org.jetbrains.kotlinx.serialization.compiler.resolve.*
+import org.jetbrains.kotlinx.serialization.compiler.resolve.CallingConventions
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
 
 class SerializerForInlineClassGenerator(
     irClass: IrClass,
@@ -44,7 +39,7 @@
         val inlineEncoder = irTemporary(encodeInlineCall, nameHint = "inlineEncoder")
 
         val property = serializableProperties.first()
-        val value = getFromBox(irGet(saveFunc.valueParameters[1]), property)
+        val value = getProperty(irGet(saveFunc.valueParameters[1]), property.ir)
 
         // inlineEncoder.encodeInt/String/SerializableValue
         val elementCall = formEncodeDecodePropertyCall(irGet(inlineEncoder), saveFunc.dispatchReceiverParameter!!, property, {innerSerial, sti ->
@@ -109,6 +104,4 @@
             listOf(expression)
         )
 
-    private fun IrBlockBodyBuilder.getFromBox(expression: IrExpression, serializableProperty: IrSerializableProperty): IrExpression =
-        getProperty(expression, serializableProperty.descriptor)
 }
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt
index 75c4587..706be67 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt
@@ -37,7 +37,6 @@
 import org.jetbrains.kotlin.resolve.isInlineClass
 import org.jetbrains.kotlin.util.OperatorNameConventions
 import org.jetbrains.kotlin.utils.addToStdlib.cast
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
 import org.jetbrains.kotlinx.serialization.compiler.resolve.*
@@ -55,10 +54,10 @@
 
 open class SerializerIrGenerator(
     val irClass: IrClass,
-    final override val compilerContext: SerializationPluginContext,
+    compilerContext: SerializationPluginContext,
     metadataPlugin: SerializationDescriptorSerializerPlugin?,
     private val serialInfoJvmGenerator: SerialInfoImplJvmIrGenerator,
-) : AbstractIrGenerator(irClass), IrBuilderExtension {
+) : BaseIrGenerator(irClass, compilerContext) {
     protected val serializableIrClass = getSerializableClassDescriptorBySerializer(irClass)!!
 
     protected val serialName: String = serializableIrClass.serialName()
@@ -91,7 +90,7 @@
         if (count == 0) return emptyList()
         val propNames = (0 until count).map { "${SerialEntityNames.typeArgPrefix}$it" }
         return propNames.mapNotNull { name ->
-            getProperty(name) { isKSerializer(it.getter!!.returnType) }
+            getProperty(name) { it.getter!!.returnType.isKSerializer() }
         }
     }
 
@@ -184,7 +183,7 @@
             if (classProp.transient) continue
             +addFieldCall(classProp)
             // add property annotations
-            val property = classProp.descriptor//.getIrPropertyFrom(serializableIrClass)
+            val property = classProp.ir//.getIrPropertyFrom(serializableIrClass)
             copySerialInfoAnnotationsToDescriptor(
                 property.annotations,
                 localDescriptor,
@@ -305,8 +304,8 @@
                 createInitializerAdapter(serializableIrClass, propertyByParamReplacer, thisSymbol to { irGet(objectToSerialize) })
 
             serializeAllProperties(
-                this@SerializerIrGenerator, serializableIrClass, serializableProperties, objectToSerialize,
-                localOutput, localSerialDesc, kOutputClass, ignoreIndexTo = -1, initializerAdapter
+                serializableProperties, objectToSerialize, localOutput,
+                localSerialDesc, kOutputClass, ignoreIndexTo = -1, initializerAdapter
             ) { it, _ ->
                 val (_, ir) = localSerializersFieldsDescriptors[it]
                 irGetField(irGet(saveFunc.dispatchReceiverParameter!!), ir.backingField!!)
@@ -326,7 +325,6 @@
         whenDoNot: (sti: IrSerialTypeInfo) -> FunctionWithArgs,
         returnTypeHint: IrType? = null
     ): IrExpression = formEncodeDecodePropertyCall(
-        this@SerializerIrGenerator,
         encoder,
         property,
         whenHaveSerializer,
@@ -385,7 +383,7 @@
 
         val serialPropertiesIndexes = serializableProperties
             .mapIndexed { i, property -> property to i }
-            .associate { (p, i) -> p.descriptor to i }
+            .associate { (p, i) -> p.ir to i }
 
         val transients = serializableIrClass.declarations.asSequence()
             .filterIsInstance<IrProperty>()
@@ -395,7 +393,7 @@
         // var bitMask0 = 0, bitMask1 = 0...
         val bitMasks = (0 until blocksCnt).map { irTemporary(irInt(0), "bitMask$it", isMutable = true) }
         // var local0 = null, local1 = null ...
-        val serialPropertiesMap = serializableProperties.mapIndexed { i, prop -> i to prop.descriptor }.associate { (i, descriptor) ->
+        val serialPropertiesMap = serializableProperties.mapIndexed { i, prop -> i to prop.ir }.associate { (i, descriptor) ->
             val (expr, type) = defaultValueAndType(descriptor)
             descriptor to irTemporary(expr, "local$i", type, isMutable = true)
         }
@@ -425,7 +423,7 @@
                                 it.owner.name.asString() == "${CallingConventions.decode}${sti.elementMethodPrefix}Serializable${CallingConventions.elementPostfix}" &&
                                         it.owner.valueParameters.size == 4
                             } to listOf(
-                                localSerialDesc.get(), irInt(index), innerSerial, serialPropertiesMap.getValue(property.descriptor).get()
+                                localSerialDesc.get(), irInt(index), innerSerial, serialPropertiesMap.getValue(property.ir).get()
                             )
                         }, {sti ->
                                                          inputClass.functions.single {
@@ -435,7 +433,7 @@
                                                      }, returnTypeHint = property.type)
                     // local$i = localInput.decode...(...)
                     +irSet(
-                        serialPropertiesMap.getValue(property.descriptor).symbol,
+                        serialPropertiesMap.getValue(property.ir).symbol,
                         decodeFuncToCall
                     )
                     // bitMask[i] |= 1 << x
@@ -492,9 +490,9 @@
         )
 
         val typeArgs = (loadFunc.returnType as IrSimpleType).arguments.map { (it as IrTypeProjection).type }
-        val deserCtor: IrConstructorSymbol? = serializableSyntheticConstructor(serializableIrClass)
+        val deserCtor: IrConstructorSymbol? = serializableIrClass.serializableSyntheticConstructor()
         if (serializableIrClass.isInternalSerializable && deserCtor != null) {
-            var args: List<IrExpression> = serializableProperties.map { serialPropertiesMap.getValue(it.descriptor).get() }
+            var args: List<IrExpression> = serializableProperties.map { serialPropertiesMap.getValue(it.ir).get() }
             args = bitMasks.map { irGet(it) } + args + irNull()
             +irReturn(irInvoke(null, deserCtor, typeArgs, args))
         } else {
@@ -574,9 +572,9 @@
         bitMasks: List<IrVariable>
     ) {
         for (property in properties.serializableStandaloneProperties) {
-            val localPropIndex = propIndexes(property.descriptor)
+            val localPropIndex = propIndexes(property.ir)
             // generate setter call
-            val setter = property.descriptor.setter!!
+            val setter = property.ir.setter!!
             val propSeenTest =
                 irNotEquals(
                     irInt(0),
@@ -587,13 +585,12 @@
                     )
                 )
 
-            val setterInvokeExpr = irSet(setter.returnType, irGet(serializableVar), setter.symbol, irGet(propVars(property.descriptor)))
+            val setterInvokeExpr = irSet(setter.returnType, irGet(serializableVar), setter.symbol, irGet(propVars(property.ir)))
 
             +irIfThen(propSeenTest, setterInvokeExpr)
         }
     }
 
-    // !!! TODO: this doesn't work with OLD FE !!!
     fun generate() {
         val prop = generatedSerialDescPropertyDescriptor?.let { generateSerializableClassProperty(it); true } ?: false
         if (prop)
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerSearchUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerSearchUtil.kt
new file mode 100644
index 0000000..048f837
--- /dev/null
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerSearchUtil.kt
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlinx.serialization.compiler.backend.ir
+
+import org.jetbrains.kotlin.descriptors.ClassKind
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.expressions.IrClassReference
+import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
+import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.types.*
+import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlinx.serialization.compiler.backend.common.findStandardKotlinTypeSerializer
+import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
+import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SpecialBuiltins
+
+class IrSerialTypeInfo(
+    val property: IrSerializableProperty,
+    val elementMethodPrefix: String,
+    val serializer: IrClassSymbol? = null
+)
+
+fun BaseIrGenerator.getIrSerialTypeInfo(property: IrSerializableProperty, ctx: SerializationPluginContext): IrSerialTypeInfo {
+    fun SerializableInfo(serializer: IrClassSymbol?) =
+        IrSerialTypeInfo(property, if (property.type.isNullable()) "Nullable" else "", serializer)
+
+    val T = property.type
+    property.serializableWith(ctx)?.let { return SerializableInfo(it) }
+    findAddOnSerializer(T, ctx)?.let { return SerializableInfo(it) }
+    T.overridenSerializer?.let { return SerializableInfo(it) }
+    return when {
+        T.isTypeParameter() -> IrSerialTypeInfo(property, if (property.type.isMarkedNullable()) "Nullable" else "", null)
+        T.isPrimitiveType() -> IrSerialTypeInfo(
+            property,
+            T.classFqName!!.asString().removePrefix("kotlin.")
+        )
+        T.isString() -> IrSerialTypeInfo(property, "String")
+        T.isArray() -> {
+            val serializer = property.serializableWith(ctx) ?: ctx.getClassFromInternalSerializationPackage(SpecialBuiltins.referenceArraySerializer)
+            SerializableInfo(serializer)
+        }
+        else -> {
+            val serializer =
+                findTypeSerializerOrContext(ctx, property.type)
+            SerializableInfo(serializer)
+        }
+    }
+}
+
+fun BaseIrGenerator.findAddOnSerializer(propertyType: IrType, ctx: SerializationPluginContext): IrClassSymbol? {
+    val classSymbol = propertyType.classOrNull ?: return null
+    additionalSerializersInScopeOfCurrentFile[classSymbol to propertyType.isNullable()]?.let { return it }
+    if (classSymbol in contextualKClassListInCurrentFile)
+        return ctx.getClassFromRuntime(SpecialBuiltins.contextSerializer)
+    if (classSymbol.owner.annotations.hasAnnotation(SerializationAnnotations.polymorphicFqName))
+        return ctx.getClassFromRuntime(SpecialBuiltins.polymorphicSerializer)
+    if (propertyType.isNullable()) return findAddOnSerializer(propertyType.makeNotNull(), ctx)
+    return null
+}
+
+fun BaseIrGenerator.findTypeSerializerOrContext(
+    context: SerializationPluginContext, kType: IrType
+): IrClassSymbol? {
+    if (kType.isTypeParameter()) return null
+    return findTypeSerializerOrContextUnchecked(context, kType) ?: error("Serializer for element of type ${kType.render()} has not been found")
+}
+
+fun BaseIrGenerator.findTypeSerializerOrContextUnchecked(
+    context: SerializationPluginContext, kType: IrType
+): IrClassSymbol? {
+    val annotations = kType.annotations
+    if (kType.isTypeParameter()) return null
+    annotations.serializableWith()?.let { return it }
+    additionalSerializersInScopeOfCurrentFile[kType.classOrNull!! to kType.isNullable()]?.let {
+        return it
+    }
+    if (kType.isMarkedNullable()) return findTypeSerializerOrContextUnchecked(context, kType.makeNotNull())
+    if (kType.classOrNull in contextualKClassListInCurrentFile) return context.referenceClass(contextSerializerId)
+    return analyzeSpecialSerializers(context, annotations) ?: findTypeSerializer(context, kType)
+}
+
+fun analyzeSpecialSerializers(
+    context: SerializationPluginContext,
+    annotations: List<IrConstructorCall>
+): IrClassSymbol? = when {
+    annotations.hasAnnotation(SerializationAnnotations.contextualFqName) || annotations.hasAnnotation(SerializationAnnotations.contextualOnPropertyFqName) ->
+        context.referenceClass(contextSerializerId)
+    // can be annotation on type usage, e.g. List<@Polymorphic Any>
+    annotations.hasAnnotation(SerializationAnnotations.polymorphicFqName) ->
+        context.referenceClass(polymorphicSerializerId)
+    else -> null
+}
+
+
+fun findTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
+    type.overridenSerializer?.let { return it }
+    if (type.isTypeParameter()) return null
+    if (type.isArray()) return context.referenceClass(referenceArraySerializerId)
+    if (type.isGeneratedSerializableObject()) return context.referenceClass(objectSerializerId)
+    val stdSer = findStandardKotlinTypeSerializer(context, type) // see if there is a standard serializer
+        ?: findEnumTypeSerializer(context, type)
+    if (stdSer != null) return stdSer
+    if (type.isInterface() && type.classOrNull?.owner?.isSealedSerializableInterface == false) return context.referenceClass(
+        polymorphicSerializerId
+    )
+    return type.classOrNull?.owner.classSerializer(context) // check for serializer defined on the type
+}
+fun findEnumTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
+    val classSymbol = type.classOrNull?.owner ?: return null
+    return if (classSymbol.kind == ClassKind.ENUM_CLASS && !classSymbol.isEnumWithLegacyGeneratedSerializer())
+        context.referenceClass(enumSerializerId)
+    else null
+}
+
+internal fun IrClass?.classSerializer(context: SerializationPluginContext): IrClassSymbol? = this?.let {
+    // serializer annotation on class?
+    serializableWith?.let { return it }
+    // companion object serializer?
+    if (hasCompanionObjectAsSerializer) return companionObject()?.symbol
+    // can infer @Poly?
+    polymorphicSerializerIfApplicableAutomatically(context)?.let { return it }
+    // default serializable?
+    if (shouldHaveGeneratedSerializer) {
+        // $serializer nested class
+        return this.declarations
+            .filterIsInstance<IrClass>()
+            .singleOrNull { it.name == SerialEntityNames.SERIALIZER_CLASS_NAME }?.symbol
+    }
+    return null
+}
+
+internal fun IrClass.polymorphicSerializerIfApplicableAutomatically(context: SerializationPluginContext): IrClassSymbol? {
+    val serializer = when {
+        kind == ClassKind.INTERFACE && modality == Modality.SEALED -> SpecialBuiltins.sealedSerializer
+        kind == ClassKind.INTERFACE -> SpecialBuiltins.polymorphicSerializer
+        isInternalSerializable && modality == Modality.ABSTRACT -> SpecialBuiltins.polymorphicSerializer
+        isInternalSerializable && modality == Modality.SEALED -> SpecialBuiltins.sealedSerializer
+        else -> null
+    }
+    return serializer?.let {
+        context.getClassFromRuntimeOrNull(
+            it,
+            SerializationPackages.packageFqName,
+            SerializationPackages.internalPackageFqName
+        )
+    }
+}
+
+internal val IrType.overridenSerializer: IrClassSymbol?
+    get() {
+        val desc = this.classOrNull ?: return null
+        desc.owner.serializableWith?.let { return it }
+        return null
+    }
+
+internal val IrClass.serializableWith: IrClassSymbol?
+    get() = annotations.serializableWith()
+
+internal val IrClass.serializerForClass: IrClassSymbol?
+    get() = (annotations.findAnnotation(SerializationAnnotations.serializerAnnotationFqName)
+        ?.getValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol
+
+fun findStandardKotlinTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
+    val typeName = type.classFqName?.toString()
+    val name = when (typeName) {
+        "Z" -> if (type.isBoolean()) "BooleanSerializer" else null
+        "B" -> if (type.isByte()) "ByteSerializer" else null
+        "S" -> if (type.isShort()) "ShortSerializer" else null
+        "I" -> if (type.isInt()) "IntSerializer" else null
+        "J" -> if (type.isLong()) "LongSerializer" else null
+        "F" -> if (type.isFloat()) "FloatSerializer" else null
+        "D" -> if (type.isDouble()) "DoubleSerializer" else null
+        "C" -> if (type.isChar()) "CharSerializer" else null
+        null -> null
+        else -> findStandardKotlinTypeSerializer(typeName)
+    } ?: return null
+    return context.getClassFromRuntimeOrNull(name, SerializationPackages.internalPackageFqName, SerializationPackages.packageFqName)
+}
+
+// @Serializable(X::class) -> X
+internal fun List<IrConstructorCall>.serializableWith(): IrClassSymbol? {
+    val annotation = findAnnotation(SerializationAnnotations.serializableAnnotationFqName) ?: return null
+    val arg = annotation.getValueArgument(0) as? IrClassReference ?: return null
+    return arg.symbol as? IrClassSymbol
+}
+
+internal fun getSerializableClassByCompanion(companionClass: IrClass): IrClass? {
+    if (companionClass.isSerializableObject) return companionClass
+    if (!companionClass.isCompanion) return null
+    val classDescriptor = (companionClass.parent as? IrClass) ?: return null
+    if (!classDescriptor.shouldHaveGeneratedMethodsInCompanion) return null
+    return classDescriptor
+}
+
+fun BaseIrGenerator.allSealedSerializableSubclassesFor(
+    irClass: IrClass,
+    context: SerializationPluginContext
+): Pair<List<IrSimpleType>, List<IrClassSymbol>> {
+    assert(irClass.modality == Modality.SEALED)
+    fun recursiveSealed(klass: IrClass): Collection<IrClass> {
+        return klass.sealedSubclasses.map { it.owner }.flatMap { if (it.modality == Modality.SEALED) recursiveSealed(it) else setOf(it) }
+    }
+
+    val serializableSubtypes = recursiveSealed(irClass).map { it.defaultType }
+    return serializableSubtypes.mapNotNull { subtype ->
+        findTypeSerializerOrContextUnchecked(context, subtype)?.let { Pair(subtype, it) }
+    }.unzip()
+}
+
+internal fun getSerializableClassDescriptorBySerializer(serializer: IrClass): IrClass? {
+    val serializerForClass = serializer.serializerForClass
+    if (serializerForClass != null) return serializerForClass.owner
+    if (serializer.name !in setOf(
+            SerialEntityNames.SERIALIZER_CLASS_NAME,
+            SerialEntityNames.GENERATED_SERIALIZER_CLASS
+        )
+    ) return null
+    val classDescriptor = (serializer.parent as? IrClass) ?: return null
+    if (!classDescriptor.shouldHaveGeneratedSerializer) return null
+    return classDescriptor
+}
+
+fun SerializationPluginContext.getClassFromRuntimeOrNull(className: String, vararg packages: FqName): IrClassSymbol? {
+    val listToSearch = if (packages.isEmpty()) SerializationPackages.allPublicPackages else packages.toList()
+    for (pkg in listToSearch) {
+        referenceClass(ClassId(pkg, Name.identifier(className)))?.let { return it }
+    }
+    return null
+}
+
+fun SerializationPluginContext.getClassFromRuntime(className: String, vararg packages: FqName): IrClassSymbol {
+    return getClassFromRuntimeOrNull(className, *packages) ?: error(
+        "Class $className wasn't found in ${packages.toList().ifEmpty { SerializationPackages.allPublicPackages }}. " +
+                "Check that you have correct version of serialization runtime in classpath."
+    )
+}
+
+fun SerializationPluginContext.getClassFromInternalSerializationPackage(className: String): IrClassSymbol =
+    getClassFromRuntimeOrNull(className, SerializationPackages.internalPackageFqName)
+        ?: error("Class $className wasn't found in ${SerializationPackages.internalPackageFqName}. Check that you have correct version of serialization runtime in classpath.")
+
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/Synthetics.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/Synthetics.kt
deleted file mode 100644
index 0f04d46..0000000
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/Synthetics.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.jetbrains.kotlinx.serialization.compiler.backend.ir
-
-import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
-import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.types.KotlinType
-
-
-/**
- * Simple property descriptor with backing field without getters/setters for ir generation purposes
- */
-class SimpleSyntheticPropertyDescriptor(
-    owner: ClassDescriptor,
-    name: String,
-    type: KotlinType,
-    isVar: Boolean = false,
-    visibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE
-) : PropertyDescriptorImpl(
-    owner,
-    null,
-    Annotations.EMPTY,
-    Modality.FINAL,
-    visibility,
-    isVar,
-    Name.identifier(name),
-    CallableMemberDescriptor.Kind.SYNTHESIZED,
-    owner.source,
-    false, false, false, false, false, false
-    ) {
-
-    private val _backingField = FieldDescriptorImpl(Annotations.EMPTY, this)
-
-    init {
-        super.setType(type, emptyList(), owner.thisAsReceiverParameter, null, emptyList())
-        super.initialize(null, null, _backingField, null)
-    }
-}
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt
index 6145145..1d55337 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt
@@ -6,15 +6,6 @@
 package org.jetbrains.kotlinx.serialization.compiler.resolve
 
 import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.ir.declarations.IrClass
-import org.jetbrains.kotlin.ir.declarations.IrProperty
-import org.jetbrains.kotlin.ir.declarations.lazy.IrMaybeDeserializedClass
-import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
-import org.jetbrains.kotlin.ir.types.IrSimpleType
-import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.ir.types.classOrNull
-import org.jetbrains.kotlin.ir.types.isAny
-import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.psi.KtDeclarationWithInitializer
 import org.jetbrains.kotlin.psi.KtParameter
@@ -27,15 +18,11 @@
 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
 import org.jetbrains.kotlin.serialization.deserialization.getName
 import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext.isInterface
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.isInitializePropertyFromParameter
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.isInternalSerializable
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.isInternallySerializableEnum
 import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SERIALIZABLE_PROPERTIES
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin
 import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginMetadataExtensions
 
-interface ISerializableProperties<D, T, S : ISerializableProperty<D, T>> {
+interface ISerializableProperties<T, S : ISerializableProperty<T>> {
     val serializableProperties: List<S>
     val isExternallySerializable: Boolean
     val serializableConstructorProperties: List<S>
@@ -43,7 +30,7 @@
 }
 
 class SerializableProperties(private val serializableClass: ClassDescriptor, val bindingContext: BindingContext) :
-    ISerializableProperties<PropertyDescriptor, KotlinType, SerializableProperty> {
+    ISerializableProperties<KotlinType, SerializableProperty> {
     private val primaryConstructorParameters: List<ValueParameterDescriptor> =
         serializableClass.unsubstitutedPrimaryConstructor?.valueParameters ?: emptyList()
 
@@ -134,7 +121,7 @@
 }
 
 
-internal val ISerializableProperties<*, *, *>.goldenMask: Int
+internal val ISerializableProperties<*, *>.goldenMask: Int
     get() {
         var goldenMask = 0
         var requiredBit = 1
@@ -147,7 +134,7 @@
         return goldenMask
     }
 
-internal val ISerializableProperties<*, *, *>.goldenMaskList: List<Int>
+internal val ISerializableProperties<*, *>.goldenMaskList: List<Int>
     get() {
         val maskSlotCount = serializableProperties.bitMaskSlotCount()
         val goldenMaskList = MutableList(maskSlotCount) { 0 }
@@ -162,7 +149,7 @@
         return goldenMaskList
     }
 
-internal fun List<ISerializableProperty<*, *>>.bitMaskSlotCount() = size / 32 + 1
+internal fun List<ISerializableProperty<*>>.bitMaskSlotCount() = size / 32 + 1
 internal fun bitMaskSlotAt(propertyIndex: Int) = propertyIndex / 32
 
 internal fun BindingContext.serializablePropertiesFor(
@@ -180,75 +167,4 @@
         .map { descriptor.c.nameResolver.getName(it) }
     val propsMap = props.associateBy { it.descriptor.name }
     return correctOrder.map { propsMap.getValue(it) }
-}
-
-class IrSerializableProperties(
-    override val serializableProperties: List<IrSerializableProperty>,
-    override val isExternallySerializable: Boolean,
-    override val serializableConstructorProperties: List<IrSerializableProperty>,
-    override val serializableStandaloneProperties: List<IrSerializableProperty>
-) : ISerializableProperties<IrProperty, IrSimpleType, IrSerializableProperty> {
-}
-
-internal fun serializablePropertiesForIrBackend(
-    classDescriptor: IrClass,
-    serializationDescriptorSerializer: SerializationDescriptorSerializerPlugin? = null
-): IrSerializableProperties {
-    val properties = classDescriptor.properties.toList()
-    val primaryConstructorParams = classDescriptor.primaryConstructor?.valueParameters.orEmpty()
-    val primaryParamsAsProps = properties.associateBy { it.name }.let { namesMap ->
-        primaryConstructorParams.mapNotNull {
-            if (it.name !in namesMap) null else namesMap.getValue(it.name) to it.hasDefaultValue()
-        }.toMap()
-    }
-
-    fun isPropSerializable(it: IrProperty) =
-        if (classDescriptor.isInternalSerializable) !it.annotations.hasAnnotation(SerializationAnnotations.serialTransientFqName)
-        else !DescriptorVisibilities.isPrivate(it.visibility) && ((it.isVar && !it.annotations.hasAnnotation(SerializationAnnotations.serialTransientFqName)) || primaryParamsAsProps.contains(
-            it
-        ))
-
-    val (primaryCtorSerializableProps, bodySerializableProps) = properties
-        .asSequence()
-        .filter { !it.isFakeOverride && !it.isDelegated }
-        .filter(::isPropSerializable)
-        .map {
-            val isConstructorParameterWithDefault = primaryParamsAsProps[it] ?: false
-            // FIXME: workaround because IrLazyProperty doesn't deserialize information about backing fields. Fallback to descriptor won't work with FIR.
-            val isPropertyFromAnotherModuleDeclaresDefaultValue = it.descriptor is DeserializedPropertyDescriptor &&  it.descriptor.declaresDefaultValue()
-            val isPropertyWithBackingFieldFromAnotherModule = it.descriptor is DeserializedPropertyDescriptor && (it.descriptor.backingField != null || isPropertyFromAnotherModuleDeclaresDefaultValue)
-            IrSerializableProperty(
-                it,
-                isConstructorParameterWithDefault,
-                it.backingField != null || isPropertyWithBackingFieldFromAnotherModule,
-                it.backingField?.initializer.let { init -> init != null && !init.expression.isInitializePropertyFromParameter() } || isConstructorParameterWithDefault
-                        || isPropertyFromAnotherModuleDeclaresDefaultValue
-            )
-        }
-        .filterNot { it.transient }
-        .partition { primaryParamsAsProps.contains(it.descriptor) }
-
-    val serializableProps = run {
-        val supers = classDescriptor.getParentClassNotAny()
-        if (supers == null || !supers.isInternalSerializable)
-            primaryCtorSerializableProps + bodySerializableProps
-        else
-            serializablePropertiesForIrBackend(
-                supers,
-                serializationDescriptorSerializer
-            ).serializableProperties + primaryCtorSerializableProps + bodySerializableProps
-    } // todo: implement unsorting
-
-    val isExternallySerializable =
-        classDescriptor.isInternallySerializableEnum() || primaryConstructorParams.size == primaryParamsAsProps.size
-
-    return IrSerializableProperties(serializableProps, isExternallySerializable, primaryCtorSerializableProps, bodySerializableProps)
-}
-
-fun IrClass.getParentClassNotAny(): IrClass? {
-    val parentClass =
-        superTypes
-            .mapNotNull { it.classOrNull?.owner }
-            .singleOrNull { it.kind == ClassKind.CLASS || it.kind == ClassKind.ENUM_CLASS } ?: return null
-    return if (parentClass.defaultType.isAny()) null else parentClass
 }
\ No newline at end of file
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperty.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperty.kt
index d51337a..a06e5e4 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperty.kt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperty.kt
@@ -16,40 +16,12 @@
 
 package org.jetbrains.kotlinx.serialization.compiler.resolve
 
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
 import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.ir.declarations.IrProperty
-import org.jetbrains.kotlin.ir.types.IrSimpleType
-import org.jetbrains.kotlin.ir.util.hasAnnotation
-import org.jetbrains.kotlin.psi.ValueArgument
 import org.jetbrains.kotlin.resolve.descriptorUtil.module
 import org.jetbrains.kotlin.types.KotlinType
 import org.jetbrains.kotlinx.serialization.compiler.backend.common.analyzeSpecialSerializers
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.genericIndex
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.serialNameValue
-import org.jetbrains.kotlinx.serialization.compiler.backend.common.serializableWith
-import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
 
-class SerializableProperty(
-    override val descriptor: PropertyDescriptor,
-    override val isConstructorParameterWithDefault: Boolean,
-    hasBackingField: Boolean,
-    declaresDefaultValue: Boolean
-) : ISerializableProperty<PropertyDescriptor, KotlinType> {
-    override val name = descriptor.annotations.serialNameValue ?: descriptor.name.asString()
-    override val type = descriptor.type
-    override val genericIndex = type.genericIndex
-    val module = descriptor.module
-    val serializableWith = descriptor.serializableWith ?: analyzeSpecialSerializers(module, descriptor.annotations)?.defaultType
-    override val optional = !descriptor.annotations.serialRequired && declaresDefaultValue
-    override val transient = descriptor.annotations.serialTransient || !hasBackingField
-    val annotationsWithArguments: List<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
-        descriptor.annotationsWithArguments()
-}
-
-interface ISerializableProperty<D, T> {
-    val descriptor: D
+interface ISerializableProperty<T> {
     val isConstructorParameterWithDefault: Boolean
     val name: String
     val type: T
@@ -58,16 +30,18 @@
     val transient: Boolean
 }
 
-class IrSerializableProperty(
-    override val descriptor: IrProperty,
+class SerializableProperty(
+    val descriptor: PropertyDescriptor,
     override val isConstructorParameterWithDefault: Boolean,
     hasBackingField: Boolean,
     declaresDefaultValue: Boolean
-) : ISerializableProperty<IrProperty, IrSimpleType> {
+) : ISerializableProperty<KotlinType> {
     override val name = descriptor.annotations.serialNameValue ?: descriptor.name.asString()
-    override val type = descriptor.getter!!.returnType as IrSimpleType
+    override val type = descriptor.type
     override val genericIndex = type.genericIndex
-    fun serializableWith(ctx: SerializationPluginContext) = descriptor.annotations.serializableWith() ?: analyzeSpecialSerializers(ctx, descriptor.annotations)
-    override val optional = !descriptor.annotations.hasAnnotation(SerializationAnnotations.requiredAnnotationFqName) && declaresDefaultValue
-    override val transient = descriptor.annotations.hasAnnotation(SerializationAnnotations.serialTransientFqName) || !hasBackingField
-}
\ No newline at end of file
+    val module = descriptor.module
+    val serializableWith = descriptor.serializableWith ?: analyzeSpecialSerializers(module, descriptor.annotations)?.defaultType
+    override val optional = !descriptor.annotations.serialRequired && declaresDefaultValue
+    override val transient = descriptor.annotations.serialTransient || !hasBackingField
+}
+
diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Sealed.ir.txt b/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Sealed.ir.txt
index 077967a..9728edc 100644
--- a/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Sealed.ir.txt
+++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/testData/codegen/Sealed.ir.txt
@@ -326,7 +326,9 @@
           DUP
           LDC (Result.Err)
           GETSTATIC (Result$Err, INSTANCE, LResult$Err;)
-          INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;)V)
+          ICONST_0
+          ANEWARRAY (java/lang/annotation/Annotation)
+          INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/annotation/Annotation;)V)
           CHECKCAST (kotlinx/serialization/KSerializer)
           AASTORE
           ALOAD (1)
@@ -335,7 +337,9 @@
           CHECKCAST (kotlinx/serialization/KSerializer)
           AASTORE
           ALOAD (1)
-          INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, <init>, (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V)
+          ICONST_0
+          ANEWARRAY (java/lang/annotation/Annotation)
+          INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, <init>, (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;[Ljava/lang/annotation/Annotation;)V)
           CHECKCAST (kotlinx/serialization/KSerializer)
           ARETURN
         LABEL (L1)
@@ -410,7 +414,9 @@
           DUP
           LDC (Result.Err)
           GETSTATIC (Result$Err, INSTANCE, LResult$Err;)
-          INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;)V)
+          ICONST_0
+          ANEWARRAY (java/lang/annotation/Annotation)
+          INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/annotation/Annotation;)V)
           CHECKCAST (kotlinx/serialization/KSerializer)
           ARETURN
         LABEL (L1)
@@ -859,7 +865,9 @@
           DUP
           LDC (Result.Err)
           GETSTATIC (Result$Err, INSTANCE, LResult$Err;)
-          INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;)V)
+          ICONST_0
+          ANEWARRAY (java/lang/annotation/Annotation)
+          INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/annotation/Annotation;)V)
           CHECKCAST (kotlinx/serialization/KSerializer)
           AASTORE
           ALOAD (1)
@@ -868,7 +876,9 @@
           CHECKCAST (kotlinx/serialization/KSerializer)
           AASTORE
           ALOAD (1)
-          INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, <init>, (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V)
+          ICONST_0
+          ANEWARRAY (java/lang/annotation/Annotation)
+          INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, <init>, (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;[Ljava/lang/annotation/Annotation;)V)
           CHECKCAST (kotlinx/serialization/KSerializer)
           ARETURN
         LABEL (L1)
