diff --git a/.idea/artifacts/KotlinPlugin.xml b/.idea/artifacts/KotlinPlugin.xml
index 857c5128ff4..e69ea537167 100644
--- a/.idea/artifacts/KotlinPlugin.xml
+++ b/.idea/artifacts/KotlinPlugin.xml
@@ -100,6 +100,9 @@
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index d68d76f1106..79e1cc0a506 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -74,6 +74,7 @@
+
diff --git a/idea/idea.iml b/idea/idea.iml
index f9955257518..9cf85b87c4e 100644
--- a/idea/idea.iml
+++ b/idea/idea.iml
@@ -58,5 +58,6 @@
+
\ No newline at end of file
diff --git a/idea/kotlin-gradle-tooling/kotlin-gradle-tooling.iml b/idea/kotlin-gradle-tooling/kotlin-gradle-tooling.iml
new file mode 100644
index 00000000000..8d6ac6d91f9
--- /dev/null
+++ b/idea/kotlin-gradle-tooling/kotlin-gradle-tooling.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt b/idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt
new file mode 100644
index 00000000000..641f4322ac4
--- /dev/null
+++ b/idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.gradle
+
+import org.gradle.api.Project
+import org.gradle.api.artifacts.ProjectDependency
+import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
+import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
+import java.io.Serializable
+import java.lang.Exception
+
+interface KotlinGradleModel : Serializable {
+ val implements: String?
+}
+
+class KotlinGradleModelImpl(override val implements: String?) : KotlinGradleModel
+
+class KotlinGradleModelBuilder : ModelBuilderService {
+ override fun getErrorMessageBuilder(project: Project, e: Exception): ErrorMessageBuilder {
+ return ErrorMessageBuilder.create(project, e, "Gradle import errors").withDescription("Unable to build Kotlin project configuration")
+ }
+
+ override fun canBuild(modelName: String?): Boolean = modelName == KotlinGradleModel::class.java.name
+
+ override fun buildAll(modelName: String?, project: Project): Any {
+ val implementsConfiguration = project.configurations.findByName("implement")
+ if (implementsConfiguration != null) {
+ val implementsProjectDependency = implementsConfiguration.dependencies.filterIsInstance().firstOrNull()
+ if (implementsProjectDependency != null) {
+ return KotlinGradleModelImpl(implementsProjectDependency.dependencyProject.path)
+ }
+ }
+ return KotlinGradleModelImpl(null)
+ }
+}
diff --git a/idea/kotlin-gradle-tooling/src/META-INF/services/org.jetbrains.plugins.gradle.tooling.ModelBuilderService b/idea/kotlin-gradle-tooling/src/META-INF/services/org.jetbrains.plugins.gradle.tooling.ModelBuilderService
new file mode 100644
index 00000000000..b8452a8e834
--- /dev/null
+++ b/idea/kotlin-gradle-tooling/src/META-INF/services/org.jetbrains.plugins.gradle.tooling.ModelBuilderService
@@ -0,0 +1 @@
+org.jetbrains.kotlin.gradle.KotlinGradleModelBuilder
diff --git a/idea/src/META-INF/gradle.xml b/idea/src/META-INF/gradle.xml
index 5f861ec32b6..25c3ed02c85 100644
--- a/idea/src/META-INF/gradle.xml
+++ b/idea/src/META-INF/gradle.xml
@@ -2,6 +2,7 @@
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt
new file mode 100644
index 00000000000..08645035277
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.configuration
+
+import com.intellij.openapi.externalSystem.model.DataNode
+import com.intellij.openapi.externalSystem.model.ProjectKeys
+import com.intellij.openapi.externalSystem.model.project.ModuleData
+import com.intellij.openapi.externalSystem.model.project.ModuleDependencyData
+import com.intellij.openapi.externalSystem.model.project.ProjectData
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
+import com.intellij.openapi.roots.DependencyScope
+import org.gradle.tooling.model.idea.IdeaModule
+import org.jetbrains.kotlin.gradle.KotlinGradleModel
+import org.jetbrains.kotlin.gradle.KotlinGradleModelBuilder
+import org.jetbrains.plugins.gradle.model.ExternalProject
+import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
+import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
+import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil.getModuleId
+
+class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension() {
+ override fun getToolingExtensionsClasses(): Set> {
+ return setOf(KotlinGradleModelBuilder::class.java, Unit::class.java)
+ }
+
+ override fun getExtraProjectModelClasses(): Set> {
+ return setOf(KotlinGradleModel::class.java)
+ }
+
+ override fun populateModuleDependencies(gradleModule: IdeaModule,
+ ideModule: DataNode,
+ ideProject: DataNode) {
+ val gradleModel = resolverCtx.getExtraProject(gradleModule, KotlinGradleModel::class.java) ?: return
+ gradleModel.implements?.let { implementsModuleId ->
+ val targetModule = findModule(ideProject, implementsModuleId) ?: return
+ if (resolverCtx.isResolveModulePerSourceSet) {
+ populateSourceSetDependencies(gradleModule, ideModule, targetModule)
+ }
+ else {
+ addDependency(ideModule, targetModule)
+ }
+ }
+
+ super.populateModuleDependencies(gradleModule, ideModule, ideProject)
+ }
+
+ private fun addDependency(ideModule: DataNode, targetModule: DataNode) {
+ val moduleDependencyData = ModuleDependencyData(ideModule.data, targetModule.data)
+ moduleDependencyData.scope = DependencyScope.COMPILE
+ moduleDependencyData.isExported = false
+ ideModule.createChild(ProjectKeys.MODULE_DEPENDENCY, moduleDependencyData)
+ }
+
+ private fun findModule(ideProject: DataNode, moduleId: String): DataNode? {
+ return ideProject.children.find { (it.data as? ModuleData)?.id == moduleId } as DataNode?
+ }
+
+ private fun populateSourceSetDependencies(gradleModule: IdeaModule,
+ fromModule: DataNode,
+ targetModule: DataNode) {
+ val fromSourceSets = ExternalSystemApiUtil.findAll(fromModule, GradleSourceSetData.KEY)
+ .associateBy { it.data.id }
+ val targetSourceSets = ExternalSystemApiUtil.findAll(targetModule, GradleSourceSetData.KEY)
+ .associateBy { it.data.id.substringAfterLast(':') }
+
+ val externalProject = resolverCtx.getExtraProject(gradleModule, ExternalProject::class.java) ?: return
+ for (sourceSet in externalProject.sourceSets.values) {
+ if (sourceSet == null || sourceSet.sources.isEmpty()) continue
+
+ val moduleId = getModuleId(externalProject, sourceSet)
+ val fromModuleDataNode = (if (fromSourceSets.isEmpty()) fromModule else fromSourceSets[moduleId]) ?: continue
+ val targetModuleDataNode = (if (targetSourceSets.isEmpty()) targetModule else targetSourceSets[sourceSet.name]) ?: continue
+ addDependency(fromModuleDataNode, targetModuleDataNode)
+ }
+ }
+}