init sampler
diff --git a/idea-runner/build.gradle.kts b/idea-runner/build.gradle.kts
index 580719e..e3d2890 100644
--- a/idea-runner/build.gradle.kts
+++ b/idea-runner/build.gradle.kts
@@ -9,6 +9,7 @@
     compileOnly(project(":idea:idea-maven"))
     compileOnly(project(":idea:idea-gradle"))
     compileOnly(project(":idea:idea-jvm"))
+    compileOnly(project(":idea:idea-sampler"))
 
     runtimeOnly(intellijDep())
     runtimeOnly(intellijRuntimeAnnotations())
diff --git a/idea/idea-sampler/build.gradle.kts b/idea/idea-sampler/build.gradle.kts
new file mode 100644
index 0000000..9ed8ba7
--- /dev/null
+++ b/idea/idea-sampler/build.gradle.kts
@@ -0,0 +1,16 @@
+plugins {
+    kotlin("jvm")
+    id("jps-compatible")
+}
+
+dependencies {
+    compileOnly(project(":idea"))
+    compileOnly(project(":idea:idea-core"))
+
+    compileOnly(intellijDep())
+}
+
+sourceSets {
+    "main" { projectDefault() }
+    "test" { projectDefault() }
+}
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/KotlinSamplerModuleBuilder.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/KotlinSamplerModuleBuilder.kt
new file mode 100644
index 0000000..2087349
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/KotlinSamplerModuleBuilder.kt
@@ -0,0 +1,158 @@
+/*
+ * 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.ide.sampler
+
+import com.intellij.ide.actions.ImportModuleAction
+import com.intellij.ide.util.newProjectWizard.AddModuleWizard
+import com.intellij.ide.util.projectWizard.ModuleBuilder
+import com.intellij.ide.util.projectWizard.ModuleWizardStep
+import com.intellij.ide.util.projectWizard.WizardContext
+import com.intellij.openapi.components.ServiceManager
+import com.intellij.openapi.externalSystem.service.project.ProjectDataManager
+import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalModuleBuilder
+import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings
+import com.intellij.openapi.module.JavaModuleType
+import com.intellij.openapi.module.ModifiableModuleModel
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.module.ModuleType
+import com.intellij.openapi.progress.ProgressManager
+import com.intellij.openapi.roots.ModifiableRootModel
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider
+import com.intellij.ui.components.JBTextField
+import org.jetbrains.kotlin.idea.KotlinIcons
+import org.jetbrains.kotlin.idea.framework.SAMPLER_SYSTEM_ID
+import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportBuilder
+import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportProvider
+import java.io.File
+import javax.swing.Icon
+import javax.swing.JComponent
+import javax.swing.event.DocumentEvent
+import javax.swing.event.DocumentListener
+
+class KotlinSamplerModuleBuilder : AbstractExternalModuleBuilder<SamplerProjectSettings>(SAMPLER_SYSTEM_ID, SamplerProjectSettings()) {
+
+    private val samples = mutableMapOf<String, SampleInfo>()
+
+    private val settingsComponents = SampleTemplateList()
+
+    private val searchField: JBTextField = JBTextField().apply {
+        emptyText.text = "input some int"
+    }
+
+    override fun getGroupName(): String = "Kotlin"
+
+    override fun getNodeIcon(): Icon = KotlinIcons.SMALL_LOGO
+
+    override fun getBuilderId() = "KotlinSamplerBuilderId"
+
+    override fun getModuleType(): ModuleType<*> = JavaModuleType.getModuleType()
+
+    override fun createModule(moduleModel: ModifiableModuleModel): Module {
+        val oldPath = moduleFilePath
+        val file = File(oldPath)
+        val path = file.parent + "/" + file.name.toLowerCase()
+        moduleFilePath = path
+
+        val settings = externalProjectSettings
+        settings.externalProjectPath = path
+        settings.isUseAutoImport = false
+        settings.isCreateEmptyContentRootDirectories = false
+
+        ModuleBuilder.deleteModuleFile(oldPath)
+
+        val module: Module = moduleModel.newModule(path, moduleType.id)
+        moduleModel.commit()
+
+        setupModule(module)
+        return module
+    }
+
+    // TODO
+    override fun setupRootModel(model: ModifiableRootModel) {
+        val info = settingsComponents.list.selectedValue
+        val moduleDir = File(contentEntryPath!!)
+        val sample = SamplerInteraction.getSample(info.id)!!
+        createTemplate(sample, moduleDir)
+
+        when (sample.type) {
+            BuildSystemType.GRADLE -> {
+                val buildFile = sample.files.find { it.extension == "gradle" }!!
+                val gradleFile = File(moduleDir, buildFile.fullPath())
+                val projectDataManager = ServiceManager.getService(ProjectDataManager::class.java)
+                val gradleProjectImportBuilder = GradleProjectImportBuilder(projectDataManager)
+                val gradleProjectImportProvider = GradleProjectImportProvider(gradleProjectImportBuilder)
+                val wizard = AddModuleWizard(model.project, gradleFile.getPath(), gradleProjectImportProvider)
+                if (wizard.stepCount <= 0 || wizard.showAndGet()) {
+                    ImportModuleAction.createFromWizard(model.project, wizard)
+                }
+            }
+            BuildSystemType.MAVEN -> TODO()
+            BuildSystemType.NONE -> {
+            }
+        }
+    }
+
+    private fun createTemplate(sample: Sample, moduleDir: File) {
+        sample.files.forEach { sf ->
+            val file = File(
+                moduleDir,
+                "${sf.path}/${sf.name}.${sf.extension}"
+            )
+            if (!file.exists()) {
+                file.parentFile.mkdirs()
+                file.createNewFile()
+            }
+            file.printWriter().use { out -> out.print(sf.content) }
+        }
+    }
+
+    override fun createWizardSteps(wizardContext: WizardContext, modulesProvider: ModulesProvider): Array<ModuleWizardStep> {
+        settingsComponents.setItems(SamplerInteraction.getSamplerInfos())
+        val step = object : ModuleWizardStep() {
+            override fun updateDataModel() {
+            }
+
+            override fun getComponent(): JComponent = settingsComponents.mainPanel
+        }
+
+        searchField.document.addDocumentListener(object : DocumentListener {
+            override fun changedUpdate(e: DocumentEvent?) {
+            }
+
+            override fun insertUpdate(e: DocumentEvent?) {
+            }
+
+            override fun removeUpdate(e: DocumentEvent?) {
+            }
+        })
+
+        return arrayOf(step)
+    }
+
+    private fun downloadSamples() {
+        doWithProgress(
+            // TODO report errors
+            {
+                SamplerInteraction.getSamplerInfos().forEach { samples[it.name] = it }
+            },
+            "Downloading list of templates..."
+        )
+    }
+
+
+    private fun doWithProgress(body: () -> Unit, title: String) {
+        ProgressManager.getInstance().runProcessWithProgressSynchronously(
+            body, title, false, null
+        )
+    }
+}
+
+
+class SamplerProjectSettings : ExternalProjectSettings() {
+    override fun clone(): ExternalProjectSettings {
+        return SamplerProjectSettings()
+    }
+}
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SampleTemplateList.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SampleTemplateList.kt
new file mode 100644
index 0000000..a10e7ac
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SampleTemplateList.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.ide.sampler
+
+import com.intellij.ui.components.JBList
+import com.intellij.ui.components.JBScrollPane
+import com.intellij.ui.components.JBTextField
+import com.intellij.ui.layout.GrowPolicy
+import com.intellij.ui.layout.panel
+import javax.swing.JPanel
+import javax.swing.JTextPane
+
+class SampleTemplateList {
+    lateinit var search: JBTextField
+    lateinit var description: JTextPane
+    lateinit var list: JBList<SampleInfo>
+        private set
+
+    fun setItems(items: List<SampleInfo>) {
+        list.model = JBList.createDefaultListModel(items)
+    }
+
+    val mainPanel: JPanel =
+        panel {
+            row {
+                cell {
+                    JBTextField().apply { search = this }(growX, pushX)
+                }
+            }
+            row {
+                JBScrollPane(JBList<SampleInfo>().apply { list = this })(growX, pushX, growPolicy = GrowPolicy.MEDIUM_TEXT)
+                JTextPane().apply {
+                    description = this
+                    isRequestFocusEnabled = true
+                }(growX, pushX)
+            }
+        }
+
+    init {
+        list.addListSelectionListener {
+            list.selectedValue?.let {
+                description.text = assemblyText(it)
+                description.caretPosition = 0
+            }
+        }
+    }
+
+    private fun assemblyText(item: SampleInfo): String {
+        return StringBuilder()
+            .append(item.description).append("\n")
+            .append("Tags: ").append(item.tags).append("\n")
+            .append("Libraries: ").append(item.libraries)
+            .toString()
+    }
+}
\ No newline at end of file
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerInteraction.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerInteraction.kt
new file mode 100644
index 0000000..22b5b70
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerInteraction.kt
@@ -0,0 +1,122 @@
+/*
+ * 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.ide.sampler
+
+data class SampleInfo(
+    val id: Int,
+    val name: String,
+    val description: String,
+    val libraries: List<String>,
+    val tags: List<String>
+) {
+    override fun toString(): String {
+        return name
+    }
+}
+
+class Sample(
+    val id: Int,
+    val name: String,
+    val description: String,
+    val libraries: List<String>,
+    val tags: List<String>,
+    val files: List<File>,
+    val type: BuildSystemType
+)
+
+enum class BuildSystemType {
+    MAVEN, GRADLE, NONE
+}
+
+data class File(
+    val id: Int,
+    val snapshotId: Int,
+    val path: String,
+    val name: String,
+    val extension: String,
+    val content: String
+) {
+    fun fullPath() : String = "$path/$name.$extension"
+}
+
+object SamplerInteraction {
+    private val samples = (1..10).map { nameNo ->
+        SampleInfo(
+            nameNo,
+            "Name$nameNo",
+            "Description$nameNo",
+            (1..nameNo).map { "Library$it" },
+            (nameNo..10).map { "Tag$it" }
+        )
+    }
+
+    fun getSamplerInfos(
+        namePattern: String = "",
+        libraries: List<String> = emptyList(),
+        tags: List<String> = emptyList()
+    ): List<SampleInfo> {
+        return samples.filter { it.name.contains(namePattern) }
+            .filter { it.libraries.containsAll(libraries) }
+            .filter { it.tags.containsAll(tags) }
+    }
+
+    fun getSample(id: Int): Sample? {
+        return samples.get(id).let {
+            Sample(
+                it.id,
+                it.name,
+                it.description,
+                it.libraries,
+                it.tags,
+                listOf(
+                    File(
+                        1,
+                        100 + id,
+                        "",
+                        "build",
+                        "gradle",
+                        buldGradle
+                    ),
+                    File(
+                        id, 100 + id, "src/main/kotlin", "app", "kt", "fun main(){\n" +
+                                "    println(\"Hello world!\")\n" +
+                                "}"
+                    )
+                ),
+                BuildSystemType.GRADLE
+            )
+        }
+    }
+
+    private val buldGradle = """
+        plugins {
+            id 'java'
+            id 'org.jetbrains.kotlin.jvm' version '1.3.40'
+        }
+        
+        group 'asd'
+        version '1.0-SNAPSHOT'
+        
+        sourceCompatibility = 1.8
+        
+        repositories {
+            maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
+            mavenCentral()
+        }
+        
+        dependencies {
+            implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
+            testCompile group: 'junit', name: 'junit', version: '4.12'
+        }
+        
+        compileKotlin {
+            kotlinOptions.jvmTarget = "1.8"
+        }
+        compileTestKotlin {
+            kotlinOptions.jvmTarget = "1.8"
+        }
+    """.trimIndent()
+}
\ No newline at end of file
diff --git a/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerProjectTemplate.kt b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerProjectTemplate.kt
new file mode 100644
index 0000000..1563bdf
--- /dev/null
+++ b/idea/idea-sampler/src/org/jetbrains/kotlin/ide/sampler/SamplerProjectTemplate.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.ide.sampler
+
+import com.intellij.ide.util.projectWizard.AbstractModuleBuilder
+import com.intellij.openapi.ui.ValidationInfo
+import com.intellij.platform.ProjectTemplate
+import org.jetbrains.kotlin.idea.KotlinIcons
+import javax.swing.Icon
+
+class SamplerProjectTemplate : ProjectTemplate {
+    override fun getName(): String = "Kotlin Sampler"
+
+    override fun getIcon(): Icon = KotlinIcons.SMALL_LOGO
+
+    override fun getDescription(): String = "Create project from samples published on Git-Hub."
+
+    override fun validateSettings(): ValidationInfo? = null
+
+    override fun createModuleBuilder(): AbstractModuleBuilder = KotlinSamplerModuleBuilder()
+}
\ No newline at end of file
diff --git a/idea/resources/META-INF/gradle-java.xml b/idea/resources/META-INF/gradle-java.xml
index 18558b5..4f98237 100644
--- a/idea/resources/META-INF/gradle-java.xml
+++ b/idea/resources/META-INF/gradle-java.xml
@@ -48,5 +48,6 @@
         <moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleWebMultiplatformModuleBuilder"/>
         <moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMobileMultiplatformModuleBuilder"/>
         <moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMobileSharedMultiplatformModuleBuilder"/>
+        <moduleBuilder implementation="org.jetbrains.kotlin.ide.sampler.KotlinSamplerModuleBuilder"/>
     </extensions>
 </idea-plugin>
diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt b/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt
index d78a8e0..4145091 100644
--- a/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/framework/KotlinLibraryUtil.kt
@@ -13,12 +13,14 @@
 val MAVEN_SYSTEM_ID = ProjectSystemId("Maven")
 val GRADLE_SYSTEM_ID = ProjectSystemId("GRADLE")
 val KOBALT_SYSTEM_ID = ProjectSystemId("KOBALT")
+val SAMPLER_SYSTEM_ID = ProjectSystemId("SAMPLER")
 
 fun isExternalLibrary(library: Library): Boolean {
     return ExternalSystemApiUtil.isExternalSystemLibrary(library, ProjectSystemId.IDE) ||
            ExternalSystemApiUtil.isExternalSystemLibrary(library, GRADLE_SYSTEM_ID) ||
            ExternalSystemApiUtil.isExternalSystemLibrary(library, KOBALT_SYSTEM_ID) ||
-           ExternalSystemApiUtil.isExternalSystemLibrary(library, MAVEN_SYSTEM_ID)
+           ExternalSystemApiUtil.isExternalSystemLibrary(library, MAVEN_SYSTEM_ID) ||
+           ExternalSystemApiUtil.isExternalSystemLibrary(library, SAMPLER_SYSTEM_ID)
 }
 
 
diff --git a/prepare/idea-plugin/build.gradle.kts b/prepare/idea-plugin/build.gradle.kts
index aafcc9b..b7e718a 100644
--- a/prepare/idea-plugin/build.gradle.kts
+++ b/prepare/idea-plugin/build.gradle.kts
@@ -52,6 +52,7 @@
         ":idea:idea-core",
         ":idea:idea-gradle",
         ":idea:idea-gradle-native",
+        ":idea:idea-sampler",
         ":compiler:ir.psi2ir",
         ":compiler:ir.tree",
         ":js:js.ast",
diff --git a/settings.gradle b/settings.gradle
index ab3999a..d443fd3 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -102,6 +102,7 @@
         ":idea:idea-test-framework",
         ":idea:idea-native",
         ":idea:idea-gradle-native",
+        ":idea:idea-sampler",
         ":idea",
         ":idea-runner",
         ":idea:jvm-debugger:eval4j",