Kapt lite
diff --git a/.idea/dictionaries/yan.xml b/.idea/dictionaries/yan.xml
index b6690ed..f39332f 100644
--- a/.idea/dictionaries/yan.xml
+++ b/.idea/dictionaries/yan.xml
@@ -7,13 +7,18 @@
       <w>hacky</w>
       <w>impls</w>
       <w>kapt</w>
+      <w>kaptlite</w>
       <w>kotlinc</w>
       <w>parceler</w>
+      <w>renderable</w>
       <w>repl</w>
+      <w>subplugin</w>
+      <w>testdata</w>
       <w>uast</w>
       <w>unbox</w>
       <w>unboxed</w>
       <w>unmute</w>
+      <w>xplugin</w>
     </words>
   </dictionary>
 </component>
\ No newline at end of file
diff --git a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt
index 4e42947..62df046 100644
--- a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt
+++ b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt
@@ -61,7 +61,12 @@
         classDescriptors.add(classDescriptor)
     }
 
-    override fun onCompletedAnalysis(module: ModuleDescriptor) {
+    override fun onCompletedAnalysis(module: ModuleDescriptor, discardAnalysisResults: Boolean) {
+        if (discardAnalysisResults) {
+            classDescriptors.clear()
+            return
+        }
+
         for (classId in cache.getObsoleteJavaClasses() + untrackedJavaClasses) {
             // Just force the loading obsolete classes
             // We assume here that whenever an LazyJavaClassDescriptor instances is created
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java
index 01fab5e..4f72322 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java
@@ -23,6 +23,8 @@
     public final boolean generateMetadata;
     public final boolean generateSourceRetentionAnnotations;
     public final boolean generateMultiFileFacadePartClasses;
+    public final boolean generateAnnotationForJvmOverloads;
+    public final boolean replaceAnonymousTypesInSignatures;
     public final boolean mightBeIncorrectCode;
 
     private ClassBuilderMode(
@@ -30,12 +32,16 @@
             boolean generateMetadata,
             boolean generateSourceRetentionAnnotations,
             boolean generateMultiFileFacadePartClasses,
+            boolean generateAnnotationForJvmOverloads,
+            boolean replaceAnonymousTypesInSignatures,
             boolean mightBeIncorrectCode
     ) {
         this.generateBodies = generateBodies;
         this.generateMetadata = generateMetadata;
         this.generateSourceRetentionAnnotations = generateSourceRetentionAnnotations;
         this.generateMultiFileFacadePartClasses = generateMultiFileFacadePartClasses;
+        this.generateAnnotationForJvmOverloads = generateAnnotationForJvmOverloads;
+        this.replaceAnonymousTypesInSignatures = replaceAnonymousTypesInSignatures;
         this.mightBeIncorrectCode = mightBeIncorrectCode;
     }
 
@@ -47,6 +53,8 @@
             /* metadata = */ true,
             /* sourceRetention = */ false,
             /* generateMultiFileFacadePartClasses = */ true,
+            /* generateAnnotationForJvmOverloads = */ false,
+            /* replaceAnonymousTypesInSignatures = */ false,
             /* mightBeIncorrectCode = */ false);
 
     /**
@@ -57,6 +65,8 @@
             /* metadata = */ true,
             /* sourceRetention = */ false,
             /* generateMultiFileFacadePartClasses = */ true,
+            /* generateAnnotationForJvmOverloads = */ false,
+            /* replaceAnonymousTypesInSignatures = */ false,
             /* mightBeIncorrectCode = */ false);
 
     /**
@@ -67,6 +77,8 @@
             /* metadata = */ false,
             /* sourceRetention = */ true,
             /* generateMultiFileFacadePartClasses = */ false,
+            /* generateAnnotationForJvmOverloads = */ false,
+            /* replaceAnonymousTypesInSignatures = */ false,
             /* mightBeIncorrectCode = */ true);
 
     /**
@@ -77,6 +89,17 @@
             /* metadata = */ true,
             /* sourceRetention = */ true,
             /* generateMultiFileFacadePartClasses = */ true,
+            /* generateAnnotationForJvmOverloads = */ true,
+            /* replaceAnonymousTypesInSignatures = */ false,
+            /* mightBeIncorrectCode = */ true);
+
+    public final static ClassBuilderMode KAPT_LITE = new ClassBuilderMode(
+            /* bodies = */ false,
+            /* metadata = */ true,
+            /* sourceRetention = */ true,
+            /* generateMultiFileFacadePartClasses = */ true,
+            /* generateAnnotationForJvmOverloads = */ false,
+            /* replaceAnonymousTypesInSignatures = */ true,
             /* mightBeIncorrectCode = */ true);
 
     private final static ClassBuilderMode LIGHT_ANALYSIS_FOR_TESTS = new ClassBuilderMode(
@@ -84,6 +107,8 @@
             /* metadata = */ true,
             /* sourceRetention = */ false,
             /* generateMultiFileFacadePartClasses = */ true,
+            /* generateAnnotationForJvmOverloads = */ false,
+            /* replaceAnonymousTypesInSignatures = */ false,
             /* mightBeIncorrectCode = */ true);
 
     @TestOnly
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt
index d05dc98..5c279ee 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt
@@ -152,7 +152,7 @@
 
         AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(functionDescriptor, signature.returnType)
 
-        if (state.classBuilderMode == ClassBuilderMode.KAPT3) {
+        if (state.classBuilderMode.generateAnnotationForJvmOverloads) {
             mv.visitAnnotation(ANNOTATION_TYPE_DESCRIPTOR_FOR_JVM_OVERLOADS_GENERATED_METHODS, false)
         }
 
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java
index a6651f1..8153792 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java
@@ -386,7 +386,7 @@
         }
 
         KotlinType kotlinType = isDelegate ? getDelegateTypeForProperty(propertyDescriptor, bindingContext) : propertyDescriptor.getType();
-        Type type = typeMapper.mapType(kotlinType);
+        Type type = typeMapper.mapType(typeMapper.patchAnonymousTypeIfNeeded(kotlinType));
 
         ClassBuilder builder = v;
 
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt
index 35f2245..c74c4f0 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt
@@ -72,6 +72,7 @@
 import org.jetbrains.kotlin.types.checker.convertVariance
 import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*
 import org.jetbrains.kotlin.types.model.*
+import org.jetbrains.kotlin.types.typeUtil.builtIns
 import org.jetbrains.kotlin.util.OperatorNameConventions
 import org.jetbrains.org.objectweb.asm.Opcodes.*
 import org.jetbrains.org.objectweb.asm.Type
@@ -195,19 +196,72 @@
     }
 
     private fun mapReturnType(descriptor: CallableDescriptor, sw: JvmSignatureWriter?, returnType: KotlinType): Type {
+        val patchedType = patchAnonymousTypeIfNeeded(returnType)
+
         val isAnnotationMethod = isAnnotationClass(descriptor.containingDeclaration)
         if (sw == null || sw.skipGenericSignature()) {
-            return mapType(returnType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod))
+            return mapType(patchedType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod))
         }
 
-        val typeMappingModeFromAnnotation = extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod)
+        val typeMappingModeFromAnnotation = extractTypeMappingModeFromAnnotation(descriptor, patchedType, isAnnotationMethod)
         if (typeMappingModeFromAnnotation != null) {
-            return mapType(returnType, sw, typeMappingModeFromAnnotation)
+            return mapType(patchedType, sw, typeMappingModeFromAnnotation)
         }
 
-        val mappingMode = TypeMappingMode.getOptimalModeForReturnType(returnType, isAnnotationMethod)
+        val mappingMode = TypeMappingMode.getOptimalModeForReturnType(patchedType, isAnnotationMethod)
 
-        return mapType(returnType, sw, mappingMode)
+        return mapType(patchedType, sw, mappingMode)
+    }
+
+    fun patchAnonymousTypeIfNeeded(type: KotlinType): KotlinType {
+        if (!classBuilderMode.replaceAnonymousTypesInSignatures) {
+            return type
+        }
+
+        val declaration = type.constructor.declarationDescriptor ?: return type
+
+        if (KotlinBuiltIns.isArray(type)) {
+            val elementTypeProjection = type.arguments.singleOrNull()
+            if (elementTypeProjection != null && !elementTypeProjection.isStarProjection) {
+                return type.builtIns.getArrayType(
+                    elementTypeProjection.projectionKind,
+                    patchAnonymousTypeIfNeeded(elementTypeProjection.type)
+                )
+            }
+        }
+
+        if (isAnonymousObject(declaration) || isLocal(declaration)) {
+            return patchAnonymousTypeIfNeeded(chooseBestNonAnonymousSuperType(type))
+        }
+
+        if (type.arguments.isEmpty()) {
+            return type
+        }
+
+        val arguments = type.arguments.map { typeArg ->
+            if (typeArg.isStarProjection)
+                return@map typeArg
+
+            TypeProjectionImpl(typeArg.projectionKind, patchAnonymousTypeIfNeeded(typeArg.type))
+        }
+
+        return type.replace(newArguments = arguments)
+    }
+
+    private fun chooseBestNonAnonymousSuperType(type: KotlinType): KotlinType {
+        // It doesn't really matter what particular type there will be. It just needs to be stable enough.
+
+        val sortedSuperTypes = type.constructor.supertypes
+            .sortedBy { it.constructor.declarationDescriptor?.name?.asString() ?: "" }
+
+        for (superType in sortedSuperTypes) {
+            val classDescriptor = superType.constructor.declarationDescriptor
+            if (classDescriptor is ClassDescriptor && classDescriptor.kind != ClassKind.INTERFACE) {
+                return superType
+            }
+        }
+
+        return sortedSuperTypes.firstOrNull() ?: type.builtIns.anyType
     }
 
     fun mapSupertype(type: KotlinType, signatureVisitor: JvmSignatureWriter?): Type {
diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt
index ba6c0ee..765496c 100644
--- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt
+++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt
@@ -22,10 +22,10 @@
 interface JavaClassesTracker {
     fun reportClass(classDescriptor: JavaClassDescriptor)
 
-    fun onCompletedAnalysis(module: ModuleDescriptor)
+    fun onCompletedAnalysis(module: ModuleDescriptor, discardAnalysisResults: Boolean)
 
     object Default : JavaClassesTracker {
         override fun reportClass(classDescriptor: JavaClassDescriptor) {}
-        override fun onCompletedAnalysis(module: ModuleDescriptor) {}
+        override fun onCompletedAnalysis(module: ModuleDescriptor, discardAnalysisResults: Boolean) {}
     }
 }
diff --git a/generators/build.gradle.kts b/generators/build.gradle.kts
index b5da3a2..066274e 100644
--- a/generators/build.gradle.kts
+++ b/generators/build.gradle.kts
@@ -25,6 +25,7 @@
     compile(projectTests(":plugins:android-extensions-ide"))
     compile(projectTests(":kotlin-annotation-processing"))
     compile(projectTests(":kotlin-annotation-processing-cli"))
+    compile(projectTests(":kapt-lite:kapt-lite-compiler-plugin"))
     compile(projectTests(":kotlin-allopen-compiler-plugin"))
     compile(projectTests(":kotlin-noarg-compiler-plugin"))
     compile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
index 1fd77a3..5d93e2d 100644
--- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
+++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
@@ -5,6 +5,7 @@
 
 package org.jetbrains.kotlin.generators.tests
 
+import org.jetbrains.kaptlite.test.AbstractStubGeneratorTest
 import org.jetbrains.kotlin.AbstractDataFlowValueRenderingTest
 import org.jetbrains.kotlin.addImport.AbstractAddImportTest
 import org.jetbrains.kotlin.allopen.AbstractBytecodeListingTestForAllOpen
@@ -1224,6 +1225,12 @@
         }
     }
 
+    testGroup("plugins/kapt-lite/kapt-lite-compiler-plugin/test", "plugins/kapt-lite/kapt-lite-compiler-plugin/testData") {
+        testClass<AbstractStubGeneratorTest>() {
+            model("stubs")
+        }
+    }
+
     testGroup("plugins/kapt3/kapt3-compiler/test", "plugins/kapt3/kapt3-compiler/testData") {
         testClass<AbstractClassFileToSourceStubConverterTest> {
             model("converter")
diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
index b56d24b..bfedc49 100644
--- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
+++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
@@ -29,17 +29,19 @@
 
 class FilesSubpluginOption(
     key: String,
-    val files: Iterable<File>,
+    val files: Lazy<Iterable<File>>,
     val kind: FilesOptionKind = FilesOptionKind.INTERNAL,
-    lazyValue: Lazy<String> = lazy { files.joinToString(File.pathSeparator) { it.canonicalPath } }
+    lazyValue: Lazy<String> = lazy { files.value.joinToString(File.pathSeparator) { it.canonicalPath } }
 ) : SubpluginOption(key, lazyValue) {
 
+    constructor(key: String, files: Iterable<File>) : this(key, lazyOf(files))
+
     constructor(
         key: String,
         files: List<File>,
         kind: FilesOptionKind = FilesOptionKind.INTERNAL,
         value: String? = null
-    ) : this(key, files, kind, lazy { value ?: files.joinToString(File.pathSeparator) { it.canonicalPath } })
+    ) : this(key, lazyOf(files), kind, lazy { value ?: files.joinToString(File.pathSeparator) { it.canonicalPath } })
 }
 
 class CompositeSubpluginOption(
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kaptlite/KaptLiteGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kaptlite/KaptLiteGradleSubplugin.kt
new file mode 100644
index 0000000..5695707
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kaptlite/KaptLiteGradleSubplugin.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.internal.kaptlite
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.tasks.compile.AbstractCompile
+import org.gradle.api.tasks.compile.JavaCompile
+import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
+import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
+import org.jetbrains.kotlin.gradle.plugin.*
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import java.io.File
+
+class KaptLiteGradleSubplugin : Plugin<Project> {
+    companion object {
+        fun isEnabled(project: Project) = project.plugins.findPlugin(KaptLiteGradleSubplugin::class.java) != null
+    }
+
+    override fun apply(project: Project) {
+        KaptLiteKotlinGradleSubplugin().run {
+            project.configurations.create(KaptLiteKotlinGradleSubplugin.JAVAC_PLUGIN_CONFIGURATION_NAME).apply {
+                val kotlinPluginVersion = project.getKotlinPluginVersion()
+                if (kotlinPluginVersion != null) {
+                    dependencies.add(project.dependencies.create("org.jetbrains.kotlin:kapt-lite-javac-plugin:$kotlinPluginVersion"))
+                } else {
+                    project.logger.error("Kotlin plugin should be enabled before 'kotlin-kapt-lite'")
+                }
+            }
+        }
+    }
+}
+
+class KaptLiteKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
+    companion object {
+        const val JAVAC_PLUGIN_CONFIGURATION_NAME = "kotlinKaptLiteJavacPluginClasspath"
+    }
+
+    override fun isApplicable(project: Project, task: AbstractCompile): Boolean {
+        return task is KotlinCompile && KaptLiteGradleSubplugin.isEnabled(project)
+    }
+
+    override fun apply(
+        project: Project,
+        kotlinCompile: AbstractCompile,
+        javaCompile: AbstractCompile?,
+        variantData: Any?,
+        androidProjectHandler: Any?,
+        kotlinCompilation: KotlinCompilation<KotlinCommonOptions>?
+    ): List<SubpluginOption> {
+        fun reportError(message: String) = project.logger.error(project.path + ": " + message)
+
+        val baseName = getBaseName(kotlinCompile)
+
+        if (Kapt3GradleSubplugin.isEnabled(project)) {
+            reportError("'kotlin-kapt' and 'kotlin-kapt-lite' plugins can not work together. Remove one.")
+            return emptyList()
+        }
+
+        if (javaCompile !is JavaCompile) {
+            reportError("Java compile task is absent or incompatible. Kapt-lite requires 'JavaCompile' in order to work properly.")
+            return emptyList()
+        }
+
+        val kotlinPluginVersion = project.getKotlinPluginVersion()
+        if (kotlinPluginVersion == null) {
+            reportError("Kotlin plugin is not enabled.")
+            return emptyList()
+        }
+
+        val javacProcessorDependencies = javaCompile.options.annotationProcessorPath
+        if (javacProcessorDependencies == null) {
+            reportError("Annotation processor dependencies are not set.")
+            return emptyList()
+        }
+
+        run /* Register Javac plugin */ {
+            val javacPluginConfiguration = project.configurations.getByName(JAVAC_PLUGIN_CONFIGURATION_NAME)
+            javaCompile.options.annotationProcessorPath = javacProcessorDependencies + javacPluginConfiguration
+            javaCompile.options.compilerArgs.add("-Xplugin:KaptJavacPlugin")
+        }
+
+        val stubsOutputDir = getKaptStubsOutputPath(project, baseName)
+        javaCompile.source(stubsOutputDir)
+
+        return listOf(
+            FilesSubpluginOption("stubs", listOf(stubsOutputDir))
+        )
+    }
+
+    private fun getKaptStubsOutputPath(project: Project, baseName: String): File {
+        val dirNameForSourceSet = if (baseName.isEmpty()) "main" else baseName
+        return File(project.buildDir, "tmp/kaptLite/stubs/$dirNameForSourceSet")
+    }
+
+    private fun getBaseName(kotlinCompile: AbstractCompile): String {
+        val name = kotlinCompile.name
+        assert(name.startsWith("compile") && name.endsWith("Kotlin"))
+        return name.drop("compile".length).dropLast("Kotlin".length).decapitalize()
+    }
+
+    override fun getCompilerPluginId(): String = "org.jetbrains.kotlin.kaptlite"
+
+    override fun getPluginArtifact(): SubpluginArtifact {
+        return SubpluginArtifact("org.jetbrains.kotlin", "kapt-lite-compiler-plugin-embeddable")
+    }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt-lite.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt-lite.properties
new file mode 100644
index 0000000..7cbc8fe
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt-lite.properties
@@ -0,0 +1 @@
+implementation-class=org.jetbrains.kotlin.gradle.internal.kaptlite.KaptLiteGradleSubplugin
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.kaptlite.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.kaptlite.properties
new file mode 100644
index 0000000..7cbc8fe
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.kaptlite.properties
@@ -0,0 +1 @@
+implementation-class=org.jetbrains.kotlin.gradle.internal.kaptlite.KaptLiteGradleSubplugin
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
index e6839bb..f53be8e 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
@@ -1,3 +1,4 @@
 org.jetbrains.kotlin.gradle.internal.AndroidSubplugin
 org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
+org.jetbrains.kotlin.gradle.internal.kaptlite.KaptLiteKotlinGradleSubplugin
 org.jetbrains.kotlin.gradle.scripting.internal.ScriptingKotlinGradleSubplugin
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/build.gradle.kts b/plugins/kapt-lite/kapt-lite-compiler-plugin/build.gradle.kts
new file mode 100644
index 0000000..ef86814
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/build.gradle.kts
@@ -0,0 +1,42 @@
+description = "Lightweight annotation processing support – Kotlin compiler plugin"
+
+plugins {
+    kotlin("jvm")
+    id("jps-compatible")
+}
+
+dependencies {
+    compileOnly(project(":compiler:plugin-api"))
+    compileOnly(project(":compiler:cli"))
+    compileOnly(project(":compiler:frontend"))
+    compileOnly(project(":compiler:backend"))
+
+    compileOnly(project(":kapt-lite:kapt-lite-kdoc"))
+    embedded(project(":kapt-lite:kapt-lite-kdoc")) { isTransitive = false }
+
+    compileOnly(project(":kapt-lite:kapt-lite-signature-parser"))
+    embedded(project(":kapt-lite:kapt-lite-signature-parser")) { isTransitive = false }
+
+    compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
+    compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
+
+    testCompile(toolsJar())
+    testCompile(commonDep("junit:junit"))
+    testCompile(projectTests(":compiler:tests-common"))
+    testCompile(intellijCoreDep()) { includeJars("intellij-core") }
+}
+
+sourceSets {
+    "main" { projectDefault() }
+    "test" { projectDefault() }
+}
+
+runtimeJar()
+sourcesJar()
+javadocJar()
+
+testsJar {}
+
+projectTest {
+    workingDir = rootDir
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
new file mode 100644
index 0000000..d9a838c
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
@@ -0,0 +1 @@
+org.jetbrains.kaptlite.KaptLiteCommandLineProcessor
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
new file mode 100644
index 0000000..67c1d62
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
@@ -0,0 +1 @@
+org.jetbrains.kaptlite.KaptLiteComponentRegistrar
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteAnalysisHandlerExtension.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteAnalysisHandlerExtension.kt
new file mode 100644
index 0000000..9fceda9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteAnalysisHandlerExtension.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite
+
+import com.intellij.openapi.project.Project
+import org.jetbrains.kaptlite.diagnostic.DefaultErrorMessagesKaptLite
+import org.jetbrains.kaptlite.diagnostic.ErrorsKaptLite
+import org.jetbrains.kaptlite.stubs.GeneratorOutput
+import org.jetbrains.kaptlite.stubs.StubGenerator
+import org.jetbrains.kaptlite.stubs.util.CodeScope
+import org.jetbrains.kotlin.analyzer.AnalysisResult
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
+import org.jetbrains.kotlin.codegen.ClassBuilderMode
+import org.jetbrains.kotlin.codegen.CompilationErrorHandler
+import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
+import org.jetbrains.kotlin.codegen.OriginCollectingClassBuilderFactory
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.CommonConfigurationKeys
+import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.descriptors.ModuleDescriptor
+import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
+import org.jetbrains.kotlin.diagnostics.reportFromPlugin
+import org.jetbrains.kotlin.modules.TargetId
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.BindingTrace
+import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
+import java.io.File
+import java.io.PrintStream
+import kotlin.system.measureTimeMillis
+
+class KaptLiteAnalysisHandlerExtension(
+    configuration: CompilerConfiguration,
+    private val options: KaptLiteOptions,
+    override val messageCollector: MessageCollector
+) : AbstractKaptLiteAnalysisHandlerExtension(configuration) {
+    override fun getOutput(state: GenerationState): GeneratorOutput = RealFileGeneratorOutput(state, options.stubsOutputDir)
+
+    private class RealFileGeneratorOutput(private val state: GenerationState, private val outputDir: File) : GeneratorOutput {
+        private val messageCollector = state.configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
+
+        override fun produce(internalName: String, path: String, block: CodeScope.() -> Unit) {
+            val file = File(outputDir, path)
+            file.parentFile.mkdirs()
+            file.outputStream().use { os ->
+                val scope = CodeScope(PrintStream(os))
+                scope.block()
+            }
+
+            if (state.configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)) {
+                val sourceFiles = state.factory["$internalName.class"]?.sourceFiles ?: emptyList()
+                if (sourceFiles.isNotEmpty()) {
+                    messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sourceFiles, file))
+                }
+            }
+        }
+    }
+}
+
+abstract class AbstractKaptLiteAnalysisHandlerExtension(private val configuration: CompilerConfiguration) : AnalysisHandlerExtension {
+    abstract val messageCollector: MessageCollector
+
+    abstract fun getOutput(state: GenerationState): GeneratorOutput
+
+    override fun analysisCompleted(
+        project: Project, module: ModuleDescriptor,
+        bindingTrace: BindingTrace, files: Collection<KtFile>
+    ): AnalysisResult? {
+        if (DiagnosticUtils.hasError(bindingTrace.bindingContext.diagnostics)) {
+            return AnalysisResult.compilationError(bindingTrace.bindingContext)
+        }
+
+        if (!generateStubs(project, module, bindingTrace.bindingContext, files.toList())) {
+            return AnalysisResult.compilationError(bindingTrace.bindingContext)
+        }
+        return null
+    }
+
+    private fun generateStubs(
+        project: Project,
+        module: ModuleDescriptor,
+        bindingContext: BindingContext,
+        files: List<KtFile>
+    ): Boolean {
+        val builderFactory = OriginCollectingClassBuilderFactory(ClassBuilderMode.KAPT_LITE)
+
+        val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME] ?: module.name.asString()
+        val targetId = TargetId(moduleName, "java-production")
+
+        val generationState = GenerationState.Builder(project, builderFactory, module, bindingContext, files, configuration)
+            .targetId(targetId)
+            .isIrBackend(false)
+            .build()
+
+        val diagnosticsTrace = DelegatingBindingTrace(bindingContext, "For kapt-lite diagnostics in ${this::class.java}", false)
+
+        try {
+            KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
+
+            val time = measureTimeMillis {
+                val compiledClasses = builderFactory.compiledClasses
+                val origins = builderFactory.origins
+                StubGenerator(diagnosticsTrace, compiledClasses, origins, generationState).use { stubGenerator ->
+                    stubGenerator.generate(getOutput(generationState))
+                }
+            }
+
+            diagnosticsTrace.reportFromPlugin(ErrorsKaptLite.TIME.on(files[0], "${time}ms"), DefaultErrorMessagesKaptLite)
+        } finally {
+            generationState.destroy()
+        }
+
+        return !AnalyzerWithCompilerReport.Companion.reportDiagnostics(diagnosticsTrace.bindingContext.diagnostics, messageCollector)
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteClassBuilderInterceptorExtension.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteClassBuilderInterceptorExtension.kt
new file mode 100644
index 0000000..90a468a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteClassBuilderInterceptorExtension.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2010-2019 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.kaptlite
+
+import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.codegen.ClassBuilder
+import org.jetbrains.kotlin.codegen.ClassBuilderFactory
+import org.jetbrains.kotlin.codegen.DelegatingClassBuilder
+import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.FieldVisitor
+import org.jetbrains.org.objectweb.asm.MethodVisitor
+
+typealias OriginConsumer = MutableMap<String, JvmDeclarationOrigin>
+
+class KaptLiteClassBuilderInterceptorExtension(private val originConsumer: OriginConsumer) : ClassBuilderInterceptorExtension {
+    override fun interceptClassBuilderFactory(
+        interceptedFactory: ClassBuilderFactory,
+        bindingContext: BindingContext,
+        diagnostics: DiagnosticSink
+    ): ClassBuilderFactory {
+        return KaptLiteClassBuilderFactory(interceptedFactory, originConsumer)
+    }
+}
+
+private class KaptLiteClassBuilderFactory(
+    private val delegateFactory: ClassBuilderFactory,
+    private val originConsumer: OriginConsumer
+) : ClassBuilderFactory {
+    override fun getClassBuilderMode() = delegateFactory.classBuilderMode
+
+    override fun newClassBuilder(origin: JvmDeclarationOrigin): ClassBuilder {
+        return KaptLiteClassBuilder(delegateFactory.newClassBuilder(origin), origin, originConsumer)
+    }
+
+    override fun asText(builder: ClassBuilder?): String? {
+        return delegateFactory.asText((builder as KaptLiteClassBuilder).delegateBuilder)
+    }
+
+    override fun asBytes(builder: ClassBuilder?): ByteArray? {
+        return delegateFactory.asBytes((builder as KaptLiteClassBuilder).delegateBuilder)
+    }
+
+    override fun close() {
+        delegateFactory.close()
+    }
+}
+
+private class KaptLiteClassBuilder(
+    val delegateBuilder: ClassBuilder,
+    private val origin: JvmDeclarationOrigin,
+    private val originConsumer: OriginConsumer
+) : DelegatingClassBuilder() {
+    override fun getDelegate() = delegateBuilder
+
+    private lateinit var className: String
+
+    override fun defineClass(
+        origin: PsiElement?,
+        version: Int,
+        access: Int,
+        name: String,
+        signature: String?,
+        superName: String,
+        interfaces: Array<out String>
+    ) {
+        className = name
+        originConsumer[name] = this.origin
+        super.defineClass(origin, version, access, name, signature, superName, interfaces)
+    }
+
+    override fun newField(
+        origin: JvmDeclarationOrigin,
+        access: Int,
+        name: String,
+        desc: String,
+        signature: String?,
+        value: Any?
+    ): FieldVisitor {
+        originConsumer["$className#$name"] = origin
+        return super.newField(origin, access, name, desc, signature, value)
+    }
+
+    override fun newMethod(
+        origin: JvmDeclarationOrigin,
+        access: Int,
+        name: String,
+        desc: String,
+        signature: String?,
+        exceptions: Array<out String>?
+    ): MethodVisitor {
+        originConsumer["$className#$name$desc"] = origin
+        return super.newMethod(origin, access, name, desc, signature, exceptions)
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteCliOption.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteCliOption.kt
new file mode 100644
index 0000000..b60e84e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteCliOption.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2019 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.kaptlite
+
+import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
+
+enum class KaptLiteCliOption(
+    override val optionName: String,
+    override val valueDescription: String,
+    override val description: String,
+    override val allowMultipleOccurrences: Boolean = false
+) : AbstractCliOption {
+    STUBS_OUTPUT_DIR("stubs", "<path>", "Output path for kapt stubs");
+
+    override val required: Boolean = false
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteOptions.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteOptions.kt
new file mode 100644
index 0000000..e878e00
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteOptions.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2019 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.kaptlite
+
+import org.jetbrains.kotlin.config.CompilerConfigurationKey
+import java.io.File
+
+val KAPT_LITE_OPTIONS = CompilerConfigurationKey.create<KaptLiteOptions.Builder>("Kapt-lite options")
+
+class KaptLiteOptions(val stubsOutputDir: File) {
+    class Builder {
+        var stubsOutputDir: File? = null
+
+        fun build(): KaptLiteOptions? {
+            val stubsOutputDir = this.stubsOutputDir ?: return null
+            return KaptLiteOptions(stubsOutputDir)
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLitePlugin.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLitePlugin.kt
new file mode 100644
index 0000000..a8beb00
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLitePlugin.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010-2019 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.kaptlite
+
+import com.intellij.mock.MockProject
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
+import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
+import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
+import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
+import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
+import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
+import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
+import java.io.File
+
+class KaptLiteCommandLineProcessor : CommandLineProcessor {
+    override val pluginId: String
+        get() = "org.jetbrains.kotlin.kaptlite"
+
+    override val pluginOptions: Collection<AbstractCliOption>
+        get() = KaptLiteCliOption.values().asList()
+
+    override fun processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) {
+        if (option !is KaptLiteCliOption) {
+            throw CliOptionProcessingException("Unknown option: ${option.optionName}")
+        }
+
+        val options = configuration[KAPT_LITE_OPTIONS]
+            ?: KaptLiteOptions.Builder().also { configuration.put(KAPT_LITE_OPTIONS, it) }
+
+        when (option) {
+            KaptLiteCliOption.STUBS_OUTPUT_DIR -> {
+                options.stubsOutputDir = File(value)
+            }
+        }
+    }
+}
+
+class KaptLiteComponentRegistrar : ComponentRegistrar {
+    override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
+        val options = configuration[KAPT_LITE_OPTIONS]?.build() ?: return
+
+        val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
+            ?: PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)
+
+        AnalysisHandlerExtension.registerExtension(project, KaptLiteAnalysisHandlerExtension(configuration, options, messageCollector))
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/DefaultErrorMessagesKaptLite.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/DefaultErrorMessagesKaptLite.kt
new file mode 100644
index 0000000..5620069
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/DefaultErrorMessagesKaptLite.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kaptlite.diagnostic
+
+import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
+import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
+import org.jetbrains.kotlin.diagnostics.rendering.Renderers
+
+object DefaultErrorMessagesKaptLite : DefaultErrorMessages.Extension {
+    private val MAP = DiagnosticFactoryToRendererMap("KaptLite")
+    override fun getMap() = MAP
+
+    init {
+        MAP.put(
+            ErrorsKaptLite.KAPT_INCOMPATIBLE_NAME,
+            "Name ''{0}'' is forbidden in kapt. Use only Java-compatible names",
+            Renderers.TO_STRING
+        )
+
+        MAP.put(
+            ErrorsKaptLite.KAPT_NESTED_NAME_CLASH,
+            "Class name ''{0}'' is forbidden in kapt. Java prohibits name clashes with outer classes",
+            Renderers.TO_STRING
+        )
+
+        MAP.put(
+            ErrorsKaptLite.TIME,
+            "Time spent in stub generation: ''{0}''",
+            Renderers.TO_STRING
+        )
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/ErrorsKaptLite.java b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/ErrorsKaptLite.java
new file mode 100644
index 0000000..556d6c8
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/ErrorsKaptLite.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kaptlite.diagnostic;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
+import org.jetbrains.kotlin.diagnostics.Errors;
+
+import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
+import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
+
+public interface ErrorsKaptLite {
+    DiagnosticFactory1<PsiElement, String> KAPT_INCOMPATIBLE_NAME = DiagnosticFactory1.create(ERROR);
+    DiagnosticFactory1<PsiElement, String> KAPT_NESTED_NAME_CLASH = DiagnosticFactory1.create(ERROR);
+    DiagnosticFactory1<PsiElement, String> TIME = DiagnosticFactory1.create(WARNING);
+
+    @SuppressWarnings("UnusedDeclaration")
+    Object _initializer = new Object() {
+        {
+            Errors.Initializer.initializeFactoryNames(ErrorsKaptLite.class);
+        }
+    };
+
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/ClassFileLoader.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/ClassFileLoader.kt
new file mode 100644
index 0000000..0a1712a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/ClassFileLoader.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import java.util.*
+import kotlin.collections.HashMap
+
+internal const val JAVA_LANG_OBJECT = "java/lang/Object"
+
+class ClassFileLoader(private val inputs: List<GeneratorInput>) {
+    private val cached = HashMap<String, Optional<ClassNode>>()
+
+    fun load(internalName: String, cache: Boolean = false): ClassNode? {
+        val cachedNode = cached[internalName]
+        if (cachedNode != null) {
+            return cachedNode.get()
+        }
+
+        val file = inputs.firstNotNullResult { it.find(internalName) } ?: return null
+        val classNode = file.readClass()
+
+        if (cache) {
+            cached[internalName] = Optional.of(classNode)
+        }
+
+        return classNode
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorInput.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorInput.kt
new file mode 100644
index 0000000..fa29f57
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorInput.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import org.jetbrains.org.objectweb.asm.ClassReader
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import java.io.Closeable
+import java.io.File
+import java.util.zip.ZipEntry
+import java.util.zip.ZipFile
+
+interface ClassFile {
+    val internalName: String
+    fun readClass(): ClassNode
+}
+
+interface GeneratorInput : Closeable {
+    fun iterate(block: (ClassFile) -> Unit)
+    fun find(internalName: String): ClassFile?
+}
+
+class CompiledFilesGeneratorInput(compiledFiles: List<ClassNode>) : GeneratorInput {
+    private val compiledFiles: Map<String, ClassFile> = run {
+        val map = LinkedHashMap<String, ClassFile>(compiledFiles.size)
+        compiledFiles.forEach { map[it.name] = CompiledClassFile(it) }
+        return@run map
+    }
+
+    override fun iterate(block: (ClassFile) -> Unit) {
+        compiledFiles.values.forEach(block)
+    }
+
+    override fun find(internalName: String) = compiledFiles[internalName]
+
+    override fun close() {}
+
+    private class CompiledClassFile(private val classNode: ClassNode) : ClassFile {
+        override val internalName: String = classNode.name
+        override fun readClass() = classNode
+    }
+}
+
+abstract class ByteClassFile : ClassFile {
+    abstract fun readBytes(): ByteArray
+
+    override fun readClass(): ClassNode {
+        val bytes = readBytes()
+        val classNode = ClassNode()
+        ClassReader(bytes).accept(classNode, ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES)
+        return classNode
+    }
+}
+
+class DirectoryGeneratorInput(private val dir: File) : GeneratorInput {
+    override fun iterate(block: (ClassFile) -> Unit) {
+        for (file in dir.walk()) {
+            if (!file.isFile) {
+                continue
+            }
+
+            val path = file.toRelativeString(dir)
+            if (!path.endsWith(".class")) {
+                continue
+            }
+
+            val internalName = path.dropLast(".class".length)
+            block(RealClassFile(internalName, file))
+        }
+    }
+
+    override fun find(internalName: String): ClassFile? {
+        val file = File(dir, "$internalName.class")
+        if (file.exists()) {
+            return RealClassFile(internalName, file)
+        }
+
+        return null
+    }
+
+    override fun close() {}
+
+    private class RealClassFile(override val internalName: String, val file: File) : ByteClassFile() {
+        override fun readBytes() = file.readBytes()
+    }
+}
+
+class JarGeneratorInput(file: File) : GeneratorInput {
+    private val zipFile = ZipFile(file)
+
+    override fun iterate(block: (ClassFile) -> Unit) {
+        for (entry in zipFile.entries()) {
+            if (entry.isDirectory) {
+                continue
+            }
+
+            val name = entry.name
+            if (!name.endsWith(".class")) {
+                continue
+            }
+
+            val internalName = name.dropLast(".class".length)
+            block(ZipEntryClassFile(internalName, entry))
+        }
+    }
+
+    override fun find(internalName: String): ClassFile? {
+        val entry = zipFile.getEntry("$internalName.class") ?: return null
+        return ZipEntryClassFile(internalName, entry)
+    }
+
+    override fun close() {
+        zipFile.close()
+    }
+
+    private inner class ZipEntryClassFile(override val internalName: String, private val entry: ZipEntry) : ByteClassFile() {
+        override fun readBytes(): ByteArray {
+            return zipFile.getInputStream(entry).use { it.readBytes() }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorOutput.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorOutput.kt
new file mode 100644
index 0000000..dc3e3c6
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorOutput.kt
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs
+
+import org.jetbrains.kaptlite.stubs.util.CodeScope
+
+interface GeneratorOutput {
+    fun produce(internalName: String, path: String, block: CodeScope.() -> Unit)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubChecker.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubChecker.kt
new file mode 100644
index 0000000..5365658
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubChecker.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import com.intellij.lang.java.lexer.JavaLexer
+import com.intellij.pom.java.LanguageLevel
+import com.intellij.psi.PsiElement
+import org.jetbrains.kaptlite.diagnostic.DefaultErrorMessagesKaptLite
+import org.jetbrains.kaptlite.diagnostic.ErrorsKaptLite
+import org.jetbrains.kaptlite.signature.ClassSignature
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeArgument
+import org.jetbrains.kaptlite.stubs.model.JavaAnnotationStub
+import org.jetbrains.kaptlite.stubs.model.JavaClassStub
+import org.jetbrains.kaptlite.stubs.model.JavaMethodStub
+import org.jetbrains.kaptlite.stubs.util.JavaClassName
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.JvmTarget
+import org.jetbrains.kotlin.diagnostics.Diagnostic
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.diagnostics.reportFromPlugin
+import org.jetbrains.kotlin.psi.KtConstructor
+import org.jetbrains.kotlin.psi.KtFunctionLiteral
+import org.jetbrains.kotlin.psi.KtNamedDeclaration
+import org.jetbrains.kotlin.psi.KtObjectDeclaration
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+
+class StubChecker(private val state: GenerationState, private val diagnostics: DiagnosticSink) {
+    private val languageLevel = when (state.target) {
+        JvmTarget.JVM_1_6 -> LanguageLevel.JDK_1_6
+        JvmTarget.JVM_1_8 -> LanguageLevel.JDK_1_8
+        JvmTarget.JVM_9 -> LanguageLevel.JDK_1_9
+        JvmTarget.JVM_10 -> LanguageLevel.JDK_10
+        JvmTarget.JVM_11 -> LanguageLevel.JDK_11
+        JvmTarget.JVM_12 -> LanguageLevel.JDK_12
+    }
+
+    fun checkClass(
+        name: JavaClassName, signature: ClassSignature,
+        enumValues: List<JavaClassStub.JavaEnumValue>,
+        annotations: List<JavaAnnotationStub>,
+        origin: JvmDeclarationOrigin
+    ): Boolean {
+        return checkName(name, origin)
+                && checkType(signature.superClass, origin)
+                && signature.interfaces.all { checkType(it, origin) }
+                && signature.typeParameters.all { checkName(it.name, origin) && it.bounds.all { bound -> checkType(bound, origin) } }
+                && enumValues.all { checkName(it.name, origin) }
+                && checkAnnotations(annotations, origin)
+    }
+
+    fun checkField(name: String, type: SigType, annotations: List<JavaAnnotationStub>, origin: JvmDeclarationOrigin): Boolean {
+        // TODO check field initializer
+        return checkName(name, origin) && checkType(type, origin) && checkAnnotations(annotations, origin)
+    }
+
+    fun checkMethod(
+        name: String, data: JavaMethodStub.MethodData,
+        annotations: List<JavaAnnotationStub>,
+        origin: JvmDeclarationOrigin
+    ): Boolean {
+        return checkName(name, origin)
+                && data.typeParameters.all { checkName(it.name, origin) && it.bounds.all { bound -> checkType(bound, origin) } }
+                && data.parameters.all { checkName(it.name, origin) && checkType(it.type, origin) }
+                && data.exceptionTypes.all { checkType(it, origin) }
+                && checkType(data.returnType, origin)
+                && checkAnnotations(annotations, origin)
+    }
+
+    private fun checkAnnotations(annotations: List<JavaAnnotationStub>, origin: JvmDeclarationOrigin): Boolean {
+        // TODO check annotation args
+        return annotations.all { checkName(it.name, origin) }
+    }
+
+    private fun checkName(name: JavaClassName, origin: JvmDeclarationOrigin): Boolean {
+        return (name.packageName.isEmpty() || name.packageName.split('.').all { checkName(it, origin) })
+                && name.className.split('.').all { checkName(it, origin) }
+    }
+
+    private fun checkName(name: String, origin: JvmDeclarationOrigin): Boolean {
+        if (!isValidIdentifier(name, languageLevel)) {
+            report(origin) { ErrorsKaptLite.KAPT_INCOMPATIBLE_NAME.on(it, name) }
+            return false
+        }
+
+        return true
+    }
+
+    private fun checkType(type: SigType, origin: JvmDeclarationOrigin): Boolean {
+        return when (type) {
+            is SigType.TypeVariable -> checkName(type.name, origin)
+            is SigType.Array -> checkType(type.elementType, origin)
+            is SigType.Class -> type.fqName.split('.').all { checkName(it, origin) }
+            is SigType.Nested -> checkType(type.outer, origin) && checkName(type.name, origin)
+            is SigType.Generic -> checkType(type.base, origin) && type.args.all { checkTypeArgument(it, origin) }
+            is SigType.Primitive -> true
+        }
+    }
+
+    private fun checkTypeArgument(arg: SigTypeArgument, origin: JvmDeclarationOrigin): Boolean {
+        return when (arg) {
+            SigTypeArgument.Unbound -> true
+            is SigTypeArgument.Invariant -> checkType(arg.type, origin)
+            is SigTypeArgument.Extends -> checkType(arg.type, origin)
+            is SigTypeArgument.Super -> checkType(arg.type, origin)
+        }
+    }
+
+    private fun report(origin: JvmDeclarationOrigin, factory: (PsiElement) -> Diagnostic) {
+        val reportElement = findReportElement(origin)
+        val diagnostic = factory(reportElement)
+        diagnostics.reportFromPlugin(diagnostic, DefaultErrorMessagesKaptLite)
+    }
+
+    private fun findReportElement(origin: JvmDeclarationOrigin): PsiElement {
+        val element = origin.element
+
+        when (element) {
+            is KtObjectDeclaration -> element.getObjectKeyword()?.let { return it }
+            is KtConstructor<*> -> element.getConstructorKeyword()?.let { return it }
+            is KtFunctionLiteral -> return element.lBrace
+        }
+
+        if (element is KtNamedDeclaration) {
+            val identifier = element.nameIdentifier
+            if (identifier != null) {
+                return identifier
+            }
+        } else if (element != null) {
+            return element
+        }
+
+        return state.files.first()
+    }
+
+    fun isValidIdentifier(name: String, languageLevel: LanguageLevel = LanguageLevel.JDK_1_8): Boolean {
+        if (JavaLexer.isKeyword(name, languageLevel) || name.isEmpty() || !Character.isJavaIdentifierStart(name.first())) {
+            return false
+        }
+
+        for (i in 1 until name.length) {
+            if (!Character.isJavaIdentifierPart(name[i])) {
+                return false
+            }
+        }
+
+        return true
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGenerator.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGenerator.kt
new file mode 100644
index 0000000..f342c5a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGenerator.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs
+
+import org.jetbrains.kaptlite.stubs.model.JavaClassStub
+import org.jetbrains.kaptlite.stubs.util.append
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import java.io.Closeable
+
+class StubGenerator(
+    diagnostics: DiagnosticSink,
+    compiledClasses: List<ClassNode>,
+    origins: Map<Any, JvmDeclarationOrigin>,
+    state: GenerationState
+) : Closeable {
+    private val compiledFilesInput = CompiledFilesGeneratorInput(compiledClasses)
+
+    private val classpathInputs = run {
+        val contentRoots = state.configuration[CLIConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
+        val classpathRoots = contentRoots.filterIsInstance<JvmClasspathRoot>()
+        classpathRoots.map { if (it.file.isDirectory) DirectoryGeneratorInput(it.file) else JarGeneratorInput(it.file) }
+    }
+
+    private val inputs = listOf(compiledFilesInput) + classpathInputs
+
+    private val loader = ClassFileLoader(inputs)
+    private val context = StubGeneratorContext(loader, diagnostics, state, origins)
+
+    fun generate(output: GeneratorOutput) {
+        compiledFilesInput.iterate { classFile ->
+            generate(classFile, output)
+        }
+    }
+
+    override fun close() {
+        inputs.forEach { it.close() }
+    }
+
+    private fun generate(file: ClassFile, output: GeneratorOutput) {
+        val cls = parse(file) ?: return
+        output(file.internalName, cls, output)
+    }
+
+    private fun parse(file: ClassFile): JavaClassStub? {
+        val node = context.loader.load(file.internalName) ?: return null
+        for (innerClass in node.innerClasses) {
+            if (innerClass.name == file.internalName) {
+                // Only top-level classes should be parsed
+                return null
+            }
+        }
+
+        return JavaClassStub.parse(context, node, JavaClassStub.NestingKind.TOP_LEVEL)
+    }
+
+    private fun output(internalName: String, cls: JavaClassStub, output: GeneratorOutput) {
+        val targetDirPath = cls.name.packageName.replace('.', '/')
+        val targetFilePath = (if (targetDirPath.isEmpty()) "" else "$targetDirPath/") + cls.name.className + ".java"
+
+        output.produce(internalName, targetFilePath) {
+            append("/**").newLine()
+            append(" * This file was generated by the kapt-lite stub generator.").newLine()
+            append(" * Do not change it manually.").newLine()
+            append(" */").newLine()
+
+            if (cls.name.packageName.isNotEmpty()) {
+                append("package ").append(cls.name.packageName).append(';')
+                newLine().newLine()
+            } else {
+                // We have to add package/import directives before declarations.
+                // Otherwise, the file comment will become a class one.
+                append("import java.lang.Object;")
+                newLine().newLine()
+            }
+
+            append(cls)
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGeneratorContext.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGeneratorContext.kt
new file mode 100644
index 0000000..52ff1e4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGeneratorContext.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs
+
+import com.intellij.openapi.vfs.StandardFileSystems
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiJavaFile
+import com.intellij.psi.PsiManager
+import org.jetbrains.kaptlite.stubs.util.JavaClassName
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.LanguageVersionSettings
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import org.jetbrains.org.objectweb.asm.tree.FieldNode
+import org.jetbrains.org.objectweb.asm.tree.MethodNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+
+class StubGeneratorContext(
+    val loader: ClassFileLoader,
+    diagnostics: DiagnosticSink,
+    private val state: GenerationState,
+    private val origins: Map<Any, JvmDeclarationOrigin>
+) {
+    val checker = StubChecker(state, diagnostics)
+
+    private val javaClassNameMappings: Map<String, JavaClassName> = run {
+        val contentRoots = state.configuration[CLIConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
+        val javaSourceRoots = contentRoots.filterIsInstance<JavaSourceRoot>()
+        if (javaSourceRoots.isEmpty()) {
+            return@run emptyMap()
+        }
+
+        val psiManager = PsiManager.getInstance(state.project)
+        val mappings = HashMap<String, JavaClassName>()
+
+        for (root in javaSourceRoots) {
+            root.file.walk().filter { it.isFile && it.extension == "java" }.forEach {
+                val vFile = StandardFileSystems.local().findFileByPath(it.absolutePath)
+                if (vFile != null) {
+                    val javaFile = psiManager.findFile(vFile) as? PsiJavaFile
+                    if (javaFile != null) {
+                        mappings.putAll(collectNameMappings(javaFile))
+                    }
+                }
+            }
+        }
+
+        mappings
+    }
+
+    val bindingContext: BindingContext
+        get() = state.bindingContext
+
+    val languageVersionSettings: LanguageVersionSettings
+        get() = state.languageVersionSettings
+
+    fun getKDocComment(kind: KDocParsingHelper.DeclarationKind, origin: JvmDeclarationOrigin): String? {
+        return KDocParsingHelper.getKDocComment(kind, origin, bindingContext)
+    }
+
+    fun getClassOrigin(node: ClassNode): JvmDeclarationOrigin {
+        return origins[node] ?: JvmDeclarationOrigin.NO_ORIGIN
+    }
+
+    fun getMethodOrigin(node: MethodNode): JvmDeclarationOrigin {
+        return origins[node] ?: JvmDeclarationOrigin.NO_ORIGIN
+    }
+
+    fun getFieldOrigin(node: FieldNode): JvmDeclarationOrigin {
+        return origins[node] ?: JvmDeclarationOrigin.NO_ORIGIN
+    }
+
+    fun getClassName(internalName: String): JavaClassName {
+        if ('$' !in internalName) {
+            return getClassNameSimple(internalName)
+        }
+
+        javaClassNameMappings[internalName]?.let { return it }
+        loader.load(internalName, cache = true)?.let { return getClassName(it) }
+        return getClassNameSimple(internalName)
+    }
+
+    fun getClassName(classNode: ClassNode): JavaClassName {
+        val internalName = classNode.name
+
+        for (innerClass in classNode.innerClasses) {
+            if (innerClass.name == internalName) {
+                val innerName = innerClass.innerName
+                val outerName = innerClass.outerName
+                if (innerName == null || outerName == null) {
+                    return getClassNameForAnonymousClass(classNode)
+                }
+
+                return JavaClassName.Nested(getClassName(outerName), innerName)
+            }
+        }
+
+        return getClassNameSimple(internalName)
+    }
+
+    private fun getClassNameForAnonymousClass(classNode: ClassNode): JavaClassName {
+        val superName = classNode.superName ?: JAVA_LANG_OBJECT
+        if (superName == JAVA_LANG_OBJECT) {
+            val interfaces = classNode.interfaces?.sorted() ?: emptyList()
+            val firstInterface = interfaces.firstOrNull()
+            if (firstInterface != null) {
+                return getClassName(firstInterface)
+            }
+        }
+
+        return getClassName(superName)
+    }
+
+    private fun getClassNameSimple(internalName: String): JavaClassName {
+        val packageName = internalName.substringBeforeLast('/', missingDelimiterValue = "").replace('/', '.')
+        val simpleName = if (packageName.isEmpty()) internalName else internalName.drop(packageName.length + 1)
+        return JavaClassName.TopLevel(packageName, simpleName)
+    }
+
+    private fun collectNameMappings(javaFile: PsiJavaFile): Map<String, JavaClassName> {
+        val mappings = HashMap<String, JavaClassName>()
+        val packageName = javaFile.packageName
+
+        fun process(javaClass: PsiClass) {
+            val className = getClassName(packageName, javaClass)
+            if (className != null) {
+                mappings[className.getInternalName()] = className
+            }
+        }
+
+        for (javaClass in javaFile.classes) {
+            process(javaClass)
+            javaClass.allInnerClasses.forEach { process(it) }
+        }
+
+        return mappings
+    }
+
+    private fun getClassName(packageName: String, javaClass: PsiClass): JavaClassName? {
+        val chunks = mutableListOf<String>()
+
+        var current: PsiClass? = javaClass
+        while (current != null) {
+            val name = current.name ?: return null
+            chunks.add(name)
+            current = current.containingClass
+        }
+
+        val reversed = chunks.asReversed()
+        var className: JavaClassName = JavaClassName.TopLevel(packageName, reversed.first())
+        for (index in 1 until reversed.size) {
+            className = JavaClassName.Nested(className, reversed[index])
+        }
+        return className
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaAnnotationStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaAnnotationStub.kt
new file mode 100644
index 0000000..f7f19df
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaAnnotationStub.kt
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.tree.AnnotationNode
+import org.jetbrains.org.objectweb.asm.Type
+
+class JavaAnnotationStub(val name: JavaClassName, val values: List<JavaAnnotationValue>) : Renderable {
+    companion object {
+        fun parse(
+            context: StubGeneratorContext,
+            access: Int,
+            visibleAnnotations: List<AnnotationNode>?,
+            invisibleAnnotations: List<AnnotationNode>?
+        ): List<JavaAnnotationStub> {
+            val visible = visibleAnnotations ?: emptyList()
+            val invisible = invisibleAnnotations ?: emptyList()
+
+            val annotations = ArrayList<JavaAnnotationStub>(visible.size + invisible.size)
+            visible.forEach { annotations += parse(context, it) }
+            invisible.forEach { annotations += parse(context, it) }
+
+            if (access.test(Opcodes.ACC_DEPRECATED)) {
+                if (annotations.none { it.name.packageName == "java.lang" && it.name.className == "Deprecated" }) {
+                    annotations += JavaAnnotationStub(JavaClassName.TopLevel("java.lang", "Deprecated"), emptyList())
+                }
+            }
+
+            return annotations
+        }
+
+        fun parse(context: StubGeneratorContext, node: AnnotationNode): JavaAnnotationStub {
+            val internalName = Type.getType(node.desc).internalName
+            val name = context.getClassName(internalName)
+            val values = parseValues(context, node.values ?: emptyList())
+            return JavaAnnotationStub(name, values)
+        }
+
+        private fun parseValues(context: StubGeneratorContext, values: List<Any?>): List<JavaAnnotationValue> {
+            val result = ArrayList<JavaAnnotationValue>(values.size / 2)
+            for (index in 0 until values.size / 2) {
+                val name = values[index * 2] as? String ?: continue
+                val value = JavaValue.parse(context, values[index * 2 + 1])
+                result += JavaAnnotationValue(name, value)
+            }
+            return result
+        }
+    }
+
+    override fun CodeScope.render() {
+        append('@')
+        append(name)
+        appendList(values, prefix = "(", postfix = ")")
+    }
+}
+
+class JavaAnnotationValue(val name: String, val value: JavaValue) : Renderable {
+    override fun CodeScope.render() {
+        append(name).append(" = ")
+        append(value)
+    }
+}
+
+sealed class JavaValue : Renderable {
+    companion object {
+        fun parse(context: StubGeneratorContext, value: Any?): JavaValue {
+            return when (value) {
+                is Byte -> VByte(value)
+                is Boolean -> VBoolean(value)
+                is Char -> VChar(value)
+                is Short -> VShort(value)
+                is Int -> VInt(value)
+                is Long -> VLong(value)
+                is Float -> VFloat(value)
+                is Double -> VDouble(value)
+                is String -> VString(value)
+                is Type -> VType(parseType(context, value))
+                is Array<*> -> {
+                    if (value.size != 2 || value[0] !is String || value[1] !is String) {
+                        error("Unexpected enum value: " + value.contentDeepToString())
+                    }
+
+                    val enum = context.getClassName(Type.getType(value[0] as String).internalName)
+                    VEnumEntry(enum, value[1] as String)
+                }
+                is AnnotationNode -> return VAnnotation(JavaAnnotationStub.parse(context, value))
+                is List<*> -> VArray(value.map { parse(context, it) })
+                else -> error("Unexpected value type $value")
+            }
+        }
+    }
+
+    class VByte(private val value: Byte) : JavaValue() {
+        override fun CodeScope.render() {
+            append(value.toString())
+        }
+    }
+
+    class VBoolean(private val value: Boolean) : JavaValue() {
+        override fun CodeScope.render() {
+            append(if (value) "true" else "false")
+        }
+    }
+
+    class VChar(private val value: Char) : JavaValue() {
+        override fun CodeScope.render() {
+            append("'${escape(value)}'")
+        }
+    }
+
+    class VShort(private val value: Short) : JavaValue() {
+        override fun CodeScope.render() {
+            append(value.toString())
+        }
+    }
+
+    class VInt(private val value: Int) : JavaValue() {
+        override fun CodeScope.render() {
+            append(value.toString())
+        }
+    }
+
+    class VLong(private val value: Long) : JavaValue() {
+        override fun CodeScope.render() {
+            append(value.toString()).append('L')
+        }
+    }
+
+    class VFloat(private val value: Float) : JavaValue() {
+        override fun CodeScope.render() {
+            when {
+                value.isNaN() -> append("java.lang.Float.NaN")
+                value == Float.POSITIVE_INFINITY -> append("java.lang.Float.POSITIVE_INFINITY")
+                value == Float.NEGATIVE_INFINITY -> append("java.lang.Float.NEGATIVE_INFINITY")
+                else -> append(value.toString()).append('f')
+            }
+        }
+    }
+
+    class VDouble(private val value: Double) : JavaValue() {
+        override fun CodeScope.render() {
+            when {
+                value.isNaN() -> append("java.lang.Double.NaN")
+                value == Double.POSITIVE_INFINITY -> append("java.lang.Double.POSITIVE_INFINITY")
+                value == Double.NEGATIVE_INFINITY -> append("java.lang.Double.NEGATIVE_INFINITY")
+                else -> append(value.toString())
+            }
+        }
+    }
+
+    class VString(private val value: String) : JavaValue() {
+        override fun CodeScope.render() {
+            val escaped = buildString {
+                for (char in value) {
+                    append(escape(char))
+                }
+            }
+            append("\"$escaped\"")
+        }
+    }
+
+    class VType(private val type: SigType) : JavaValue() {
+        override fun CodeScope.render() {
+            append(type).append(".class")
+        }
+    }
+
+    class VEnumEntry(private val enum: JavaClassName, private val value: String) : JavaValue() {
+        override fun CodeScope.render() {
+            append(enum).append('.').append(value)
+        }
+    }
+
+    class VAnnotation(private val value: JavaAnnotationStub) : JavaValue() {
+        override fun CodeScope.render() {
+            append(value)
+        }
+    }
+
+    class VArray(private val values: List<JavaValue>) : JavaValue() {
+        override fun CodeScope.render() {
+            append('{').appendList(values).append('}')
+        }
+    }
+
+    class VExpressionUnsafe(private val value: String) : JavaValue() {
+        override fun CodeScope.render() {
+            append(value)
+        }
+    }
+
+    object VNull : JavaValue() {
+        override fun CodeScope.render() {
+            append("null")
+        }
+    }
+}
+
+private fun escape(char: Char): String {
+    return when (char) {
+        '\t' -> "\\t"
+        '\b' -> "\\b"
+        '\n' -> "\\n"
+        '\r' -> "\\r"
+        '\u000c' -> "\\f"
+        '\'' -> "\\'"
+        '"' -> "\\\""
+        '\\' -> "\\\\"
+        in ' '..'~' -> "$char"
+        else -> String.format("\\u%04x", char.toInt())
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaClassStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaClassStub.kt
new file mode 100644
index 0000000..9044301
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaClassStub.kt
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.stubs.JAVA_LANG_OBJECT
+import org.jetbrains.kaptlite.signature.ClassSignature
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SignatureParser
+import org.jetbrains.kaptlite.signature.isJavaLangObject
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.ClassKind
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.Type
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+import javax.lang.model.element.Modifier
+import kotlin.collections.ArrayList
+
+class JavaClassStub(
+    val name: JavaClassName,
+    private val modifiers: Set<Modifier>,
+    private val kind: TypeKind,
+    private val signature: ClassSignature,
+    private val enumValues: List<JavaEnumValue>,
+    private val methods: List<JavaMethodStub>,
+    private val fields: List<JavaFieldStub>,
+    private val nestedClasses: List<JavaClassStub>,
+    private val annotations: List<JavaAnnotationStub>,
+    private val javadoc: String?
+) : Renderable {
+    enum class NestingKind {
+        TOP_LEVEL, NESTED, INNER
+    }
+
+    companion object {
+        fun parse(context: StubGeneratorContext, node: ClassNode, nestingKind: NestingKind): JavaClassStub? {
+            if (node.isSynthetic) {
+                return null
+            }
+
+            val origin = context.getClassOrigin(node)
+
+            val descriptor = origin.descriptor
+            val isDefaultImpls = descriptor is ClassDescriptor
+                    && descriptor.kind == ClassKind.INTERFACE
+                    && node.isPublic && node.isFinal
+                    && node.name.endsWith("${descriptor.name.asString()}\$DefaultImpls")
+
+            // DefaultImpls without any contents don't have INNERCLASS'es inside it (and inside the parent interface)
+            if (isDefaultImpls && (nestingKind == NestingKind.TOP_LEVEL || (node.fields.isEmpty() && node.methods.isEmpty()))) {
+                return null
+            }
+
+            val name = context.getClassName(node)
+
+            val typeKind = getTypeKind(node.access)
+            val signature = parseClassSignature(context, node)
+            val constructorData = JavaMethodStub.ConstructorData(emptyList(), emptyList()) // getConstructorData(context, node)
+
+            val methods = (node.methods ?: emptyList())
+                .mapNotNullTo(mutableListOf()) {
+                    JavaMethodStub.parse(context, it, node, name, nestingKind == NestingKind.INNER, constructorData)
+                }
+
+            if (methods.none { it.isConstructor } && typeKind == TypeKind.CLASS) {
+                methods += JavaMethodStub(
+                    name = name.className,
+                    modifiers = setOf(Modifier.PRIVATE),
+                    isConstructor = true,
+                    data = JavaMethodStub.MethodData(emptyList(), emptyList(), SigType.Primitive.VOID, emptyList()),
+                    annotations = emptyList(),
+                    javadoc = null,
+                    constructorData = constructorData
+                )
+            }
+
+            val enumValues = (node.fields ?: emptyList())
+                .filter { it.isEnumValue }
+                .mapNotNull { field ->
+                    val valueOrigin = context.getFieldOrigin(field)
+                    JavaEnumValue(field.name, context.getKDocComment(KDocParsingHelper.DeclarationKind.FIELD, valueOrigin))
+                }
+
+            val fields = (node.fields ?: emptyList())
+                .filter { !it.isEnumValue }
+                .mapNotNull { JavaFieldStub.parse(context, it) }
+
+            val nestedClasses = ArrayList<JavaClassStub>(0)
+            for (innerClass in node.innerClasses) {
+                if (innerClass.outerName == node.name) {
+                    if (enumValues.any { it.name == innerClass.innerName }) {
+                        continue
+                    }
+
+                    val childNode = context.loader.load(innerClass.name) ?: continue
+                    val childNestingKind = when {
+                        nestingKind == NestingKind.INNER || isInner(childNode, node) -> NestingKind.INNER
+                        else -> NestingKind.NESTED
+                    }
+                    val childClass = parse(context, childNode, childNestingKind) ?: continue
+                    nestedClasses += childClass
+                }
+            }
+
+            // kotlin.jvm.JvmName is applicable to file facades but not applicable to classes
+            val annotations = JavaAnnotationStub.parse(context, node.access, node.visibleAnnotations, node.invisibleAnnotations)
+                .filter { it.name.toString() != "kotlin.jvm.JvmName" }
+
+            val javadoc = context.getKDocComment(KDocParsingHelper.DeclarationKind.CLASS, origin)
+
+            var modifiers = parseModifiers(node)
+            if (nestingKind == NestingKind.NESTED) {
+                modifiers = modifiers + Modifier.STATIC
+            }
+
+            if (!context.checker.checkClass(name, signature, enumValues, annotations, origin)) {
+                return null
+            }
+
+            return JavaClassStub(
+                name,
+                modifiers, typeKind,
+                signature,
+                enumValues, methods, fields, nestedClasses,
+                annotations,
+                javadoc
+            )
+        }
+
+        private fun isInner(node: ClassNode, owner: ClassNode): Boolean {
+            val thisField = node.fields.find { it.name == "this$0" } ?: return false
+            return Type.getType(thisField.desc).internalName == owner.name
+        }
+
+        private fun parseClassSignature(context: StubGeneratorContext, node: ClassNode): ClassSignature {
+            return if (node.signature == null) {
+                val superClass = parseType(context, (node.superName ?: JAVA_LANG_OBJECT))
+                val interfaces = (node.interfaces ?: emptyList()).map { parseType(context, it) }
+                ClassSignature(emptyList(), superClass, interfaces)
+            } else {
+                val signature = SignatureParser.parseClassSignature(node.signature)
+                return ClassSignature(
+                    typeParameters = signature.typeParameters.map { it.copy(bounds = it.bounds.patchTypes(context)) },
+                    superClass = signature.superClass.patchType(context),
+                    interfaces = signature.interfaces.patchTypes(context)
+                )
+            }
+        }
+
+        private fun getTypeKind(access: Int): TypeKind {
+            if (access.test(Opcodes.ACC_ANNOTATION)) return TypeKind.ANNOTATION
+            if (access.test(Opcodes.ACC_INTERFACE)) return TypeKind.INTERFACE
+            if (access.test(Opcodes.ACC_ENUM)) return TypeKind.ENUM
+            return TypeKind.CLASS
+        }
+    }
+
+    class JavaEnumValue(val name: String, val javadoc: String?)
+
+    enum class TypeKind(val keyword: String) {
+        INTERFACE("interface"), ANNOTATION("@interface"), ENUM("enum"), CLASS("class")
+    }
+
+    override fun CodeScope.render() {
+        appendJavadoc(javadoc)
+        appendList(annotations, "\n", postfix = "\n")
+        appendModifiers(modifiers).append(' ')
+        append(kind.keyword).append(' ').append(name.className)
+        appendList(signature.typeParameters, prefix = "<", postfix = ">") { append(it) }
+        if (kind == TypeKind.CLASS && !signature.superClass.isJavaLangObject) {
+            append(" extends ").append(signature.superClass)
+        }
+        if (kind != TypeKind.ANNOTATION) {
+            val keyword = if (kind == TypeKind.INTERFACE) "extends" else "implements"
+            appendList(signature.interfaces, prefix = " $keyword ") { append(it) }
+        }
+
+        append(' ').block {
+            var isFirst = true
+
+            if (kind == TypeKind.ENUM) {
+                val implMethods = methods
+                    .filter { it.modifiers.contains(Modifier.ABSTRACT) }
+                    .map { it.copy(modifiers = it.modifiers - Modifier.ABSTRACT) }
+
+                val constructorParameters = methods.asSequence()
+                    .filter { it.isConstructor }
+                    .minBy { it.data.parameters.size }?.data?.parameters
+                    ?: emptyList()
+
+                for (value in enumValues) {
+                    appendJavadoc(value.javadoc)
+                    append(value.name)
+                    appendList(constructorParameters, prefix = "(", postfix = ")") { append(it.type.defaultValue) }
+
+                    if (implMethods.isNotEmpty()) {
+                        append(' ').block {
+                            appendList(implMethods, "\n\n")
+                        }
+                    }
+
+                    append(',').newLine()
+                }
+                append(";")
+                isFirst = false
+            }
+
+            appendList(fields, "\n", prefix = if (!isFirst) "\n\n" else "")
+            isFirst = isFirst && fields.isEmpty()
+
+            appendList(methods, "\n\n", prefix = if (!isFirst) "\n\n" else "")
+            isFirst = isFirst && methods.isEmpty()
+
+            appendList(nestedClasses, "\n\n", prefix = if (!isFirst) "\n\n" else "")
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaFieldStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaFieldStub.kt
new file mode 100644
index 0000000..5eb545b
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaFieldStub.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SignatureParser
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.PropertyDescriptor
+import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
+import org.jetbrains.kotlin.psi.KtProperty
+import org.jetbrains.kotlin.psi.KtPsiUtil
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.Type
+import org.jetbrains.org.objectweb.asm.tree.FieldNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+import javax.lang.model.element.Modifier
+
+class JavaFieldStub(
+    private val name: String,
+    private val modifiers: Set<Modifier>,
+    private val type: SigType,
+    private val initializer: JavaValue?,
+    private val annotations: List<JavaAnnotationStub>,
+    private val javadoc: String?
+) : Renderable {
+    companion object {
+        fun parse(context: StubGeneratorContext, node: FieldNode): JavaFieldStub? {
+            if (node.isSynthetic) {
+                return null
+            }
+
+            val origin = context.getFieldOrigin(node)
+            val name = node.name
+            val type = parseType(context, node)
+
+            val initializer = getEnhancedFieldInitializer(context, node, origin) ?: parseInitializer(context, node, type)
+            val annotations = JavaAnnotationStub.parse(context, node.access, node.visibleAnnotations, node.invisibleAnnotations)
+            val javadoc = context.getKDocComment(KDocParsingHelper.DeclarationKind.FIELD, origin)
+
+            if (!context.checker.checkField(name, type, annotations, origin)) {
+                return null
+            }
+
+            return JavaFieldStub(name, parseModifiers(node), type, initializer, annotations, javadoc)
+        }
+
+        private fun getEnhancedFieldInitializer(context: StubGeneratorContext, node: FieldNode, origin: JvmDeclarationOrigin): JavaValue? {
+            val value = node.value
+
+            if (value != null && isSimpleValue(value)) {
+                val propertyDescriptor = origin.descriptor as? PropertyDescriptor
+                val ktProperty = origin.element as? KtProperty
+                val initializer = ktProperty?.initializer
+                if (propertyDescriptor != null && propertyDescriptor.compileTimeInitializer != null) {
+                    if (ktProperty != null && !ktProperty.hasDelegate() && initializer != null) {
+                        val expression = KtPsiUtil.deparenthesize(initializer)
+                        val descriptor = expression.getResolvedCall(context.bindingContext)?.resultingDescriptor
+                        if (descriptor is JavaPropertyDescriptor && descriptor.isConst && !isBuiltInConst(descriptor)) {
+                            return JavaValue.VExpressionUnsafe(descriptor.fqNameSafe.asString())
+                        }
+                    }
+                }
+            }
+
+            return null
+        }
+
+        private fun isBuiltInConst(descriptor: PropertyDescriptor): Boolean {
+            val containingClassDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+            if (!containingClassDescriptor.isCompanionObject) {
+                return false
+            }
+
+            val classDescriptor = containingClassDescriptor.containingDeclaration as? ClassDescriptor ?: return false
+            return KotlinBuiltIns.isPrimitiveType(classDescriptor.defaultType)
+        }
+
+        private fun isSimpleValue(value: Any?): Boolean {
+            return when (value) {
+                is Byte, is Short, is Int, is Long, is Char, is Boolean, is Float, is Double -> true
+                is String -> true
+                is List<*> -> value.isNotEmpty() && isSimpleValue(value.first())
+                else -> false
+            }
+        }
+
+        private fun parseInitializer(context: StubGeneratorContext, node: FieldNode, type: SigType): JavaValue? {
+            val value = node.value ?: return if (node.isStatic) type.defaultValue else null
+
+            if (node.desc == "Z") {
+                return JavaValue.VBoolean(value != 0)
+            }
+
+            return JavaValue.parse(context, value)
+        }
+
+        private fun parseType(context: StubGeneratorContext, node: FieldNode): SigType {
+            val signature = node.signature
+            return if (signature == null) {
+                parseType(context, Type.getType(node.desc)).patchType(context)
+            } else {
+                SignatureParser.parseFieldSignature(signature).patchType(context)
+            }
+        }
+    }
+
+    override fun CodeScope.render() {
+        appendJavadoc(javadoc)
+        appendList(annotations, "\n", postfix = "\n")
+        appendModifiers(modifiers).append(' ')
+        append(type).append(' ')
+        append(name)
+        if (initializer != null) {
+            append(" = ")
+            append(initializer)
+        }
+        append(';')
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaMethodStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaMethodStub.kt
new file mode 100644
index 0000000..5309149
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaMethodStub.kt
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.signature.SigParameter
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeParameter
+import org.jetbrains.kaptlite.signature.SignatureParser
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.kotlin.codegen.AsmUtil
+import org.jetbrains.kotlin.codegen.state.getInlineClassSignatureManglingSuffix
+import org.jetbrains.kotlin.descriptors.*
+import org.jetbrains.kotlin.load.java.JvmAbi.DEFAULT_IMPLS_SUFFIX
+import org.jetbrains.kotlin.load.java.JvmAbi.IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS
+import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver.isSpecializedEqualsMethod
+import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver.isSynthesizedBoxOrUnboxMethod
+import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.Type
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import org.jetbrains.org.objectweb.asm.tree.MethodNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+import javax.lang.model.element.Modifier
+
+data class JavaMethodStub(
+    val name: String,
+    val modifiers: Set<Modifier>,
+    val isConstructor: Boolean,
+    val data: MethodData,
+    private val annotations: List<JavaAnnotationStub>,
+    private val javadoc: String?,
+    private val constructorData: ConstructorData
+) : Renderable {
+    class ConstructorData(val uninitializedFields: List<UninitializedField>, val superConstructorArgs: List<JavaValue>)
+
+    class MethodData(
+        val typeParameters: List<SigTypeParameter>,
+        val parameters: List<JavaParameterStub>,
+        val returnType: SigType,
+        val exceptionTypes: List<SigType>
+    )
+
+    companion object {
+        fun parse(
+            context: StubGeneratorContext, node: MethodNode,
+            owner: ClassNode, ownerName: JavaClassName, ownerIsInner: Boolean, constructorData: ConstructorData
+        ): JavaMethodStub? {
+            if (node.isStaticInitializer || node.isBridge || node.isSynthetic || isEnumGeneratedMember(node, owner)) {
+                return null
+            }
+
+            val isConstructor = node.isConstructor
+            val name = if (isConstructor) ownerName.className else node.name
+
+            val origin = context.getMethodOrigin(node)
+            val descriptor = origin.descriptor
+            if (descriptor != null && hasInlineClassesInSignature(descriptor, node)) {
+                return null
+            }
+
+            val data = parseData(context, node, owner, ownerIsInner, origin)
+
+            val annotations = JavaAnnotationStub.parse(context, node.access, node.visibleAnnotations, node.invisibleAnnotations)
+            val javadoc = context.getKDocComment(KDocParsingHelper.DeclarationKind.METHOD, origin)
+
+            if (!context.checker.checkMethod(name, data, annotations, origin)) {
+                return null
+            }
+
+            return JavaMethodStub(name, parseModifiers(node), isConstructor, data, annotations, javadoc, constructorData)
+        }
+
+        private fun hasInlineClassesInSignature(descriptor: DeclarationDescriptor, node: MethodNode): Boolean {
+            if (descriptor is CallableMemberDescriptor) {
+                if (isSynthesizedBoxOrUnboxMethod(descriptor) || isSpecializedEqualsMethod(descriptor)) {
+                    return true
+                }
+
+                val manglingSuffix = getInlineClassSignatureManglingSuffix(descriptor)
+                if (manglingSuffix != null) {
+                    return true
+                }
+            }
+
+            if (descriptor is CallableDescriptor) {
+                val containingClass = descriptor.containingDeclaration
+                if (node.name.endsWith(IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS) && containingClass.isInlineClassThatRequiresMangling()) {
+                    return true
+                }
+            }
+
+            return false
+        }
+
+        private fun isEnumGeneratedMember(node: MethodNode, owner: ClassNode): Boolean {
+            if (!owner.isEnum) {
+                return false
+            }
+
+            val enumName = owner.name
+            return when {
+                node.name == "values" && node.desc == "()[L$enumName;" -> true
+                node.name == "valueOf" && node.desc == "(Ljava/lang/String;)L$enumName;" -> true
+                else -> false
+            }
+        }
+
+        private fun parseData(
+            context: StubGeneratorContext,
+            node: MethodNode, owner: ClassNode, ownerIsInner: Boolean,
+            origin: JvmDeclarationOrigin
+        ): MethodData {
+            val methodType = Type.getMethodType(node.desc)
+            val rawParameterTypes = parseArgumentTypes(context, methodType, node, owner, ownerIsInner)
+            val parameterNames = getParameterNamesFromSource(context, node, owner, rawParameterTypes.size, origin)
+                ?: (rawParameterTypes.indices).map { "p$it" }
+            val rawParameters = rawParameterTypes.mapIndexed { index, type -> SigParameter(parameterNames[index], type) }
+
+            return if (node.signature == null) {
+                val parameters = rawParameters.mapIndexed { index, param ->
+                    parseParameter(context, node, param, index, rawParameters.size)
+                }
+                val returnType = parseType(context, methodType.returnType)
+                val exceptionTypes = node.exceptions.map { parseType(context, it) }
+                MethodData(emptyList(), parameters, returnType, exceptionTypes)
+            } else {
+                val signature = SignatureParser.parseMethodSignature(node.signature, rawParameters)
+                val parameters = signature.parameters.mapIndexed { index, param ->
+                    parseParameter(context, node, param.copy(type = param.type.patchType(context)), index, rawParameters.size)
+                }
+                MethodData(
+                    signature.typeParameters.map { it.copy(bounds = it.bounds.patchTypes(context)) },
+                    parameters,
+                    signature.returnType.patchType(context),
+                    signature.exceptionTypes.patchTypes(context)
+                )
+            }
+        }
+
+        private fun parseArgumentTypes(
+            context: StubGeneratorContext,
+            type: Type, node: MethodNode,
+            owner: ClassNode, ownerIsInner: Boolean
+        ): List<SigType> {
+            val types = type.argumentTypes.map { parseType(context, it) }
+
+            if (node.isConstructor) {
+                if (ownerIsInner) {
+                    assert(type.argumentTypes.isNotEmpty())
+                    return types.drop(1)
+                } else if (owner.isEnum) {
+                    assert(type.argumentTypes.size >= 2)
+                    assert(type.argumentTypes[0].descriptor == "Ljava/lang/String;")
+                    assert(type.argumentTypes[1].sort == Type.INT)
+                    return types.drop(2)
+                }
+            }
+
+            return types
+        }
+
+        private fun getParameterNamesFromSource(
+            context: StubGeneratorContext,
+            node: MethodNode, owner: ClassNode,
+            parameterCount: Int,
+            origin: JvmDeclarationOrigin
+        ): List<String>? {
+            val descriptor = origin.descriptor as? FunctionDescriptor ?: return null
+
+            fun getReceiverParameterName(): String {
+                return AsmUtil.getNameForReceiverParameter(descriptor, context.bindingContext, context.languageVersionSettings)
+            }
+
+            if (descriptor.valueParameters.any { it.name.isSpecial }) {
+                return null
+            }
+
+            val parameterNames = when (descriptor) {
+                is PropertyGetterDescriptor -> if (descriptor.isExtension) listOf(getReceiverParameterName()) else emptyList()
+                is PropertySetterDescriptor -> {
+                    val parameterName = descriptor.valueParameters.singleOrNull()?.name?.takeIf { !it.isSpecial } ?: return null
+
+                    when {
+                        descriptor.isExtension -> {
+                            val receiverParameterName = getReceiverParameterName()
+                            if (receiverParameterName == parameterName.asString()) {
+                                return null
+                            }
+                            listOf(receiverParameterName, parameterName.asString())
+                        }
+                        else -> listOf(parameterName.asString())
+                    }
+                }
+                else -> {
+                    val ordinaryParameterNames = descriptor.valueParameters.map { it.name.asString() }
+                    when {
+                        descriptor.isExtension -> {
+                            val receiverParameterName = getReceiverParameterName()
+                            if (receiverParameterName in ordinaryParameterNames) {
+                                return null
+                            }
+                            listOf(getReceiverParameterName()) + ordinaryParameterNames
+                        }
+                        else -> ordinaryParameterNames
+                    }
+                }
+            }
+
+            val prefix = ArrayList<String>(1)
+
+            if (isDefaultImplsMethod(descriptor, node, owner)) {
+                if (descriptor.valueParameters.any { it.name.asString() == AsmUtil.THIS_IN_DEFAULT_IMPLS }) {
+                    // In theory, we can invent some good unique name here, but... nevermind.
+                    return null
+                }
+                prefix += AsmUtil.THIS_IN_DEFAULT_IMPLS
+            }
+
+            val delta = when {
+                isEnumConstructor(descriptor) -> 2
+                isInnerClassConstructor(descriptor) -> 1
+                else -> 0
+            }
+
+            val expectedNameCount = parameterNames.size + prefix.size + delta
+            if (expectedNameCount != parameterCount) {
+                return null
+            }
+
+            return prefix + parameterNames
+        }
+
+        private fun parseParameter(
+            context: StubGeneratorContext,
+            node: MethodNode,
+            param: SigParameter,
+            index: Int, count: Int
+        ): JavaParameterStub {
+            val isVarargs = node.isVarargs && index == count - 1 && param.type is SigType.Array
+            val visibleAnnotations = node.visibleParameterAnnotations?.getOrNull(index)
+            val invisibleAnnotations = node.invisibleParameterAnnotations?.getOrNull(index)
+            val annotations = JavaAnnotationStub.parse(context, 0, visibleAnnotations, invisibleAnnotations)
+            val patchedType = param.type.patchType(context).fixVarargType(isVarargs)
+            return JavaParameterStub(param.name, patchedType, 0, isVarargs, annotations)
+        }
+
+        private fun SigType.fixVarargType(isVarargs: Boolean): SigType {
+            if (isVarargs) {
+                val arrayType = this as SigType.Array
+                return arrayType.elementType
+            }
+
+            return this
+        }
+
+        private fun isEnumConstructor(descriptor: FunctionDescriptor): Boolean {
+            val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+            return containingClass.kind == ClassKind.ENUM_CLASS && descriptor is ConstructorDescriptor
+        }
+
+        private fun isInnerClassConstructor(descriptor: FunctionDescriptor): Boolean {
+            val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+            return containingClass.kind == ClassKind.CLASS && containingClass.isInner && descriptor is ConstructorDescriptor
+        }
+
+        private fun isDefaultImplsMethod(descriptor: FunctionDescriptor, node: MethodNode, owner: ClassNode): Boolean {
+            if (!owner.name.endsWith(DEFAULT_IMPLS_SUFFIX) || node.isAbstract) {
+                return false
+            }
+
+            val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+            return containingClass.kind == ClassKind.INTERFACE
+        }
+    }
+
+    override fun CodeScope.render() {
+        appendJavadoc(javadoc)
+        appendList(annotations, "\n", postfix = "\n")
+        appendModifiers(modifiers).append(' ')
+        appendList(data.typeParameters, prefix = "<", postfix = "> ") { append(it) }
+        if (!isConstructor) {
+            append(data.returnType).append(' ')
+        }
+        append(name)
+        append('(')
+        appendList(data.parameters)
+        append(')')
+
+        if (data.exceptionTypes.isNotEmpty()) {
+            appendList(data.exceptionTypes, prefix = " throws ") { append(it) }
+        }
+
+        if (Modifier.ABSTRACT !in modifiers) {
+            val uninitializedFields = constructorData.uninitializedFields
+            val superConstructorArgs = constructorData.superConstructorArgs
+
+            if (!data.returnType.isVoid || isConstructor && (uninitializedFields.isNotEmpty() || superConstructorArgs.isNotEmpty())) {
+                append(' ').block {
+                    if (isConstructor) {
+                        if (superConstructorArgs.isNotEmpty()) {
+                            append("super(")
+                            appendList(superConstructorArgs)
+                            append(");")
+                        }
+
+                        appendList(uninitializedFields, "\n", prefix = if (superConstructorArgs.isNotEmpty()) "\n" else "") {
+                            append("this.").append(it.name).append(" = ").append(it.type.defaultValue).append(';')
+                        }
+                    }
+                    if (!data.returnType.isVoid) {
+                        newLineIfNeeded()
+                        append("return ").append(data.returnType.defaultValue).append(';')
+                    }
+                }
+            } else {
+                append(" {}")
+            }
+        } else {
+            append(';')
+        }
+    }
+}
+
+class UninitializedField(val name: String, val type: SigType)
+
+class JavaParameterStub(
+    val name: String,
+    val type: SigType,
+    private val access: Int,
+    private val isVarargs: Boolean,
+    private val annotations: List<JavaAnnotationStub>
+) : Renderable {
+    override fun CodeScope.render() {
+        appendList(annotations, " ", postfix = " ")
+        if ((access and Opcodes.ACC_FINAL) != 0) {
+            append("final ")
+        }
+        append(type)
+        if (isVarargs) {
+            append("...")
+        }
+        append(' ')
+        append(name)
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/CodeScope.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/CodeScope.kt
new file mode 100644
index 0000000..a8d0305
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/CodeScope.kt
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs.util
+
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeArgument
+import org.jetbrains.kaptlite.signature.SigTypeParameter
+import javax.lang.model.element.Modifier
+
+interface Renderable {
+    fun CodeScope.render()
+}
+
+class CodeScope(private val appendable: Appendable, val indent: String = "    ") {
+    private var depth: Int = 0
+    private var lastNewLine = false
+
+    fun append(c: Char): CodeScope {
+        if (c == '\n') {
+            newLine()
+        } else {
+            appendable.append(c)
+        }
+        lastNewLine = c == '\n'
+        return this
+    }
+
+    fun append(str: CharSequence): CodeScope {
+        var isFirst = true
+        for (line in str.lineSequence()) {
+            if (isFirst) {
+                isFirst = false
+            } else {
+                newLine()
+            }
+
+            appendable.append(line)
+        }
+        lastNewLine = str.lastOrNull() == '\n'
+        return this
+    }
+
+    fun newLine(): CodeScope {
+        appendable.append(System.lineSeparator())
+        for (i in 1..depth) {
+            appendable.append(indent)
+        }
+        lastNewLine = true
+        return this
+    }
+
+    fun newLineIfNeeded(): CodeScope {
+        if (!lastNewLine) {
+            newLine()
+        }
+        return this
+    }
+
+    fun incDepth(): CodeScope {
+        depth += 1
+        return this
+    }
+
+    fun decDepth(): CodeScope {
+        depth -= 1
+        return this
+    }
+}
+
+fun CodeScope.block(block: CodeScope.() -> Unit) {
+    append("{")
+    incDepth()
+    newLine()
+    block()
+    decDepth()
+    newLine()
+    append("}")
+}
+
+fun CodeScope.append(renderable: Renderable): CodeScope {
+    with(renderable) { render() }
+    return this
+}
+
+fun CodeScope.append(type: SigType): CodeScope {
+    when (type) {
+        is SigType.TypeVariable -> append(type.name)
+        is SigType.Array -> append(type.elementType).append("[]")
+        is SigType.Primitive -> append(type.javaName)
+        is SigType.Class -> append(type.fqName)
+        is SigType.Nested -> append(type.outer).append('.').append(type.name)
+        is SigType.Generic -> {
+            append(type.base)
+            appendList(type.args, prefix = "<", postfix = ">") { append(it) }
+        }
+    }
+    return this
+}
+
+fun CodeScope.append(param: SigTypeParameter): CodeScope {
+    append(param.name)
+    appendList(param.bounds, " & ", prefix = " extends ") { append(it) }
+    return this
+}
+
+fun CodeScope.append(arg: SigTypeArgument): CodeScope {
+    when (arg) {
+        SigTypeArgument.Unbound -> append('?')
+        is SigTypeArgument.Invariant -> append(arg.type)
+        is SigTypeArgument.Extends -> append("? extends ").append(arg.type)
+        is SigTypeArgument.Super -> append("? super ").append(arg.type)
+    }
+    return this
+}
+
+fun <T : Renderable> CodeScope.appendList(
+    list: Collection<T>,
+    separator: String = ", ",
+    prefix: String = "",
+    postfix: String = ""
+): CodeScope {
+    return appendList(list, separator, prefix, postfix) { append(it) }
+}
+
+fun <T> CodeScope.appendList(
+    list: Collection<T>,
+    separator: String = ", ",
+    prefix: String = "",
+    postfix: String = "",
+    block: CodeScope.(T) -> Unit
+): CodeScope {
+    if (list.isEmpty()) {
+        return this
+    }
+
+    append(prefix)
+    var isFirst = true
+    for (item in list) {
+        if (isFirst) {
+            isFirst = false
+        } else {
+            append(separator)
+        }
+
+        block(item)
+    }
+    append(postfix)
+    return this
+}
+
+fun CodeScope.appendModifiers(modifiers: Set<Modifier>): CodeScope {
+    appendList(modifiers, " ") { append(it.toString()) }
+    return this
+}
+
+fun CodeScope.appendJavadoc(text: String?): CodeScope {
+    if (text != null && text.isNotBlank()) {
+        append("/**").newLine()
+        for (line in text.lineSequence()) {
+            append(" * ").append(line).newLine()
+        }
+        append(" */").newLine()
+    }
+
+    return this
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/parseModifiers.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/parseModifiers.kt
new file mode 100644
index 0000000..41e770f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/parseModifiers.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs.util
+
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.tree.*
+import java.util.EnumSet
+import javax.lang.model.element.Modifier
+
+fun Int.test(flag: Int): Boolean {
+    return (this and flag) > 0
+}
+
+val ClassNode.isPublic: Boolean get() = access.test(Opcodes.ACC_PUBLIC)
+val ClassNode.isFinal: Boolean get() = access.test(Opcodes.ACC_FINAL)
+val ClassNode.isSynthetic: Boolean get() = access.test(Opcodes.ACC_SYNTHETIC)
+val ClassNode.isEnum: Boolean get() = access.test(Opcodes.ACC_ENUM)
+
+val FieldNode.isSynthetic: Boolean get() = access.test(Opcodes.ACC_SYNTHETIC)
+val FieldNode.isStatic: Boolean get() = access.test(Opcodes.ACC_STATIC)
+val FieldNode.isEnumValue: Boolean get() = access.test(Opcodes.ACC_ENUM)
+
+val MethodNode.isSynthetic: Boolean get() = access.test(Opcodes.ACC_SYNTHETIC)
+val MethodNode.isBridge: Boolean get() = access.test(Opcodes.ACC_BRIDGE)
+val MethodNode.isVarargs: Boolean get() = access.test(Opcodes.ACC_VARARGS)
+val MethodNode.isAbstract: Boolean get() = access.test(Opcodes.ACC_ABSTRACT)
+val MethodNode.isStaticInitializer: Boolean get() = name == "<clinit>"
+val MethodNode.isConstructor: Boolean get() = name == "<init>"
+
+private fun parseVisibilityModifiers(access: Int, consumer: EnumSet<Modifier>) {
+    if (access.test(Opcodes.ACC_PUBLIC)) consumer.add(Modifier.PUBLIC)
+    if (access.test(Opcodes.ACC_PROTECTED)) consumer.add(Modifier.PROTECTED)
+    if (access.test(Opcodes.ACC_PRIVATE)) consumer.add(Modifier.PRIVATE)
+}
+
+private fun parseModalityModifiers(access: Int, consumer: EnumSet<Modifier>) {
+    val isEnum = access.test(Opcodes.ACC_ENUM)
+    if (access.test(Opcodes.ACC_FINAL) && !isEnum) consumer.add(Modifier.FINAL)
+    if (access.test(Opcodes.ACC_ABSTRACT) && !isEnum) consumer.add(Modifier.ABSTRACT)
+}
+
+fun parseModifiers(node: ClassNode): Set<Modifier> {
+    val access = node.access
+    val modifiers = EnumSet.noneOf(Modifier::class.java)
+    parseVisibilityModifiers(access, modifiers)
+    parseModalityModifiers(access, modifiers)
+    return modifiers
+}
+
+fun parseModifiers(node: MethodNode): Set<Modifier> {
+    val access = node.access
+    val modifiers = EnumSet.noneOf(Modifier::class.java)
+    parseVisibilityModifiers(access, modifiers)
+    parseModalityModifiers(access, modifiers)
+    if (access.test(Opcodes.ACC_SYNCHRONIZED)) modifiers.add(Modifier.SYNCHRONIZED)
+    if (access.test(Opcodes.ACC_NATIVE)) modifiers.add(Modifier.NATIVE)
+    if (access.test(Opcodes.ACC_STRICT)) modifiers.add(Modifier.STRICTFP)
+    if (access.test(Opcodes.ACC_STATIC)) modifiers.add(Modifier.STATIC)
+    return modifiers
+}
+
+fun parseModifiers(node: FieldNode): Set<Modifier> {
+    val access = node.access
+    val modifiers = EnumSet.noneOf(Modifier::class.java)
+    parseVisibilityModifiers(access, modifiers)
+    parseModalityModifiers(access, modifiers)
+    if (access.test(Opcodes.ACC_VOLATILE)) modifiers.add(Modifier.VOLATILE)
+    if (access.test(Opcodes.ACC_TRANSIENT)) modifiers.add(Modifier.TRANSIENT)
+    if (access.test(Opcodes.ACC_STATIC)) modifiers.add(Modifier.STATIC)
+    return modifiers
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/typeUtils.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/typeUtils.kt
new file mode 100644
index 0000000..fdbc981
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/typeUtils.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.stubs.util
+
+import org.jetbrains.kaptlite.stubs.model.JavaValue
+import org.jetbrains.kaptlite.stubs.model.JavaValue.*
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeArgument
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.org.objectweb.asm.Type
+
+sealed class JavaClassName(val packageName: String, val className: String) : Renderable {
+    abstract fun getInternalName(): String
+
+    class TopLevel(packageName: String, simpleName: String) : JavaClassName(packageName, simpleName) {
+        override fun CodeScope.render() {
+            if (packageName.isNotEmpty()) {
+                append(packageName).append('.')
+            }
+            append(className)
+        }
+
+        override fun getInternalName() = if (packageName.isEmpty()) className else packageName.replace('.', '/') + '/' + className
+        override fun toString() = if (packageName.isNotEmpty()) "$packageName.$className" else className
+    }
+
+    class Nested(private val outer: JavaClassName, simpleName: String) : JavaClassName(outer.packageName, simpleName) {
+        override fun CodeScope.render() {
+            append(outer).append('.').append(className)
+        }
+
+        override fun getInternalName() = outer.getInternalName() + "$" + className
+        override fun toString() = "$outer.$className"
+    }
+}
+
+fun parseType(context: StubGeneratorContext, internalName: String): SigType {
+    return parseType(context, Type.getObjectType(internalName))
+}
+
+fun parseType(context: StubGeneratorContext, type: Type): SigType {
+    return when (type.sort) {
+        Type.ARRAY -> SigType.Array(parseType(context, type.elementType))
+        Type.OBJECT -> {
+            val className = context.getClassName(type.internalName)
+            SigType.Class(className.toString())
+        }
+        else -> SigType.Primitive.get(type.descriptor.single())
+    }
+}
+
+fun List<SigType>.patchTypes(context: StubGeneratorContext): List<SigType> {
+    return this.map { it.patchType(context) }
+}
+
+fun SigType.patchType(context: StubGeneratorContext): SigType {
+    return when (this) {
+        is SigType.Primitive, is SigType.TypeVariable -> this
+        is SigType.Array -> SigType.Array(elementType.patchType(context))
+        is SigType.Class -> {
+            val internalName = fqName.replace('.', '/')
+            SigType.Class(context.getClassName(internalName).toString())
+        }
+        is SigType.Nested -> SigType.Nested(outer.patchType(context), name)
+        is SigType.Generic -> SigType.Generic(base.patchType(context), args.map { arg ->
+            when (arg) {
+                SigTypeArgument.Unbound -> arg
+                is SigTypeArgument.Invariant -> SigTypeArgument.Invariant(arg.type.patchType(context))
+                is SigTypeArgument.Extends -> SigTypeArgument.Extends(arg.type.patchType(context))
+                is SigTypeArgument.Super -> SigTypeArgument.Super(arg.type.patchType(context))
+            }
+        })
+    }
+}
+
+val SigType.defaultValue: JavaValue
+    get() = when (this) {
+        is SigType.Primitive -> {
+            when (this) {
+                SigType.Primitive.VOID -> VNull
+                SigType.Primitive.BYTE -> VByte(0)
+                SigType.Primitive.SHORT -> VShort(0)
+                SigType.Primitive.INT -> VInt(0)
+                SigType.Primitive.LONG -> VLong(0)
+                SigType.Primitive.BOOLEAN -> VBoolean(false)
+                SigType.Primitive.CHAR -> VChar('\u0000')
+                SigType.Primitive.FLOAT -> VFloat(0f)
+                SigType.Primitive.DOUBLE -> VDouble(0.0)
+                else -> error("Unknown primitive type")
+            }
+        }
+        else -> VNull
+    }
+
+val SigType.isVoid: Boolean
+    get() = this === SigType.Primitive.VOID
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/AbstractStubGeneratorTest.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/AbstractStubGeneratorTest.kt
new file mode 100644
index 0000000..0632d34
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/AbstractStubGeneratorTest.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.test
+
+import com.intellij.compiler.JavaInMemoryCompiler
+import org.jetbrains.kaptlite.AbstractKaptLiteAnalysisHandlerExtension
+import org.jetbrains.kaptlite.KaptLiteClassBuilderInterceptorExtension
+import org.jetbrains.kaptlite.stubs.GeneratorOutput
+import org.jetbrains.kaptlite.stubs.util.CodeScope
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace
+import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
+import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration
+import org.jetbrains.kotlin.codegen.CodegenTestCase
+import org.jetbrains.kotlin.codegen.CodegenTestCase.TestFile
+import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
+import org.jetbrains.kotlin.test.ConfigurationKind
+import org.jetbrains.kotlin.test.KotlinTestUtils
+import java.io.File
+import java.util.*
+import javax.lang.model.element.NestingKind
+import javax.tools.DiagnosticListener
+import javax.tools.JavaFileObject
+import javax.tools.SimpleJavaFileObject
+import javax.tools.ToolProvider
+import kotlin.collections.ArrayList
+
+abstract class AbstractStubGeneratorTest : CodegenTestCase() {
+    companion object {
+        private const val KOTLIN_METADATA_GROUP = "[a-z0-9]+ = (\\{.+?\\}|[0-9]+)"
+        private val KOTLIN_METADATA_REGEX = "@kotlin\\.Metadata\\(($KOTLIN_METADATA_GROUP)(, $KOTLIN_METADATA_GROUP)*\\)".toRegex()
+
+        private fun removeMetadataAnnotationContents(test: String): String {
+            return test.replace(KOTLIN_METADATA_REGEX, "@kotlin.Metadata()")
+        }
+    }
+
+    private val origins = mutableMapOf<String, JvmDeclarationOrigin>()
+
+    override fun setupEnvironment(environment: KotlinCoreEnvironment) {
+        ClassBuilderInterceptorExtension.registerExtension(environment.project, KaptLiteClassBuilderInterceptorExtension(origins))
+    }
+
+    override fun tearDown() {
+        origins.clear()
+        super.tearDown()
+    }
+
+    override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
+        createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *listOfNotNull(writeJavaFiles(files)).toTypedArray())
+
+        val messageCollector = object : MessageCollector {
+            val errors = ArrayList<String>(0)
+
+            override fun hasErrors() = errors.isNotEmpty()
+            override fun clear() = errors.clear()
+
+            override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
+                if (severity.isError) {
+                    errors += message
+                }
+            }
+        }
+
+        val analysisHandlerExtension = KaptLiteAnalysisHandlerExtensionForTests(myEnvironment.configuration, messageCollector)
+        AnalysisHandlerExtension.registerExtension(myEnvironment.project, analysisHandlerExtension)
+
+        loadMultiFiles(files)
+
+        val trace = CliBindingTrace()
+        analyzeFilesWithJavaIntegration(
+            myEnvironment.project,
+            myFiles.psiFiles,
+            trace,
+            myEnvironment.configuration,
+            myEnvironment::createPackagePartProvider
+        )
+
+        val expectedFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
+
+        if (messageCollector.hasErrors()) {
+            KotlinTestUtils.assertEqualsToFile(expectedFile, messageCollector.errors.joinToString("\n"))
+            return
+        }
+
+        checkGeneratorOutput(analysisHandlerExtension.output, expectedFile, files)
+    }
+
+    private fun checkGeneratorOutput(output: TestGeneratorOutput, expectedFile: File, files: List<TestFile>) {
+        val filesContent = output.files
+            .sortedBy { it.name }
+            .joinToString("\n\n") { "// FILE: " + it.name + "\n" + it.content }
+            .lineSequence()
+            .map { line -> if (line.isBlank()) "" else line }
+            .joinToString("\n")
+            .let(::removeMetadataAnnotationContents)
+
+        val diagnostics = checkWithJavac(output.files + files.filter { it.name.endsWith(".java") })
+
+        val actualContent = buildString {
+            append(filesContent)
+            if (diagnostics.isNotEmpty()) {
+                appendln().appendln().append(diagnostics)
+            }
+        }
+
+        KotlinTestUtils.assertEqualsToFile(expectedFile, actualContent)
+    }
+
+    private fun checkWithJavac(files: List<TestFile>): String {
+        val locale = Locale.US
+        val compiler = ToolProvider.getSystemJavaCompiler()
+        val diagnostics = mutableListOf<String>()
+
+        val diagnosticListener = DiagnosticListener<JavaFileObject> { diagnostic ->
+            val path = diagnostic.source.name
+            val line = diagnostic.lineNumber
+            val column = diagnostic.columnNumber
+            val message = diagnostic.getMessage(locale)
+            diagnostics += "$path[$line:$column]: $message"
+        }
+
+        val fileManager = JavaInMemoryCompiler.JavaMemFileManager()
+        val javaFiles = files.map { createJavaFile(it) }
+        val task = compiler.getTask(null, fileManager, diagnosticListener, null, null, javaFiles)
+        task.call()
+
+        return diagnostics.joinToString("\n")
+    }
+
+    private fun createJavaFile(file: TestFile): SimpleJavaFileObject {
+        val uri = File(file.name).toURI()
+        return object : SimpleJavaFileObject(uri, JavaFileObject.Kind.SOURCE) {
+            private fun unsupported(): Nothing = throw UnsupportedOperationException("File is read-only")
+
+            override fun getName() = file.name
+            override fun getNestingKind() = NestingKind.TOP_LEVEL
+
+            override fun openInputStream() = file.content.byteInputStream()
+            override fun getCharContent(ignoreEncodingErrors: Boolean) = file.content
+
+            override fun openWriter() = unsupported()
+            override fun openOutputStream() = unsupported()
+            override fun delete() = unsupported()
+        }
+    }
+}
+
+class KaptLiteAnalysisHandlerExtensionForTests(
+    configuration: CompilerConfiguration,
+    override val messageCollector: MessageCollector
+) : AbstractKaptLiteAnalysisHandlerExtension(configuration) {
+    val output = TestGeneratorOutput()
+    override fun getOutput(state: GenerationState) = output
+}
+
+class TestGeneratorOutput : GeneratorOutput {
+    val files = mutableListOf<TestFile>()
+
+    override fun produce(internalName: String, path: String, block: CodeScope.() -> Unit) {
+        val sb = StringBuilder()
+        CodeScope(sb).block()
+        files += TestFile(path, sb.toString())
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/StubGeneratorTestGenerated.java b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/StubGeneratorTestGenerated.java
new file mode 100644
index 0000000..ece6dc4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/StubGeneratorTestGenerated.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.test;
+
+import com.intellij.testFramework.TestDataPath;
+import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
+import org.jetbrains.kotlin.test.KotlinTestUtils;
+import org.jetbrains.kotlin.test.TargetBackend;
+import org.jetbrains.kotlin.test.TestMetadata;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
+@SuppressWarnings("all")
+@TestMetadata("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs")
+@TestDataPath("$PROJECT_ROOT")
+@RunWith(JUnit3RunnerWithInners.class)
+public class StubGeneratorTestGenerated extends AbstractStubGeneratorTest {
+    private void runTest(String testDataFilePath) throws Exception {
+        KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+    }
+
+    @TestMetadata("abstractList.kt")
+    public void testAbstractList() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt");
+    }
+
+    public void testAllFilesPresentInStubs() throws Exception {
+        KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
+    }
+
+    @TestMetadata("annotationDeclarationSiteTargets.kt")
+    public void testAnnotationDeclarationSiteTargets() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt");
+    }
+
+    @TestMetadata("customPropertyDelegates.kt")
+    public void testCustomPropertyDelegates() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt");
+    }
+
+    @TestMetadata("dataClasses.kt")
+    public void testDataClasses() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt");
+    }
+
+    @TestMetadata("declarations.kt")
+    public void testDeclarations() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt");
+    }
+
+    @TestMetadata("defaultPackage.kt")
+    public void testDefaultPackage() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt");
+    }
+
+    @TestMetadata("deprecated.kt")
+    public void testDeprecated() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt");
+    }
+
+    @TestMetadata("enums.kt")
+    public void testEnums() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt");
+    }
+
+    @TestMetadata("facades.kt")
+    public void testFacades() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt");
+    }
+
+    @TestMetadata("fieldInitializers.kt")
+    public void testFieldInitializers() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt");
+    }
+
+    @TestMetadata("flags.kt")
+    public void testFlags() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt");
+    }
+
+    @TestMetadata("generics.kt")
+    public void testGenerics() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt");
+    }
+
+    @TestMetadata("implicitReturnTypes.kt")
+    public void testImplicitReturnTypes() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt");
+    }
+
+    @TestMetadata("inheritance.kt")
+    public void testInheritance() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt");
+    }
+
+    @TestMetadata("inlineClasses.kt")
+    public void testInlineClasses() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt");
+    }
+
+    @TestMetadata("interfaceDelegates.kt")
+    public void testInterfaceDelegates() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt");
+    }
+
+    @TestMetadata("javaNested.kt")
+    public void testJavaNested() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt");
+    }
+
+    @TestMetadata("javadoc.kt")
+    public void testJavadoc() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt");
+    }
+
+    @TestMetadata("javadocFormatting.kt")
+    public void testJavadocFormatting() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt");
+    }
+
+    @TestMetadata("jvmField.kt")
+    public void testJvmField() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt");
+    }
+
+    @TestMetadata("jvmName.kt")
+    public void testJvmName() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt");
+    }
+
+    @TestMetadata("jvmOverloads.kt")
+    public void testJvmOverloads() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt");
+    }
+
+    @TestMetadata("jvmThrows.kt")
+    public void testJvmThrows() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt");
+    }
+
+    @TestMetadata("lateinit.kt")
+    public void testLateinit() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt");
+    }
+
+    @TestMetadata("multiFileFacades.kt")
+    public void testMultiFileFacades() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt");
+    }
+
+    @TestMetadata("nestedSameName.kt")
+    public void testNestedSameName() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt");
+    }
+
+    @TestMetadata("parameterNames.kt")
+    public void testParameterNames() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt");
+    }
+
+    @TestMetadata("primitiveLiterals.kt")
+    public void testPrimitiveLiterals() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt");
+    }
+
+    @TestMetadata("propertyDelegates.kt")
+    public void testPropertyDelegates() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt");
+    }
+
+    @TestMetadata("sealedClasses.kt")
+    public void testSealedClasses() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt");
+    }
+
+    @TestMetadata("simple.kt")
+    public void testSimple() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt");
+    }
+
+    @TestMetadata("specialJavaKeywords.kt")
+    public void testSpecialJavaKeywords() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt");
+    }
+
+    @TestMetadata("suspendMain.kt")
+    public void testSuspendMain() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt");
+    }
+
+    @TestMetadata("suspendWithRuntime.kt")
+    public void testSuspendWithRuntime() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt");
+    }
+
+    @TestMetadata("suspendWithoutRuntime.kt")
+    public void testSuspendWithoutRuntime() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt");
+    }
+
+    @TestMetadata("varargs.kt")
+    public void testVarargs() throws Exception {
+        runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt");
+    }
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt
new file mode 100644
index 0000000..8282724
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+package abstractList
+
+class MappedList<out T, R>(val list: List<T>, private val function: (T) -> R) : AbstractList<R>(), List<R> {
+    override fun get(index: Int) = function(list[index])
+    override val size get() = list.size
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.txt
new file mode 100644
index 0000000..c87969d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.txt
@@ -0,0 +1,30 @@
+// FILE: abstractList/MappedList.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package abstractList;
+
+@kotlin.Metadata()
+public final class MappedList<T, R> extends kotlin.collections.AbstractList<R> implements java.util.List<R>, kotlin.jvm.internal.markers.KMappedMarker {
+    @org.jetbrains.annotations.NotNull
+    private final java.util.List<T> list;
+    private final kotlin.jvm.functions.Function1<T, R> function;
+
+    public R get(int index) {
+        return null;
+    }
+
+    public int getSize() {
+        return 0;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.util.List<T> getList() {
+        return null;
+    }
+
+    public MappedList(@org.jetbrains.annotations.NotNull java.util.List<? extends T> list, @org.jetbrains.annotations.NotNull kotlin.jvm.functions.Function1<? super T, ? extends R> function) {}
+}
+
+abstractList/MappedList.java[26:193]: variable list might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt
new file mode 100644
index 0000000..f9c328d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt
@@ -0,0 +1,25 @@
+package test
+
+@Target(AnnotationTarget.FIELD)
+annotation class FieldAnno
+
+@Target(AnnotationTarget.PROPERTY)
+annotation class PropertyAnno
+
+@Target(AnnotationTarget.VALUE_PARAMETER)
+annotation class ParameterAnno
+
+annotation class Anno
+
+class Foo(@FieldAnno @PropertyAnno @ParameterAnno @Anno val a: String)
+
+class Bar {
+    @FieldAnno @PropertyAnno @Anno
+    val a: String = ""
+}
+
+class Baz {
+    @FieldAnno @Anno
+    @JvmField
+    val a: String = ""
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt
new file mode 100644
index 0000000..6b9f12d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt
@@ -0,0 +1,38 @@
+// WITH_RUNTIME
+
+package test
+
+import kotlin.properties.ReadWriteProperty
+import kotlin.reflect.KProperty
+
+inline fun charSequence(key: String? = null) = object : BundleProperty<CharSequence>(key) {
+    override fun getValue(bundle: Any, key: String): CharSequence? = TODO()
+    override fun setValue(bundle: Any, key: String, value: CharSequence) {}
+}
+
+abstract class NullableBundleProperty<EE>(private val key: String?) : ReadWriteProperty<Any, EE?> {
+    private inline fun KProperty<*>.toKey(): String {
+        return toString()
+    }
+
+    override fun getValue(thisRef: Any, property: KProperty<*>): EE? = getValue(thisRef, key ?: property.toKey())
+    override fun setValue(thisRef: Any, property: KProperty<*>, value: EE?) {
+        setNullableValue(thisRef, key ?: property.toKey(), value)
+    }
+
+    abstract fun getValue(bundle: Any, key: String): EE?
+    abstract fun setNullableValue(bundle: Any, key: String, value: EE?)
+}
+
+abstract class BundleProperty<AA>(key: String?) : NullableBundleProperty<AA>(key) {
+    final override fun setValue(thisRef: Any, property: KProperty<*>, value: AA?) {
+        super.setValue(thisRef, property, value)
+    }
+
+    final override fun getValue(thisRef: Any, property: KProperty<*>): AA = super.getValue(thisRef, property)!!
+    final override fun setNullableValue(bundle: Any, key: String, value: AA?) {
+        setValue(bundle, key, value!!)
+    }
+
+    abstract fun setValue(bundle: Any, key: String, value: AA)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.txt
new file mode 100644
index 0000000..c2733e1
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.txt
@@ -0,0 +1,73 @@
+// FILE: test/BundleProperty.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract class BundleProperty<AA> extends test.NullableBundleProperty<AA> {
+    public final void setValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property, @org.jetbrains.annotations.Nullable AA value) {}
+
+    public final AA getValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property) {
+        return null;
+    }
+
+    public final void setNullableValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key, @org.jetbrains.annotations.Nullable AA value) {}
+
+    public abstract void setValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key, AA value);
+
+    public BundleProperty(@org.jetbrains.annotations.Nullable java.lang.String key) {}
+}
+
+// FILE: test/CustomPropertyDelegatesKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class CustomPropertyDelegatesKt {
+    @org.jetbrains.annotations.NotNull
+    public static final test.BundleProperty<java.lang.CharSequence> charSequence(@org.jetbrains.annotations.Nullable java.lang.String key) {
+        return null;
+    }
+
+    private CustomPropertyDelegatesKt() {}
+}
+
+// FILE: test/NullableBundleProperty.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract class NullableBundleProperty<EE> implements kotlin.properties.ReadWriteProperty<java.lang.Object, EE> {
+    private final java.lang.String key;
+
+    private final java.lang.String toKey(@org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> $this$toKey) {
+        return null;
+    }
+
+    @org.jetbrains.annotations.Nullable
+    public EE getValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property) {
+        return null;
+    }
+
+    public void setValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property, @org.jetbrains.annotations.Nullable EE value) {}
+
+    @org.jetbrains.annotations.Nullable
+    public abstract EE getValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key);
+
+    public abstract void setNullableValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key, @org.jetbrains.annotations.Nullable EE value);
+
+    public NullableBundleProperty(@org.jetbrains.annotations.Nullable java.lang.String key) {}
+}
+
+test/BundleProperty.java[19:85]: constructor NullableBundleProperty in class test.NullableBundleProperty<EE> cannot be applied to given types;
+  required: java.lang.String
+  found: no arguments
+  reason: actual and formal argument lists differ in length
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt
new file mode 100644
index 0000000..d3d0659
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt
@@ -0,0 +1,13 @@
+package dataClasses
+
+data class User(val firstName: String, val lastName: String, val age: Int) {
+    enum class Foo {
+        FOO, BAR
+    }
+
+    interface Intf {
+        fun foo() {}
+    }
+}
+
+data class Either<F, S>(val first: F, val second: S)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.txt
new file mode 100644
index 0000000..b6d0d2a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.txt
@@ -0,0 +1,135 @@
+// FILE: dataClasses/Either.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package dataClasses;
+
+@kotlin.Metadata()
+public final class Either<F, S> {
+    private final F first;
+    private final S second;
+
+    public final F getFirst() {
+        return null;
+    }
+
+    public final S getSecond() {
+        return null;
+    }
+
+    public Either(F first, S second) {}
+
+    public final F component1() {
+        return null;
+    }
+
+    public final S component2() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final dataClasses.Either<F, S> copy(F first, S second) {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public java.lang.String toString() {
+        return null;
+    }
+
+    public int hashCode() {
+        return 0;
+    }
+
+    public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) {
+        return false;
+    }
+}
+
+// FILE: dataClasses/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package dataClasses;
+
+@kotlin.Metadata()
+public final class User {
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String firstName;
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String lastName;
+    private final int age;
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getFirstName() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getLastName() {
+        return null;
+    }
+
+    public final int getAge() {
+        return 0;
+    }
+
+    public User(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {}
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String component1() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String component2() {
+        return null;
+    }
+
+    public final int component3() {
+        return 0;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final dataClasses.User copy(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public java.lang.String toString() {
+        return null;
+    }
+
+    public int hashCode() {
+        return 0;
+    }
+
+    public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) {
+        return false;
+    }
+
+    @kotlin.Metadata()
+    public static enum Foo {
+        FOO,
+        BAR,
+        ;
+
+        private Foo() {}
+    }
+
+    @kotlin.Metadata()
+    public abstract static interface Intf {
+        public abstract void foo();
+
+        @kotlin.Metadata()
+        public final static class DefaultImpls {
+            public static void foo(dataClasses.User.Intf $this) {}
+
+            private DefaultImpls() {}
+        }
+    }
+}
+
+dataClasses/User.java[29:152]: variable firstName might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt
new file mode 100644
index 0000000..eb9e9e6
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt
@@ -0,0 +1,83 @@
+package declarations
+
+class Foo {
+    val a: Int = 0
+    fun foo() {}
+    fun bar(str: String, num: Int) {}
+
+    class Nested {
+        fun nested() {}
+
+        class Nested2 {
+            fun nested2() {}
+        }
+    }
+
+    inner class Inner {
+        fun inner() {}
+
+        inner class Inner2 {
+            fun inner2() {}
+        }
+    }
+
+    interface NestedIntf {
+        fun nestedIntf(x: Int) {}
+    }
+
+    enum class NestedEnum {
+        GOOD, BAD
+    }
+
+    annotation class Anno(val value: String)
+}
+
+interface Intf {
+    val a: Int
+    fun foo() {}
+    fun bar(str: String, num: Int)
+
+    fun fooImpl(a: Int, b: String) {}
+    suspend fun barImpl(a: Int, b: String) {}
+}
+
+annotation class Anno(val a: String, val b: Int, val c: IntArray)
+annotation class ValueAnno(val value: String)
+
+enum class FooEnum {
+    FOO, BAR
+}
+
+enum class FooEnum2 {
+    FOO, BAR;
+
+    enum class NestedEnum {
+        GOOD, BAD
+    }
+}
+
+object Obj
+
+class ClassWithCompanion {
+    companion object {
+        fun foo() {}
+    }
+}
+
+class ClassWithNamedCompanion {
+    companion object Com {
+        fun foo() {}
+    }
+}
+
+class InterfaceWithCompanion {
+    companion object {
+        fun foo() {}
+    }
+}
+
+class InterfaceWithNamedCompanion {
+    companion object ComIntf {
+        fun foo() {}
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.txt
new file mode 100644
index 0000000..2182cfe
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.txt
@@ -0,0 +1,280 @@
+// FILE: declarations/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface Anno {
+    public abstract java.lang.String a();
+
+    public abstract int b();
+
+    public abstract int[] c();
+}
+
+// FILE: declarations/ClassWithCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class ClassWithCompanion {
+    public static final declarations.ClassWithCompanion.Companion Companion = null;
+
+    public ClassWithCompanion() {}
+
+    @kotlin.Metadata()
+    public final static class Companion {
+        public final void foo() {}
+
+        private Companion() {}
+    }
+}
+
+// FILE: declarations/ClassWithNamedCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class ClassWithNamedCompanion {
+    public static final declarations.ClassWithNamedCompanion.Com Com = null;
+
+    public ClassWithNamedCompanion() {}
+
+    @kotlin.Metadata()
+    public final static class Com {
+        public final void foo() {}
+
+        private Com() {}
+    }
+}
+
+// FILE: declarations/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class Foo {
+    private final int a = 0;
+
+    public final int getA() {
+        return 0;
+    }
+
+    public final void foo() {}
+
+    public final void bar(@org.jetbrains.annotations.NotNull java.lang.String str, int num) {}
+
+    public Foo() {}
+
+    @kotlin.Metadata()
+    public final static class Nested {
+        public final void nested() {}
+
+        public Nested() {}
+
+        @kotlin.Metadata()
+        public final static class Nested2 {
+            public final void nested2() {}
+
+            public Nested2() {}
+        }
+    }
+
+    @kotlin.Metadata()
+    public final class Inner {
+        public final void inner() {}
+
+        public Inner() {}
+
+        @kotlin.Metadata()
+        public final class Inner2 {
+            public final void inner2() {}
+
+            public Inner2() {}
+        }
+    }
+
+    @kotlin.Metadata()
+    public abstract static interface NestedIntf {
+        public abstract void nestedIntf(int x);
+
+        @kotlin.Metadata()
+        public final static class DefaultImpls {
+            public static void nestedIntf(declarations.Foo.NestedIntf $this, int x) {}
+
+            private DefaultImpls() {}
+        }
+    }
+
+    @kotlin.Metadata()
+    public static enum NestedEnum {
+        GOOD,
+        BAD,
+        ;
+
+        private NestedEnum() {}
+    }
+
+    @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+    @kotlin.Metadata()
+    public abstract static @interface Anno {
+        public abstract java.lang.String value();
+    }
+}
+
+// FILE: declarations/FooEnum.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public enum FooEnum {
+    FOO,
+    BAR,
+    ;
+
+    private FooEnum() {}
+}
+
+// FILE: declarations/FooEnum2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public enum FooEnum2 {
+    FOO,
+    BAR,
+    ;
+
+    private FooEnum2() {}
+
+    @kotlin.Metadata()
+    public static enum NestedEnum {
+        GOOD,
+        BAD,
+        ;
+
+        private NestedEnum() {}
+    }
+}
+
+// FILE: declarations/InterfaceWithCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class InterfaceWithCompanion {
+    public static final declarations.InterfaceWithCompanion.Companion Companion = null;
+
+    public InterfaceWithCompanion() {}
+
+    @kotlin.Metadata()
+    public final static class Companion {
+        public final void foo() {}
+
+        private Companion() {}
+    }
+}
+
+// FILE: declarations/InterfaceWithNamedCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class InterfaceWithNamedCompanion {
+    public static final declarations.InterfaceWithNamedCompanion.ComIntf ComIntf = null;
+
+    public InterfaceWithNamedCompanion() {}
+
+    @kotlin.Metadata()
+    public final static class ComIntf {
+        public final void foo() {}
+
+        private ComIntf() {}
+    }
+}
+
+// FILE: declarations/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+    public abstract int getA();
+
+    public abstract void foo();
+
+    public abstract void bar(@org.jetbrains.annotations.NotNull java.lang.String str, int num);
+
+    public abstract void fooImpl(int a, @org.jetbrains.annotations.NotNull java.lang.String b);
+
+    @org.jetbrains.annotations.Nullable
+    public abstract java.lang.Object barImpl(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
+
+    @kotlin.Metadata()
+    public final static class DefaultImpls {
+        public static void foo(declarations.Intf $this) {}
+
+        public static void fooImpl(declarations.Intf $this, int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+        @org.jetbrains.annotations.Nullable
+        public static java.lang.Object barImpl(declarations.Intf $this, int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+            return null;
+        }
+
+        private DefaultImpls() {}
+    }
+}
+
+// FILE: declarations/Obj.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class Obj {
+    public static final declarations.Obj INSTANCE = null;
+
+    private Obj() {}
+}
+
+// FILE: declarations/ValueAnno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface ValueAnno {
+    public abstract java.lang.String value();
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt
new file mode 100644
index 0000000..3302c26
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt
@@ -0,0 +1,11 @@
+class ClassInDefaultPackage {
+    fun foo() {}
+}
+
+fun funInDefaultPackage() {}
+
+const val valInDefaultPackage: String = ""
+
+fun String.extensionFunInDefaultPackage(): Boolean {
+    return this.length > 0
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.txt
new file mode 100644
index 0000000..57e2838
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.txt
@@ -0,0 +1,34 @@
+// FILE: ClassInDefaultPackage.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class ClassInDefaultPackage {
+    public final void foo() {}
+
+    public ClassInDefaultPackage() {}
+}
+
+// FILE: DefaultPackageKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class DefaultPackageKt {
+    @org.jetbrains.annotations.NotNull
+    public static final java.lang.String valInDefaultPackage = "";
+
+    public static final void funInDefaultPackage() {}
+
+    public static final boolean extensionFunInDefaultPackage(@org.jetbrains.annotations.NotNull java.lang.String $this$extensionFunInDefaultPackage) {
+        return false;
+    }
+
+    private DefaultPackageKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt
new file mode 100644
index 0000000..c67b05f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt
@@ -0,0 +1,54 @@
+// WITH_RUNTIME
+package deprecated
+
+@Deprecated("Foo is deprecated")
+class Foo @Deprecated("constructor is deprecated") public constructor(@Deprecated("n1 is deprecated") val n1: Int) {
+
+    @Deprecated("secondary constructor is deprecated")
+    constructor() : this(0)
+
+    @Deprecated("foo() is deprecated")
+    fun foo(a: Int, b: String) {}
+
+    @Deprecated("x is deprecated")
+    val x: String = ""
+
+    var y: Int
+        @Deprecated("y/get is deprecated") get() = 1
+        @Deprecated("y/set is deprecated") set(newValue) {}
+
+    @Deprecated("Nested is deprecated")
+    class Nested {
+        @Deprecated("p() is deprecated")
+        fun p() {}
+    }
+}
+
+@Deprecated("EnumClass is deprecated")
+enum class EnumClass {
+    FOO, @Deprecated("BAR is deprecated") BAR;
+
+    @Deprecated("goo is deprecated")
+    fun goo() {}
+}
+
+fun String.ext() {}
+
+@Deprecated("topLevel() is deprecated")
+fun topLevel() {}
+
+@Deprecated("Intf is deprecated")
+interface Intf
+
+@Deprecated("Obj is deprecated")
+object Obj {
+    @JvmField
+    @Deprecated("f is deprecated")
+    val f: Int = 0
+
+    @Deprecated("c is deprecated")
+    const val c: Int = 5
+}
+
+@Deprecated("Anno is deprecated")
+annotation class Anno(@Deprecated("value is deprecated") val value: String)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.txt
new file mode 100644
index 0000000..81e1416
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.txt
@@ -0,0 +1,154 @@
+// FILE: deprecated/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Anno is deprecated")
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+@java.lang.Deprecated
+public abstract @interface Anno {
+    public abstract java.lang.String value();
+}
+
+// FILE: deprecated/DeprecatedKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Metadata()
+public final class DeprecatedKt {
+    public static final void ext(@org.jetbrains.annotations.NotNull java.lang.String $this$ext) {}
+
+    @kotlin.Deprecated(message = "topLevel() is deprecated")
+    @java.lang.Deprecated
+    public static final void topLevel() {}
+
+    private DeprecatedKt() {}
+}
+
+// FILE: deprecated/EnumClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "EnumClass is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public enum EnumClass {
+    FOO,
+    BAR,
+    ;
+
+    @kotlin.Deprecated(message = "goo is deprecated")
+    @java.lang.Deprecated
+    public final void goo() {}
+
+    private EnumClass() {}
+}
+
+// FILE: deprecated/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Foo is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public final class Foo {
+    @org.jetbrains.annotations.NotNull
+    @java.lang.Deprecated
+    private final java.lang.String x = "";
+    @java.lang.Deprecated
+    private final int n1;
+
+    @kotlin.Deprecated(message = "foo() is deprecated")
+    @java.lang.Deprecated
+    public final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+    @org.jetbrains.annotations.NotNull
+    @java.lang.Deprecated
+    public final java.lang.String getX() {
+        return null;
+    }
+
+    @kotlin.Deprecated(message = "y/get is deprecated")
+    @java.lang.Deprecated
+    public final int getY() {
+        return 0;
+    }
+
+    @kotlin.Deprecated(message = "y/set is deprecated")
+    @java.lang.Deprecated
+    public final void setY(int newValue) {}
+
+    @java.lang.Deprecated
+    public final int getN1() {
+        return 0;
+    }
+
+    @kotlin.Deprecated(message = "constructor is deprecated")
+    @java.lang.Deprecated
+    public Foo(int n1) {}
+
+    @kotlin.Deprecated(message = "secondary constructor is deprecated")
+    @java.lang.Deprecated
+    public Foo() {}
+
+    @kotlin.Deprecated(message = "Nested is deprecated")
+    @kotlin.Metadata()
+    @java.lang.Deprecated
+    public final static class Nested {
+        @kotlin.Deprecated(message = "p() is deprecated")
+        @java.lang.Deprecated
+        public final void p() {}
+
+        public Nested() {}
+    }
+}
+
+// FILE: deprecated/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Intf is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public abstract interface Intf {
+
+}
+
+// FILE: deprecated/Obj.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Obj is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public final class Obj {
+    @kotlin.jvm.JvmField
+    @java.lang.Deprecated
+    public static final int f = 0;
+    @java.lang.Deprecated
+    public static final int c = 5;
+    public static final deprecated.Obj INSTANCE = null;
+
+    private Obj() {}
+}
+
+deprecated/Foo.java[44:25]: variable n1 might not have been initialized
+deprecated/Foo.java[48:19]: variable n1 might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt
new file mode 100644
index 0000000..ab5651b
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt
@@ -0,0 +1,46 @@
+package enums
+
+enum class Foo {
+    FOO, BAR
+}
+
+enum class Foo2 {
+    FOO {
+        override val good = Good.GOOD
+        override fun isGood() = true
+    },
+    BAR {
+        override val good = Good.BAD
+        override fun isGood() = false
+    };
+
+    abstract val good: Good
+    abstract fun isGood(): Boolean
+
+    fun baz(a: Int, b: String, c: Long) {}
+
+    enum class Good {
+        GOOD, BAD
+    }
+}
+
+enum class Foo3 {
+    FOO(5), BAR("");
+
+    val n: Int
+    val s: String
+
+    constructor(n: Int) {
+        this.n = n
+        this.s = ""
+    }
+
+    constructor(s: String) {
+        this.n = 0
+        this.s = s
+    }
+}
+
+enum class Foo4(val n: Int, val s: String) {
+    FOO(1, "foo"), BAR(2, "bar")
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.txt
new file mode 100644
index 0000000..a311b29
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.txt
@@ -0,0 +1,128 @@
+// FILE: enums/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo {
+    FOO,
+    BAR,
+    ;
+
+    private Foo() {}
+}
+
+// FILE: enums/Foo2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo2 {
+    FOO {
+        @org.jetbrains.annotations.NotNull
+        public enums.Foo2.Good getGood() {
+            return null;
+        }
+
+        public boolean isGood() {
+            return false;
+        }
+    },
+    BAR {
+        @org.jetbrains.annotations.NotNull
+        public enums.Foo2.Good getGood() {
+            return null;
+        }
+
+        public boolean isGood() {
+            return false;
+        }
+    },
+    ;
+
+    @org.jetbrains.annotations.NotNull
+    public abstract enums.Foo2.Good getGood();
+
+    public abstract boolean isGood();
+
+    public final void baz(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+    private Foo2() {}
+
+    @kotlin.Metadata()
+    public static enum Good {
+        GOOD,
+        BAD,
+        ;
+
+        private Good() {}
+    }
+}
+
+// FILE: enums/Foo3.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo3 {
+    FOO(0),
+    BAR(0),
+    ;
+
+    private final int n;
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String s;
+
+    public final int getN() {
+        return 0;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getS() {
+        return null;
+    }
+
+    private Foo3(int p0) {}
+
+    private Foo3(java.lang.String p0) {}
+}
+
+// FILE: enums/Foo4.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo4 {
+    FOO(0, null),
+    BAR(0, null),
+    ;
+
+    private final int n;
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String s;
+
+    public final int getN() {
+        return 0;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getS() {
+        return null;
+    }
+
+    private Foo4(int p0, java.lang.String p1) {}
+}
+
+enums/Foo3.java[26:27]: variable n might not have been initialized
+enums/Foo3.java[28:40]: variable n might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt
new file mode 100644
index 0000000..1bd0cc4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt
@@ -0,0 +1,9 @@
+// FILE: a.kt
+package facades
+
+fun foo() {}
+
+// FILE: b.kt
+package facades
+
+fun bar() {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.txt
new file mode 100644
index 0000000..ae3d1da
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.txt
@@ -0,0 +1,27 @@
+// FILE: facades/AKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package facades;
+
+@kotlin.Metadata()
+public final class AKt {
+    public static final void foo() {}
+
+    private AKt() {}
+}
+
+// FILE: facades/BKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package facades;
+
+@kotlin.Metadata()
+public final class BKt {
+    public static final void bar() {}
+
+    private BKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt
new file mode 100644
index 0000000..231cdb9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt
@@ -0,0 +1,54 @@
+package fieldInitializers
+
+object JavaConst {
+    val boolValue: Boolean = java.lang.Boolean.TRUE
+    val charValue: Char = java.lang.Character.MAX_VALUE
+    val byteValue: Byte = java.lang.Byte.MIN_VALUE
+    val shortValue: Short = java.lang.Short.MIN_VALUE
+    val intValue: Int = java.lang.Byte.SIZE
+    val longValue: Long = java.lang.Long.MAX_VALUE
+    val floatValue: Float = java.lang.Float.MAX_VALUE
+    val floatInf: Float = java.lang.Float.POSITIVE_INFINITY
+    val floatNegInf: Float = java.lang.Float.NEGATIVE_INFINITY
+    val floatNan: Float = java.lang.Float.NaN
+    val doubleValue: Double = java.lang.Double.MAX_VALUE
+    val doubleInf: Double = java.lang.Double.POSITIVE_INFINITY
+    val doubleNegInf: Double = java.lang.Double.NEGATIVE_INFINITY
+    val doubleNan: Double = java.lang.Double.NaN
+    val separator: String = java.io.File.separator
+}
+
+object KotlinMaxValue {
+    val byteMax = Byte.MAX_VALUE
+    val shortMax = Short.MAX_VALUE
+    val intMax = Int.MAX_VALUE
+    val longMax = Long.MAX_VALUE
+    val charMax = Char.MAX_VALUE
+    val floatMax = Float.MAX_VALUE
+    val doubleMax = Double.MAX_VALUE
+}
+
+object KotlinConst {
+    const val n: Int = 1
+    const val b: Boolean = true
+    const val s: String = "foo"
+}
+
+object KotlinVal {
+    val n: Int = 1
+    val b: Boolean = true
+    val s: String = "foo"
+}
+
+object KotlinUsage {
+    val nConst = KotlinConst.n
+    val bConst = KotlinConst.b
+    val sConst = KotlinConst.s
+
+    val n = KotlinVal.n
+    val b = KotlinVal.b
+    val s = KotlinVal.s
+}
+
+val topLevelJava = java.lang.Long.MAX_VALUE
+val topLevelKotlin = KotlinConst.n
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.txt
new file mode 100644
index 0000000..8311e43
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.txt
@@ -0,0 +1,259 @@
+// FILE: fieldInitializers/FieldInitializersKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class FieldInitializersKt {
+    private static final long topLevelJava = java.lang.Long.MAX_VALUE;
+    private static final int topLevelKotlin = 1;
+
+    public static final long getTopLevelJava() {
+        return 0L;
+    }
+
+    public static final int getTopLevelKotlin() {
+        return 0;
+    }
+
+    private FieldInitializersKt() {}
+}
+
+// FILE: fieldInitializers/JavaConst.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class JavaConst {
+    private static final boolean boolValue = false;
+    private static final char charValue = java.lang.Character.MAX_VALUE;
+    private static final byte byteValue = java.lang.Byte.MIN_VALUE;
+    private static final short shortValue = java.lang.Short.MIN_VALUE;
+    private static final int intValue = java.lang.Byte.SIZE;
+    private static final long longValue = java.lang.Long.MAX_VALUE;
+    private static final float floatValue = java.lang.Float.MAX_VALUE;
+    private static final float floatInf = java.lang.Float.POSITIVE_INFINITY;
+    private static final float floatNegInf = java.lang.Float.NEGATIVE_INFINITY;
+    private static final float floatNan = java.lang.Float.NaN;
+    private static final double doubleValue = java.lang.Double.MAX_VALUE;
+    private static final double doubleInf = java.lang.Double.POSITIVE_INFINITY;
+    private static final double doubleNegInf = java.lang.Double.NEGATIVE_INFINITY;
+    private static final double doubleNan = java.lang.Double.NaN;
+    @org.jetbrains.annotations.NotNull
+    private static final java.lang.String separator = null;
+    public static final fieldInitializers.JavaConst INSTANCE = null;
+
+    public final boolean getBoolValue() {
+        return false;
+    }
+
+    public final char getCharValue() {
+        return '\u0000';
+    }
+
+    public final byte getByteValue() {
+        return 0;
+    }
+
+    public final short getShortValue() {
+        return 0;
+    }
+
+    public final int getIntValue() {
+        return 0;
+    }
+
+    public final long getLongValue() {
+        return 0L;
+    }
+
+    public final float getFloatValue() {
+        return 0.0f;
+    }
+
+    public final float getFloatInf() {
+        return 0.0f;
+    }
+
+    public final float getFloatNegInf() {
+        return 0.0f;
+    }
+
+    public final float getFloatNan() {
+        return 0.0f;
+    }
+
+    public final double getDoubleValue() {
+        return 0.0;
+    }
+
+    public final double getDoubleInf() {
+        return 0.0;
+    }
+
+    public final double getDoubleNegInf() {
+        return 0.0;
+    }
+
+    public final double getDoubleNan() {
+        return 0.0;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getSeparator() {
+        return null;
+    }
+
+    private JavaConst() {}
+}
+
+// FILE: fieldInitializers/KotlinConst.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinConst {
+    public static final int n = 1;
+    public static final boolean b = true;
+    @org.jetbrains.annotations.NotNull
+    public static final java.lang.String s = "foo";
+    public static final fieldInitializers.KotlinConst INSTANCE = null;
+
+    private KotlinConst() {}
+}
+
+// FILE: fieldInitializers/KotlinMaxValue.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinMaxValue {
+    private static final byte byteMax = 127;
+    private static final short shortMax = 32767;
+    private static final int intMax = 2147483647;
+    private static final long longMax = 9223372036854775807L;
+    private static final char charMax = '\uffff';
+    private static final float floatMax = 0.0f;
+    private static final double doubleMax = 0.0;
+    public static final fieldInitializers.KotlinMaxValue INSTANCE = null;
+
+    public final byte getByteMax() {
+        return 0;
+    }
+
+    public final short getShortMax() {
+        return 0;
+    }
+
+    public final int getIntMax() {
+        return 0;
+    }
+
+    public final long getLongMax() {
+        return 0L;
+    }
+
+    public final char getCharMax() {
+        return '\u0000';
+    }
+
+    public final float getFloatMax() {
+        return 0.0f;
+    }
+
+    public final double getDoubleMax() {
+        return 0.0;
+    }
+
+    private KotlinMaxValue() {}
+}
+
+// FILE: fieldInitializers/KotlinUsage.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinUsage {
+    private static final int nConst = 1;
+    private static final boolean bConst = true;
+    @org.jetbrains.annotations.NotNull
+    private static final java.lang.String sConst = "foo";
+    private static final int n = 1;
+    private static final boolean b = true;
+    @org.jetbrains.annotations.NotNull
+    private static final java.lang.String s = "foo";
+    public static final fieldInitializers.KotlinUsage INSTANCE = null;
+
+    public final int getNConst() {
+        return 0;
+    }
+
+    public final boolean getBConst() {
+        return false;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getSConst() {
+        return null;
+    }
+
+    public final int getN() {
+        return 0;
+    }
+
+    public final boolean getB() {
+        return false;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getS() {
+        return null;
+    }
+
+    private KotlinUsage() {}
+}
+
+// FILE: fieldInitializers/KotlinVal.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinVal {
+    private static final int n = 1;
+    private static final boolean b = true;
+    @org.jetbrains.annotations.NotNull
+    private static final java.lang.String s = "foo";
+    public static final fieldInitializers.KotlinVal INSTANCE = null;
+
+    public final int getN() {
+        return 0;
+    }
+
+    public final boolean getB() {
+        return false;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getS() {
+        return null;
+    }
+
+    private KotlinVal() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt
new file mode 100644
index 0000000..d9a5001
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt
@@ -0,0 +1,36 @@
+public open class PubClass {
+    private companion object {}
+
+    public class NestedPubClass
+    protected class NestedProtectedClass
+    internal class NestedInternalClass
+    private class NestedPrivateClass
+
+    private interface NestedPrivateIntf
+    private object NestedPrivateObj
+
+    public fun publicFun() {}
+    protected fun protectedFun() {}
+    internal fun internalFun() {}
+    private fun privateFun() {}
+
+    public val publicVal: Int = 0
+    protected val protectedVal: Int = 0
+    internal val internalVal: Int = 0
+    private val privateVal: Int = 0
+}
+
+internal class InternalClass
+private class PrivateClass
+
+abstract class AbstractClass {}
+open class OpenClass {}
+final class FinalClass {}
+
+private enum class PrivateEnum {
+    FOO
+}
+
+private interface PrivateIntf
+private object PrivateObj
+private annotation class PrivateAnno
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.txt
new file mode 100644
index 0000000..8cb8108
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.txt
@@ -0,0 +1,189 @@
+// FILE: AbstractClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public abstract class AbstractClass {
+    public AbstractClass() {}
+}
+
+// FILE: FinalClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class FinalClass {
+    public FinalClass() {}
+}
+
+// FILE: InternalClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class InternalClass {
+    public InternalClass() {}
+}
+
+// FILE: OpenClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public class OpenClass {
+    public OpenClass() {}
+}
+
+// FILE: PrivateAnno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+abstract @interface PrivateAnno {
+
+}
+
+// FILE: PrivateClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+final class PrivateClass {
+    public PrivateClass() {}
+}
+
+// FILE: PrivateEnum.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+ enum PrivateEnum {
+    FOO,
+    ;
+
+    private PrivateEnum() {}
+}
+
+// FILE: PrivateIntf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+abstract interface PrivateIntf {
+
+}
+
+// FILE: PrivateObj.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+final class PrivateObj {
+    public static final PrivateObj INSTANCE = null;
+
+    private PrivateObj() {}
+}
+
+// FILE: PubClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public class PubClass {
+    private final int publicVal = 0;
+    private final int protectedVal = 0;
+    private final int internalVal = 0;
+    private final int privateVal = 0;
+    @java.lang.Deprecated
+    public static final PubClass.Companion Companion = null;
+
+    public final void publicFun() {}
+
+    protected final void protectedFun() {}
+
+    public final void internalFun$test_module() {}
+
+    private final void privateFun() {}
+
+    public final int getPublicVal() {
+        return 0;
+    }
+
+    protected final int getProtectedVal() {
+        return 0;
+    }
+
+    public final int getInternalVal$test_module() {
+        return 0;
+    }
+
+    public PubClass() {}
+
+    @kotlin.Metadata()
+    public final static class NestedPubClass {
+        public NestedPubClass() {}
+    }
+
+    @kotlin.Metadata()
+    public final static class NestedProtectedClass {
+        public NestedProtectedClass() {}
+    }
+
+    @kotlin.Metadata()
+    public final static class NestedInternalClass {
+        public NestedInternalClass() {}
+    }
+
+    @kotlin.Metadata()
+    final static class NestedPrivateClass {
+        public NestedPrivateClass() {}
+    }
+
+    @kotlin.Metadata()
+    abstract static interface NestedPrivateIntf {
+
+    }
+
+    @kotlin.Metadata()
+    final static class NestedPrivateObj {
+        public static final PubClass.NestedPrivateObj INSTANCE = null;
+
+        private NestedPrivateObj() {}
+    }
+
+    @kotlin.Metadata()
+    final static class Companion {
+        private Companion() {}
+    }
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt
new file mode 100644
index 0000000..b20d6a4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt
@@ -0,0 +1,23 @@
+package generics
+
+class CIn<in T>
+class COut<out T>
+class C<T>
+
+fun x(a: CIn<CharSequence>, b: COut<CharSequence>, c: C<CharSequence>) {}
+fun y(a: C<in CharSequence>, b: C<out CharSequence>, c: C<CharSequence>, d: C<*>) {}
+
+class Foo<T> {
+    inner class Bar<U> {
+        fun foo(t: T, u: U) {}
+    }
+}
+
+fun <T : CharSequence> T.ext(x: Int) {}
+
+fun <Z> List<Z>.ext2() {}
+
+fun List<*>.ext3() {}
+
+val <MyType : Runnable> MyType.extProp: Int
+    get() = 0
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.txt
new file mode 100644
index 0000000..5952621
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.txt
@@ -0,0 +1,80 @@
+// FILE: generics/C.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class C<T> {
+    public C() {}
+}
+
+// FILE: generics/CIn.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class CIn<T> {
+    public CIn() {}
+}
+
+// FILE: generics/COut.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class COut<T> {
+    public COut() {}
+}
+
+// FILE: generics/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class Foo<T> {
+    public Foo() {}
+
+    @kotlin.Metadata()
+    public final class Bar<U> {
+        public final void foo(T t, U u) {}
+
+        public Bar() {}
+    }
+}
+
+// FILE: generics/GenericsKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class GenericsKt {
+    public static final void x(@org.jetbrains.annotations.NotNull generics.CIn<? super java.lang.CharSequence> a, @org.jetbrains.annotations.NotNull generics.COut<? extends java.lang.CharSequence> b, @org.jetbrains.annotations.NotNull generics.C<java.lang.CharSequence> c) {}
+
+    public static final void y(@org.jetbrains.annotations.NotNull generics.C<? super java.lang.CharSequence> a, @org.jetbrains.annotations.NotNull generics.C<? extends java.lang.CharSequence> b, @org.jetbrains.annotations.NotNull generics.C<java.lang.CharSequence> c, @org.jetbrains.annotations.NotNull generics.C<?> d) {}
+
+    public static final <T extends java.lang.CharSequence> void ext(@org.jetbrains.annotations.NotNull T $this$ext, int x) {}
+
+    public static final <Z> void ext2(@org.jetbrains.annotations.NotNull java.util.List<? extends Z> $this$ext2) {}
+
+    public static final void ext3(@org.jetbrains.annotations.NotNull java.util.List<?> $this$ext3) {}
+
+    public static final <MyType extends java.lang.Runnable> int getExtProp(@org.jetbrains.annotations.NotNull MyType $this$extProp) {
+        return 0;
+    }
+
+    private GenericsKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt
new file mode 100644
index 0000000..7168277
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt
@@ -0,0 +1,104 @@
+// WITH_RUNTIME
+
+// FILE: lib/Prop.java
+package lib;
+
+public abstract class Prop<T> {
+    public abstract int get(T key);
+    public abstract void set(T key, int value);
+}
+
+// FILE: test.kt
+package test
+
+import lib.Prop
+
+class Cl(var name: String)
+
+val testObj = object : Prop<Cl>() {
+    override fun get(key: Cl) = key.name.length
+    override fun set(key: Cl, value: Int) {
+        key.name = " ".repeat(value)
+    }
+}
+
+private val testArray = arrayOf(object : Prop<Cl>() {
+    override fun get(key: Cl) = key.name.length
+    override fun set(key: Cl, value: Int) {
+        key.name = " ".repeat(value)
+    }
+})
+
+private val testList = listOf(object : Prop<Cl>() {
+    override fun get(key: Cl) = key.name.length
+    override fun set(key: Cl, value: Int) {
+        key.name = " ".repeat(value)
+    }
+})
+
+private fun test1() = (0..10).map { n ->
+    object {
+        override fun hashCode() = n
+    }
+}
+
+private fun test2() = (0..10).map { n ->
+    object : Runnable {
+        override fun run() {}
+    }
+}
+
+abstract class Foo
+
+private fun test3() = (0..10).map { n ->
+    object : Foo() {}
+}
+
+private fun test4() = (0..10).map { n ->
+    object : Foo(), Runnable {
+        override fun run() {}
+    }
+}
+
+open class Bar {
+    private val notReally = object : Runnable {
+        override fun run() {
+            throw UnsupportedOperationException()
+        }
+    }
+
+    private fun a() = object : Runnable {
+        override fun run() {}
+    }
+
+    private fun b() = object : java.io.Serializable, Runnable {
+        override fun run() {}
+    }
+
+    private fun c() = object : Bar(), Runnable {
+        override fun run() {}
+    }
+
+    private fun d() = listOf(object : Runnable {
+        override fun run() {}
+    })
+
+    private fun e() = arrayOf(object : Runnable {
+        override fun run() {}
+    })
+}
+
+fun e1(a: Array<CharSequence>) {}
+fun e2(a: Array<in CharSequence>) {}
+fun e3(a: Array<out CharSequence>) {}
+fun e3(a: Array<*>) {}
+
+class Test<T : CharSequence, N : Number> {
+    private val x = object : MyCallback {
+        override fun fire(a: Int, b: String) {}
+    }
+}
+
+interface MyCallback {
+    fun fire(a: Int, b: String)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.txt
new file mode 100644
index 0000000..19314de
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.txt
@@ -0,0 +1,141 @@
+// FILE: test/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public class Bar {
+    private final java.lang.Runnable notReally;
+
+    private final java.lang.Runnable a() {
+        return null;
+    }
+
+    private final java.lang.Runnable b() {
+        return null;
+    }
+
+    private final test.Bar c() {
+        return null;
+    }
+
+    private final java.util.List<java.lang.Runnable> d() {
+        return null;
+    }
+
+    private final java.lang.Runnable[] e() {
+        return null;
+    }
+
+    public Bar() {}
+}
+
+// FILE: test/Cl.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Cl {
+    @org.jetbrains.annotations.NotNull
+    private java.lang.String name;
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getName() {
+        return null;
+    }
+
+    public final void setName(@org.jetbrains.annotations.NotNull java.lang.String p0) {}
+
+    public Cl(@org.jetbrains.annotations.NotNull java.lang.String name) {}
+}
+
+// FILE: test/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract class Foo {
+    public Foo() {}
+}
+
+// FILE: test/MyCallback.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract interface MyCallback {
+    public abstract void fire(int a, @org.jetbrains.annotations.NotNull java.lang.String b);
+}
+
+// FILE: test/Test.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Test<T extends java.lang.CharSequence, N extends java.lang.Number> {
+    private final test.MyCallback x;
+
+    public Test() {}
+}
+
+// FILE: test/TestKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class TestKt {
+    @org.jetbrains.annotations.NotNull
+    private static final lib.Prop<test.Cl> testObj = null;
+    private static final lib.Prop<test.Cl>[] testArray = null;
+    private static final java.util.List<lib.Prop<test.Cl>> testList = null;
+
+    @org.jetbrains.annotations.NotNull
+    public static final lib.Prop<test.Cl> getTestObj() {
+        return null;
+    }
+
+    private static final java.util.List<java.lang.Object> test1() {
+        return null;
+    }
+
+    private static final java.util.List<java.lang.Runnable> test2() {
+        return null;
+    }
+
+    private static final java.util.List<test.Foo> test3() {
+        return null;
+    }
+
+    private static final java.util.List<test.Foo> test4() {
+        return null;
+    }
+
+    public static final void e1(@org.jetbrains.annotations.NotNull java.lang.CharSequence[] a) {}
+
+    public static final void e2(@org.jetbrains.annotations.NotNull java.lang.Object[] a) {}
+
+    public static final void e3(@org.jetbrains.annotations.NotNull java.lang.CharSequence[] a) {}
+
+    public static final void e3(@org.jetbrains.annotations.NotNull java.lang.Object[] a) {}
+
+    private TestKt() {}
+}
+
+test/Bar.java[31:19]: variable notReally might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt
new file mode 100644
index 0000000..84a9e32
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt
@@ -0,0 +1,45 @@
+package inheritance
+
+interface Intf
+abstract class Base
+
+class Foo : Base(), Intf
+
+//
+
+interface A1 {
+    fun foo()
+}
+
+interface A2 {
+    fun bar()
+}
+
+class A1A2 : A1, A2 {
+    override fun foo() {}
+    override fun bar() {}
+}
+
+//
+
+interface B1 {
+    fun foo() {}
+}
+
+interface B2 {
+    fun foo() {}
+}
+
+class B1B2 : B1, B2 {
+    override fun foo() {}
+}
+
+//
+
+abstract class C1
+abstract class C2 : C1()
+abstract class C3 : C1()
+class C4 : C3(), Intf, A1, A2, B1, B2 {
+    override fun foo() {}
+    override fun bar() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.txt
new file mode 100644
index 0000000..8570e9f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.txt
@@ -0,0 +1,179 @@
+// FILE: inheritance/A1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface A1 {
+    public abstract void foo();
+}
+
+// FILE: inheritance/A1A2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class A1A2 implements inheritance.A1, inheritance.A2 {
+    public void foo() {}
+
+    public void bar() {}
+
+    public A1A2() {}
+}
+
+// FILE: inheritance/A2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface A2 {
+    public abstract void bar();
+}
+
+// FILE: inheritance/B1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface B1 {
+    public abstract void foo();
+
+    @kotlin.Metadata()
+    public final static class DefaultImpls {
+        public static void foo(inheritance.B1 $this) {}
+
+        private DefaultImpls() {}
+    }
+}
+
+// FILE: inheritance/B1B2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class B1B2 implements inheritance.B1, inheritance.B2 {
+    public void foo() {}
+
+    public B1B2() {}
+}
+
+// FILE: inheritance/B2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface B2 {
+    public abstract void foo();
+
+    @kotlin.Metadata()
+    public final static class DefaultImpls {
+        public static void foo(inheritance.B2 $this) {}
+
+        private DefaultImpls() {}
+    }
+}
+
+// FILE: inheritance/Base.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class Base {
+    public Base() {}
+}
+
+// FILE: inheritance/C1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class C1 {
+    public C1() {}
+}
+
+// FILE: inheritance/C2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class C2 extends inheritance.C1 {
+    public C2() {}
+}
+
+// FILE: inheritance/C3.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class C3 extends inheritance.C1 {
+    public C3() {}
+}
+
+// FILE: inheritance/C4.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class C4 extends inheritance.C3 implements inheritance.Intf, inheritance.A1, inheritance.A2, inheritance.B1, inheritance.B2 {
+    public void foo() {}
+
+    public void bar() {}
+
+    public C4() {}
+}
+
+// FILE: inheritance/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class Foo extends inheritance.Base implements inheritance.Intf {
+    public Foo() {}
+}
+
+// FILE: inheritance/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt
new file mode 100644
index 0000000..54af349
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt
@@ -0,0 +1,21 @@
+package inlineClasses
+
+inline class Foo(val value: Int) {
+    fun foo() {}
+}
+
+class Bar {
+    fun bar(foo: Foo) {}
+
+    val x: Foo?
+        get() = null
+
+    var y: Foo? = null
+}
+
+class Baz(val value: Foo)
+
+fun Foo.ext() = 0
+
+val Foo.prop: String
+    get() = ""
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.txt
new file mode 100644
index 0000000..371d96a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.txt
@@ -0,0 +1,86 @@
+// FILE: inlineClasses/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class Bar {
+    @org.jetbrains.annotations.Nullable
+    private inlineClasses.Foo y;
+
+    @org.jetbrains.annotations.Nullable
+    public final inlineClasses.Foo getX() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.Nullable
+    public final inlineClasses.Foo getY() {
+        return null;
+    }
+
+    public Bar() {}
+}
+
+// FILE: inlineClasses/Baz.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class Baz {
+    private final int value;
+
+    public final int getValue() {
+        return 0;
+    }
+
+    private Baz(int value) {}
+}
+
+// FILE: inlineClasses/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class Foo {
+    private final int value;
+
+    public final int getValue() {
+        return 0;
+    }
+
+    public java.lang.String toString() {
+        return null;
+    }
+
+    public int hashCode() {
+        return 0;
+    }
+
+    public boolean equals(java.lang.Object other) {
+        return false;
+    }
+
+    private Foo() {}
+}
+
+// FILE: inlineClasses/InlineClassesKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class InlineClassesKt {
+    private InlineClassesKt() {}
+}
+
+inlineClasses/Foo.java[27:20]: variable value might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt
new file mode 100644
index 0000000..d0e3f0a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt
@@ -0,0 +1,9 @@
+package test
+
+interface Intf {
+    val x: Int
+}
+
+class Impl(override val x: Int) : Intf
+
+class Foo : Intf by Impl(5)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.txt
new file mode 100644
index 0000000..646f5c0
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.txt
@@ -0,0 +1,47 @@
+// FILE: test/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Foo implements test.Intf {
+    public Foo() {}
+
+    public int getX() {
+        return 0;
+    }
+}
+
+// FILE: test/Impl.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Impl implements test.Intf {
+    private final int x;
+
+    public int getX() {
+        return 0;
+    }
+
+    public Impl(int x) {}
+}
+
+// FILE: test/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+    public abstract int getX();
+}
+
+test/Impl.java[15:25]: variable x might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt
new file mode 100644
index 0000000..659b1c8
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt
@@ -0,0 +1,11 @@
+// FILE: lib/Lib.java
+package lib;
+
+public class Lib {
+    public static class Nested {
+        public static void foo() {}
+    }
+}
+
+// FILE: test.kt
+fun foo(): lib.Lib.Nested? = null
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.txt
new file mode 100644
index 0000000..b2571cb
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.txt
@@ -0,0 +1,16 @@
+// FILE: TestKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class TestKt {
+    @org.jetbrains.annotations.Nullable
+    public static final lib.Lib.Nested foo() {
+        return null;
+    }
+
+    private TestKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt
new file mode 100644
index 0000000..636850c
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt
@@ -0,0 +1,67 @@
+package javadoc
+
+/** Foo */
+class Foo /** primary ctor */ constructor(/** x */ x: Int, y: Int) {
+    /** secondary ctor */
+    constructor(/** only x */ x: Int) : this(x, 0)
+
+    /** foo() */
+    fun foo(/** a */ a: Int) {}
+
+    /** prop */
+    val prop: Int = 0
+
+    var prop2: Int
+        /** prop2/get */ get() = 0
+        /** prop2/set */ set(/** sparam */ value) {}
+
+    /** Nested */
+    class Nested {}
+
+    /** Inner */
+    inner class Inner {
+        /** u */
+        fun u() {}
+    }
+
+    // simple comment
+    fun comment() {}
+
+    /* block comment */
+    fun blockComment() {}
+}
+
+/** FooEnum */
+enum class FooEnum {
+    /** FOO */ FOO {
+        /** FOO/foo */
+        override fun foo(a: Int) {}
+    },
+    /** BAR */ BAR {
+        override fun foo(a: Int) {}
+    };
+
+    /** FooEnum/foo */
+    abstract fun foo(/** a */ a: Int)
+}
+
+/** Anno */
+annotation class Anno(/** Anno/value */ val value: String, /** Anno/x */ val x: Int)
+
+/** topLevel */
+fun topLevel() {}
+
+/** topLevelExt */
+fun String.topLevelExt() {}
+
+/** topLevelConst */
+const val topLevelConst: Int = 0
+
+/** topLevelExtProperty */
+val String.topLevelExtProperty: Int
+    /** topLevelExtProperty/get */ get() = 0
+
+/**
+ * `/* Failure */`
+ */
+interface TestComponent
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.txt
new file mode 100644
index 0000000..97e8341
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.txt
@@ -0,0 +1,183 @@
+// FILE: javadoc/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * Anno
+ */
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface Anno {
+    /**
+     * Anno/value
+     */
+    public abstract java.lang.String value();
+
+    /**
+     * Anno/x
+     */
+    public abstract int x();
+}
+
+// FILE: javadoc/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * Foo
+ */
+@kotlin.Metadata()
+public final class Foo {
+    /**
+     * prop
+     */
+    private final int prop = 0;
+
+    /**
+     * foo()
+     */
+    public final void foo(int a) {}
+
+    public final int getProp() {
+        return 0;
+    }
+
+    /**
+     * prop2/get
+     */
+    public final int getProp2() {
+        return 0;
+    }
+
+    /**
+     * prop2/set
+     */
+    public final void setProp2(int value) {}
+
+    public final void comment() {}
+
+    public final void blockComment() {}
+
+    public Foo(int x, int y) {}
+
+    /**
+     * secondary ctor
+     */
+    public Foo(int x) {}
+
+    /**
+     * Nested
+     */
+    @kotlin.Metadata()
+    public final static class Nested {
+        public Nested() {}
+    }
+
+    /**
+     * Inner
+     */
+    @kotlin.Metadata()
+    public final class Inner {
+        /**
+         * u
+         */
+        public final void u() {}
+
+        public Inner() {}
+    }
+}
+
+// FILE: javadoc/FooEnum.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * FooEnum
+ */
+@kotlin.Metadata()
+public enum FooEnum {
+    /**
+     * FOO
+     */
+    FOO {
+        /**
+         * FooEnum/foo
+         */
+        public void foo(int a) {}
+    },
+    /**
+     * BAR
+     */
+    BAR {
+        /**
+         * FooEnum/foo
+         */
+        public void foo(int a) {}
+    },
+    ;
+
+    /**
+     * FooEnum/foo
+     */
+    public abstract void foo(int a);
+
+    private FooEnum() {}
+}
+
+// FILE: javadoc/JavadocKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+@kotlin.Metadata()
+public final class JavadocKt {
+    /**
+     * topLevelConst
+     */
+    public static final int topLevelConst = 0;
+
+    /**
+     * topLevel
+     */
+    public static final void topLevel() {}
+
+    /**
+     * topLevelExt
+     */
+    public static final void topLevelExt(@org.jetbrains.annotations.NotNull java.lang.String $this$topLevelExt) {}
+
+    /**
+     * topLevelExtProperty/get
+     */
+    public static final int getTopLevelExtProperty(@org.jetbrains.annotations.NotNull java.lang.String $this$topLevelExtProperty) {
+        return 0;
+    }
+
+    private JavadocKt() {}
+}
+
+// FILE: javadoc/TestComponent.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * `/ * Failure * /`
+ */
+@kotlin.Metadata()
+public abstract interface TestComponent {
+
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt
new file mode 100644
index 0000000..e3299ce
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt
@@ -0,0 +1,32 @@
+package javadocFormatting
+
+/**
+ * Multi
+ * line
+ * comment.
+ */
+class Foo {
+    /** Nested
+     * member
+     * comment. */
+    val a = ""
+
+	/**
+	 * Mixed
+	 * tabs/spaces
+	 */
+    val b = ""
+
+    /**
+     * List:
+     * * first item
+     * * second item
+     */
+    val c = ""
+
+    /**
+    Without
+    stars
+     */
+    val d = ""
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.txt
new file mode 100644
index 0000000..df080f3
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.txt
@@ -0,0 +1,63 @@
+// FILE: javadocFormatting/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadocFormatting;
+
+/**
+ * Multi
+ * line
+ * comment.
+ */
+@kotlin.Metadata()
+public final class Foo {
+    /**
+     * Nested
+     * member
+     * comment.
+     */
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String a = "";
+    /**
+     * Mixed
+     * tabs/spaces
+     */
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String b = "";
+    /**
+     * List:
+     * * first item
+     * * second item
+     */
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String c = "";
+    /**
+     * Without
+     * stars
+     */
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String d = "";
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getA() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getB() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getC() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getD() {
+        return null;
+    }
+
+    public Foo() {}
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt
new file mode 100644
index 0000000..8ff82ce
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt
@@ -0,0 +1,17 @@
+// WITH_RUNTIME
+package jvmField
+
+class Foo {
+    @JvmField
+    var x: String = ""
+}
+
+object Bar {
+    @JvmField
+    val y: Int = 0
+}
+
+@JvmField
+val q: Array<String>? = null
+
+class User(@JvmField val firstName: String)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.txt
new file mode 100644
index 0000000..add1652
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.txt
@@ -0,0 +1,65 @@
+// FILE: jvmField/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class Bar {
+    @kotlin.jvm.JvmField
+    public static final int y = 0;
+    public static final jvmField.Bar INSTANCE = null;
+
+    private Bar() {}
+}
+
+// FILE: jvmField/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class Foo {
+    @kotlin.jvm.JvmField
+    @org.jetbrains.annotations.NotNull
+    public java.lang.String x;
+
+    public Foo() {}
+}
+
+// FILE: jvmField/JvmFieldKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class JvmFieldKt {
+    @kotlin.jvm.JvmField
+    @org.jetbrains.annotations.Nullable
+    public static final java.lang.String[] q = null;
+
+    private JvmFieldKt() {}
+}
+
+// FILE: jvmField/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class User {
+    @kotlin.jvm.JvmField
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String firstName;
+
+    public User(@org.jetbrains.annotations.NotNull java.lang.String firstName) {}
+}
+
+jvmField/User.java[13:81]: variable firstName might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt
new file mode 100644
index 0000000..f331eac
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt
@@ -0,0 +1,15 @@
+// WITH_RUNTIME
+@file:JvmName("QPackage")
+package jvmName
+
+@JvmName("QTopLevel")
+fun topLevel() {}
+
+class Foo {
+    @JvmName("QFoo")
+    fun foo() {}
+
+    var x: Int
+        @JvmName("QGetInt") get() = 0
+        @JvmName("QSetInt") set(v) {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.txt
new file mode 100644
index 0000000..5c61828
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.txt
@@ -0,0 +1,37 @@
+// FILE: jvmName/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmName;
+
+@kotlin.Metadata()
+public final class Foo {
+    @kotlin.jvm.JvmName(name = "QFoo")
+    public final void QFoo() {}
+
+    @kotlin.jvm.JvmName(name = "QGetInt")
+    public final int QGetInt() {
+        return 0;
+    }
+
+    @kotlin.jvm.JvmName(name = "QSetInt")
+    public final void QSetInt(int v) {}
+
+    public Foo() {}
+}
+
+// FILE: jvmName/QPackage.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmName;
+
+@kotlin.Metadata()
+public final class QPackage {
+    @kotlin.jvm.JvmName(name = "QTopLevel")
+    public static final void QTopLevel() {}
+
+    private QPackage() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt
new file mode 100644
index 0000000..919c19c
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt
@@ -0,0 +1,14 @@
+// WITH_RUNTIME
+package jvmOverloads
+
+class User /** ctor */ @JvmOverloads constructor(val firstName: String = "", val secondName: String = "", val age: Int = 0) {
+    /** foo */
+    @JvmOverloads
+    fun foo(a: Int, b: String, c: Long = 0) {}
+
+    /** bar */
+    fun bar(a: Int, b: String = "", c: Long = 0) {}
+
+    /** baz */
+    fun baz(a: Int = 0, b: String = "", c: Long = 0) {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.txt
new file mode 100644
index 0000000..1b9cfd0
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.txt
@@ -0,0 +1,71 @@
+// FILE: jvmOverloads/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmOverloads;
+
+/**
+ * ctor
+ */
+@kotlin.Metadata()
+public final class User {
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String firstName;
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String secondName;
+    private final int age;
+
+    /**
+     * foo
+     */
+    @kotlin.jvm.JvmOverloads
+    public final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+    /**
+     * foo
+     */
+    @kotlin.jvm.JvmOverloads
+    public final void foo(int p0, @org.jetbrains.annotations.NotNull java.lang.String p1) {}
+
+    /**
+     * bar
+     */
+    public final void bar(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+    /**
+     * baz
+     */
+    public final void baz(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getFirstName() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getSecondName() {
+        return null;
+    }
+
+    public final int getAge() {
+        return 0;
+    }
+
+    @kotlin.jvm.JvmOverloads
+    public User(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String secondName, int age) {}
+
+    @kotlin.jvm.JvmOverloads
+    public User(@org.jetbrains.annotations.NotNull java.lang.String p0, @org.jetbrains.annotations.NotNull java.lang.String p1) {}
+
+    @kotlin.jvm.JvmOverloads
+    public User(@org.jetbrains.annotations.NotNull java.lang.String p0) {}
+
+    @kotlin.jvm.JvmOverloads
+    public User() {}
+}
+
+jvmOverloads/User.java[55:154]: variable firstName might not have been initialized
+jvmOverloads/User.java[58:130]: variable firstName might not have been initialized
+jvmOverloads/User.java[61:74]: variable firstName might not have been initialized
+jvmOverloads/User.java[64:20]: variable firstName might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt
new file mode 100644
index 0000000..be8c3ae
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt
@@ -0,0 +1,14 @@
+// WITH_RUNTIME
+
+import java.io.IOException
+import java.lang.ArithmeticException
+import java.lang.RuntimeException
+
+@Throws(RuntimeException::class)
+fun a() {}
+
+@Throws(Throwable::class)
+fun b() {}
+
+@Throws(IOException::class, ArithmeticException::class)
+fun c() {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.txt
new file mode 100644
index 0000000..4a8f06f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.txt
@@ -0,0 +1,20 @@
+// FILE: JvmThrowsKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class JvmThrowsKt {
+    @kotlin.jvm.Throws(exceptionClasses = {java.lang.RuntimeException.class})
+    public static final void a() throws java.lang.RuntimeException {}
+
+    @kotlin.jvm.Throws(exceptionClasses = {java.lang.Throwable.class})
+    public static final void b() throws java.lang.Throwable {}
+
+    @kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, java.lang.ArithmeticException.class})
+    public static final void c() throws java.io.IOException, java.lang.ArithmeticException {}
+
+    private JvmThrowsKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt
new file mode 100644
index 0000000..d1bc412
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt
@@ -0,0 +1,5 @@
+lateinit var foo: String
+
+class Bar {
+    lateinit var bar: Bar
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.txt
new file mode 100644
index 0000000..08f4f8d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.txt
@@ -0,0 +1,43 @@
+// FILE: Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class Bar {
+    @org.jetbrains.annotations.NotNull
+    public Bar bar;
+
+    @org.jetbrains.annotations.NotNull
+    public final Bar getBar() {
+        return null;
+    }
+
+    public final void setBar(@org.jetbrains.annotations.NotNull Bar p0) {}
+
+    public Bar() {}
+}
+
+// FILE: LateinitKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class LateinitKt {
+    @org.jetbrains.annotations.NotNull
+    public static java.lang.String foo = null;
+
+    @org.jetbrains.annotations.NotNull
+    public static final java.lang.String getFoo() {
+        return null;
+    }
+
+    public static final void setFoo(@org.jetbrains.annotations.NotNull java.lang.String p0) {}
+
+    private LateinitKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt
new file mode 100644
index 0000000..f266f57
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt
@@ -0,0 +1,22 @@
+// WITH_RUNTIME
+
+// FILE: a.kt
+@file:JvmMultifileClass
+@file:JvmName("M1")
+package test
+
+fun foo() {}
+
+// FILE: b.kt
+@file:JvmMultifileClass
+@file:JvmName("M1")
+package test
+
+fun bar() {}
+
+// FILE: c.kt
+@file:JvmMultifileClass
+@file:JvmName("M2")
+package test
+
+fun baz() {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.txt
new file mode 100644
index 0000000..e6fcf37
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.txt
@@ -0,0 +1,29 @@
+// FILE: test/M1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class M1 {
+    public static final void bar() {}
+
+    public static final void foo() {}
+
+    private M1() {}
+}
+
+// FILE: test/M2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class M2 {
+    public static final void baz() {}
+
+    private M2() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt
new file mode 100644
index 0000000..a608446
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt
@@ -0,0 +1,7 @@
+package nestedSameName
+
+class Foo {
+    class Bar {
+        class Bar
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.txt
new file mode 100644
index 0000000..0fcabe9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.txt
@@ -0,0 +1,23 @@
+// FILE: nestedSameName/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package nestedSameName;
+
+@kotlin.Metadata()
+public final class Foo {
+    public Foo() {}
+
+    @kotlin.Metadata()
+    public final static class Bar {
+        public Bar() {}
+
+        @kotlin.Metadata()
+        public final static class Bar {
+            public Bar() {}
+        }
+    }
+}
+
+nestedSameName/Foo.java[16:29]: class nestedSameName.Foo.Bar is already defined in class nestedSameName.Foo
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt
new file mode 100644
index 0000000..7e1c213
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt
@@ -0,0 +1,60 @@
+package parameterNames
+
+fun topLevel(a: Int, b: String) {}
+
+var topLevel: Int
+    get() = 0
+    set(newValueParam) {}
+
+fun String.ext(other: Int) {}
+fun String.ext2(`$this$ext2`: Int) {}
+
+class ExtContainer {
+    fun String.ext(other: Int) {}
+    fun String.ext2(`$this$ext2`: Int) {}
+}
+
+suspend fun main() {}
+
+class Foo {
+    fun foo(a: Int, b: String) {}
+    suspend fun fooSuspend(a: Int, b: String) {}
+
+    var prop: Int
+        get() = 0
+        set(newValueParam) {}
+
+    object NestedObj {
+        fun bar(a: Int, b: String) {}
+    }
+
+    interface NestedIntf {
+        fun bar(c: Int, d: String) {}
+    }
+
+    inner class InnerCl(val e: Int, f: String)
+}
+
+interface Intf {
+    fun foo(g: Int, h: String) {}
+    suspend fun fooSuspend(i: Int, j: String) {}
+
+    fun foo2(`$this`: Int, h: String) {}
+    suspend fun fooSuspend2(`$this`: Int, j: String) {}
+}
+
+enum class Enm {
+    FOO(1, ""), BAR(2, "");
+
+    fun foo(l: Int, m: String) {}
+
+    constructor(n: Int, s: String) {}
+}
+
+annotation class Anno(val t: Int, val o: String) {}
+
+data class User(val firstName: String, val lastName: String, val age: Int)
+
+class Bar(val x: Int) {
+    constructor(y: Long) : this(0)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.txt
new file mode 100644
index 0000000..9a7b195
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.txt
@@ -0,0 +1,259 @@
+// FILE: parameterNames/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface Anno {
+    public abstract int t();
+
+    public abstract java.lang.String o();
+}
+
+// FILE: parameterNames/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class Bar {
+    private final int x;
+
+    public final int getX() {
+        return 0;
+    }
+
+    public Bar(int x) {}
+
+    public Bar(long y) {}
+}
+
+// FILE: parameterNames/Enm.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public enum Enm {
+    FOO(0, null),
+    BAR(0, null),
+    ;
+
+    public final void foo(int l, @org.jetbrains.annotations.NotNull java.lang.String m) {}
+
+    private Enm(int p0, java.lang.String p1) {}
+}
+
+// FILE: parameterNames/ExtContainer.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class ExtContainer {
+    public final void ext(@org.jetbrains.annotations.NotNull java.lang.String $this$ext, int other) {}
+
+    public final void ext2(@org.jetbrains.annotations.NotNull java.lang.String p0, int p1) {}
+
+    public ExtContainer() {}
+}
+
+// FILE: parameterNames/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class Foo {
+    public final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+    @org.jetbrains.annotations.Nullable
+    public final java.lang.Object fooSuspend(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+        return null;
+    }
+
+    public final int getProp() {
+        return 0;
+    }
+
+    public final void setProp(int newValueParam) {}
+
+    public Foo() {}
+
+    @kotlin.Metadata()
+    public final static class NestedObj {
+        public static final parameterNames.Foo.NestedObj INSTANCE = null;
+
+        public final void bar(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+        private NestedObj() {}
+    }
+
+    @kotlin.Metadata()
+    public abstract static interface NestedIntf {
+        public abstract void bar(int c, @org.jetbrains.annotations.NotNull java.lang.String d);
+
+        @kotlin.Metadata()
+        public final static class DefaultImpls {
+            public static void bar(parameterNames.Foo.NestedIntf $this, int c, @org.jetbrains.annotations.NotNull java.lang.String d) {}
+
+            private DefaultImpls() {}
+        }
+    }
+
+    @kotlin.Metadata()
+    public final class InnerCl {
+        private final int e;
+
+        public final int getE() {
+            return 0;
+        }
+
+        public InnerCl(int p0, @org.jetbrains.annotations.NotNull java.lang.String p1) {}
+    }
+}
+
+// FILE: parameterNames/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+    public abstract void foo(int g, @org.jetbrains.annotations.NotNull java.lang.String h);
+
+    @org.jetbrains.annotations.Nullable
+    public abstract java.lang.Object fooSuspend(int i, @org.jetbrains.annotations.NotNull java.lang.String j, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
+
+    public abstract void foo2(int $this, @org.jetbrains.annotations.NotNull java.lang.String h);
+
+    @org.jetbrains.annotations.Nullable
+    public abstract java.lang.Object fooSuspend2(int $this, @org.jetbrains.annotations.NotNull java.lang.String j, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
+
+    @kotlin.Metadata()
+    public final static class DefaultImpls {
+        public static void foo(parameterNames.Intf $this, int g, @org.jetbrains.annotations.NotNull java.lang.String h) {}
+
+        @org.jetbrains.annotations.Nullable
+        public static java.lang.Object fooSuspend(parameterNames.Intf $this, int i, @org.jetbrains.annotations.NotNull java.lang.String j, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+            return null;
+        }
+
+        public static void foo2(parameterNames.Intf p0, int p1, @org.jetbrains.annotations.NotNull java.lang.String p2) {}
+
+        @org.jetbrains.annotations.Nullable
+        public static java.lang.Object fooSuspend2(parameterNames.Intf p0, int p1, @org.jetbrains.annotations.NotNull java.lang.String p2, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> p3) {
+            return null;
+        }
+
+        private DefaultImpls() {}
+    }
+}
+
+// FILE: parameterNames/ParameterNamesKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class ParameterNamesKt {
+    public static final void topLevel(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+    public static final int getTopLevel() {
+        return 0;
+    }
+
+    public static final void setTopLevel(int newValueParam) {}
+
+    public static final void ext(@org.jetbrains.annotations.NotNull java.lang.String $this$ext, int other) {}
+
+    public static final void ext2(@org.jetbrains.annotations.NotNull java.lang.String p0, int p1) {}
+
+    @org.jetbrains.annotations.Nullable
+    public static final java.lang.Object main(@org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+        return null;
+    }
+
+    private ParameterNamesKt() {}
+}
+
+// FILE: parameterNames/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class User {
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String firstName;
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String lastName;
+    private final int age;
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getFirstName() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getLastName() {
+        return null;
+    }
+
+    public final int getAge() {
+        return 0;
+    }
+
+    public User(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {}
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String component1() {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String component2() {
+        return null;
+    }
+
+    public final int component3() {
+        return 0;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public final parameterNames.User copy(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {
+        return null;
+    }
+
+    @org.jetbrains.annotations.NotNull
+    public java.lang.String toString() {
+        return null;
+    }
+
+    public int hashCode() {
+        return 0;
+    }
+
+    public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) {
+        return false;
+    }
+}
+
+parameterNames/Foo.java[53:89]: variable e might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt
new file mode 100644
index 0000000..beb53b5
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt
@@ -0,0 +1,44 @@
+package primitive
+
+object PrimitiveTypes {
+    const val booleanFalse: Boolean = false
+    const val booleanTrue: Boolean = true
+
+    const val int0: Int = 0
+    const val intMinus1000: Int = -1000
+    const val intMinValue: Int = Int.MIN_VALUE
+    const val intMaxValue: Int = Int.MAX_VALUE
+    const val intHex: Int = 0xffffffff.toInt()
+
+    const val byte0: Byte = 0.toByte()
+    const val byte50: Byte = 50.toByte()
+    const val byteMinus5: Byte = (-5).toByte()
+
+    const val short5: Short = 5.toShort()
+
+    const val charC: Char = 'C'
+    const val char0: Char = 0.toChar()
+    const val char10: Char = 10.toChar()
+    const val char13: Char = 13.toChar()
+
+    const val long0: Long = 0L
+    const val longMaxValue: Long = Long.MAX_VALUE
+    const val longMinValue: Long = Long.MIN_VALUE
+    const val longHex: Long = 0xffffffff
+
+    const val float54 = 5.4f
+    val floatMaxValue = Float.MAX_VALUE
+    val floatNan = Float.NaN
+    val floatPositiveInfinity = Float.POSITIVE_INFINITY
+    val floatNegativeInfinity = Float.NEGATIVE_INFINITY
+
+    const val double54 = 5.4
+    val doubleMaxValue = Double.MAX_VALUE
+    val doubleNan = Double.NaN
+    val doublePositiveInfinity = Double.POSITIVE_INFINITY
+    val doubleNegativeInfinity = Double.NEGATIVE_INFINITY
+
+    const val stringHelloWorld: String = "Hello, world!"
+    const val stringQuotes: String = "quotes \" \\ ''quotes"
+    const val specialSymbols: String = "\t\b\n\r\u000c\u0000\u1234"
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.txt
new file mode 100644
index 0000000..c98231e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.txt
@@ -0,0 +1,80 @@
+// FILE: primitive/PrimitiveTypes.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package primitive;
+
+@kotlin.Metadata()
+public final class PrimitiveTypes {
+    public static final boolean booleanFalse = true;
+    public static final boolean booleanTrue = true;
+    public static final int int0 = 0;
+    public static final int intMinus1000 = -1000;
+    public static final int intMinValue = -2147483648;
+    public static final int intMaxValue = 2147483647;
+    public static final int intHex = -1;
+    public static final byte byte0 = 0;
+    public static final byte byte50 = 50;
+    public static final byte byteMinus5 = -5;
+    public static final short short5 = 5;
+    public static final char charC = 'C';
+    public static final char char0 = '\u0000';
+    public static final char char10 = '\n';
+    public static final char char13 = '\r';
+    public static final long long0 = 0L;
+    public static final long longMaxValue = 9223372036854775807L;
+    public static final long longMinValue = -9223372036854775808L;
+    public static final long longHex = 4294967295L;
+    public static final float float54 = 5.4f;
+    private static final float floatMaxValue = 0.0f;
+    private static final float floatNan = 0.0f;
+    private static final float floatPositiveInfinity = 0.0f;
+    private static final float floatNegativeInfinity = 0.0f;
+    public static final double double54 = 5.4;
+    private static final double doubleMaxValue = 0.0;
+    private static final double doubleNan = 0.0;
+    private static final double doublePositiveInfinity = 0.0;
+    private static final double doubleNegativeInfinity = 0.0;
+    @org.jetbrains.annotations.NotNull
+    public static final java.lang.String stringHelloWorld = "Hello, world!";
+    @org.jetbrains.annotations.NotNull
+    public static final java.lang.String stringQuotes = "quotes \" \\ \'\'quotes";
+    @org.jetbrains.annotations.NotNull
+    public static final java.lang.String specialSymbols = "\t\b\n\r\f\u0000\u1234";
+    public static final primitive.PrimitiveTypes INSTANCE = null;
+
+    public final float getFloatMaxValue() {
+        return 0.0f;
+    }
+
+    public final float getFloatNan() {
+        return 0.0f;
+    }
+
+    public final float getFloatPositiveInfinity() {
+        return 0.0f;
+    }
+
+    public final float getFloatNegativeInfinity() {
+        return 0.0f;
+    }
+
+    public final double getDoubleMaxValue() {
+        return 0.0;
+    }
+
+    public final double getDoubleNan() {
+        return 0.0;
+    }
+
+    public final double getDoublePositiveInfinity() {
+        return 0.0;
+    }
+
+    public final double getDoubleNegativeInfinity() {
+        return 0.0;
+    }
+
+    private PrimitiveTypes() {}
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt
new file mode 100644
index 0000000..f1e33bc2
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+class Foo {
+    val foo by lazy { "foo" }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.txt
new file mode 100644
index 0000000..15b69f3
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.txt
@@ -0,0 +1,21 @@
+// FILE: Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class Foo {
+    @org.jetbrains.annotations.NotNull
+    private final kotlin.Lazy foo$delegate;
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getFoo() {
+        return null;
+    }
+
+    public Foo() {}
+}
+
+Foo.java[17:19]: variable foo$delegate might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt
new file mode 100644
index 0000000..dfb2a7e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt
@@ -0,0 +1,27 @@
+package sealedClasses
+
+sealed class Foo(val x: Int) {
+    abstract fun foo(q: Int)
+
+    class Bar(val a: String, x: Int) : Foo(x) {
+        override fun foo(q: Int) {}
+        fun bar(z: String) {}
+    }
+
+    object Baz : Foo(1) {
+        override fun foo(q: Int) {}
+    }
+}
+
+sealed class Foo2(val x: Int) {
+    abstract fun foo(q: Int)
+}
+
+class Bar2(val a: String, x: Int) : Foo2(x) {
+    override fun foo(q: Int) {}
+    fun bar(z: String) {}
+}
+
+object Baz2 : Foo2(1) {
+    override fun foo(q: Int) {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.txt
new file mode 100644
index 0000000..16f0966
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.txt
@@ -0,0 +1,122 @@
+// FILE: sealedClasses/Bar2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public final class Bar2 extends sealedClasses.Foo2 {
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String a;
+
+    public void foo(int q) {}
+
+    public final void bar(@org.jetbrains.annotations.NotNull java.lang.String z) {}
+
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getA() {
+        return null;
+    }
+
+    public Bar2(@org.jetbrains.annotations.NotNull java.lang.String a, int x) {}
+}
+
+// FILE: sealedClasses/Baz2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public final class Baz2 extends sealedClasses.Foo2 {
+    public static final sealedClasses.Baz2 INSTANCE = null;
+
+    public void foo(int q) {}
+
+    private Baz2() {}
+}
+
+// FILE: sealedClasses/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public abstract class Foo {
+    private final int x;
+
+    public abstract void foo(int q);
+
+    public final int getX() {
+        return 0;
+    }
+
+    private Foo(int x) {}
+
+    @kotlin.Metadata()
+    public final static class Bar extends sealedClasses.Foo {
+        @org.jetbrains.annotations.NotNull
+        private final java.lang.String a;
+
+        public void foo(int q) {}
+
+        public final void bar(@org.jetbrains.annotations.NotNull java.lang.String z) {}
+
+        @org.jetbrains.annotations.NotNull
+        public final java.lang.String getA() {
+            return null;
+        }
+
+        public Bar(@org.jetbrains.annotations.NotNull java.lang.String a, int x) {}
+    }
+
+    @kotlin.Metadata()
+    public final static class Baz extends sealedClasses.Foo {
+        public static final sealedClasses.Foo.Baz INSTANCE = null;
+
+        public void foo(int q) {}
+
+        private Baz() {}
+    }
+}
+
+// FILE: sealedClasses/Foo2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public abstract class Foo2 {
+    private final int x;
+
+    public abstract void foo(int q);
+
+    public final int getX() {
+        return 0;
+    }
+
+    private Foo2(int x) {}
+}
+
+sealedClasses/Foo.java[33:82]: constructor Foo in class sealedClasses.Foo cannot be applied to given types;
+  required: int
+  found: no arguments
+  reason: actual and formal argument lists differ in length
+sealedClasses/Foo.java[42:23]: constructor Foo in class sealedClasses.Foo cannot be applied to given types;
+  required: int
+  found: no arguments
+  reason: actual and formal argument lists differ in length
+sealedClasses/Bar2.java[21:79]: constructor Foo2 in class sealedClasses.Foo2 cannot be applied to given types;
+  required: int
+  found: no arguments
+  reason: actual and formal argument lists differ in length
+sealedClasses/Baz2.java[13:20]: constructor Foo2 in class sealedClasses.Foo2 cannot be applied to given types;
+  required: int
+  found: no arguments
+  reason: actual and formal argument lists differ in length
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt
new file mode 100644
index 0000000..6c9af47
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt
@@ -0,0 +1,20 @@
+package simple
+
+/**
+ * Simple class.
+ */
+class Foo(val x: Int) {
+    /**
+     * Simple property.
+     */
+    val abc: String = "a"
+        /** Simple getter. */ get
+
+    /**
+     * Simple method.
+     */
+    @Deprecated("foo() is deprecated")
+    fun foo(): Float {
+        return 0f
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.txt
new file mode 100644
index 0000000..6f8dae0
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.txt
@@ -0,0 +1,44 @@
+// FILE: simple/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package simple;
+
+/**
+ * Simple class.
+ */
+@kotlin.Metadata()
+public final class Foo {
+    /**
+     * Simple property.
+     */
+    @org.jetbrains.annotations.NotNull
+    private final java.lang.String abc = "a";
+    private final int x;
+
+    /**
+     * Simple getter.
+     */
+    @org.jetbrains.annotations.NotNull
+    public final java.lang.String getAbc() {
+        return null;
+    }
+
+    /**
+     * Simple method.
+     */
+    @kotlin.Deprecated(message = "foo() is deprecated")
+    @java.lang.Deprecated
+    public final float foo() {
+        return 0.0f;
+    }
+
+    public final int getX() {
+        return 0;
+    }
+
+    public Foo(int x) {}
+}
+
+simple/Foo.java[40:24]: variable x might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt
new file mode 100644
index 0000000..ce0a461
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt
@@ -0,0 +1,16 @@
+// WITH_RUNTIME
+import kotlin.jvm.Strictfp
+
+class Foo {
+    @Transient
+    val tr: Int = 0
+
+    @Volatile
+    var vl: Int = 0
+
+    @Strictfp
+    fun sfp() {}
+
+    @Synchronized
+    fun sync() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.txt
new file mode 100644
index 0000000..ddd8c60
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.txt
@@ -0,0 +1,32 @@
+// FILE: Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class Foo {
+    @kotlin.jvm.Transient
+    private final transient int tr = 0;
+    @kotlin.jvm.Volatile
+    private volatile int vl;
+
+    public final int getTr() {
+        return 0;
+    }
+
+    public final int getVl() {
+        return 0;
+    }
+
+    public final void setVl(int p0) {}
+
+    @kotlin.jvm.Strictfp
+    public final strictfp void sfp() {}
+
+    @kotlin.jvm.Synchronized
+    public final synchronized void sync() {}
+
+    public Foo() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt
new file mode 100644
index 0000000..a103eec
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt
@@ -0,0 +1,9 @@
+// FILE: suspendMain1.kt
+package suspendMain
+
+suspend fun main() {}
+
+// FILE: suspendMain2.kt
+package suspendMain2
+
+suspend fun main(args: Array<String>) {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.txt
new file mode 100644
index 0000000..f5c0836
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.txt
@@ -0,0 +1,33 @@
+// FILE: suspendMain/SuspendMain1Kt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package suspendMain;
+
+@kotlin.Metadata()
+public final class SuspendMain1Kt {
+    @org.jetbrains.annotations.Nullable
+    public static final java.lang.Object main(@org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+        return null;
+    }
+
+    private SuspendMain1Kt() {}
+}
+
+// FILE: suspendMain2/SuspendMain2Kt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package suspendMain2;
+
+@kotlin.Metadata()
+public final class SuspendMain2Kt {
+    @org.jetbrains.annotations.Nullable
+    public static final java.lang.Object main(@org.jetbrains.annotations.NotNull java.lang.String[] args, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+        return null;
+    }
+
+    private SuspendMain2Kt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt
new file mode 100644
index 0000000..18a0a64
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+suspend fun foo(a: Int, b: String): Int {
+    return 0
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.txt
new file mode 100644
index 0000000..5be0e32
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.txt
@@ -0,0 +1,16 @@
+// FILE: SuspendWithRuntimeKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class SuspendWithRuntimeKt {
+    @org.jetbrains.annotations.Nullable
+    public static final java.lang.Object foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super java.lang.Integer> continuation) {
+        return null;
+    }
+
+    private SuspendWithRuntimeKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt
new file mode 100644
index 0000000..ce43b49
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt
@@ -0,0 +1,3 @@
+suspend fun foo(a: Int, b: String): Int {
+    return 0
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.txt
new file mode 100644
index 0000000..a011b15
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.txt
@@ -0,0 +1,16 @@
+// FILE: SuspendWithoutRuntimeKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class SuspendWithoutRuntimeKt {
+    @org.jetbrains.annotations.Nullable
+    public static final java.lang.Object foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super java.lang.Integer> continuation) {
+        return null;
+    }
+
+    private SuspendWithoutRuntimeKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt
new file mode 100644
index 0000000..92c13ca
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt
@@ -0,0 +1,3 @@
+package foo
+
+fun foo(a: Int, vararg b: String) {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.txt
new file mode 100644
index 0000000..9c1f0f9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.txt
@@ -0,0 +1,13 @@
+// FILE: foo/VarargsKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package foo;
+
+@kotlin.Metadata()
+public final class VarargsKt {
+    public static final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String... b) {}
+
+    private VarargsKt() {}
+}
diff --git a/plugins/kapt-lite/kapt-lite-javac-plugin/build.gradle.kts b/plugins/kapt-lite/kapt-lite-javac-plugin/build.gradle.kts
new file mode 100644
index 0000000..b3c4870
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-javac-plugin/build.gradle.kts
@@ -0,0 +1,21 @@
+description = "Lightweight annotation processing support – Java compiler plugin"
+
+plugins {
+    `java`
+    id("jps-compatible")
+}
+
+dependencies {
+    compileOnly(toolsJar())
+}
+
+sourceSets {
+    "main" { projectDefault() }
+    "test" { }
+}
+
+publish()
+
+runtimeJar()
+sourcesJar()
+javadocJar()
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-javac-plugin/resources/META-INF/services/com.sun.source.util.Plugin b/plugins/kapt-lite/kapt-lite-javac-plugin/resources/META-INF/services/com.sun.source.util.Plugin
new file mode 100644
index 0000000..68c7b8e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-javac-plugin/resources/META-INF/services/com.sun.source.util.Plugin
@@ -0,0 +1 @@
+org.jetbrains.kaptlite.javac.KaptJavacPlugin
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-javac-plugin/src/org/jetbrains/kaptlite/javac/KaptJavacPlugin.java b/plugins/kapt-lite/kapt-lite-javac-plugin/src/org/jetbrains/kaptlite/javac/KaptJavacPlugin.java
new file mode 100644
index 0000000..5bf025f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-javac-plugin/src/org/jetbrains/kaptlite/javac/KaptJavacPlugin.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.javac;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.Plugin;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.parser.Tokens;
+import com.sun.tools.javac.tree.DocCommentTable;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.List;
+
+public class KaptJavacPlugin implements Plugin {
+    @Override
+    public String getName() {
+        return "KaptJavacPlugin";
+    }
+
+    @Override
+    public void init(JavacTask task, String... args) {
+        task.addTaskListener(new TaskListener() {
+            private boolean annotationProcessingFinished = false;
+
+            @Override
+            public void started(TaskEvent e) {
+                if (e.getKind() == TaskEvent.Kind.ENTER && annotationProcessingFinished) {
+                    CompilationUnitTree unit = e.getCompilationUnit();
+                    if (unit instanceof JCCompilationUnit) {
+                        patch((JCCompilationUnit) unit);
+                    }
+                }
+            }
+
+            @Override
+            public void finished(TaskEvent e) {
+                if (e.getKind() == TaskEvent.Kind.ANNOTATION_PROCESSING) {
+                    annotationProcessingFinished = true;
+                }
+            }
+        });
+    }
+
+    private static void patch(JCCompilationUnit unit) {
+        if (isKaptStubFile(unit)) {
+            unit.pid = null;
+            unit.docComments = null;
+            unit.defs = List.nil();
+        }
+    }
+
+    private static boolean isKaptStubFile(JCCompilationUnit unit) {
+        DocCommentTable docs = unit.docComments;
+        if (docs == null) {
+            return false;
+        }
+
+        Tokens.Comment comment = docs.getComment(unit);
+        if (comment == null) {
+            return false;
+        }
+
+        String text = comment.getText();
+        return text.contains("This file was generated by the kapt-lite stub generator.")
+               && text.contains("Do not change it manually.");
+    }
+}
diff --git a/plugins/kapt-lite/kapt-lite-kdoc/build.gradle.kts b/plugins/kapt-lite/kapt-lite-kdoc/build.gradle.kts
new file mode 100644
index 0000000..be246c4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-kdoc/build.gradle.kts
@@ -0,0 +1,19 @@
+description = "Lightweight annotation processing support – KDoc parser"
+
+plugins {
+    kotlin("jvm")
+    id("jps-compatible")
+}
+
+dependencies {
+    compileOnly(project(":compiler:frontend"))
+    compileOnly(project(":compiler:backend"))
+
+    compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
+    compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
+}
+
+sourceSets {
+    "main" { projectDefault() }
+    "test" { }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-kdoc/src/KDocParsingHelper.kt b/plugins/kapt-lite/kapt-lite-kdoc/src/KDocParsingHelper.kt
new file mode 100644
index 0000000..47e2492
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-kdoc/src/KDocParsingHelper.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010-2019 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.kotlin.kaptlite.kdoc
+
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiRecursiveElementVisitor
+import com.intellij.psi.impl.source.tree.LeafPsiElement
+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
+import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
+import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
+import org.jetbrains.kotlin.kdoc.psi.api.KDoc
+import org.jetbrains.kotlin.psi.KtClassOrObject
+import org.jetbrains.kotlin.psi.KtDeclaration
+import org.jetbrains.kotlin.psi.KtObjectDeclaration
+import org.jetbrains.kotlin.psi.KtProperty
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+
+object KDocParsingHelper {
+    enum class DeclarationKind {
+        CLASS, METHOD, FIELD
+    }
+
+    fun getKDocComment(kind: DeclarationKind, origin: JvmDeclarationOrigin, bindingContext: BindingContext): String? {
+        val psiElement = origin.element as? KtDeclaration ?: return null
+        val descriptor = origin.descriptor
+        val docComment = psiElement.docComment ?: return null
+
+        if (descriptor is ConstructorDescriptor && psiElement is KtClassOrObject) {
+            // We don't want the class comment to be duplicated on <init>()
+            return null
+        }
+
+        if (kind == DeclarationKind.METHOD
+            && psiElement is KtProperty
+            && descriptor is PropertyAccessorDescriptor
+            && bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor.correspondingProperty] == true
+        ) {
+            // Do not place documentation on backing field and property accessors
+            return null
+        }
+
+        if (kind == DeclarationKind.FIELD && psiElement is KtObjectDeclaration && descriptor == null) {
+            // Do not write KDoc on object instance field
+            return null
+        }
+
+        return escapeNestedComments(extractCommentText(docComment))
+    }
+
+    private fun escapeNestedComments(text: String): String {
+        val result = StringBuilder()
+
+        var index = 0
+        var commentLevel = 0
+
+        while (index < text.length) {
+            val currentChar = text[index]
+            fun nextChar() = text.getOrNull(index + 1)
+
+            if (currentChar == '/' && nextChar() == '*') {
+                commentLevel++
+                index++
+                result.append("/ *")
+            } else if (currentChar == '*' && nextChar() == '/') {
+                commentLevel = maxOf(0, commentLevel - 1)
+                index++
+                result.append("* /")
+            } else {
+                result.append(currentChar)
+            }
+
+            index++
+        }
+
+        return result.toString()
+    }
+
+    private fun extractCommentText(docComment: KDoc): String {
+        return buildString {
+            docComment.accept(object : PsiRecursiveElementVisitor() {
+                override fun visitElement(element: PsiElement) {
+                    if (element is LeafPsiElement) {
+                        if (element.isKDocLeadingAsterisk()) {
+                            val indent = takeLastWhile { it == ' ' || it == '\t' }.length
+                            if (indent > 0) {
+                                delete(length - indent, length)
+                            }
+                        } else if (!element.isKDocStart() && !element.isKDocEnd()) {
+                            append(element.text)
+                        }
+                    }
+
+                    super.visitElement(element)
+                }
+            })
+        }.trimIndent().trim()
+    }
+
+    private fun LeafPsiElement.isKDocStart() = elementType == KDocTokens.START
+    private fun LeafPsiElement.isKDocEnd() = elementType == KDocTokens.END
+    private fun LeafPsiElement.isKDocLeadingAsterisk() = elementType == KDocTokens.LEADING_ASTERISK
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/build.gradle.kts b/plugins/kapt-lite/kapt-lite-signature-parser/build.gradle.kts
new file mode 100644
index 0000000..9817857
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/build.gradle.kts
@@ -0,0 +1,14 @@
+plugins {
+    kotlin("jvm")
+    id("jps-compatible")
+}
+
+dependencies {
+    compile(kotlinStdlib())
+    compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
+}
+
+sourceSets {
+    "main" { projectDefault() }
+    "test" { }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureNode.kt b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureNode.kt
new file mode 100644
index 0000000..69d283b
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureNode.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.signature
+
+/*
+    Root (Class)
+        * TypeParameter
+        + SuperClass
+        * Interface
+
+    Root (Method)
+        * TypeParameter
+        * ParameterType
+        + ReturnType
+        * ExceptionType
+
+    Root (Field)
+        + SuperClass
+
+    TypeParameter < Root
+        + ClassBound
+        * InterfaceBound
+
+    ParameterType < Root
+        + Type
+
+    ReturnType < Root
+        + Type
+
+    Type :: ClassType | TypeVariable | PrimitiveType | ArrayType
+
+    ClassBound < TypeParameter
+        + ClassType
+
+    InterfaceBound < TypeParameter
+        ? ClassType
+        ? TypeVariable
+
+    TypeVariable < InterfaceBound
+
+    SuperClass < TopLevel
+        ! ClassType
+
+    Interface < TopLevel
+        ! ClassType
+
+    ClassType < *
+        * TypeArgument
+        * InnerClass
+
+    InnerClass < ClassType
+        ! TypeArgument
+
+    TypeArgument < ClassType | InnerClass
+        + ClassType
+ */
+
+internal enum class ElementKind {
+    Root, TypeParameter, ClassBound, InterfaceBound, SuperClass, Interface, TypeArgument, ParameterType, ReturnType, ExceptionType,
+    ClassType, InnerClass, TypeVariable, PrimitiveType, ArrayType
+}
+
+internal class SignatureNode(val kind: ElementKind, val name: String? = null) {
+    val children: MutableList<SignatureNode> = ArrayList(1)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParser.kt b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParser.kt
new file mode 100644
index 0000000..40e4a1d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParser.kt
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.signature
+
+import org.jetbrains.org.objectweb.asm.signature.SignatureReader
+import org.jetbrains.kaptlite.signature.ElementKind.*
+
+data class ClassSignature(
+    val typeParameters: List<SigTypeParameter>,
+    val superClass: SigType,
+    val interfaces: List<SigType>
+)
+
+data class MethodSignature(
+    val typeParameters: List<SigTypeParameter>,
+    val parameters: List<SigParameter>,
+    val exceptionTypes: List<SigType>,
+    val returnType: SigType
+)
+
+data class SigParameter(val name: String, val type: SigType)
+data class SigTypeParameter(val name: String, val bounds: List<SigType>)
+
+sealed class SigType {
+    class Primitive private constructor(val javaName: String, val descriptor: Char) : SigType() {
+        companion object {
+            val VOID = Primitive("void", 'V')
+            val BYTE = Primitive("byte", 'B')
+            val SHORT = Primitive("short", 'S')
+            val INT = Primitive("int", 'I')
+            val LONG = Primitive("long", 'J')
+            val BOOLEAN = Primitive("boolean", 'Z')
+            val CHAR = Primitive("char", 'C')
+            val FLOAT = Primitive("float", 'F')
+            val DOUBLE = Primitive("double", 'D')
+
+            private val ALL = listOf(VOID, BYTE, SHORT, INT, LONG, BOOLEAN, CHAR, FLOAT, DOUBLE)
+                .map { it.descriptor to it }.toMap()
+
+            fun get(descriptor: Char): Primitive = ALL.getValue(descriptor)
+        }
+    }
+
+    class TypeVariable(val name: String) : SigType()
+    class Array(val elementType: SigType) : SigType()
+    class Class(val fqName: String) : SigType()
+    class Nested(val outer: SigType, val name: String) : SigType()
+    class Generic(val base: SigType, val args: List<SigTypeArgument>) : SigType()
+}
+
+val SigType.isJavaLangObject: Boolean
+    get() = this is SigType.Class && this.fqName == Object::class.java.name
+
+sealed class SigTypeArgument {
+    object Unbound : SigTypeArgument()
+    class Invariant(val type: SigType) : SigTypeArgument()
+    class Extends(val type: SigType) : SigTypeArgument()
+    class Super(val type: SigType) : SigTypeArgument()
+}
+
+object SignatureParser {
+    fun parseClassSignature(signature: String): ClassSignature {
+        val root = parse(signature)
+        val sigTypeParameters = ArrayList<SignatureNode>(1)
+        val sigSuperClasses = ArrayList<SignatureNode>(1)
+        val sigInterfaces = ArrayList<SignatureNode>(1)
+        root.split(sigTypeParameters, TypeParameter, sigSuperClasses, SuperClass, sigInterfaces, Interface)
+
+        val typeParameters = sigTypeParameters.map { parseTypeParameter(it) }
+        val superClass = parseType(sigSuperClasses.single().children.single())
+        val interfaces = sigInterfaces.map { parseType(it.children.single()) }
+        return ClassSignature(typeParameters, superClass, interfaces)
+    }
+
+    fun parseMethodSignature(
+        signature: String,
+        rawParameters: List<SigParameter>? = null,
+        parameterTypeTransformer: (Int, () -> SigType) -> SigType = { _, f -> f() }
+    ): MethodSignature {
+        val root = parse(signature)
+        val sigTypeParameters = ArrayList<SignatureNode>(1)
+        val sigParameterTypes = ArrayList<SignatureNode>(2)
+        val sigExceptionTypes = ArrayList<SignatureNode>(0)
+        val sigReturnTypes = ArrayList<SignatureNode>(1)
+
+        root.split(
+            sigTypeParameters, TypeParameter,
+            sigParameterTypes, ParameterType,
+            sigExceptionTypes, ExceptionType,
+            sigReturnTypes, ReturnType
+        )
+
+        val typeParameters = sigTypeParameters.map { parseTypeParameter(it) }
+
+        val parameters = if (rawParameters != null) {
+            assert(rawParameters.size >= sigParameterTypes.size)
+            val offset = rawParameters.size - sigParameterTypes.size
+            sigParameterTypes.mapIndexed { index, param ->
+                val rawParameter = rawParameters[index + offset]
+                val transformedType = parameterTypeTransformer(index) { parseType(param.children.single()) }
+                SigParameter(rawParameter.name, transformedType)
+            }
+        } else {
+            sigParameterTypes.mapIndexed { index, param ->
+                SigParameter("p$index", parseType(param.children.single()))
+            }
+        }
+
+        val exceptionTypes = sigExceptionTypes.map { parseType(it) }
+        val returnType = parseType(sigReturnTypes.single().children.single())
+        return MethodSignature(typeParameters, parameters, exceptionTypes, returnType)
+    }
+
+    fun parseFieldSignature(signature: String): SigType {
+        val root = parse(signature)
+        val superClass = root.children.single()
+        assert(superClass.kind == SuperClass)
+        return parseType(superClass.children.single())
+    }
+
+    private fun parseTypeParameter(node: SignatureNode): SigTypeParameter {
+        assert(node.kind == TypeParameter)
+
+        val sigClassBounds = ArrayList<SignatureNode>(1)
+        val sigInterfaceBounds = ArrayList<SignatureNode>(1)
+        node.split(sigClassBounds, ClassBound, sigInterfaceBounds, InterfaceBound)
+        assert(sigClassBounds.size <= 1)
+
+        val classBound = sigClassBounds.firstOrNull()?.let { parseBound(it) }?.takeIf { !it.isJavaLangObject }
+        val interfaceBounds = sigInterfaceBounds.map { parseBound(it) }
+        val allBounds = if (classBound != null) listOf(classBound) + interfaceBounds else interfaceBounds
+        return SigTypeParameter(node.name!!, allBounds)
+    }
+
+    private fun parseBound(node: SignatureNode): SigType {
+        assert(node.kind == ClassBound || node.kind == InterfaceBound)
+        return parseType(node.children.single())
+    }
+
+    private fun parseType(node: SignatureNode): SigType {
+        return when (node.kind) {
+            ClassType -> {
+                val typeArgs = mutableListOf<SignatureNode>()
+                val innerClasses = mutableListOf<SignatureNode>()
+                node.split(typeArgs, TypeArgument, innerClasses, InnerClass)
+
+                val baseType = SigType.Class(node.name!!.replace('/', '.'))
+                var type = parseGenericArgs(baseType, typeArgs)
+                if (innerClasses.isEmpty()) return type
+
+                for (innerClass in innerClasses) {
+                    val nestedType = SigType.Nested(type, innerClass.name!!)
+                    type = parseGenericArgs(nestedType, innerClass.children)
+                }
+
+                type
+            }
+            TypeVariable -> SigType.TypeVariable(node.name!!)
+            ArrayType -> SigType.Array(parseType(node.children.single()))
+            PrimitiveType -> SigType.Primitive.get(node.name!!.single())
+            else -> error("Unsupported type: $node")
+        }
+    }
+
+    private fun parseGenericArgs(base: SigType, args: List<SignatureNode>): SigType {
+        if (args.isEmpty()) {
+            return base
+        }
+
+        return SigType.Generic(base, args.map { arg ->
+            assert(arg.kind == TypeArgument) { "Unexpected kind ${arg.kind}, $TypeArgument expected" }
+            val variance = arg.name ?: return@map SigTypeArgument.Unbound
+
+            val argType = parseType(arg.children.single())
+            when (variance.single()) {
+                '=' -> SigTypeArgument.Invariant(argType)
+                '+' -> SigTypeArgument.Extends(argType)
+                '-' -> SigTypeArgument.Super(argType)
+                else -> error("Unknown variance, '=', '+' or '-' expected")
+            }
+        })
+    }
+
+    private fun parse(signature: String): SignatureNode {
+        val parser = SignatureParserVisitor()
+        SignatureReader(signature).accept(parser)
+        return parser.root
+    }
+}
+
+private fun SignatureNode.split(l1: MutableList<SignatureNode>, e1: ElementKind, l2: MutableList<SignatureNode>, e2: ElementKind) {
+    for (child in children) {
+        when (val kind = child.kind) {
+            e1 -> l1 += child
+            e2 -> l2 += child
+            else -> error("Unknown kind: $kind")
+        }
+    }
+}
+
+private fun SignatureNode.split(
+    l1: MutableList<SignatureNode>,
+    e1: ElementKind,
+    l2: MutableList<SignatureNode>,
+    e2: ElementKind,
+    l3: MutableList<SignatureNode>,
+    e3: ElementKind
+) {
+    for (child in children) {
+        when (val kind = child.kind) {
+            e1 -> l1 += child
+            e2 -> l2 += child
+            e3 -> l3 += child
+            else -> error("Unknown kind: $kind")
+        }
+    }
+}
+
+private fun SignatureNode.split(
+    l1: MutableList<SignatureNode>,
+    e1: ElementKind,
+    l2: MutableList<SignatureNode>,
+    e2: ElementKind,
+    l3: MutableList<SignatureNode>,
+    e3: ElementKind,
+    l4: MutableList<SignatureNode>,
+    e4: ElementKind
+) {
+    for (child in children) {
+        when (val kind = child.kind) {
+            e1 -> l1 += child
+            e2 -> l2 += child
+            e3 -> l3 += child
+            e4 -> l4 += child
+            else -> error("Unknown kind: $kind")
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParserVisitor.kt b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParserVisitor.kt
new file mode 100644
index 0000000..7d9ec71
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParserVisitor.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2010-2019 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.kaptlite.signature
+
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor
+import org.jetbrains.kaptlite.signature.ElementKind.*
+import java.util.*
+
+internal class SignatureParserVisitor : SignatureVisitor(Opcodes.API_VERSION) {
+    val root = SignatureNode(Root)
+    private val stack = ArrayDeque<SignatureNode>(5).apply { add(root) }
+
+    private fun popUntil(kind: ElementKind?) {
+        if (kind != null) {
+            while (stack.peek().kind != kind) {
+                stack.pop()
+            }
+        }
+    }
+
+    private fun popUntil(vararg kinds: ElementKind) {
+        while (stack.peek().kind !in kinds) {
+            stack.pop()
+        }
+    }
+
+    private fun push(kind: ElementKind, parent: ElementKind? = null, name: String? = null) {
+        popUntil(parent)
+
+        val newNode = SignatureNode(kind, name)
+        stack.peek().children += newNode
+        stack.push(newNode)
+    }
+
+    override fun visitSuperclass(): SignatureVisitor {
+        push(SuperClass, parent = Root)
+        return super.visitSuperclass()
+    }
+
+    override fun visitInterface(): SignatureVisitor {
+        push(Interface, parent = Root)
+        return super.visitInterface()
+    }
+
+    override fun visitFormalTypeParameter(name: String) {
+        push(TypeParameter, parent = Root, name = name)
+    }
+
+    override fun visitClassBound(): SignatureVisitor {
+        push(ClassBound, parent = TypeParameter)
+        return super.visitClassBound()
+    }
+
+    override fun visitInterfaceBound(): SignatureVisitor {
+        push(InterfaceBound, parent = TypeParameter)
+        return super.visitInterfaceBound()
+    }
+
+    override fun visitTypeArgument() {
+        popUntil(ClassType, InnerClass)
+        push(TypeArgument)
+    }
+
+    override fun visitTypeArgument(variance: Char): SignatureVisitor {
+        popUntil(ClassType, InnerClass)
+        push(TypeArgument, name = variance.toString())
+        return super.visitTypeArgument(variance)
+    }
+
+    override fun visitInnerClassType(name: String) {
+        push(InnerClass, name = name, parent = ClassType)
+    }
+
+    override fun visitParameterType(): SignatureVisitor {
+        push(ParameterType, parent = Root)
+        return super.visitParameterType()
+    }
+
+    override fun visitReturnType(): SignatureVisitor {
+        push(ReturnType, parent = Root)
+        return super.visitReturnType()
+    }
+
+    override fun visitExceptionType(): SignatureVisitor {
+        push(ExceptionType, parent = Root)
+        return super.visitExceptionType()
+    }
+
+    override fun visitClassType(name: String) {
+        push(ClassType, name = name)
+    }
+
+    override fun visitTypeVariable(name: String) {
+        push(TypeVariable, name = name)
+    }
+
+    override fun visitBaseType(descriptor: Char) {
+        push(PrimitiveType, name = descriptor.toString())
+    }
+
+    override fun visitArrayType(): SignatureVisitor {
+        push(ArrayType)
+        return super.visitArrayType()
+    }
+
+    override fun visitEnd() {
+        while (stack.peek().kind != ClassType) {
+            stack.pop()
+        }
+        stack.pop()
+    }
+}
diff --git a/plugins/kapt3/kapt3-compiler/build.gradle.kts b/plugins/kapt3/kapt3-compiler/build.gradle.kts
index cb13628..72f2a66 100644
--- a/plugins/kapt3/kapt3-compiler/build.gradle.kts
+++ b/plugins/kapt3/kapt3-compiler/build.gradle.kts
@@ -13,6 +13,9 @@
 
     testCompileOnly(intellijDep()) { includeJars("platform-api", "platform-impl") }
 
+    compileOnly(project(":kapt-lite:kapt-lite-kdoc"))
+    embedded(project(":kapt-lite:kapt-lite-kdoc")) { isTransitive = false }
+
     Platform[192].orHigher {
         testRuntime(intellijPluginDep("java"))
     }
diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt
index a937c40..d908cd6 100644
--- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt
+++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt
@@ -16,24 +16,17 @@
 
 package org.jetbrains.kotlin.kapt3.stubs
 
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiRecursiveElementVisitor
-import com.intellij.psi.impl.source.tree.LeafPsiElement
 import com.sun.tools.javac.parser.Tokens
 import com.sun.tools.javac.tree.DCTree
 import com.sun.tools.javac.tree.DocCommentTable
 import com.sun.tools.javac.tree.JCTree
 import com.sun.tools.javac.tree.TreeScanner
-import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
 import org.jetbrains.kotlin.kapt3.KaptContextForStubGeneration
-import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
-import org.jetbrains.kotlin.kdoc.psi.api.KDoc
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.resolve.BindingContext
 import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
 import org.jetbrains.org.objectweb.asm.tree.FieldNode
 import org.jetbrains.org.objectweb.asm.tree.MethodNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
 
 class KDocCommentKeeper(private val kaptContext: KaptContextForStubGeneration) {
     private val docCommentTable = KaptDocCommentTable()
@@ -73,84 +66,16 @@
 
     fun saveKDocComment(tree: JCTree, node: Any) {
         val origin = kaptContext.origins[node] ?: return
-        val psiElement = origin.element as? KtDeclaration ?: return
-        val descriptor = origin.descriptor
-        val docComment = psiElement.docComment ?: return
-
-        if (descriptor is ConstructorDescriptor && psiElement is KtClassOrObject) {
-            // We don't want the class comment to be duplicated on <init>()
-            return
+        val kind = when (node) {
+            is ClassNode -> KDocParsingHelper.DeclarationKind.CLASS
+            is MethodNode -> KDocParsingHelper.DeclarationKind.METHOD
+            is FieldNode -> KDocParsingHelper.DeclarationKind.FIELD
+            else -> return
         }
 
-        if (node is MethodNode
-            && psiElement is KtProperty
-            && descriptor is PropertyAccessorDescriptor
-            && kaptContext.bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor.correspondingProperty] == true
-        ) {
-            // Do not place documentation on backing field and property accessors
-            return
-        }
-
-        if (node is FieldNode && psiElement is KtObjectDeclaration && descriptor == null) {
-            // Do not write KDoc on object instance field
-            return
-        }
-
-        docCommentTable.putComment(tree, KDocComment(escapeNestedComments(extractCommentText(docComment))))
+        val text = KDocParsingHelper.getKDocComment(kind, origin, kaptContext.bindingContext) ?: return
+        docCommentTable.putComment(tree, KDocComment(text))
     }
-
-    private fun escapeNestedComments(text: String): String {
-        val result = StringBuilder()
-
-        var index = 0
-        var commentLevel = 0
-
-        while (index < text.length) {
-            val currentChar = text[index]
-            fun nextChar() = text.getOrNull(index + 1)
-
-            if (currentChar == '/' && nextChar() == '*') {
-                commentLevel++
-                index++
-                result.append("/ *")
-            } else if (currentChar == '*' && nextChar() == '/') {
-                commentLevel = maxOf(0, commentLevel - 1)
-                index++
-                result.append("* /")
-            } else {
-                result.append(currentChar)
-            }
-
-            index++
-        }
-
-        return result.toString()
-    }
-
-    private fun extractCommentText(docComment: KDoc): String {
-        return buildString {
-            docComment.accept(object : PsiRecursiveElementVisitor() {
-                override fun visitElement(element: PsiElement) {
-                    if (element is LeafPsiElement) {
-                        if (element.isKDocLeadingAsterisk()) {
-                            val indent = takeLastWhile { it == ' ' || it == '\t' }.length
-                            if (indent > 0) {
-                                delete(length - indent, length)
-                            }
-                        } else if (!element.isKDocStart() && !element.isKDocEnd()) {
-                            append(element.text)
-                        }
-                    }
-
-                    super.visitElement(element)
-                }
-            })
-        }.trimIndent().trim()
-    }
-
-    private fun LeafPsiElement.isKDocStart() = elementType == KDocTokens.START
-    private fun LeafPsiElement.isKDocEnd() = elementType == KDocTokens.END
-    private fun LeafPsiElement.isKDocLeadingAsterisk() = elementType == KDocTokens.LEADING_ASTERISK
 }
 
 private class KDocComment(val body: String) : Tokens.Comment {
diff --git a/prepare/kapt-lite-compiler-plugin-embeddable/build.gradle.kts b/prepare/kapt-lite-compiler-plugin-embeddable/build.gradle.kts
new file mode 100644
index 0000000..3fb76e1
--- /dev/null
+++ b/prepare/kapt-lite-compiler-plugin-embeddable/build.gradle.kts
@@ -0,0 +1,18 @@
+import org.gradle.jvm.tasks.Jar
+
+description = "Lightweight annotation processing support – Kotlin compiler plugin (for using with embeddable compiler)"
+
+plugins {
+    `java`
+}
+
+dependencies {
+    embedded(project(":kapt-lite:kapt-lite-compiler-plugin")) { isTransitive = false }
+}
+
+publish()
+
+runtimeJar(rewriteDefaultJarDepsToShadedCompiler())
+
+sourcesJar()
+javadocJar()
diff --git a/settings.gradle b/settings.gradle
index 531b68e7..6b0ffb8 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -189,6 +189,11 @@
         ":kotlin-annotation-processing-runtime",
         ":kotlin-annotation-processing-gradle",
         ":kotlin-annotation-processing-embeddable",
+        ":kapt-lite:kapt-lite-signature-parser",
+        ":kapt-lite:kapt-lite-kdoc",
+        ":kapt-lite:kapt-lite-compiler-plugin",
+        ":kapt-lite:kapt-lite-compiler-plugin-embeddable",
+        ":kapt-lite:kapt-lite-javac-plugin",
         ":kotlin-daemon-embeddable",
         ":examples:kotlin-jsr223-local-example",
         ":examples:kotlin-jsr223-daemon-local-eval-example",
@@ -370,6 +375,11 @@
 project(':kotlin-script-util').projectDir = "$rootDir/libraries/tools/kotlin-script-util" as File
 project(':kotlin-annotation-processing-gradle').projectDir = "$rootDir/libraries/tools/kotlin-annotation-processing" as File
 project(':kotlin-annotation-processing-embeddable').projectDir = "$rootDir/prepare/kotlin-annotation-processing-embeddable" as File
+project(':kapt-lite:kapt-lite-signature-parser').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-signature-parser" as File
+project(':kapt-lite:kapt-lite-kdoc').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-kdoc" as File
+project(':kapt-lite:kapt-lite-compiler-plugin').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-compiler-plugin" as File
+project(':kapt-lite:kapt-lite-compiler-plugin-embeddable').projectDir = "$rootDir/prepare/kapt-lite-compiler-plugin-embeddable" as File
+project(':kapt-lite:kapt-lite-javac-plugin').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-javac-plugin" as File
 project(':kotlin-daemon-embeddable').projectDir = "$rootDir/prepare/kotlin-daemon-embeddable" as File
 project(':kotlin-annotation-processing').projectDir = "$rootDir/plugins/kapt3/kapt3-compiler" as File
 project(':kotlin-annotation-processing-cli').projectDir = "$rootDir/plugins/kapt3/kapt3-cli" as File