diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/expected.log b/libraries/tools/kotlin-maven-plugin/src/it/plugins/expected.log
new file mode 100644
index 00000000000..b04da699ab2
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/expected.log
@@ -0,0 +1,15 @@
+[INFO] Kotlin Compiler version @snapshot@
+[INFO] Compiling Kotlin sources from [/test-extension/src/main/kotlin]
+[INFO] Module name is test-extension
+[INFO] Kotlin Compiler version @snapshot@
+[WARNING] No sources found skipping Kotlin compile
+[INFO] Kotlin Compiler version @snapshot@
+[INFO] Compiling Kotlin sources from [/use-test-extension/src/main/kotlin]
+[INFO] Module name is use-test-extension
+[INFO] Applicability test for project use-test-extension
+[INFO] Applying plugin test-me
+[INFO] Configuring test plugin with arguments
+[INFO] Plugin applied
+[INFO] Option value: my-special-value
+[INFO] Kotlin Compiler version @snapshot@
+[WARNING] No sources found skipping Kotlin compile
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/pom.xml b/libraries/tools/kotlin-maven-plugin/src/it/plugins/pom.xml
new file mode 100644
index 00000000000..4ac87a3899b
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ org.jetbrains.kotlin
+ kotlin-compiler-extensions-test
+ 1.1-SNAPSHOT
+
+ test-extension
+ use-test-extension
+
+ pom
+
+
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/pom.xml b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/pom.xml
new file mode 100644
index 00000000000..5664b741ced
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/pom.xml
@@ -0,0 +1,85 @@
+
+
+
+ kotlin-compiler-extensions-test
+ org.jetbrains.kotlin
+ 1.1-SNAPSHOT
+
+ 4.0.0
+
+ test-extension
+
+
+ 1.1-SNAPSHOT
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-test
+ ${kotlin.version}
+ test
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+ provided
+
+
+
+
+ src/main/kotlin
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+
+
+ org.codehaus.plexus
+ plexus-component-metadata
+ 1.7.1
+
+
+ process-classes
+
+ generate-metadata
+
+
+
+ process-test-classes
+
+ generate-test-metadata
+
+
+
+
+
+
+
+
+
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/kotlin/org/jetbrains/kotlin/test/MavenPluginComponent.kt b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/kotlin/org/jetbrains/kotlin/test/MavenPluginComponent.kt
new file mode 100644
index 00000000000..fe881b9fd01
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/kotlin/org/jetbrains/kotlin/test/MavenPluginComponent.kt
@@ -0,0 +1,25 @@
+package org.jetbrains.kotlin.test
+
+import org.apache.maven.plugin.*
+import org.apache.maven.project.*
+import org.codehaus.plexus.component.annotations.*
+import org.codehaus.plexus.logging.*
+import org.jetbrains.kotlin.maven.*
+
+@Component(role = KotlinMavenPluginExtension::class, hint = "test-me")
+class MavenPluginComponent : KotlinMavenPluginExtension {
+ @Requirement
+ lateinit var logger: Logger
+
+ override fun isApplicable(project: MavenProject, execution: MojoExecution): Boolean {
+ logger.info("Applicability test for project ${project.artifactId}")
+
+ return true
+ }
+
+ override fun getPluginArguments(project: MavenProject, execution: MojoExecution): MutableList {
+ logger.info("Configuring test plugin with arguments")
+
+ return mutableListOf("plugin:${TestCommandLineProcessor.TestPluginId}:${TestCommandLineProcessor.MyTestOption.name}=my-special-value")
+ }
+}
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/kotlin/org/jetbrains/kotlin/test/TestKotlinPluginRegistrar.kt b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/kotlin/org/jetbrains/kotlin/test/TestKotlinPluginRegistrar.kt
new file mode 100644
index 00000000000..6da7b4afa7c
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/kotlin/org/jetbrains/kotlin/test/TestKotlinPluginRegistrar.kt
@@ -0,0 +1,41 @@
+package org.jetbrains.kotlin.test
+
+import com.intellij.mock.*
+import org.jetbrains.kotlin.cli.common.*
+import org.jetbrains.kotlin.cli.common.messages.*
+import org.jetbrains.kotlin.compiler.plugin.*
+import org.jetbrains.kotlin.config.*
+
+object TestPluginKeys {
+ val TestOption = CompilerConfigurationKey.create("test option")!!
+}
+
+class TestCommandLineProcessor : CommandLineProcessor {
+ companion object {
+ val TestPluginId = "org.jetbrains.kotlin.test.test-plugin"
+ val MyTestOption = CliOption("test-option", "", "", true, false)
+ }
+
+ override val pluginId: String = TestPluginId
+
+ override val pluginOptions: Collection = listOf(MyTestOption)
+
+ override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
+ when (option) {
+ MyTestOption -> {
+ configuration.put(TestPluginKeys.TestOption, value)
+ }
+ else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
+ }
+ }
+}
+
+class TestKotlinPluginRegistrar : ComponentRegistrar {
+ override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
+ val collector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)!!
+ val option = configuration.get(TestPluginKeys.TestOption)!!
+
+ collector.report(CompilerMessageSeverity.INFO, "Plugin applied", CompilerMessageLocation.NO_LOCATION)
+ collector.report(CompilerMessageSeverity.INFO, "Option value: $option", CompilerMessageLocation.NO_LOCATION)
+ }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
new file mode 100644
index 00000000000..ca912fba429
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
@@ -0,0 +1 @@
+org.jetbrains.kotlin.test.TestCommandLineProcessor
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
new file mode 100644
index 00000000000..812ac85bae7
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/test-extension/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
@@ -0,0 +1 @@
+org.jetbrains.kotlin.test.TestKotlinPluginRegistrar
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/use-test-extension/pom.xml b/libraries/tools/kotlin-maven-plugin/src/it/plugins/use-test-extension/pom.xml
new file mode 100644
index 00000000000..c68e5ff6e99
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/use-test-extension/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+ kotlin-compiler-extensions-test
+ org.jetbrains.kotlin
+ 1.1-SNAPSHOT
+
+ 4.0.0
+
+ use-test-extension
+
+
+
+ 1.1-SNAPSHOT
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-test
+ ${kotlin.version}
+ test
+
+
+
+
+ src/main/kotlin
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+
+
+
+ test-me
+
+
+
+ plugin:test-me:...=....
+
+
+
+
+
+
+ org.jetbrains.kotlin
+ test-extension
+ ${project.version}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/use-test-extension/src/main/kotlin/main.kt b/libraries/tools/kotlin-maven-plugin/src/it/plugins/use-test-extension/src/main/kotlin/main.kt
new file mode 100644
index 00000000000..9f35c803aa1
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/use-test-extension/src/main/kotlin/main.kt
@@ -0,0 +1,5 @@
+package org.jetbrains.kotlin.test
+
+fun main(args: Array) {
+ println("OK")
+}
diff --git a/libraries/tools/kotlin-maven-plugin/src/it/plugins/verify.groovy b/libraries/tools/kotlin-maven-plugin/src/it/plugins/verify.groovy
new file mode 100644
index 00000000000..2ad351b67fe
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/it/plugins/verify.groovy
@@ -0,0 +1,65 @@
+import java.util.regex.Pattern
+
+class State {
+ def currentPlugin = ""
+ def lines = []
+}
+
+def removePaths(String path, File basedir) {
+ while (basedir.parentFile != null) {
+ path = path.replace(basedir.absolutePath, "").replace(basedir.path, "")
+ basedir = basedir.parentFile
+ }
+
+ return path
+}
+
+System.out.flush()
+def buildLogFile = new File(basedir, "build.log")
+
+def pattern = Pattern.compile(/\[INFO\] --- ([^:]+):.*:\S+ \([^)]+\) @ [a-zA-Z_-]+ ---/)
+State state = buildLogFile.readLines().collect { it.replaceAll("\\u001b[^m]*m", "") }.inject(new State()) { acc, line ->
+ def m = pattern.matcher(line)
+ if (m.find()) {
+ acc.currentPlugin = m.group(1)
+ } else if (line.startsWith("[INFO] Downloaded:") ||
+ line.startsWith("[INFO] Downloading:") ||
+ line.startsWith("Downloaded:") ||
+ line.startsWith("Downloading:") ||
+ line.startsWith("[INFO] PERF:")) {
+ // ignore line
+ } else if (acc.currentPlugin == "kotlin-maven-plugin") {
+ def filtered = removePaths(line, basedir).
+ replace("\\", "/").
+ replaceAll(/[0-9]+\s*ms/, "LLL ms").
+ trim().
+ replaceAll(/^\[[A-Z]+\]$/, "").
+ replaceAll(/version [0-9a-z-+\.]+/, "version @snapshot@")
+
+ if (filtered != "") {
+ acc.lines << filtered
+ }
+ }
+
+ acc
+}
+
+def expectedLog = new File(basedir, "expected.log").readLines().join("\n").trim()
+def actualLog = state.lines.join("\n").trim()
+
+if (expectedLog != actualLog) {
+ println "Expected and actual log differs!"
+ println ""
+
+ println "Actual log (from $buildLogFile):"
+ println actualLog
+ println ""
+ println "Expected log (from ${new File(basedir, "expected.log").absolutePath}):"
+ println expectedLog
+ println ""
+ return false
+} else {
+ println "Log comparison succeeded"
+}
+
+return true