~~~~ switch 191 ~~~~
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/MockExternalAnnotationsManager.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/MockExternalAnnotationsManager.kt
index a6d2a75..ebb3b44 100644
--- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/MockExternalAnnotationsManager.kt
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/MockExternalAnnotationsManager.kt
@@ -51,7 +51,11 @@
         throw UnsupportedOperationException("not implemented")
     }
 
-    override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean {
-        throw UnsupportedOperationException("not implemented")
-    }
+    override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean = false
+
+    override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass, annotationFQN: String): List<PsiAnnotation> = emptyList()
+
+    override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass): List<PsiAnnotation> = emptyList()
+
+    override fun findExternalAnnotations(listOwner: PsiModifierListOwner, annotationFQN: String): List<PsiAnnotation> = emptyList()
 }
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/MockExternalAnnotationsManager.kt.183 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/MockExternalAnnotationsManager.kt.183
new file mode 100644
index 0000000..a6d2a75
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/MockExternalAnnotationsManager.kt.183
@@ -0,0 +1,57 @@
+/*
+ * 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.cli.jvm.compiler
+
+import com.intellij.codeInsight.ExternalAnnotationsManager
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.psi.*
+
+class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
+    override fun chooseAnnotationsPlace(element: PsiElement): AnnotationPlace? = null
+
+    override fun isExternalAnnotationWritable(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean = false
+    override fun isExternalAnnotation(annotation: PsiAnnotation): Boolean = false
+
+    override fun findExternalAnnotationsFiles(listOwner: PsiModifierListOwner): List<PsiFile>? = null
+    override fun findExternalAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String): PsiAnnotation? = null
+    override fun findExternalAnnotations(listOwner: PsiModifierListOwner): Array<out PsiAnnotation>? = null
+
+    override fun annotateExternally(
+        listOwner: PsiModifierListOwner,
+        annotationFQName: String,
+        fromFile: PsiFile,
+        value: Array<out PsiNameValuePair>?
+    ) {
+        throw UnsupportedOperationException("not implemented")
+    }
+
+    override fun deannotate(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean {
+        throw UnsupportedOperationException("not implemented")
+    }
+
+    override fun editExternalAnnotation(
+        listOwner: PsiModifierListOwner,
+        annotationFQN: String,
+        value: Array<out PsiNameValuePair>?
+    ): Boolean {
+        throw UnsupportedOperationException("not implemented")
+    }
+
+    override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean {
+        throw UnsupportedOperationException("not implemented")
+    }
+}
diff --git a/compiler/compiler.pro b/compiler/compiler.pro
index 10a361d..01c7dce 100644
--- a/compiler/compiler.pro
+++ b/compiler/compiler.pro
@@ -16,6 +16,7 @@
 
 -dontnote **
 -dontwarn com.intellij.util.ui.IsRetina*
+-dontwarn com.intellij.util.ui.UIUtilities
 -dontwarn com.intellij.util.RetinaImage*
 -dontwarn apple.awt.*
 -dontwarn dk.brics.automaton.*
@@ -196,7 +197,6 @@
 -keep class org.jetbrains.org.objectweb.asm.tree.FieldNode { *; }
 -keep class org.jetbrains.org.objectweb.asm.tree.ParameterNode { *; }
 -keep class org.jetbrains.org.objectweb.asm.tree.TypeAnnotationNode { *; }
--keep class org.jetbrains.org.objectweb.asm.tree.InsnList { *; }
 
 -keep class org.jetbrains.org.objectweb.asm.signature.SignatureReader { *; }
 -keep class org.jetbrains.org.objectweb.asm.signature.SignatureVisitor { *; }
diff --git a/compiler/compiler.pro.183 b/compiler/compiler.pro.183
new file mode 100644
index 0000000..10a361d
--- /dev/null
+++ b/compiler/compiler.pro.183
@@ -0,0 +1,250 @@
+-injars '<kotlin-compiler-jar-before-shrink>'(
+!org/apache/log4j/jmx/Agent*,
+!org/apache/log4j/net/JMS*,
+!org/apache/log4j/net/SMTP*,
+!org/apache/log4j/or/jms/MessageRenderer*,
+!org/jdom/xpath/Jaxen*,
+!org/jline/builtins/ssh/**,
+!org/mozilla/javascript/xml/impl/xmlbeans/**,
+!net/sf/cglib/**,
+!META-INF/maven**,
+**.class,**.properties,**.kt,**.kotlin_*,**.jnilib,**.so,**.dll,**.txt,**.caps,
+META-INF/services/**,META-INF/native/**,META-INF/extensions/**,META-INF/MANIFEST.MF,
+messages/**)
+
+-outjars '<kotlin-compiler-jar>'
+
+-dontnote **
+-dontwarn com.intellij.util.ui.IsRetina*
+-dontwarn com.intellij.util.RetinaImage*
+-dontwarn apple.awt.*
+-dontwarn dk.brics.automaton.*
+-dontwarn org.fusesource.**
+-dontwarn org.imgscalr.Scalr**
+-dontwarn org.xerial.snappy.SnappyBundleActivator
+-dontwarn com.intellij.util.CompressionUtil
+-dontwarn com.intellij.util.SnappyInitializer
+-dontwarn com.intellij.util.SVGLoader
+-dontwarn com.intellij.util.SVGLoader$MyTranscoder
+-dontwarn net.sf.cglib.**
+-dontwarn org.objectweb.asm.** # this is ASM3, the old version that we do not use
+-dontwarn com.sun.jna.NativeString
+-dontwarn com.sun.jna.WString
+-dontwarn com.intellij.psi.util.PsiClassUtil
+-dontwarn org.apache.hadoop.io.compress.*
+-dontwarn com.google.j2objc.annotations.Weak
+-dontwarn org.iq80.snappy.HadoopSnappyCodec$SnappyCompressionInputStream
+-dontwarn org.iq80.snappy.HadoopSnappyCodec$SnappyCompressionOutputStream
+-dontwarn com.google.common.util.concurrent.*
+-dontwarn org.apache.xerces.dom.**
+-dontwarn org.apache.xerces.util.**
+-dontwarn org.w3c.dom.ElementTraversal
+-dontwarn javaslang.match.annotation.Unapply
+-dontwarn javaslang.match.annotation.Patterns
+-dontwarn javaslang.*
+-dontwarn com.google.errorprone.**
+-dontwarn com.google.j2objc.**
+-dontwarn javax.crypto.**
+-dontwarn java.lang.invoke.MethodHandle
+-dontwarn org.jline.builtins.Nano$Buffer
+-dontwarn org.jetbrains.annotations.ReadOnly
+-dontwarn org.jetbrains.annotations.Mutable
+-dontwarn com.intellij.util.io.TarUtil
+-dontwarn com.intellij.util.io.Compressor$Tar
+
+# Nullability annotations used in Guava
+-dontwarn org.checkerframework.checker.nullness.compatqual.NullableDecl
+-dontwarn org.checkerframework.checker.nullness.compatqual.MonotonicNonNullDecl
+-dontwarn org.checkerframework.checker.nullness.qual.Nullable
+-dontwarn org.checkerframework.checker.nullness.qual.MonotonicNonNull
+
+# Depends on apache batick which has lots of dependencies
+-dontwarn com.intellij.util.SVGLoader*
+-dontwarn org.apache.batik.script.rhino.RhinoInterpreter
+-dontwarn org.apache.batik.script.rhino.RhinoInterpreterFactory
+
+-dontwarn org.jdom.xpath.jaxen.*
+-dontwarn com.intellij.util.io.Decompressor*
+-dontwarn org.w3c.dom.Location
+-dontwarn org.w3c.dom.Window
+
+
+#-libraryjars '<rtjar>'
+#-libraryjars '<jssejar>'
+#-libraryjars '<bootstrap.runtime>'
+#-libraryjars '<bootstrap.reflect>'
+#-libraryjars '<bootstrap.script.runtime>'
+#-libraryjars '<tools.jar>'
+
+-dontoptimize
+-dontobfuscate
+
+-keep class org.fusesource.** { *; }
+-keep class com.sun.jna.** { *; }
+
+-keep class org.jetbrains.annotations.** {
+    public protected *;
+}
+
+-keep class javax.inject.** {
+    public protected *;
+}
+
+-keep class org.jetbrains.kotlin.** {
+    public protected *;
+}
+
+-keep class org.jetbrains.kotlin.compiler.plugin.** {
+    public protected *;
+}
+
+-keep class org.jetbrains.kotlin.extensions.** {
+    public protected *;
+}
+
+-keep class org.jetbrains.kotlin.protobuf.** {
+    public protected *;
+}
+
+-keep class org.jetbrains.kotlin.container.** { *; }
+
+-keep class org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt { *; }
+
+-keep class org.jetbrains.org.objectweb.asm.Opcodes { *; }
+
+-keep class org.jetbrains.kotlin.codegen.extensions.** {
+    public protected *;
+}
+
+-keepclassmembers class com.intellij.openapi.vfs.VirtualFile {
+    public protected *;
+}
+
+-keep class com.intellij.openapi.vfs.StandardFileSystems {
+    public static *;
+}
+
+# needed for jar cache cleanup in the gradle plugin and compile daemon
+-keepclassmembers class com.intellij.openapi.vfs.impl.ZipHandler {
+    public static void clearFileAccessorCache();
+}
+
+-keep class jet.** {
+    public protected *;
+}
+
+-keep class com.intellij.psi.** {
+    public protected *;
+}
+
+# This is needed so that the platform code which parses XML wouldn't fail, see KT-16968
+# This API is used from org.jdom.input.SAXBuilder via reflection.
+-keep class org.jdom.input.JAXPParserFactory { public ** createParser(...); }
+# Without this class PluginManagerCore.loadDescriptorFromJar fails
+-keep class org.jdom.output.XMLOutputter { *; }
+
+# for kdoc & dokka
+-keep class com.intellij.openapi.util.TextRange { *; }
+-keep class com.intellij.lang.impl.PsiBuilderImpl* {
+    public protected *;
+}
+-keep class com.intellij.openapi.util.text.StringHash { *; }
+
+# for j2k
+-keep class com.intellij.codeInsight.NullableNotNullManager { public protected *; }
+
+# for gradle (see KT-12549)
+-keep class com.intellij.lang.properties.charset.Native2AsciiCharsetProvider { *; }
+
+# for kotlin-build-common (consider repacking compiler together with kotlin-build-common and remove this part afterwards)
+-keep class com.intellij.util.io.IOUtil { public *; }
+-keep class com.intellij.openapi.util.io.FileUtil { public *; }
+-keep class com.intellij.util.SystemProperties { public *; }
+-keep class com.intellij.util.containers.hash.LinkedHashMap { *; }
+-keep class com.intellij.util.containers.ConcurrentIntObjectMap { *; }
+-keep class com.intellij.util.containers.ComparatorUtil { *; }
+-keep class com.intellij.util.io.PersistentHashMapValueStorage { *; }
+-keep class com.intellij.util.io.PersistentHashMap { *; }
+-keep class com.intellij.util.io.BooleanDataDescriptor { *; }
+-keep class com.intellij.util.io.EnumeratorStringDescriptor { *; }
+-keep class com.intellij.util.io.ExternalIntegerKeyDescriptor { *; }
+-keep class com.intellij.util.containers.hash.EqualityPolicy { *; }
+-keep class com.intellij.util.containers.hash.EqualityPolicy.* { *; }
+-keep class com.intellij.util.containers.Interner { *; }
+-keep class gnu.trove.TIntHashSet { *; }
+-keep class gnu.trove.TIntIterator { *; }
+-keep class org.iq80.snappy.SlowMemory { *; }
+-keep class javaslang.match.PatternsProcessor { *; }
+
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keepclassmembers class * {
+    ** toString();
+    ** hashCode();
+    void start();
+    void stop();
+    void dispose();
+}
+
+-keep class org.jetbrains.org.objectweb.asm.tree.AnnotationNode { *; }
+-keep class org.jetbrains.org.objectweb.asm.tree.ClassNode { *; }
+-keep class org.jetbrains.org.objectweb.asm.tree.LocalVariableNode { *; }
+-keep class org.jetbrains.org.objectweb.asm.tree.MethodNode { *; }
+-keep class org.jetbrains.org.objectweb.asm.tree.FieldNode { *; }
+-keep class org.jetbrains.org.objectweb.asm.tree.ParameterNode { *; }
+-keep class org.jetbrains.org.objectweb.asm.tree.TypeAnnotationNode { *; }
+-keep class org.jetbrains.org.objectweb.asm.tree.InsnList { *; }
+
+-keep class org.jetbrains.org.objectweb.asm.signature.SignatureReader { *; }
+-keep class org.jetbrains.org.objectweb.asm.signature.SignatureVisitor { *; }
+
+-keep class org.jetbrains.org.objectweb.asm.Type {
+    public protected *;
+}
+
+-keepclassmembers class org.jetbrains.org.objectweb.asm.ClassReader {
+    *** SKIP_CODE;
+    *** SKIP_DEBUG;
+    *** SKIP_FRAMES;
+}
+
+-keepclassmembers class com.intellij.openapi.project.Project {
+    ** getBasePath();
+}
+
+# for kotlin-android-extensions in maven
+-keep class com.intellij.openapi.module.ModuleServiceManager { public *; }
+
+# for building kotlin-build-common-test
+-keep class org.jetbrains.kotlin.build.SerializationUtilsKt { *; }
+
+# for tools.jar
+-keep class com.sun.tools.javac.** { *; }
+-keep class com.sun.source.** { *; }
+
+# for coroutines
+-keep class kotlinx.coroutines.** { *; }
+
+# for webdemo
+-keep class com.intellij.openapi.progress.ProgressManager { *; }
+
+# for kapt
+-keep class com.intellij.openapi.project.Project { *; }
+-keepclassmembers class com.intellij.util.PathUtil {
+    public static java.lang.String getJarPathForClass(java.lang.Class);
+}
+
+-keepclassmembers class com.intellij.util.PathUtil {
+    public static java.lang.String getJarPathForClass(java.lang.Class);
+}
+
+# remove when KT-18563 would be fixed
+-keep class org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt { *; }
+
+-keep class net.jpountz.lz4.* { *; }
+
+# used in LazyScriptDescriptor
+-keep class org.jetbrains.kotlin.utils.addToStdlib.AddToStdlibKt { *; }
diff --git a/gradle/versions.properties b/gradle/versions.properties
index fd0f144..12bd112 100644
--- a/gradle/versions.properties
+++ b/gradle/versions.properties
@@ -1,6 +1,7 @@
-versions.intellijSdk=183.5153.4
+versions.intellijSdk=191-SNAPSHOT
 versions.androidBuildTools=r23.0.1
 versions.idea.NodeJS=181.3494.12
+versions.jar.asm-all=7.0
 versions.jar.guava=25.1-jre
 versions.jar.groovy-all=2.4.15
 versions.jar.lombok-ast=0.2.3
@@ -10,6 +11,5 @@
 versions.jar.gson=2.8.5
 versions.jar.oro=2.0.8
 versions.jar.picocontainer=1.2
-versions.jar.asm-all=7.0
 ignore.jar.snappy-in-java=true
 versions.gradle-api=4.5.1
diff --git a/gradle/versions.properties.183 b/gradle/versions.properties.183
new file mode 100644
index 0000000..fd0f144
--- /dev/null
+++ b/gradle/versions.properties.183
@@ -0,0 +1,15 @@
+versions.intellijSdk=183.5153.4
+versions.androidBuildTools=r23.0.1
+versions.idea.NodeJS=181.3494.12
+versions.jar.guava=25.1-jre
+versions.jar.groovy-all=2.4.15
+versions.jar.lombok-ast=0.2.3
+versions.jar.swingx-core=1.6.2-2
+versions.jar.kxml2=2.3.0
+versions.jar.streamex=0.6.7
+versions.jar.gson=2.8.5
+versions.jar.oro=2.0.8
+versions.jar.picocontainer=1.2
+versions.jar.asm-all=7.0
+ignore.jar.snappy-in-java=true
+versions.gradle-api=4.5.1
diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt
index b9172990..09884bf 100644
--- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt
+++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt
@@ -11,17 +11,14 @@
 import org.jetbrains.jps.model.java.JpsJavaExtensionService
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType
 
-sealed class KotlinResourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaResourceRootProperties>(),
-    JpsModuleSourceRootType<JavaResourceRootProperties>, KotlinRootType {
-    object Resource : KotlinResourceRootType(false)
-    object TestResource : KotlinResourceRootType(true)
+sealed class KotlinResourceRootType() : JpsElementTypeBase<JavaResourceRootProperties>(),
+    JpsModuleSourceRootType<JavaResourceRootProperties> {
+    object Resource : KotlinResourceRootType()
+
+    object TestResource : KotlinResourceRootType() {
+        override fun isForTests() = true
+    }
 
     override fun createDefaultProperties() =
         JpsJavaExtensionService.getInstance().createResourceRootProperties("", false)
-
-    override fun isTestRoot() = isTest
-
-    override fun isForTests() = isTest
-
-    override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
 }
\ No newline at end of file
diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt.183 b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt.183
new file mode 100644
index 0000000..b9172990
--- /dev/null
+++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinResourceRootType.kt.183
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2018 JetBrains s.r.o. 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.config
+
+import org.jetbrains.jps.model.ex.JpsElementTypeBase
+import org.jetbrains.jps.model.java.JavaResourceRootProperties
+import org.jetbrains.jps.model.java.JavaResourceRootType
+import org.jetbrains.jps.model.java.JpsJavaExtensionService
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType
+
+sealed class KotlinResourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaResourceRootProperties>(),
+    JpsModuleSourceRootType<JavaResourceRootProperties>, KotlinRootType {
+    object Resource : KotlinResourceRootType(false)
+    object TestResource : KotlinResourceRootType(true)
+
+    override fun createDefaultProperties() =
+        JpsJavaExtensionService.getInstance().createResourceRootProperties("", false)
+
+    override fun isTestRoot() = isTest
+
+    override fun isForTests() = isTest
+
+    override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
+}
\ No newline at end of file
diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinRootType.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinRootType.kt.183
similarity index 100%
rename from idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinRootType.kt
rename to idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinRootType.kt.183
diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt
index 8b5b3d9..551c8d2 100644
--- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt
+++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt
@@ -11,20 +11,17 @@
 import org.jetbrains.jps.model.java.JpsJavaExtensionService
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType
 
-sealed class KotlinSourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties>, KotlinRootType {
-    object Source : KotlinSourceRootType(false)
-    object TestSource : KotlinSourceRootType(true)
+sealed class KotlinSourceRootType() : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties> {
+    object Source : KotlinSourceRootType()
+
+    object TestSource : KotlinSourceRootType() {
+        override fun isForTests() = true
+    }
 
     override fun createDefaultProperties() = JpsJavaExtensionService.getInstance().createSourceRootProperties("")
 
     companion object {
         val ALL_SOURCES = setOf(Source, TestSource)
     }
-
-    override fun isTestRoot() = isTest
-
-    override fun isForTests() = isTest
-
-    override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
 }
 
diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt.183 b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt.183
new file mode 100644
index 0000000..8b5b3d9
--- /dev/null
+++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinSourceRootType.kt.183
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2018 JetBrains s.r.o. 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.config
+
+import org.jetbrains.jps.model.ex.JpsElementTypeBase
+import org.jetbrains.jps.model.java.JavaSourceRootProperties
+import org.jetbrains.jps.model.java.JavaSourceRootType
+import org.jetbrains.jps.model.java.JpsJavaExtensionService
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType
+
+sealed class KotlinSourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties>, KotlinRootType {
+    object Source : KotlinSourceRootType(false)
+    object TestSource : KotlinSourceRootType(true)
+
+    override fun createDefaultProperties() = JpsJavaExtensionService.getInstance().createSourceRootProperties("")
+
+    companion object {
+        val ALL_SOURCES = setOf(Source, TestSource)
+    }
+
+    override fun isTestRoot() = isTest
+
+    override fun isForTests() = isTest
+
+    override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
+}
+
diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt
index e60bc8b..c4f6f68 100644
--- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt
+++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt
@@ -25,10 +25,10 @@
 import com.intellij.openapi.roots.*
 import com.intellij.openapi.roots.impl.libraries.LibraryEx
 import com.intellij.openapi.roots.libraries.Library
-import com.intellij.openapi.util.AsyncResult
 import com.intellij.util.PathUtil
 import org.jdom.Element
 import org.jdom.Text
+import org.jetbrains.concurrency.AsyncPromise
 import org.jetbrains.idea.maven.importing.MavenImporter
 import org.jetbrains.idea.maven.importing.MavenRootModelAdapter
 import org.jetbrains.idea.maven.model.MavenPlugin
@@ -140,7 +140,7 @@
 
         if (toBeDownloaded.isNotEmpty()) {
             MavenProjectsManager.getInstance(module.project)
-                .scheduleArtifactsDownloading(listOf(mavenProject), toBeDownloaded, true, false, AsyncResult())
+                .scheduleArtifactsDownloading(listOf(mavenProject), toBeDownloaded, true, false, AsyncPromise())
         }
     }
 
diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.183 b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.183
new file mode 100644
index 0000000..e60bc8b
--- /dev/null
+++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.183
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2010-2017 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.idea.maven
+
+import com.intellij.openapi.components.PersistentStateComponent
+import com.intellij.openapi.components.State
+import com.intellij.openapi.components.Storage
+import com.intellij.openapi.components.StoragePathMacros
+import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.roots.*
+import com.intellij.openapi.roots.impl.libraries.LibraryEx
+import com.intellij.openapi.roots.libraries.Library
+import com.intellij.openapi.util.AsyncResult
+import com.intellij.util.PathUtil
+import org.jdom.Element
+import org.jdom.Text
+import org.jetbrains.idea.maven.importing.MavenImporter
+import org.jetbrains.idea.maven.importing.MavenRootModelAdapter
+import org.jetbrains.idea.maven.model.MavenPlugin
+import org.jetbrains.idea.maven.project.*
+import org.jetbrains.jps.model.java.JavaSourceRootType
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType
+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
+import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
+import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
+import org.jetbrains.kotlin.config.*
+import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
+import org.jetbrains.kotlin.idea.facet.*
+import org.jetbrains.kotlin.idea.framework.detectLibraryKind
+import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator
+import org.jetbrains.kotlin.idea.platform.tooling
+import org.jetbrains.kotlin.platform.IdePlatform
+import org.jetbrains.kotlin.platform.IdePlatformKind
+import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.isCommon
+import org.jetbrains.kotlin.utils.SmartList
+import org.jetbrains.kotlin.utils.addIfNotNull
+import java.io.File
+import java.util.*
+
+interface MavenProjectImportHandler {
+    companion object : ProjectExtensionDescriptor<MavenProjectImportHandler>(
+        "org.jetbrains.kotlin.mavenProjectImportHandler",
+        MavenProjectImportHandler::class.java
+    )
+
+    operator fun invoke(facet: KotlinFacet, mavenProject: MavenProject)
+}
+
+class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID) {
+    companion object {
+        const val KOTLIN_PLUGIN_GROUP_ID = "org.jetbrains.kotlin"
+        const val KOTLIN_PLUGIN_ARTIFACT_ID = "kotlin-maven-plugin"
+
+        const val KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG = "sourceDirs"
+    }
+
+    override fun preProcess(
+        module: Module,
+        mavenProject: MavenProject,
+        changes: MavenProjectChanges,
+        modifiableModelsProvider: IdeModifiableModelsProvider
+    ) {
+    }
+
+    override fun process(
+        modifiableModelsProvider: IdeModifiableModelsProvider,
+        module: Module,
+        rootModel: MavenRootModelAdapter,
+        mavenModel: MavenProjectsTree,
+        mavenProject: MavenProject,
+        changes: MavenProjectChanges,
+        mavenProjectToModuleName: MutableMap<MavenProject, String>,
+        postTasks: MutableList<MavenProjectsProcessorTask>
+    ) {
+
+        if (changes.plugins) {
+            contributeSourceDirectories(mavenProject, module, rootModel)
+        }
+    }
+
+    override fun postProcess(
+        module: Module,
+        mavenProject: MavenProject,
+        changes: MavenProjectChanges,
+        modifiableModelsProvider: IdeModifiableModelsProvider
+    ) {
+        super.postProcess(module, mavenProject, changes, modifiableModelsProvider)
+
+        if (changes.dependencies) {
+            scheduleDownloadStdlibSources(mavenProject, module)
+
+            val targetLibraryKind = detectPlatformByExecutions(mavenProject)?.tooling?.libraryKind
+            if (targetLibraryKind != null) {
+                modifiableModelsProvider.getModifiableRootModel(module).orderEntries().forEachLibrary { library ->
+                    if ((library as LibraryEx).kind == null) {
+                        val model = modifiableModelsProvider.getModifiableLibraryModel(library) as LibraryEx.ModifiableModelEx
+                        detectLibraryKind(model.getFiles(OrderRootType.CLASSES))?.let { model.kind = it }
+                    }
+                    true
+                }
+            }
+        }
+
+        configureFacet(mavenProject, modifiableModelsProvider, module)
+    }
+
+    private fun scheduleDownloadStdlibSources(mavenProject: MavenProject, module: Module) {
+        // TODO: here we have to process all kotlin libraries but for now we only handle standard libraries
+        val artifacts = mavenProject.dependencyArtifactIndex.data[KOTLIN_PLUGIN_GROUP_ID]?.values?.flatMap { it.filter { it.isResolved } }
+                ?: emptyList()
+
+        val librariesWithNoSources = ArrayList<Library>()
+        OrderEnumerator.orderEntries(module).forEachLibrary { library ->
+            if (library.modifiableModel.getFiles(OrderRootType.SOURCES).isEmpty()) {
+                librariesWithNoSources.add(library)
+            }
+            true
+        }
+        val libraryNames = librariesWithNoSources.mapTo(HashSet()) { it.name }
+        val toBeDownloaded = artifacts.filter { it.libraryName in libraryNames }
+
+        if (toBeDownloaded.isNotEmpty()) {
+            MavenProjectsManager.getInstance(module.project)
+                .scheduleArtifactsDownloading(listOf(mavenProject), toBeDownloaded, true, false, AsyncResult())
+        }
+    }
+
+    private fun configureJSOutputPaths(
+        mavenProject: MavenProject,
+        modifiableRootModel: ModifiableRootModel,
+        facetSettings: KotlinFacetSettings,
+        mavenPlugin: MavenPlugin
+    ) {
+        fun parentPath(path: String): String =
+            File(path).absoluteFile.parentFile.absolutePath
+
+        val sharedOutputFile = mavenPlugin.configurationElement?.getChild("outputFile")?.text
+
+        val compilerModuleExtension = modifiableRootModel.getModuleExtension(CompilerModuleExtension::class.java) ?: return
+        val buildDirectory = mavenProject.buildDirectory
+
+        val executions = mavenPlugin.executions
+
+        executions.forEach {
+            val explicitOutputFile = it.configurationElement?.getChild("outputFile")?.text ?: sharedOutputFile
+            if (PomFile.KotlinGoals.Js in it.goals) {
+                // see org.jetbrains.kotlin.maven.K2JSCompilerMojo
+                val outputFilePath = PathUtil.toSystemDependentName(explicitOutputFile ?: "$buildDirectory/js/${mavenProject.mavenId.artifactId}.js")
+                compilerModuleExtension.setCompilerOutputPath(parentPath(outputFilePath))
+                facetSettings.productionOutputPath = outputFilePath
+            }
+            if (PomFile.KotlinGoals.TestJs in it.goals) {
+                // see org.jetbrains.kotlin.maven.KotlinTestJSCompilerMojo
+                val outputFilePath = PathUtil.toSystemDependentName(explicitOutputFile ?: "$buildDirectory/test-js/${mavenProject.mavenId.artifactId}-tests.js")
+                compilerModuleExtension.setCompilerOutputPathForTests(parentPath(outputFilePath))
+                facetSettings.testOutputPath = outputFilePath
+            }
+        }
+    }
+
+    private fun getCompilerArgumentsByConfigurationElement(
+        mavenProject: MavenProject,
+        configuration: Element?,
+        platform: IdePlatform<*, *>
+    ): List<String> {
+        val arguments = platform.createArguments()
+
+        arguments.apiVersion = configuration?.getChild("apiVersion")?.text ?:
+                mavenProject.properties["kotlin.compiler.apiVersion"]?.toString()
+        arguments.languageVersion = configuration?.getChild("languageVersion")?.text ?:
+                mavenProject.properties["kotlin.compiler.languageVersion"]?.toString()
+        arguments.multiPlatform = configuration?.getChild("multiPlatform")?.text?.trim()?.toBoolean() ?: false
+        arguments.suppressWarnings = configuration?.getChild("nowarn")?.text?.trim()?.toBoolean() ?: false
+
+        configuration?.getChild("experimentalCoroutines")?.text?.trim()?.let {
+            arguments.coroutinesState = it
+        }
+
+        when (arguments) {
+            is K2JVMCompilerArguments -> {
+                arguments.classpath = configuration?.getChild("classpath")?.text
+                arguments.jdkHome = configuration?.getChild("jdkHome")?.text
+                arguments.jvmTarget = configuration?.getChild("jvmTarget")?.text ?:
+                        mavenProject.properties["kotlin.compiler.jvmTarget"]?.toString()
+                arguments.javaParameters = configuration?.getChild("javaParameters")?.text?.toBoolean() ?: false
+            }
+            is K2JSCompilerArguments -> {
+                arguments.sourceMap = configuration?.getChild("sourceMap")?.text?.trim()?.toBoolean() ?: false
+                arguments.sourceMapPrefix = configuration?.getChild("sourceMapPrefix")?.text?.trim() ?: ""
+                arguments.sourceMapEmbedSources = configuration?.getChild("sourceMapEmbedSources")?.text?.trim() ?: "inlining"
+                arguments.outputFile = configuration?.getChild("outputFile")?.text
+                arguments.metaInfo = configuration?.getChild("metaInfo")?.text?.trim()?.toBoolean() ?: false
+                arguments.moduleKind = configuration?.getChild("moduleKind")?.text
+                arguments.main = configuration?.getChild("main")?.text
+            }
+        }
+
+        val additionalArgs = SmartList<String>().apply {
+            val argsElement = configuration?.getChild("args")
+
+            argsElement?.content?.forEach { argElement ->
+                when (argElement) {
+                    is Text -> {
+                        argElement.text?.let { addAll(splitArgumentString(it)) }
+                    }
+                    is Element -> {
+                        if (argElement.name == "arg") {
+                            addIfNotNull(argElement.text)
+                        }
+                    }
+                }
+            }
+        }
+        parseCommandLineArguments(additionalArgs, arguments)
+
+        return ArgumentUtils.convertArgumentsToStringList(arguments)
+    }
+
+    private val compilationGoals = listOf(
+        PomFile.KotlinGoals.Compile,
+        PomFile.KotlinGoals.TestCompile,
+        PomFile.KotlinGoals.Js,
+        PomFile.KotlinGoals.TestJs,
+        PomFile.KotlinGoals.MetaData
+    )
+
+    private fun configureFacet(mavenProject: MavenProject, modifiableModelsProvider: IdeModifiableModelsProvider, module: Module) {
+        val mavenPlugin = mavenProject.findPlugin(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID) ?: return
+        val compilerVersion = mavenPlugin.version ?: LanguageVersion.LATEST_STABLE.versionString
+        val kotlinFacet = module.getOrCreateFacet(
+            modifiableModelsProvider,
+            false,
+            ExternalProjectSystemRegistry.MAVEN_EXTERNAL_SOURCE_ID
+        )
+
+        // TODO There should be a way to figure out the correct platform version
+        val platform = detectPlatform(mavenProject)?.defaultPlatform
+
+        kotlinFacet.configureFacet(compilerVersion, LanguageFeature.Coroutines.defaultState, platform, modifiableModelsProvider)
+        val facetSettings = kotlinFacet.configuration.settings
+        val configuredPlatform = kotlinFacet.configuration.settings.platform!!
+        val configuration = mavenPlugin.configurationElement
+        val sharedArguments = getCompilerArgumentsByConfigurationElement(mavenProject, configuration, configuredPlatform)
+        val executionArguments = mavenPlugin.executions
+            ?.firstOrNull { it.goals.any { it in compilationGoals } }
+            ?.configurationElement?.let { getCompilerArgumentsByConfigurationElement(mavenProject, it, configuredPlatform) }
+        parseCompilerArgumentsToFacet(sharedArguments, emptyList(), kotlinFacet, modifiableModelsProvider)
+        if (executionArguments != null) {
+            parseCompilerArgumentsToFacet(executionArguments, emptyList(), kotlinFacet, modifiableModelsProvider)
+        }
+        if (facetSettings.compilerArguments is K2JSCompilerArguments) {
+            configureJSOutputPaths(mavenProject, modifiableModelsProvider.getModifiableRootModel(module), facetSettings, mavenPlugin)
+        }
+        MavenProjectImportHandler.getInstances(module.project).forEach { it(kotlinFacet, mavenProject) }
+        setImplementedModuleName(kotlinFacet, mavenProject, module)
+        kotlinFacet.noVersionAutoAdvance()
+    }
+
+    private fun detectPlatform(mavenProject: MavenProject) =
+        detectPlatformByExecutions(mavenProject) ?: detectPlatformByLibraries(mavenProject)
+
+    private fun detectPlatformByExecutions(mavenProject: MavenProject): IdePlatformKind<*>? {
+        return mavenProject.findPlugin(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID)?.executions?.flatMap { it.goals }
+            ?.mapNotNull { goal ->
+                when (goal) {
+                    PomFile.KotlinGoals.Compile, PomFile.KotlinGoals.TestCompile -> JvmIdePlatformKind
+                    PomFile.KotlinGoals.Js, PomFile.KotlinGoals.TestJs -> JsIdePlatformKind
+                    PomFile.KotlinGoals.MetaData -> CommonIdePlatformKind
+                    else -> null
+                }
+            }?.distinct()?.singleOrNull()
+    }
+
+    private fun detectPlatformByLibraries(mavenProject: MavenProject): IdePlatformKind<*>? {
+        for (kind in IdePlatformKind.ALL_KINDS) {
+            val mavenLibraryIds = kind.tooling.mavenLibraryIds
+            if (mavenLibraryIds.any { mavenProject.findDependencies(KOTLIN_PLUGIN_GROUP_ID, it).isNotEmpty() }) {
+                // TODO we could return here the correct version
+                return kind
+            }
+        }
+
+        return null
+    }
+
+    // TODO in theory it should work like this but it doesn't as it couldn't unmark source roots that are not roots anymore.
+    //     I believe this is something should be done by the underlying maven importer implementation or somewhere else in the IDEA
+    //     For now there is a contributeSourceDirectories implementation that deals with the issue
+    //        see https://youtrack.jetbrains.com/issue/IDEA-148280
+
+    //    override fun collectSourceRoots(mavenProject: MavenProject, result: PairConsumer<String, JpsModuleSourceRootType<*>>) {
+    //        for ((type, dir) in collectSourceDirectories(mavenProject)) {
+    //            val jpsType: JpsModuleSourceRootType<*> = when (type) {
+    //                SourceType.PROD -> JavaSourceRootType.SOURCE
+    //                SourceType.TEST -> JavaSourceRootType.TEST_SOURCE
+    //            }
+    //
+    //            result.consume(dir, jpsType)
+    //        }
+    //    }
+
+    private fun contributeSourceDirectories(mavenProject: MavenProject, module: Module, rootModel: MavenRootModelAdapter) {
+        val directories = collectSourceDirectories(mavenProject)
+
+        val toBeAdded = directories.map { it.second }.toSet()
+        val state = module.kotlinImporterComponent
+
+        val isNonJvmModule = mavenProject
+            .plugins
+            .asSequence()
+            .filter { it.isKotlinPlugin() }
+            .flatMap { it.executions.asSequence() }
+            .flatMap { it.goals.asSequence() }
+            .any { it in PomFile.KotlinGoals.CompileGoals && it !in PomFile.KotlinGoals.JvmGoals }
+
+        val prodSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.Source else JavaSourceRootType.SOURCE
+        val testSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.TestSource else JavaSourceRootType.TEST_SOURCE
+
+        for ((type, dir) in directories) {
+            if (rootModel.getSourceFolder(File(dir)) == null) {
+                val jpsType: JpsModuleSourceRootType<*> = when (type) {
+                    SourceType.TEST -> testSourceRootType
+                    SourceType.PROD -> prodSourceRootType
+                }
+
+                rootModel.addSourceFolder(dir, jpsType)
+            }
+        }
+
+        if (isNonJvmModule) {
+            mavenProject.sources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.Source) }
+            mavenProject.testSources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.TestSource) }
+            mavenProject.resources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.Resource) }
+            mavenProject.testResources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.TestResource) }
+        }
+
+        state.addedSources.filter { it !in toBeAdded }.forEach {
+            rootModel.unregisterAll(it, true, true)
+            state.addedSources.remove(it)
+        }
+        state.addedSources.addAll(toBeAdded)
+    }
+
+    private fun collectSourceDirectories(mavenProject: MavenProject): List<Pair<SourceType, String>> =
+        mavenProject.plugins.filter { it.isKotlinPlugin() }.flatMap { plugin ->
+            plugin.configurationElement.sourceDirectories().map { SourceType.PROD to it } +
+                    plugin.executions.flatMap { execution ->
+                        execution.configurationElement.sourceDirectories().map { execution.sourceType() to it }
+                    }
+        }.distinct()
+
+    private fun setImplementedModuleName(kotlinFacet: KotlinFacet, mavenProject: MavenProject, module: Module) {
+        if (kotlinFacet.configuration.settings.platform.isCommon) {
+            kotlinFacet.configuration.settings.implementedModuleNames = emptyList()
+        } else {
+            val manager = MavenProjectsManager.getInstance(module.project)
+            val mavenDependencies = mavenProject.dependencies.mapNotNull { manager?.findProject(it) }
+            val implemented = mavenDependencies.filter { detectPlatformByExecutions(it).isCommon }
+
+            kotlinFacet.configuration.settings.implementedModuleNames = implemented.map { manager.findModule(it)?.name ?: it.displayName }
+        }
+    }
+}
+
+private fun MavenPlugin.isKotlinPlugin() =
+    groupId == KotlinMavenImporter.KOTLIN_PLUGIN_GROUP_ID && artifactId == KotlinMavenImporter.KOTLIN_PLUGIN_ARTIFACT_ID
+
+private fun Element?.sourceDirectories(): List<String> =
+    this?.getChildren(KotlinMavenImporter.KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG)?.flatMap { it.children ?: emptyList() }?.map { it.textTrim }
+            ?: emptyList()
+
+private fun MavenPlugin.Execution.sourceType() =
+    goals.map { if (isTestGoalName(it)) SourceType.TEST else SourceType.PROD }
+        .distinct()
+        .singleOrNull() ?: SourceType.PROD
+
+private fun isTestGoalName(goalName: String) = goalName.startsWith("test-")
+
+private enum class SourceType {
+    PROD, TEST
+}
+
+@State(
+    name = "AutoImportedSourceRoots",
+    storages = [(Storage(file = StoragePathMacros.MODULE_FILE))]
+)
+class KotlinImporterComponent : PersistentStateComponent<KotlinImporterComponent.State> {
+    class State(var directories: List<String> = ArrayList())
+
+    val addedSources: MutableSet<String> = Collections.synchronizedSet(HashSet<String>())
+
+    override fun loadState(state: State) {
+        addedSources.clear()
+        addedSources.addAll(state.directories)
+    }
+
+    override fun getState(): State {
+        return State(addedSources.sorted())
+    }
+}
+
+private val Module.kotlinImporterComponent: KotlinImporterComponent
+    get() = getComponent(KotlinImporterComponent::class.java) ?: throw IllegalStateException("No maven importer state configured")
diff --git a/idea/resources/META-INF/plugin.xml b/idea/resources/META-INF/plugin.xml
index 905aec9..79d4368 100644
--- a/idea/resources/META-INF/plugin.xml
+++ b/idea/resources/META-INF/plugin.xml
@@ -13,7 +13,7 @@
   <version>@snapshot@</version>
   <vendor url="http://www.jetbrains.com">JetBrains</vendor>
 
-  <idea-version since-build="183.1" until-build="183.*"/>
+  <idea-version since-build="191.2767" until-build="191.*"/>
 
   <depends>com.intellij.modules.platform</depends>
 
diff --git a/idea/resources/META-INF/plugin.xml.183 b/idea/resources/META-INF/plugin.xml.183
new file mode 100644
index 0000000..905aec9
--- /dev/null
+++ b/idea/resources/META-INF/plugin.xml.183
@@ -0,0 +1,74 @@
+<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude" version="2" url="http://kotlinlang.org" allow-bundled-update="true">
+  <id>org.jetbrains.kotlin</id>
+
+  <name>Kotlin</name>
+  <description><![CDATA[
+The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
+<br>
+<a href="http://kotlinlang.org/docs/tutorials/getting-started.html">Getting Started in IntelliJ IDEA</a><br>
+<a href="http://kotlinlang.org/docs/tutorials/kotlin-android.html">Getting Started in Android Studio</a><br>
+<a href="http://slack.kotlinlang.org/">Public Slack</a><br>
+<a href="https://youtrack.jetbrains.com/issues/KT">Issue tracker</a><br>
+]]></description>
+  <version>@snapshot@</version>
+  <vendor url="http://www.jetbrains.com">JetBrains</vendor>
+
+  <idea-version since-build="183.1" until-build="183.*"/>
+
+  <depends>com.intellij.modules.platform</depends>
+
+  <!-- required for Kotlin/Native plugin -->
+  <depends optional="true">org.jetbrains.kotlin.native.platform.deps</depends>
+
+  <depends optional="true" config-file="junit.xml">JUnit</depends>
+  <depends optional="true" config-file="gradle.xml">org.jetbrains.plugins.gradle</depends>
+  <depends optional="true" config-file="gradle-java.xml">org.jetbrains.plugins.gradle.java</depends>
+  <depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
+  <depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
+  <depends optional="true" config-file="android.xml">org.jetbrains.android</depends>
+  <depends optional="true" config-file="coverage.xml">Coverage</depends>
+  <depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
+  <depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
+  <depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
+  <depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
+
+  <!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
+
+  <!-- CIDR-PLUGIN-PLACEHOLDER-START -->
+  <depends>com.intellij.modules.idea</depends>
+  <depends>com.intellij.modules.java</depends>
+  <depends optional="true" config-file="javaScriptDebug.xml">JavaScriptDebugger</depends>
+  <depends optional="true" config-file="kotlin-copyright.xml">com.intellij.copyright</depends>
+  <depends optional="true" config-file="injection.xml">org.intellij.intelliLang</depends>
+  <!-- CIDR-PLUGIN-PLACEHOLDER-END -->
+
+  <xi:include href="plugin-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
+
+  <!-- CIDR-PLUGIN-EXCLUDE-START -->
+  <xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
+  <!-- CIDR-PLUGIN-EXCLUDE-END -->
+
+  <xi:include href="native.xml" xpointer="xpointer(/idea-plugin/*)"/>
+  <xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
+
+  <xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
+
+  <xi:include href="kotlinx-serialization.xml" xpointer="xpointer(/idea-plugin/*)"/>
+
+  <extensionPoints>
+    <xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
+
+    <extensionPoint qualifiedName="org.jetbrains.kotlin.pluginUpdateVerifier"
+                    interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/>
+  </extensionPoints>
+
+  <xi:include href="plugin-kotlin-extensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
+
+  <extensions defaultExtensionNs="com.intellij.jvm">
+    <declarationSearcher language="kotlin" implementationClass="org.jetbrains.kotlin.idea.jvm.KotlinDeclarationSearcher"/>
+  </extensions>
+
+  <extensions defaultExtensionNs="com.intellij.codeInsight">
+      <nonBlockingContextChecker implementation="org.jetbrains.kotlin.idea.inspections.blockingCallsDetection.CoroutineNonBlockingContextChecker"/>
+    </extensions>
+</idea-plugin>
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt
index 8786660..00ea1bd 100644
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt
@@ -203,8 +203,8 @@
         fun collectUsages(kotlinToLightElements: Map<KtNamedDeclaration, List<PsiNamedElement>>, result: MutableCollection<UsageInfo>) {
             kotlinToLightElements.values.flatten().flatMapTo(result) { lightElement ->
                 val searchScope = getSearchScope(lightElement) ?: return@flatMapTo emptyList()
-
-                val newFqName = StringUtil.getQualifiedName(newContainerName, lightElement.name)
+                val elementName = lightElement.name ?: return@flatMapTo emptyList()
+                val newFqName = StringUtil.getQualifiedName(newContainerName, elementName)
 
                 val foundReferences = HashSet<PsiReference>()
                 val results = ReferencesSearch
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt.183 b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt.183
new file mode 100644
index 0000000..8786660
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt.183
@@ -0,0 +1,373 @@
+/*
+ * 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.idea.refactoring.move.moveDeclarations
+
+import com.intellij.ide.highlighter.JavaFileType
+import com.intellij.ide.util.EditorHelper
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.Ref
+import com.intellij.openapi.util.text.StringUtil
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiNamedElement
+import com.intellij.psi.PsiReference
+import com.intellij.psi.search.GlobalSearchScope
+import com.intellij.psi.search.searches.ReferencesSearch
+import com.intellij.refactoring.BaseRefactoringProcessor
+import com.intellij.refactoring.move.MoveCallback
+import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor
+import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler
+import com.intellij.refactoring.rename.RenameUtil
+import com.intellij.refactoring.util.NonCodeUsageInfo
+import com.intellij.refactoring.util.RefactoringUIUtil
+import com.intellij.refactoring.util.TextOccurrencesUtil
+import com.intellij.usageView.UsageInfo
+import com.intellij.usageView.UsageViewBundle
+import com.intellij.usageView.UsageViewDescriptor
+import com.intellij.usageView.UsageViewUtil
+import com.intellij.util.IncorrectOperationException
+import com.intellij.util.containers.MultiMap
+import gnu.trove.THashMap
+import gnu.trove.TObjectHashingStrategy
+import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
+import org.jetbrains.kotlin.asJava.findFacadeClass
+import org.jetbrains.kotlin.asJava.namedUnwrappedElement
+import org.jetbrains.kotlin.asJava.toLightElements
+import org.jetbrains.kotlin.idea.codeInsight.shorten.addToBeShortenedDescendantsToWaitingSet
+import org.jetbrains.kotlin.idea.core.deleteSingle
+import org.jetbrains.kotlin.idea.core.quoteIfNeeded
+import org.jetbrains.kotlin.idea.refactoring.broadcastRefactoringExit
+import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
+import org.jetbrains.kotlin.idea.refactoring.move.*
+import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinClassHandler
+import org.jetbrains.kotlin.idea.search.projectScope
+import org.jetbrains.kotlin.idea.search.restrictByFileType
+import org.jetbrains.kotlin.idea.util.projectStructure.module
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
+import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
+import org.jetbrains.kotlin.psi.psiUtil.isAncestor
+import org.jetbrains.kotlin.utils.ifEmpty
+import org.jetbrains.kotlin.utils.keysToMap
+import java.lang.AssertionError
+import java.util.*
+
+interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration {
+    object Default : Mover {
+        override fun invoke(originalElement: KtNamedDeclaration, targetContainer: KtElement): KtNamedDeclaration {
+            return when (targetContainer) {
+                is KtFile -> {
+                    val declarationContainer: KtElement =
+                        if (targetContainer.isScript()) targetContainer.script!!.blockExpression else targetContainer
+                    declarationContainer.add(originalElement) as KtNamedDeclaration
+                }
+                is KtClassOrObject -> targetContainer.addDeclaration(originalElement)
+                else -> error("Unexpected element: ${targetContainer.getElementTextWithContext()}")
+            }.apply {
+                val container = originalElement.containingClassOrObject
+                if (container is KtObjectDeclaration && container.isCompanion() && container.declarations.singleOrNull() == originalElement) {
+                    container.deleteSingle()
+                }
+                else {
+                    originalElement.deleteSingle()
+                }
+            }
+        }
+    }
+}
+
+sealed class MoveSource {
+    abstract val elementsToMove: Collection<KtNamedDeclaration>
+
+    class Elements(override val elementsToMove: Collection<KtNamedDeclaration>) : MoveSource()
+
+    class File(val file: KtFile) : MoveSource() {
+        override val elementsToMove: Collection<KtNamedDeclaration>
+            get() = file.declarations.filterIsInstance<KtNamedDeclaration>()
+    }
+}
+
+fun MoveSource(declaration: KtNamedDeclaration) = MoveSource.Elements(listOf(declaration))
+fun MoveSource(declarations: Collection<KtNamedDeclaration>) = MoveSource.Elements(declarations)
+fun MoveSource(file: KtFile) = MoveSource.File(file)
+
+class MoveDeclarationsDescriptor @JvmOverloads constructor(
+    val project: Project,
+    val moveSource: MoveSource,
+    val moveTarget: KotlinMoveTarget,
+    val delegate: MoveDeclarationsDelegate,
+    val searchInCommentsAndStrings: Boolean = true,
+    val searchInNonCode: Boolean = true,
+    val deleteSourceFiles: Boolean = false,
+    val moveCallback: MoveCallback? = null,
+    val openInEditor: Boolean = false,
+    val allElementsToMove: List<PsiElement>? = null,
+    val analyzeConflicts: Boolean = true,
+    val searchReferences: Boolean = true
+)
+
+class ConflictUsageInfo(element: PsiElement, val messages: Collection<String>) : UsageInfo(element)
+
+private object ElementHashingStrategy : TObjectHashingStrategy<PsiElement> {
+    override fun equals(e1: PsiElement?, e2: PsiElement?): Boolean {
+        if (e1 === e2) return true
+        // Name should be enough to distinguish different light elements based on the same original declaration
+        if (e1 is KtLightDeclaration<*, *> && e2 is KtLightDeclaration<*, *>) {
+            return e1.kotlinOrigin == e2.kotlinOrigin && e1.name == e2.name
+        }
+        return e1 == e2
+    }
+
+    override fun computeHashCode(e: PsiElement?): Int {
+        return when (e) {
+            null -> 0
+            is KtLightDeclaration<*, *> -> (e.kotlinOrigin?.hashCode() ?: 0) * 31 + (e.name?.hashCode() ?: 0)
+            else -> e.hashCode()
+        }
+    }
+}
+
+class MoveKotlinDeclarationsProcessor(
+        val descriptor: MoveDeclarationsDescriptor,
+        val mover: Mover = Mover.Default) : BaseRefactoringProcessor(descriptor.project) {
+    companion object {
+        private val REFACTORING_NAME = "Move declarations"
+        val REFACTORING_ID = "move.kotlin.declarations"
+    }
+
+    val project get() = descriptor.project
+
+    private var nonCodeUsages: Array<NonCodeUsageInfo>? = null
+    private val moveEntireFile = descriptor.moveSource is MoveSource.File
+    private val elementsToMove = descriptor.moveSource.elementsToMove.filter { e -> e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) }
+    private val kotlinToLightElementsBySourceFile = elementsToMove
+            .groupBy { it.containingKtFile }
+            .mapValues { it.value.keysToMap { it.toLightElements().ifEmpty { listOf(it) } } }
+    private val conflicts = MultiMap<PsiElement, String>()
+
+    override fun getRefactoringId() = REFACTORING_ID
+
+    override fun createUsageViewDescriptor(usages: Array<out UsageInfo>): UsageViewDescriptor {
+        val targetContainerFqName = descriptor.moveTarget.targetContainerFqName?.let {
+            if (it.isRoot) UsageViewBundle.message("default.package.presentable.name") else it.asString()
+        }
+        return MoveMultipleElementsViewDescriptor(elementsToMove.toTypedArray(), targetContainerFqName)
+    }
+
+    fun getConflictsAsUsages(): List<UsageInfo> = conflicts.entrySet().map { ConflictUsageInfo(it.key, it.value) }
+
+    public override fun findUsages(): Array<UsageInfo> {
+        if (!descriptor.searchReferences || elementsToMove.isEmpty()) return UsageInfo.EMPTY_ARRAY
+
+        val newContainerName = descriptor.moveTarget.targetContainerFqName?.asString() ?: ""
+
+        fun getSearchScope(element: PsiElement): GlobalSearchScope? {
+            val projectScope = project.projectScope()
+            val ktDeclaration = element.namedUnwrappedElement as? KtNamedDeclaration ?: return projectScope
+            if (ktDeclaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) return projectScope
+            val moveTarget = descriptor.moveTarget
+            val (oldContainer, newContainer) = descriptor.delegate.getContainerChangeInfo(ktDeclaration, moveTarget)
+            val targetModule = moveTarget.getTargetModule(project) ?: return projectScope
+            if (oldContainer != newContainer || ktDeclaration.module != targetModule) return projectScope
+            // Check if facade class may change
+            if (newContainer is ContainerInfo.Package) {
+                val javaScope = projectScope.restrictByFileType(JavaFileType.INSTANCE)
+                val currentFile = ktDeclaration.containingKtFile
+                val newFile = when (moveTarget) {
+                    is KotlinMoveTargetForExistingElement -> moveTarget.targetElement as? KtFile ?: return null
+                    is KotlinMoveTargetForDeferredFile -> return javaScope
+                    else -> return null
+                }
+                val currentFacade = currentFile.findFacadeClass()
+                val newFacade = newFile.findFacadeClass()
+                return if (currentFacade?.qualifiedName != newFacade?.qualifiedName) javaScope else null
+            }
+            return null
+        }
+
+        fun collectUsages(kotlinToLightElements: Map<KtNamedDeclaration, List<PsiNamedElement>>, result: MutableCollection<UsageInfo>) {
+            kotlinToLightElements.values.flatten().flatMapTo(result) { lightElement ->
+                val searchScope = getSearchScope(lightElement) ?: return@flatMapTo emptyList()
+
+                val newFqName = StringUtil.getQualifiedName(newContainerName, lightElement.name)
+
+                val foundReferences = HashSet<PsiReference>()
+                val results = ReferencesSearch
+                        .search(lightElement, searchScope)
+                        .mapNotNullTo(ArrayList()) { ref ->
+                            if (foundReferences.add(ref) && elementsToMove.none { it.isAncestor(ref.element)}) {
+                                createMoveUsageInfoIfPossible(ref, lightElement, true, false)
+                            }
+                            else null
+                        }
+
+                val name = lightElement.getKotlinFqName()?.quoteIfNeeded()?.asString()
+                if (name != null) {
+                    TextOccurrencesUtil.findNonCodeUsages(
+                            lightElement,
+                            name,
+                            descriptor.searchInCommentsAndStrings,
+                            descriptor.searchInNonCode,
+                            FqName(newFqName).quoteIfNeeded().asString(),
+                            results
+                    )
+                }
+
+                MoveClassHandler.EP_NAME.extensions.forEach { handler ->
+                    if (handler !is MoveKotlinClassHandler) handler.preprocessUsages(results)
+                }
+
+                results
+            }
+        }
+
+        val usages = ArrayList<UsageInfo>()
+        val conflictChecker = MoveConflictChecker(
+                project,
+                elementsToMove,
+                descriptor.moveTarget,
+                elementsToMove.first(),
+                allElementsToMove = descriptor.allElementsToMove
+        )
+        for ((sourceFile, kotlinToLightElements) in kotlinToLightElementsBySourceFile) {
+            val internalUsages = LinkedHashSet<UsageInfo>()
+            val externalUsages = LinkedHashSet<UsageInfo>()
+
+            if (moveEntireFile) {
+                val changeInfo = ContainerChangeInfo(
+                        ContainerInfo.Package(sourceFile.packageFqName),
+                        descriptor.moveTarget.targetContainerFqName?.let { ContainerInfo.Package(it) } ?: ContainerInfo.UnknownPackage
+                )
+                internalUsages += sourceFile.getInternalReferencesToUpdateOnPackageNameChange(changeInfo)
+            }
+            else {
+                kotlinToLightElements.keys.forEach {
+                    val packageNameInfo = descriptor.delegate.getContainerChangeInfo(it, descriptor.moveTarget)
+                    internalUsages += it.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo)
+                }
+            }
+
+            internalUsages += descriptor.delegate.findInternalUsages(descriptor)
+            collectUsages(kotlinToLightElements, externalUsages)
+            if (descriptor.analyzeConflicts) {
+                conflictChecker.checkAllConflicts(externalUsages, internalUsages, conflicts)
+                descriptor.delegate.collectConflicts(descriptor, internalUsages, conflicts)
+            }
+
+            usages += internalUsages
+            usages += externalUsages
+        }
+
+        return UsageViewUtil.removeDuplicatedUsages(usages.toTypedArray())
+    }
+
+    override fun preprocessUsages(refUsages: Ref<Array<UsageInfo>>): Boolean {
+        return showConflicts(conflicts, refUsages.get())
+    }
+
+    override fun performRefactoring(usages: Array<out UsageInfo>) = doPerformRefactoring(usages.toList())
+
+    internal fun doPerformRefactoring(usages: List<UsageInfo>) {
+        fun moveDeclaration(declaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): KtNamedDeclaration {
+            val targetContainer = moveTarget.getOrCreateTargetPsi(declaration)
+                                  ?: throw AssertionError("Couldn't create Kotlin file for: ${declaration::class.java}: ${declaration.text}")
+            descriptor.delegate.preprocessDeclaration(descriptor, declaration)
+            if (moveEntireFile) return declaration
+            return mover(declaration, targetContainer).apply {
+                addToBeShortenedDescendantsToWaitingSet()
+            }
+        }
+
+        val (oldInternalUsages, externalUsages) = usages.partition { it is KotlinMoveUsage && it.isInternal }
+        val newInternalUsages = ArrayList<UsageInfo>()
+
+        markInternalUsages(oldInternalUsages)
+
+        val usagesToProcess = ArrayList(externalUsages)
+
+        try {
+            descriptor.delegate.preprocessUsages(descriptor, usages)
+
+            val oldToNewElementsMapping = THashMap<PsiElement, PsiElement>(ElementHashingStrategy)
+
+            val newDeclarations = ArrayList<KtNamedDeclaration>()
+
+            for ((sourceFile, kotlinToLightElements) in kotlinToLightElementsBySourceFile) {
+                for ((oldDeclaration, oldLightElements) in kotlinToLightElements) {
+                    val elementListener = transaction?.getElementListener(oldDeclaration)
+
+                    val newDeclaration = moveDeclaration(oldDeclaration, descriptor.moveTarget)
+                    newDeclarations += newDeclaration
+
+                    oldToNewElementsMapping[oldDeclaration] = newDeclaration
+                    oldToNewElementsMapping[sourceFile] = newDeclaration.containingKtFile
+
+                    elementListener?.elementMoved(newDeclaration)
+                    for ((oldElement, newElement) in oldLightElements.asSequence().zip(newDeclaration.toLightElements().asSequence())) {
+                        oldToNewElementsMapping[oldElement] = newElement
+                    }
+
+                    if (descriptor.openInEditor) {
+                        EditorHelper.openInEditor(newDeclaration)
+                    }
+                }
+
+                if (descriptor.deleteSourceFiles) {
+                    sourceFile.delete()
+                }
+            }
+
+            val internalUsageScopes: List<KtElement> = if (moveEntireFile) {
+                newDeclarations.asSequence().map { it.containingKtFile }.distinct().toList()
+            } else {
+                newDeclarations
+            }
+            internalUsageScopes.forEach { newInternalUsages += restoreInternalUsages(it, oldToNewElementsMapping) }
+
+            usagesToProcess += newInternalUsages
+
+            nonCodeUsages = postProcessMoveUsages(usagesToProcess, oldToNewElementsMapping).toTypedArray()
+        }
+        catch (e: IncorrectOperationException) {
+            nonCodeUsages = null
+            RefactoringUIUtil.processIncorrectOperation(myProject, e)
+        }
+        finally {
+            cleanUpInternalUsages(newInternalUsages + oldInternalUsages)
+        }
+    }
+
+    override fun performPsiSpoilingRefactoring() {
+        nonCodeUsages?.let { nonCodeUsages -> RenameUtil.renameNonCodeUsages(myProject, nonCodeUsages) }
+        descriptor.moveCallback?.refactoringCompleted()
+    }
+
+    fun execute(usages: List<UsageInfo>) {
+        execute(usages.toTypedArray())
+    }
+
+    override fun doRun() {
+        try {
+            super.doRun()
+        } finally {
+            broadcastRefactoringExit(myProject, refactoringId)
+        }
+    }
+
+    override fun getCommandName(): String = REFACTORING_NAME
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt
index 2139192..00e2f45 100644
--- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt
@@ -100,7 +100,7 @@
         val calleeExpression = refExpression?.getParentOfTypeAndBranch<KtCallElement> { calleeExpression }
         if (calleeExpression != null) {
             (ref.resolve() as? KtConstructor<*>)?.let {
-                return if (flags and JavaTargetElementEvaluator.NEW_AS_CONSTRUCTOR != 0) it else it.containingClassOrObject
+                return if (flags and JavaTargetElementEvaluator().additionalReferenceSearchFlags != 0) it else it.containingClassOrObject
             }
         }
 
diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt.183 b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt.183
new file mode 100644
index 0000000..2139192
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinTargetElementEvaluator.kt.183
@@ -0,0 +1,122 @@
+/*
+ * 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.kotlin.idea.search.ideaExtensions
+
+import com.intellij.codeInsight.JavaTargetElementEvaluator
+import com.intellij.codeInsight.TargetElementEvaluatorEx
+import com.intellij.codeInsight.TargetElementUtil
+import com.intellij.codeInsight.TargetElementUtilExtender
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiFile
+import com.intellij.psi.PsiReference
+import com.intellij.util.BitUtil
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
+import org.jetbrains.kotlin.idea.intentions.isAutoCreatedItUsage
+import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
+import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
+import org.jetbrains.kotlin.idea.references.mainReference
+import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.*
+import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
+import org.jetbrains.kotlin.resolve.source.getPsi
+
+class KotlinTargetElementEvaluator : TargetElementEvaluatorEx, TargetElementUtilExtender {
+    companion object {
+        const val DO_NOT_UNWRAP_LABELED_EXPRESSION = 0x100
+        const val BYPASS_IMPORT_ALIAS = 0x200
+
+        // Place caret after the open curly brace in lambda for generated 'it'
+        fun findLambdaOpenLBraceForGeneratedIt(ref: PsiReference): PsiElement? {
+            val element: PsiElement = ref.element
+            if (element.text != "it") return null
+
+            if (element !is KtNameReferenceExpression || !isAutoCreatedItUsage(element)) return null
+
+            val itDescriptor = element.resolveMainReferenceToDescriptors().singleOrNull() ?: return null
+            val descriptorWithSource = itDescriptor.containingDeclaration as? DeclarationDescriptorWithSource ?: return null
+            val lambdaExpression = descriptorWithSource.source.getPsi()?.parent as? KtLambdaExpression ?: return null
+            return lambdaExpression.leftCurlyBrace.treeNext?.psi
+        }
+
+        // Navigate to receiver element for this in extension declaration
+        fun findReceiverForThisInExtensionFunction(ref: PsiReference): PsiElement? {
+            val element: PsiElement = ref.element
+            if (element.text != "this") return null
+
+            if (element !is KtNameReferenceExpression) return null
+            val callableDescriptor = element.resolveMainReferenceToDescriptors().singleOrNull() as? CallableDescriptor ?: return null
+
+            if (!callableDescriptor.isExtension) return null
+            val callableDeclaration = callableDescriptor.source.getPsi() as? KtCallableDeclaration ?: return null
+
+            return callableDeclaration.receiverTypeReference
+        }
+    }
+
+    override fun getAdditionalDefinitionSearchFlags() = 0
+
+    override fun getAdditionalReferenceSearchFlags() = DO_NOT_UNWRAP_LABELED_EXPRESSION or BYPASS_IMPORT_ALIAS
+
+    override fun getAllAdditionalFlags() = additionalDefinitionSearchFlags + additionalReferenceSearchFlags
+
+    override fun includeSelfInGotoImplementation(element: PsiElement): Boolean = !(element is KtClass && element.isAbstract())
+
+    override fun getElementByReference(ref: PsiReference, flags: Int): PsiElement? {
+        if (ref is KtSimpleNameReference && ref.expression is KtLabelReferenceExpression) {
+            val refTarget = ref.resolve() as? KtExpression ?: return null
+            if (!BitUtil.isSet(flags, DO_NOT_UNWRAP_LABELED_EXPRESSION)) {
+                return refTarget.getLabeledParent(ref.expression.getReferencedName()) ?: refTarget
+            }
+            return refTarget
+        }
+
+        if (!BitUtil.isSet(flags, BYPASS_IMPORT_ALIAS)) {
+            (ref.element as? KtSimpleNameExpression)?.mainReference?.getImportAlias()?.let { return it }
+        }
+
+        // prefer destructing declaration entry to its target if element name is accepted
+        if (ref is KtDestructuringDeclarationReference && BitUtil.isSet(flags, TargetElementUtil.ELEMENT_NAME_ACCEPTED)) {
+            return ref.element
+        }
+
+        val refExpression = ref.element as? KtSimpleNameExpression
+        val calleeExpression = refExpression?.getParentOfTypeAndBranch<KtCallElement> { calleeExpression }
+        if (calleeExpression != null) {
+            (ref.resolve() as? KtConstructor<*>)?.let {
+                return if (flags and JavaTargetElementEvaluator.NEW_AS_CONSTRUCTOR != 0) it else it.containingClassOrObject
+            }
+        }
+
+        if (BitUtil.isSet(flags, TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED)) {
+            return findLambdaOpenLBraceForGeneratedIt(ref)
+                    ?: findReceiverForThisInExtensionFunction(ref)
+        }
+
+        return null
+    }
+
+    override fun isIdentifierPart(file: PsiFile, text: CharSequence?, offset: Int): Boolean {
+        val elementAtCaret = file.findElementAt(offset)
+
+        if (elementAtCaret?.node?.elementType == KtTokens.IDENTIFIER) return true
+        // '(' is considered identifier part if it belongs to primary constructor without 'constructor' keyword
+        return elementAtCaret?.getNonStrictParentOfType<KtPrimaryConstructor>()?.textOffset == offset
+    }
+}
diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt
index 3e72d6c..c1e6d7e 100644
--- a/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt
@@ -75,9 +75,9 @@
         return listOf(KotlinSliceUsage(usage.element, usage.parent, 0, false))
     }
 
-    override fun getExpressionAtCaret(atCaret: PsiElement?, dataFlowToThis: Boolean): KtExpression? {
+    override fun getExpressionAtCaret(atCaret: PsiElement, dataFlowToThis: Boolean): KtExpression? {
         val element =
-                atCaret?.parentsWithSelf
+                atCaret.parentsWithSelf
                         ?.firstOrNull {
                             it is KtProperty ||
                             it is KtParameter ||
diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt.183 b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt.183
new file mode 100644
index 0000000..3e72d6c
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt.183
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2010-2017 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.idea.slicer
+
+import com.intellij.codeInspection.dataFlow.Nullness
+import com.intellij.ide.util.treeView.AbstractTreeStructure
+import com.intellij.openapi.actionSystem.DefaultActionGroup
+import com.intellij.psi.PsiElement
+import com.intellij.slicer.*
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
+import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
+import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.guessTypes
+import org.jetbrains.kotlin.idea.references.KtReference
+import org.jetbrains.kotlin.idea.references.mainReference
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.isPlainWithEscapes
+import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
+import org.jetbrains.kotlin.types.TypeUtils
+import org.jetbrains.kotlin.types.isError
+import org.jetbrains.kotlin.types.isNullabilityFlexible
+
+class KotlinSliceProvider : SliceLanguageSupportProvider, SliceUsageTransformer {
+    companion object {
+        val LEAF_ELEMENT_EQUALITY = object : SliceLeafEquality() {
+            override fun substituteElement(element: PsiElement) = (element as? KtReference)?.resolve() ?: element
+        }
+    }
+
+    class KotlinGroupByNullnessAction(treeBuilder: SliceTreeBuilder) : GroupByNullnessActionBase(treeBuilder) {
+        override fun isAvailable() = true
+    }
+
+    val leafAnalyzer by lazy { SliceLeafAnalyzer(LEAF_ELEMENT_EQUALITY, this) }
+    val nullnessAnalyzer: SliceNullnessAnalyzerBase by lazy {
+        object : SliceNullnessAnalyzerBase(LEAF_ELEMENT_EQUALITY, this) {
+            override fun checkNullness(element: PsiElement?): Nullness {
+                val types = when (element) {
+                    is KtCallableDeclaration -> listOfNotNull((element.resolveToDescriptorIfAny() as? CallableDescriptor)?.returnType)
+                    is KtDeclaration -> emptyList()
+                    is KtExpression -> listOfNotNull(element.analyze(BodyResolveMode.PARTIAL).getType(element))
+                    else -> emptyList()
+                }
+                return when {
+                    types.isEmpty() -> return Nullness.UNKNOWN
+                    types.all { KotlinBuiltIns.isNullableNothing(it) } -> Nullness.NULLABLE
+                    types.any { it.isError || TypeUtils.isNullableType(it) || it.isNullabilityFlexible() } -> Nullness.UNKNOWN
+                    else -> Nullness.NOT_NULL
+                }
+            }
+        }
+    }
+
+    override fun createRootUsage(element: PsiElement, params: SliceAnalysisParams) = KotlinSliceUsage(element, params)
+
+    override fun transform(usage: SliceUsage): Collection<SliceUsage>? {
+        if (usage is KotlinSliceUsage) return null
+        return listOf(KotlinSliceUsage(usage.element, usage.parent, 0, false))
+    }
+
+    override fun getExpressionAtCaret(atCaret: PsiElement?, dataFlowToThis: Boolean): KtExpression? {
+        val element =
+                atCaret?.parentsWithSelf
+                        ?.firstOrNull {
+                            it is KtProperty ||
+                            it is KtParameter ||
+                            it is KtDeclarationWithBody ||
+                            (it is KtClass && !it.hasExplicitPrimaryConstructor()) ||
+                            (it is KtExpression && it !is KtDeclaration)
+                        }
+                        ?.let { KtPsiUtil.safeDeparenthesize(it as KtExpression) } ?: return null
+        if (dataFlowToThis) {
+            if (element is KtConstantExpression) return null
+            if (element is KtStringTemplateExpression && element.isPlainWithEscapes()) return null
+            if (element is KtClassLiteralExpression) return null
+            if (element is KtCallableReferenceExpression) return null
+        }
+        return element
+    }
+
+    override fun getElementForDescription(element: PsiElement): PsiElement {
+        return (element as? KtSimpleNameExpression)?.mainReference?.resolve() ?: element
+    }
+
+    override fun getRenderer() = KotlinSliceUsageCellRenderer
+
+    override fun startAnalyzeLeafValues(structure: AbstractTreeStructure, finalRunnable: Runnable) {
+        leafAnalyzer.startAnalyzeValues(structure, finalRunnable)
+    }
+
+    override fun startAnalyzeNullness(structure: AbstractTreeStructure, finalRunnable: Runnable) {
+        nullnessAnalyzer.startAnalyzeNullness(structure, finalRunnable)
+    }
+
+    override fun registerExtraPanelActions(group: DefaultActionGroup, builder: SliceTreeBuilder) {
+        if (builder.dataFlowToThis) {
+            group.add(GroupByLeavesAction(builder))
+            group.add(KotlinGroupByNullnessAction(builder))
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt
index 908675a..825b11e 100644
--- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt
+++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt
@@ -122,6 +122,12 @@
 
     override fun getOriginalElement(): PsiElement? = super<UAnnotationMethod>.getOriginalElement()
 
+    override val returnTypeReference: UTypeReferenceExpression? by lz {
+        (sourcePsi as? KtCallableDeclaration)?.typeReference?.let {
+            LazyKotlinUTypeReferenceExpression(it, this) { javaPsi.returnType ?: UastErrorType }
+        }
+    }
+
     override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
 
     companion object {
diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt.183 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt.183
new file mode 100644
index 0000000..908675a
--- /dev/null
+++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt.183
@@ -0,0 +1,138 @@
+/*
+ * 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.uast.kotlin.declarations
+
+import com.intellij.psi.*
+import org.jetbrains.kotlin.asJava.elements.KtLightElement
+import org.jetbrains.kotlin.asJava.elements.KtLightMethod
+import org.jetbrains.kotlin.asJava.elements.isGetter
+import org.jetbrains.kotlin.asJava.elements.isSetter
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
+import org.jetbrains.kotlin.utils.SmartList
+import org.jetbrains.uast.*
+import org.jetbrains.uast.java.internal.JavaUElementWithComments
+import org.jetbrains.uast.kotlin.*
+
+open class KotlinUMethod(
+        psi: KtLightMethod,
+        givenParent: UElement?
+) : KotlinAbstractUElement(givenParent), UAnnotationMethod, UMethodTypeSpecific, UAnchorOwner, JavaUElementWithComments, PsiMethod by psi {
+    override val comments: List<UComment>
+        get() = super<KotlinAbstractUElement>.comments
+
+    override val psi: KtLightMethod = unwrap<UMethod, KtLightMethod>(psi)
+
+    override val javaPsi = psi
+
+    override val sourcePsi = psi.kotlinOrigin
+
+    override fun getSourceElement() = sourcePsi ?: this
+
+    override val uastDefaultValue by lz {
+        val annotationParameter = psi.kotlinOrigin as? KtParameter ?: return@lz null
+        val defaultValue = annotationParameter.defaultValue ?: return@lz null
+        getLanguagePlugin().convertElement(defaultValue, this) as? UExpression
+    }
+
+    private val kotlinOrigin = (psi.originalElement as KtLightElement<*, *>).kotlinOrigin
+
+    override fun getContainingFile(): PsiFile? = unwrapFakeFileForLightClass(psi.containingFile)
+
+    override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
+
+    override val annotations by lz {
+        psi.annotations
+                .mapNotNull { (it as? KtLightElement<*, *>)?.kotlinOrigin as? KtAnnotationEntry }
+                .map { KotlinUAnnotation(it, this) }
+    }
+
+    private val receiver by lz { (sourcePsi as? KtCallableDeclaration)?.receiverTypeReference }
+
+    override val uastParameters by lz {
+        val lightParams = psi.parameterList.parameters
+        val receiver = receiver ?: return@lz lightParams.map {
+            KotlinUParameter(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, this)
+        }
+        val receiverLight = lightParams.firstOrNull() ?: return@lz emptyList<UParameter>()
+        val uParameters = SmartList<UParameter>(KotlinReceiverUParameter(receiverLight, receiver, this))
+        lightParams.drop(1).mapTo(uParameters) { KotlinUParameter(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, this) }
+        uParameters
+    }
+
+    override val uastAnchor by lazy {
+        KotlinUIdentifier(
+            nameIdentifier,
+            sourcePsi.let { sourcePsi ->
+                when (sourcePsi) {
+                    is PsiNameIdentifierOwner -> sourcePsi.nameIdentifier
+                    is KtObjectDeclaration -> sourcePsi.getObjectKeyword()
+                    else -> sourcePsi?.navigationElement
+                }
+            },
+            this
+        )
+    }
+
+
+    override val uastBody by lz {
+        val bodyExpression = when (kotlinOrigin) {
+            is KtFunction -> kotlinOrigin.bodyExpression
+            is KtProperty -> when {
+                psi.isGetter -> kotlinOrigin.getter?.bodyExpression
+                psi.isSetter -> kotlinOrigin.setter?.bodyExpression
+                else -> null
+            }
+            else -> null
+        } ?: return@lz null
+
+        when (bodyExpression) {
+            !is KtBlockExpression -> {
+                KotlinUBlockExpression.KotlinLazyUBlockExpression(this, { block ->
+                    val implicitReturn = KotlinUImplicitReturnExpression(block)
+                    val uBody = getLanguagePlugin().convertElement(bodyExpression, implicitReturn) as? UExpression
+                            ?: return@KotlinLazyUBlockExpression emptyList()
+                    listOf(implicitReturn.apply { returnExpression = uBody })
+                })
+
+            }
+            else -> getLanguagePlugin().convertElement(bodyExpression, this) as? UExpression
+        }
+    }
+
+    override val isOverride: Boolean
+        get() = (kotlinOrigin as? KtCallableDeclaration)?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false
+
+    override fun getBody(): PsiCodeBlock? = super<UAnnotationMethod>.getBody()
+
+    override fun getOriginalElement(): PsiElement? = super<UAnnotationMethod>.getOriginalElement()
+
+    override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
+
+    companion object {
+        fun create(psi: KtLightMethod, containingElement: UElement?) =
+                if (psi.kotlinOrigin is KtConstructor<*>) {
+                    KotlinConstructorUMethod(
+                            psi.kotlinOrigin?.containingClassOrObject,
+                            psi, containingElement
+                    )
+                }
+                else
+                    KotlinUMethod(psi, containingElement)
+    }
+}
\ No newline at end of file
diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/evaluation/KotlinEvaluatorExtension.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/evaluation/KotlinEvaluatorExtension.kt
index e2642d6..36ad440 100644
--- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/evaluation/KotlinEvaluatorExtension.kt
+++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/evaluation/KotlinEvaluatorExtension.kt
@@ -9,6 +9,7 @@
 import org.jetbrains.uast.kotlin.KotlinBinaryOperators
 import org.jetbrains.uast.kotlin.KotlinPostfixOperators
 import org.jetbrains.uast.values.*
+import org.jetbrains.uast.evaluation.to
 
 class KotlinEvaluatorExtension : AbstractEvaluatorExtension(KotlinLanguage.INSTANCE) {
 
diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/evaluation/KotlinEvaluatorExtension.kt.183 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/evaluation/KotlinEvaluatorExtension.kt.183
new file mode 100644
index 0000000..e2642d6
--- /dev/null
+++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/evaluation/KotlinEvaluatorExtension.kt.183
@@ -0,0 +1,56 @@
+package org.jetbrains.uast.kotlin.evaluation
+
+import org.jetbrains.kotlin.idea.KotlinLanguage
+import org.jetbrains.uast.UBinaryExpression
+import org.jetbrains.uast.UastPostfixOperator
+import org.jetbrains.uast.evaluation.AbstractEvaluatorExtension
+import org.jetbrains.uast.evaluation.UEvaluationInfo
+import org.jetbrains.uast.evaluation.UEvaluationState
+import org.jetbrains.uast.kotlin.KotlinBinaryOperators
+import org.jetbrains.uast.kotlin.KotlinPostfixOperators
+import org.jetbrains.uast.values.*
+
+class KotlinEvaluatorExtension : AbstractEvaluatorExtension(KotlinLanguage.INSTANCE) {
+
+    private data class Range(val from: UValue, val to: UValue) {
+        override fun toString() = "$from..$to"
+    }
+
+    private class UClosedRangeConstant(override val value: Range, override val source: UBinaryExpression?) : UAbstractConstant() {
+        constructor(from: UValue, to: UValue, source: UBinaryExpression): this(Range(from, to), source)
+    }
+
+    override fun evaluatePostfix(
+            operator: UastPostfixOperator,
+            operandValue: UValue,
+            state: UEvaluationState
+    ): UEvaluationInfo {
+        return when (operator) {
+            KotlinPostfixOperators.EXCLEXCL -> when (operandValue.toConstant()) {
+                UNullConstant -> UValue.UNREACHABLE
+                is UConstant -> operandValue
+                else -> UUndeterminedValue
+            } to state
+            else -> return super.evaluatePostfix(operator, operandValue, state)
+        }
+    }
+
+    private fun UValue.contains(value: UValue): UValue {
+        val range = (this as? UClosedRangeConstant)?.value ?: return UUndeterminedValue
+        return (value greaterOrEquals range.from) and (value lessOrEquals range.to)
+    }
+
+    override fun evaluateBinary(
+            binaryExpression: UBinaryExpression,
+            leftValue: UValue,
+            rightValue: UValue,
+            state: UEvaluationState
+    ): UEvaluationInfo {
+        return when (binaryExpression.operator) {
+            KotlinBinaryOperators.IN -> rightValue.contains(leftValue)
+            KotlinBinaryOperators.NOT_IN -> !rightValue.contains(leftValue)
+            KotlinBinaryOperators.RANGE_TO -> UClosedRangeConstant(leftValue, rightValue, binaryExpression)
+            else -> UUndeterminedValue
+        } to state
+    }
+}
\ No newline at end of file
diff --git a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt
index 42c2928..798d453 100644
--- a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt
+++ b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt
@@ -456,6 +456,22 @@
         }
     }
 
+    @Test
+    fun testMethodReturnTypeReference() {
+        doTest("Elvis") { _, file ->
+            assertEquals(
+                "UTypeReferenceExpression (name = java.lang.String)",
+                file.findElementByTextFromPsi<UMethod>("fun foo(bar: String): String? = null").returnTypeReference?.asLogString()
+            )
+            assertEquals(
+                null,
+                file.findElementByTextFromPsi<UMethod>("fun bar() = 42").returnTypeReference?.asLogString()
+            )
+
+        }
+    }
+
+
 }
 
 fun <T, R> Iterable<T>.assertedFind(value: R, transform: (T) -> R): T =
diff --git a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.183 b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.183
new file mode 100644
index 0000000..42c2928
--- /dev/null
+++ b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.183
@@ -0,0 +1,462 @@
+package org.jetbrains.uast.test.kotlin
+
+import com.intellij.psi.PsiAnnotation
+import com.intellij.psi.PsiModifier
+import com.intellij.testFramework.UsefulTestCase
+import org.jetbrains.kotlin.asJava.toLightAnnotation
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
+import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
+import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
+import org.jetbrains.kotlin.utils.addToStdlib.cast
+import org.jetbrains.kotlin.utils.sure
+import org.jetbrains.uast.*
+import org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin
+import org.jetbrains.uast.test.env.kotlin.findElementByText
+import org.jetbrains.uast.test.env.kotlin.findElementByTextFromPsi
+import org.jetbrains.uast.visitor.AbstractUastVisitor
+import org.junit.Assert
+import org.junit.Test
+
+
+class KotlinUastApiTest : AbstractKotlinUastTest() {
+    override fun check(testName: String, file: UFile) {
+    }
+
+    @Test fun testAnnotationParameters() {
+        doTest("AnnotationParameters") { _, file ->
+            val annotation = file.findElementByText<UAnnotation>("@IntRange(from = 10, to = 0)")
+            assertEquals(annotation.findAttributeValue("from")?.evaluate(), 10)
+            val toAttribute = annotation.findAttributeValue("to")!!
+            assertEquals(toAttribute.evaluate(), 0)
+            KtUsefulTestCase.assertInstanceOf(annotation.psi.toUElement(), UAnnotation::class.java)
+            KtUsefulTestCase.assertInstanceOf(
+                annotation.psi.cast<KtAnnotationEntry>().toLightAnnotation().toUElement(),
+                UAnnotation::class.java
+            )
+            KtUsefulTestCase.assertInstanceOf(toAttribute.uastParent, UNamedExpression::class.java)
+            KtUsefulTestCase.assertInstanceOf(toAttribute.psi.toUElement()?.uastParent, UNamedExpression::class.java)
+        }
+    }
+
+    @Test fun testConvertStringTemplate() {
+        doTest("StringTemplateInClass") { _, file ->
+            val literalExpression = file.findElementByText<ULiteralExpression>("lorem")
+            val psi = literalExpression.psi!!
+            Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
+            val literalExpressionAgain = psi.toUElement()
+            Assert.assertTrue(literalExpressionAgain is ULiteralExpression)
+
+        }
+    }
+
+    @Test fun testConvertStringTemplateWithExpectedType() {
+        doTest("StringTemplateWithVar") { _, file ->
+            val index = file.psi.text.indexOf("foo")
+            val stringTemplate = file.psi.findElementAt(index)!!.getParentOfType<KtStringTemplateExpression>(false)
+            val uLiteral = stringTemplate.toUElementOfType<ULiteralExpression>()
+            assertNull(uLiteral)
+        }
+    }
+
+    @Test fun testNameContainingFile() {
+        doTest("NameContainingFile") { _, file ->
+            val foo = file.findElementByText<UClass>("class Foo")
+            assertEquals(file.psi, foo.nameIdentifier!!.containingFile)
+
+            val bar = file.findElementByText<UMethod>("fun bar() {}")
+            assertEquals(file.psi, bar.nameIdentifier!!.containingFile)
+
+            val xyzzy = file.findElementByText<UVariable>("val xyzzy: Int = 0")
+            assertEquals(file.psi, xyzzy.nameIdentifier!!.containingFile)
+        }
+    }
+
+    @Test fun testInterfaceMethodWithBody() {
+        doTest("DefaultImpls") { _, file ->
+            val bar = file.findElementByText<UMethod>("fun bar() = \"Hello!\"")
+            assertFalse(bar.containingFile.text!!, bar.psi.modifierList.hasExplicitModifier(PsiModifier.DEFAULT))
+            assertTrue(bar.containingFile.text!!, bar.psi.modifierList.hasModifierProperty(PsiModifier.DEFAULT))
+        }
+    }
+
+    @Test fun testSAM() {
+        doTest("SAM") { _, file ->
+            assertNull(file.findElementByText<ULambdaExpression>("{ /* Not SAM */ }").functionalInterfaceType)
+
+            assertEquals("java.lang.Runnable",
+                         file.findElementByText<ULambdaExpression>("{/* Variable */}").functionalInterfaceType?.canonicalText)
+
+            assertEquals("java.lang.Runnable",
+                         file.findElementByText<ULambdaExpression>("{/* Assignment */}").functionalInterfaceType?.canonicalText)
+
+            assertEquals("java.lang.Runnable",
+                          file.findElementByText<ULambdaExpression>("{/* Type Cast */}").functionalInterfaceType?.canonicalText)
+
+            assertEquals("java.lang.Runnable",
+                         file.findElementByText<ULambdaExpression>("{/* Argument */}").functionalInterfaceType?.canonicalText)
+
+            assertEquals("java.lang.Runnable",
+                         file.findElementByText<ULambdaExpression>("{/* Return */}").functionalInterfaceType?.canonicalText)
+
+            assertEquals(
+                "java.lang.Runnable",
+                file.findElementByText<ULambdaExpression>("{ /* SAM */ }").functionalInterfaceType?.canonicalText
+            )
+        }
+    }
+
+    @Test fun testParameterPropertyWithAnnotation() {
+        doTest("ParameterPropertyWithAnnotation") { _, file ->
+            val test1 = file.classes.find { it.name == "Test1" }!!
+
+            val constructor1 = test1.methods.find { it.name == "Test1" }!!
+            assertTrue(constructor1.uastParameters.first().annotations.any { it.qualifiedName == "MyAnnotation" })
+
+            val getter1 = test1.methods.find { it.name == "getBar" }!!
+            assertFalse(getter1.annotations.any { it.qualifiedName == "MyAnnotation" })
+
+            val setter1 = test1.methods.find { it.name == "setBar" }!!
+            assertFalse(setter1.annotations.any { it.qualifiedName == "MyAnnotation" })
+            assertFalse(setter1.uastParameters.first().annotations.any { it.qualifiedName == "MyAnnotation" })
+
+
+            val test2 = file.classes.find { it.name == "Test2" }!!
+            val constructor2 = test2.methods.find { it.name == "Test2" }!!
+            assertFalse(constructor2.uastParameters.first().annotations.any { it.qualifiedName?.startsWith("MyAnnotation") ?: false })
+
+            val getter2 = test2.methods.find { it.name == "getBar" }!!
+            getter2.annotations.single { it.qualifiedName == "MyAnnotation" }
+
+            val setter2 = test2.methods.find { it.name == "setBar" }!!
+            setter2.annotations.single { it.qualifiedName == "MyAnnotation2" }
+            setter2.uastParameters.first().annotations.single { it.qualifiedName == "MyAnnotation3" }
+
+            test2.fields.find { it.name == "bar" }!!.annotations.single { it.qualifiedName == "MyAnnotation5" }
+        }
+    }
+
+    @Test fun testConvertTypeInAnnotation() {
+        doTest("TypeInAnnotation") { _, file ->
+            val index = file.psi.text.indexOf("Test")
+            val element = file.psi.findElementAt(index)!!.getParentOfType<KtUserType>(false)!!
+            assertNotNull(element.getUastParentOfType(UAnnotation::class.java))
+        }
+    }
+
+    @Test fun testElvisType() {
+        doTest("ElvisType") { _, file ->
+            val elvisExpression = file.findElementByText<UExpression>("text ?: return")
+            assertEquals("String", elvisExpression.getExpressionType()!!.presentableText)
+        }
+    }
+
+    @Test fun testFindAttributeDefaultValue() {
+        doTest("AnnotationParameters") { _, file ->
+            val witDefaultValue = file.findElementByText<UAnnotation>("@WithDefaultValue")
+            assertEquals(42, witDefaultValue.findAttributeValue("value")!!.evaluate())
+            assertEquals(42, witDefaultValue.findAttributeValue(null)!!.evaluate())
+        }
+    }
+
+    @Test fun testIfCondition() {
+        doTest("IfStatement") { _, file ->
+            val psiFile = file.psi
+            val element = psiFile.findElementAt(psiFile.text.indexOf("\"abc\""))!!
+            val binaryExpression = element.getParentOfType<KtBinaryExpression>(false)!!
+            val uBinaryExpression = KotlinUastLanguagePlugin().convertElementWithParent(binaryExpression, null)!!
+            UsefulTestCase.assertInstanceOf(uBinaryExpression.uastParent, UIfExpression::class.java)
+        }
+    }
+
+    @Test
+    fun testWhenStringLiteral() {
+        doTest("WhenStringLiteral") { _, file ->
+
+            file.findElementByTextFromPsi<ULiteralExpression>("abc").let { literalExpression ->
+                val psi = literalExpression.psi!!
+                Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
+                UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
+            }
+
+            file.findElementByTextFromPsi<ULiteralExpression>("def").let { literalExpression ->
+                val psi = literalExpression.psi!!
+                Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
+                UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
+            }
+
+            file.findElementByTextFromPsi<ULiteralExpression>("def1").let { literalExpression ->
+                val psi = literalExpression.psi!!
+                Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
+                UsefulTestCase.assertInstanceOf(literalExpression.uastParent, UBlockExpression::class.java)
+            }
+
+
+        }
+    }
+
+    @Test
+    fun testWhenAndDestructing() {
+        doTest("WhenAndDestructing") { _, file ->
+
+            file.findElementByTextFromPsi<UExpression>("val (bindingContext, statementFilter) = arr").let { e ->
+                val uBlockExpression = e.getParentOfType<UBlockExpression>()
+                Assert.assertNotNull(uBlockExpression)
+                val uMethod = uBlockExpression!!.getParentOfType<UMethod>()
+                Assert.assertNotNull(uMethod)
+            }
+
+        }
+    }
+
+    @Test
+    fun testBrokenMethodTypeResolve() {
+        doTest("BrokenMethod") { _, file ->
+
+            file.accept(object : AbstractUastVisitor() {
+                override fun visitCallExpression(node: UCallExpression): Boolean {
+                    node.returnType
+                    return false
+                }
+            })
+        }
+    }
+
+    @Test
+    fun testSimpleAnnotated() {
+        doTest("SimpleAnnotated") { _, file ->
+            file.findElementByTextFromPsi<UField>("@kotlin.SinceKotlin(\"1.0\")\n    val property: String = \"Mary\"").let { field ->
+                val annotation = field.annotations.assertedFind("kotlin.SinceKotlin") { it.qualifiedName }
+                Assert.assertEquals("1.0", annotation.findDeclaredAttributeValue("version")?.evaluateString())
+                Assert.assertEquals("SinceKotlin", annotation.cast<UAnchorOwner>().uastAnchor?.sourcePsi?.text)
+            }
+        }
+    }
+
+
+    fun UFile.checkUastSuperTypes(refText: String, superTypes: List<String>) {
+        findElementByTextFromPsi<UClass>(refText, false).let {
+            assertEquals("base classes", superTypes, it.uastSuperTypes.map { it.getQualifiedName() })
+        }
+    }
+
+
+    @Test
+    fun testSuperTypes() {
+        doTest("SuperCalls") { _, file ->
+            file.checkUastSuperTypes("B", listOf("A"))
+            file.checkUastSuperTypes("O", listOf("A"))
+            file.checkUastSuperTypes("innerObject ", listOf("A"))
+            file.checkUastSuperTypes("InnerClass", listOf("A"))
+            file.checkUastSuperTypes("object : A(\"textForAnon\")", listOf("A"))
+        }
+    }
+
+    @Test
+    fun testAnonymousSuperTypes() {
+        doTest("Anonymous") { _, file ->
+            file.checkUastSuperTypes("object : Runnable { override fun run() {} }", listOf("java.lang.Runnable"))
+            file.checkUastSuperTypes(
+                "object : Runnable, Closeable { override fun close() {} override fun run() {} }",
+                listOf("java.lang.Runnable", "java.io.Closeable")
+            )
+            file.checkUastSuperTypes(
+                "object : InputStream(), Runnable { override fun read(): Int = 0; override fun run() {} }",
+                listOf("java.io.InputStream", "java.lang.Runnable")
+            )
+        }
+    }
+
+    @Test
+    fun testLiteralArraysTypes() {
+        doTest("AnnotationParameters") { _, file ->
+            file.findElementByTextFromPsi<UCallExpression>("intArrayOf(1, 2, 3)").let { field ->
+                Assert.assertEquals("PsiType:int[]", field.returnType.toString())
+            }
+            file.findElementByTextFromPsi<UCallExpression>("[1, 2, 3]").let { field ->
+                Assert.assertEquals("PsiType:int[]", field.returnType.toString())
+                Assert.assertEquals("PsiType:int", field.typeArguments.single().toString())
+            }
+            file.findElementByTextFromPsi<UCallExpression>("[\"a\", \"b\", \"c\"]").let { field ->
+                Assert.assertEquals("PsiType:String[]", field.returnType.toString())
+                Assert.assertEquals("PsiType:String", field.typeArguments.single().toString())
+            }
+
+        }
+    }
+
+    @Test
+    fun testTypeAliases() {
+        doTest("TypeAliases") { _, file ->
+            val g = (file.psi as KtFile).declarations.single { it.name == "G" } as KtTypeAlias
+            val originalType = g.getTypeReference()!!.typeElement as KtFunctionType
+            val originalTypeParameters = originalType.parameterList.toUElement() as UDeclarationsExpression
+            Assert.assertTrue((originalTypeParameters.declarations.single() as UParameter).type.isValid)
+        }
+    }
+
+    @Test
+    fun testNestedAnnotation() = doTest("AnnotationComplex") { _, file ->
+        file.findElementByTextFromPsi<UElement>("@AnnotationArray(value = Annotation())")
+            .findElementByTextFromPsi<UElement>("Annotation()")
+            .sourcePsiElement
+            .let { referenceExpression ->
+                val convertedUAnnotation = referenceExpression
+                    .cast<KtReferenceExpression>()
+                    .toUElementOfType<UAnnotation>()
+                        ?: throw AssertionError("haven't got annotation from $referenceExpression(${referenceExpression?.javaClass})")
+
+                checkDescriptorsLeak(convertedUAnnotation)
+                assertEquals("Annotation", convertedUAnnotation.qualifiedName)
+                val lightAnnotation = convertedUAnnotation.getAsJavaPsiElement(PsiAnnotation::class.java)
+                        ?: throw AssertionError("can't get lightAnnotation from $convertedUAnnotation")
+                assertEquals("Annotation", lightAnnotation.qualifiedName)
+                assertEquals("Annotation", (convertedUAnnotation as UAnchorOwner).uastAnchor?.sourcePsi?.text)
+            }
+    }
+
+
+    @Test
+    fun testParametersDisorder() = doTest("ParametersDisorder") { _, file ->
+
+        fun assertArguments(argumentsInPositionalOrder: List<String?>?, refText: String) =
+            file.findElementByTextFromPsi<UCallExpression>(refText).let { call ->
+                if (call !is UCallExpressionEx) throw AssertionError("${call.javaClass} is not a UCallExpressionEx")
+                Assert.assertEquals(
+                    argumentsInPositionalOrder,
+                    call.resolve()?.let { psiMethod ->
+                        (0 until psiMethod.parameterList.parametersCount).map {
+                            call.getArgumentForParameter(it)?.asRenderString()
+                        }
+                    }
+                )
+            }
+
+
+        assertArguments(listOf("2", "2.2"), "global(b = 2.2F, a = 2)")
+        assertArguments(listOf(null, "\"bbb\""), "withDefault(d = \"bbb\")")
+        assertArguments(listOf("1.3", "3.4"), "atan2(1.3, 3.4)")
+        assertArguments(null, "unresolvedMethod(\"param1\", \"param2\")")
+        assertArguments(listOf("\"%i %i %i\"", "varargs 1 : 2 : 3"), "format(\"%i %i %i\", 1, 2, 3)")
+        assertArguments(listOf("\"%i %i %i\"", "varargs arrayOf(1, 2, 3)"), "format(\"%i %i %i\", arrayOf(1, 2, 3))")
+        assertArguments(
+            listOf("\"%i %i %i\"", "varargs arrayOf(1, 2, 3) : arrayOf(4, 5, 6)"),
+            "format(\"%i %i %i\", arrayOf(1, 2, 3), arrayOf(4, 5, 6))"
+        )
+        assertArguments(listOf("\"%i %i %i\"", "\"\".chunked(2).toTypedArray()"), "format(\"%i %i %i\", *\"\".chunked(2).toTypedArray())")
+        assertArguments(listOf("\"def\"", "8", "7.0"), "with2Receivers(8, 7.0F)")
+        assertArguments(listOf("\"foo\"", "1"), "object : Parent(b = 1, a = \"foo\")\n")
+    }
+
+    @Test
+    fun testResolvedDeserializedMethod() = doTest("Resolve") { _, file ->
+        val barMethod = file.findElementByTextFromPsi<UElement>("bar").getParentOfType<UMethod>()!!
+
+        fun UElement.assertResolveCall(callText: String, methodName: String = callText.substringBefore("(")) {
+            this.findElementByTextFromPsi<UCallExpression>(callText).let {
+                val resolve = it.resolve().sure { "resolving '$callText'" }
+                assertEquals(methodName, resolve.name)
+            }
+        }
+        barMethod.assertResolveCall("foo()")
+        barMethod.assertResolveCall("inlineFoo()")
+        barMethod.assertResolveCall("forEach { println(it) }", "forEach")
+        barMethod.assertResolveCall("joinToString()")
+        barMethod.assertResolveCall("last()")
+        barMethod.assertResolveCall("setValue(\"123\")")
+        barMethod.assertResolveCall("contains(2 as Int)", "longRangeContains")
+        barMethod.assertResolveCall("IntRange(1, 2)")
+    }
+
+    @Test
+    fun testUtilsStreamLambda() {
+        doTest("Lambdas") { _, file ->
+            val lambda = file.findElementByTextFromPsi<ULambdaExpression>("{ it.isEmpty() }")
+            assertEquals(
+                "java.util.function.Predicate<? super java.lang.String>",
+                lambda.functionalInterfaceType?.canonicalText
+            )
+            assertEquals(
+                "kotlin.jvm.functions.Function1<? super java.lang.String,? extends java.lang.Boolean>",
+                lambda.getExpressionType()?.canonicalText
+            )
+            val uCallExpression = lambda.uastParent.assertedCast<UCallExpression> { "UCallExpression expected" }
+            assertTrue(uCallExpression.valueArguments.contains(lambda))
+        }
+    }
+
+    @Test
+    fun testLambdaParamCall() {
+        doTest("Lambdas") { _, file ->
+            val lambdaCall = file.findElementByTextFromPsi<UCallExpression>("selectItemFunction()")
+            assertEquals(
+                "UIdentifier (Identifier (selectItemFunction))",
+                lambdaCall.methodIdentifier?.asLogString()
+            )
+            assertEquals(
+                "selectItemFunction",
+                lambdaCall.methodIdentifier?.name
+            )
+            assertEquals(
+                "invoke",
+                lambdaCall.methodName
+            )
+            val receiver = lambdaCall.receiver ?: kotlin.test.fail("receiver expected")
+            assertEquals("UReferenceExpression", receiver.asLogString())
+            val uParameter = (receiver as UReferenceExpression).resolve().toUElement() ?: kotlin.test.fail("uelement expected")
+            assertEquals("UParameter (name = selectItemFunction)", uParameter.asLogString())
+        }
+    }
+
+    @Test
+    fun testLocalLambdaCall() {
+        doTest("Lambdas") { _, file ->
+            val lambdaCall = file.findElementByTextFromPsi<UCallExpression>("baz()")
+            assertEquals(
+                "UIdentifier (Identifier (baz))",
+                lambdaCall.methodIdentifier?.asLogString()
+            )
+            assertEquals(
+                "baz",
+                lambdaCall.methodIdentifier?.name
+            )
+            assertEquals(
+                "invoke",
+                lambdaCall.methodName
+            )
+            val receiver = lambdaCall.receiver ?: kotlin.test.fail("receiver expected")
+            assertEquals("UReferenceExpression", receiver.asLogString())
+            val uParameter = (receiver as UReferenceExpression).resolve().toUElement() ?: kotlin.test.fail("uelement expected")
+            assertEquals("ULocalVariable (name = baz)", uParameter.asLogString())
+        }
+    }
+
+    @Test
+    fun testLocalDeclarationCall() {
+        doTest("LocalDeclarations") { _, file ->
+            val localFunction = file.findElementByTextFromPsi<UElement>("bar() == Local()").
+                findElementByText<UCallExpression>("bar()")
+            assertEquals(
+                "UIdentifier (Identifier (bar))",
+                localFunction.methodIdentifier?.asLogString()
+            )
+            assertEquals(
+                "bar",
+                localFunction.methodIdentifier?.name
+            )
+            assertEquals(
+                "bar",
+                localFunction.methodName
+            )
+            assertNull(localFunction.resolve())
+            val receiver = localFunction.receiver ?: kotlin.test.fail("receiver expected")
+            assertEquals("UReferenceExpression", receiver.asLogString())
+            val uParameter = (receiver as UReferenceExpression).resolve().toUElement() ?: kotlin.test.fail("uelement expected")
+            assertEquals("ULambdaExpression", uParameter.asLogString())
+        }
+    }
+
+}
+
+fun <T, R> Iterable<T>.assertedFind(value: R, transform: (T) -> R): T =
+    find { transform(it) == value } ?: throw AssertionError("'$value' not found, only ${this.joinToString { transform(it).toString() }}")
diff --git a/usage-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/ProjectScopeStatsReporters.kt b/usage-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/ProjectScopeStatsReporters.kt
index a5556c3..e5183a7 100644
--- a/usage-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/ProjectScopeStatsReporters.kt
+++ b/usage-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/ProjectScopeStatsReporters.kt
@@ -5,21 +5,10 @@
 
 package org.jetbrains.kotlin.statistics
 
-import com.intellij.ide.plugins.PluginManager
-import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsageTriggerCollector
-import com.intellij.internal.statistic.service.fus.collectors.FUSApplicationUsageTrigger
-import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext
-import com.intellij.openapi.extensions.PluginId
-
-open class KotlinStatisticsTrigger(private val groupIdSufix: String) : ApplicationUsageTriggerCollector() {
-    override fun getGroupId() = "statistics.kotlin.$groupIdSufix"
-
+open class KotlinStatisticsTrigger(private val groupIdSufix: String) {
     companion object {
         public fun trigger(clazz: Class<out KotlinStatisticsTrigger>, event: String) {
-            val plugin = PluginManager.getPlugin(PluginId.getId("org.jetbrains.kotlin"))
-            val version = plugin?.version ?: "undefined"
-
-            FUSApplicationUsageTrigger.getInstance().trigger(clazz, event, FUSUsageContext.create(version))
+            // FUS is not working for 182
         }
     }
 }
diff --git a/usage-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/ProjectScopeStatsReporters.kt.183 b/usage-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/ProjectScopeStatsReporters.kt.183
new file mode 100644
index 0000000..a5556c3
--- /dev/null
+++ b/usage-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/ProjectScopeStatsReporters.kt.183
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2018 JetBrains s.r.o. 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.statistics
+
+import com.intellij.ide.plugins.PluginManager
+import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsageTriggerCollector
+import com.intellij.internal.statistic.service.fus.collectors.FUSApplicationUsageTrigger
+import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext
+import com.intellij.openapi.extensions.PluginId
+
+open class KotlinStatisticsTrigger(private val groupIdSufix: String) : ApplicationUsageTriggerCollector() {
+    override fun getGroupId() = "statistics.kotlin.$groupIdSufix"
+
+    companion object {
+        public fun trigger(clazz: Class<out KotlinStatisticsTrigger>, event: String) {
+            val plugin = PluginManager.getPlugin(PluginId.getId("org.jetbrains.kotlin"))
+            val version = plugin?.version ?: "undefined"
+
+            FUSApplicationUsageTrigger.getInstance().trigger(clazz, event, FUSUsageContext.create(version))
+        }
+    }
+}
+
+open class KotlinIdeStatisticsTrigger(groupIdSufix: String) : KotlinStatisticsTrigger("ide.$groupIdSufix")
+
+open class KotlinGradlePluginStatisticsTrigger(groupIdSufix: String) : KotlinStatisticsTrigger("gradle.$groupIdSufix")
+open class KotlinMavenPluginStatisticsTrigger(groupIdSufix: String) : KotlinStatisticsTrigger("maven.$groupIdSufix")
+open class KotlinJPSPluginStatisticsTrigger(groupIdSufix: String) : KotlinStatisticsTrigger("jps.$groupIdSufix")
+
+class KotlinVersionTrigger : KotlinGradlePluginStatisticsTrigger("kotlin_version")
+
+class KotlinTargetTrigger : KotlinGradlePluginStatisticsTrigger("target")
+
+class KotlinMavenTargetTrigger : KotlinMavenPluginStatisticsTrigger("target")
+
+class KotlinJPSTargetTrigger : KotlinJPSPluginStatisticsTrigger("target")
+
+class KotlinProjectLibraryUsageTrigger : KotlinGradlePluginStatisticsTrigger("library")
+
+open class KotlinIdeActionTrigger(groupIdSufix: String? = null) : KotlinIdeStatisticsTrigger("action" + (if (groupIdSufix != null) ".$groupIdSufix" else ""))
+
+class KotlinIdeRefactoringTrigger : KotlinIdeActionTrigger("refactoring")
+
+class KotlinIdeNewFileTemplateTrigger : KotlinIdeStatisticsTrigger("newFileTempl")
\ No newline at end of file