diff --git a/idea/idea-repl/idea-repl.iml b/idea/idea-repl/idea-repl.iml
index 89c3d9819c8..5c700bafce3 100644
--- a/idea/idea-repl/idea-repl.iml
+++ b/idea/idea-repl/idea-repl.iml
@@ -12,5 +12,8 @@
+
+
+
\ No newline at end of file
diff --git a/idea/idea-repl/src/META-INF/services/javax.script.ScriptEngineFactory b/idea/idea-repl/src/META-INF/services/javax.script.ScriptEngineFactory
new file mode 100644
index 00000000000..8765a13624f
--- /dev/null
+++ b/idea/idea-repl/src/META-INF/services/javax.script.ScriptEngineFactory
@@ -0,0 +1 @@
+org.jetbrains.kotlin.jsr223.KotlinJvmJsr223StandardScriptEngineFactory4Idea
diff --git a/idea/idea-repl/src/org/jetbrains/kotlin/jsr223/KotlinJvmJsr223ScriptEngine4Idea.kt b/idea/idea-repl/src/org/jetbrains/kotlin/jsr223/KotlinJvmJsr223ScriptEngine4Idea.kt
new file mode 100644
index 00000000000..4e0fc751bd5
--- /dev/null
+++ b/idea/idea-repl/src/org/jetbrains/kotlin/jsr223/KotlinJvmJsr223ScriptEngine4Idea.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2010-2016 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.kotlin.jsr223
+
+import com.intellij.openapi.Disposable
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
+import org.jetbrains.kotlin.cli.common.repl.GenericReplCompiledEvaluator
+import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
+import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
+import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
+import org.jetbrains.kotlin.daemon.client.*
+import org.jetbrains.kotlin.daemon.common.*
+import org.jetbrains.kotlin.utils.PathUtil
+import java.io.File
+import java.io.Reader
+import javax.script.*
+
+class KotlinJvmJsr223ScriptEngine4Idea(
+ disposable: Disposable,
+ private val factory: ScriptEngineFactory,
+ templateClasspath: List,
+ templateClassName: String
+) : AbstractScriptEngine(), ScriptEngine {
+
+ private val daemon by lazy {
+ val path = PathUtil.getKotlinPathsForIdeaPlugin().compilerPath
+ assert(path.exists())
+ val compilerId = CompilerId.makeCompilerId(path)
+ val daemonOptions = configureDaemonOptions()
+ val daemonJVMOptions = DaemonJVMOptions()
+
+ val daemonReportMessages = arrayListOf()
+
+ KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true)
+ ?: throw ScriptException("Unable to connect to repl server:" + daemonReportMessages.joinToString("\n ", prefix = "\n ") { "${it.category.name} ${it.message}" })
+ }
+
+ private val replCompiler by lazy {
+ daemon.let {
+ KotlinRemoteReplCompiler(disposable,
+ it,
+ makeAutodeletingFlagFile("idea-jsr223-repl-session"),
+ CompileService.TargetPlatform.JVM,
+ templateClasspath,
+ templateClassName,
+ System.out)
+ }
+ }
+
+ val localEvaluator by lazy { GenericReplCompiledEvaluator(emptyList(), Thread.currentThread().contextClassLoader) }
+
+ private var lineCount = 0
+
+ private val history = arrayListOf()
+
+ override fun eval(script: String, context: ScriptContext?): Any? {
+
+ fun ReplCompileResult.Error.locationString() = if (location == CompilerMessageLocation.NO_LOCATION) ""
+ else " at ${location.line}:${location.column}:"
+
+ lineCount += 1
+ // TODO bind to context
+ val codeLine = ReplCodeLine(lineCount, script)
+ val compileResult = replCompiler?.compile(codeLine, history)
+ val compiled = when (compileResult) {
+ is ReplCompileResult.Error -> throw ScriptException("Error${compileResult.locationString()}: ${compileResult.message}")
+ is ReplCompileResult.Incomplete -> throw ScriptException("error: incomplete code")
+ is ReplCompileResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${compileResult.lineNo}")
+ is ReplCompileResult.CompiledClasses -> compileResult
+ }
+
+ val evalResult = localEvaluator.eval(codeLine, history, compiled.classes, compiled.hasResult, compiled.newClasspath)
+ val ret = when (evalResult) {
+ is ReplEvalResult.ValueResult -> evalResult.value
+ is ReplEvalResult.UnitResult -> null
+ is ReplEvalResult.Error -> throw ScriptException(evalResult.message)
+ is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code")
+ is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${evalResult.lineNo}")
+ }
+ history.add(codeLine)
+ // TODO update context
+ return ret
+ }
+
+ override fun eval(script: Reader, context: ScriptContext?): Any? = eval(script.readText(), context)
+
+ override fun createBindings(): Bindings = SimpleBindings()
+
+ override fun getFactory(): ScriptEngineFactory = factory
+}
diff --git a/idea/idea-repl/src/org/jetbrains/kotlin/jsr223/KotlinJvmJsr223StandardScriptEngineFactory4Idea.kt b/idea/idea-repl/src/org/jetbrains/kotlin/jsr223/KotlinJvmJsr223StandardScriptEngineFactory4Idea.kt
new file mode 100644
index 00000000000..200676a1575
--- /dev/null
+++ b/idea/idea-repl/src/org/jetbrains/kotlin/jsr223/KotlinJvmJsr223StandardScriptEngineFactory4Idea.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010-2016 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.kotlin.jsr223
+
+import com.intellij.openapi.util.Disposer
+import org.jetbrains.kotlin.cli.common.KotlinVersion
+import org.jetbrains.kotlin.utils.PathUtil
+import javax.script.ScriptEngine
+import javax.script.ScriptEngineFactory
+
+@Suppress("unused") // used in javax.script.ScriptEngineFactory META-INF file
+class KotlinJvmJsr223StandardScriptEngineFactory4Idea : ScriptEngineFactory {
+
+ override fun getLanguageName(): String = "kotlin"
+ override fun getLanguageVersion(): String = KotlinVersion.VERSION
+ override fun getEngineName(): String = "kotlin"
+ override fun getEngineVersion(): String = KotlinVersion.VERSION
+ override fun getExtensions(): List = listOf("kts")
+ override fun getMimeTypes(): List = listOf("text/x-kotlin")
+ override fun getNames(): List = listOf("kotlin")
+
+ override fun getScriptEngine(): ScriptEngine =
+ KotlinJvmJsr223ScriptEngine4Idea(
+ Disposer.newDisposable(),
+ this,
+ listOf(PathUtil.getKotlinPathsForIdeaPlugin().runtimePath),
+ "kotlin.script.StandardScriptTemplate")
+
+ override fun getOutputStatement(toDisplay: String?): String = "print(\"$toDisplay\")"
+ override fun getMethodCallSyntax(obj: String, m: String, vararg args: String): String = "$obj.$m(${args.joinToString()})"
+
+ override fun getProgram(vararg statements: String): String {
+ val sep = System.getProperty("line.separator")
+ return statements.joinToString(sep) + sep
+ }
+
+ override fun getParameter(key: String?): Any? =
+ when (key) {
+ ScriptEngine.NAME -> engineName
+ ScriptEngine.LANGUAGE -> languageName
+ ScriptEngine.LANGUAGE_VERSION -> languageVersion
+ ScriptEngine.ENGINE -> engineName
+ ScriptEngine.ENGINE_VERSION -> engineVersion
+ else -> null
+ }
+}