diff --git a/idea/kotlin-android-plugin/kotlin-android-plugin.iml b/idea/kotlin-android-plugin/kotlin-android-plugin.iml
index 894dae4c845..212437c1f39 100644
--- a/idea/kotlin-android-plugin/kotlin-android-plugin.iml
+++ b/idea/kotlin-android-plugin/kotlin-android-plugin.iml
@@ -12,5 +12,6 @@
+
\ No newline at end of file
diff --git a/idea/kotlin-android-plugin/src/org/jetbrains/kotlin/android/actions/NewKotlinActivityAction.kt b/idea/kotlin-android-plugin/src/org/jetbrains/kotlin/android/actions/NewKotlinActivityAction.kt
new file mode 100644
index 00000000000..4676344b9fe
--- /dev/null
+++ b/idea/kotlin-android-plugin/src/org/jetbrains/kotlin/android/actions/NewKotlinActivityAction.kt
@@ -0,0 +1,157 @@
+/*
+ * 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.android.actions
+
+import com.intellij.history.core.RevisionsCollector
+import com.intellij.history.core.revisions.Revision
+import com.intellij.history.integration.LocalHistoryImpl
+import com.intellij.openapi.actionSystem.*
+import com.intellij.openapi.diagnostic.Logger
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.psi.PsiJavaFile
+import org.jetbrains.android.facet.AndroidFacet
+import org.jetbrains.kotlin.idea.KotlinIcons
+import org.jetbrains.kotlin.idea.actions.JavaToKotlinAction
+import org.jetbrains.kotlin.idea.refactoring.toPsiFile
+import java.io.File
+import kotlin.reflect.functions
+import kotlin.reflect.memberFunctions
+
+private val NEW_KOTLIN_ACTIVITY_START_LABEL = "Start New Kotlin Activity Action"
+private val NEW_KOTLIN_ACTIVITY_END_LABEL = "Finish New Kotlin Activity Action"
+
+class NewKotlinActivityAction: AnAction(KotlinIcons.FILE) {
+
+ companion object {
+ private val LOG = Logger.getInstance(NewKotlinActivityAction::class.java)
+ }
+
+ override fun actionPerformed(e: AnActionEvent) {
+ val project = e.project ?: return
+
+ LocalHistoryImpl.getInstanceImpl().putSystemLabel(project, NEW_KOTLIN_ACTIVITY_START_LABEL)
+ val isSuccess = showWizard(e.dataContext)
+ LocalHistoryImpl.getInstanceImpl().putSystemLabel(project, NEW_KOTLIN_ACTIVITY_END_LABEL)
+
+ if (!isSuccess) return
+
+ val localHistory = LocalHistoryImpl.getInstanceImpl()
+ val gateway = localHistory.gateway!!
+ val localHistoryFacade = localHistory.facade
+
+ val revisionsCollector = RevisionsCollector(
+ localHistoryFacade, gateway.createTransientRootEntry(),
+ project.baseDir.path, project.locationHash, null)
+
+ val revisions = revisionsCollector.result
+ var endRevision: Revision? = null
+ for (rev in revisions) {
+ val label = rev.label ?: continue
+ if (label == NEW_KOTLIN_ACTIVITY_END_LABEL) {
+ endRevision = rev
+ }
+
+ if (label == NEW_KOTLIN_ACTIVITY_START_LABEL && endRevision != null) {
+ val javaFiles = arrayListOf()
+ val differences = endRevision.getDifferencesWith(rev)
+ for (difference in differences) {
+ if (difference.right == null && difference.isFile) {
+ val file = File(difference.left.path)
+ if (file.extension == "java") {
+ val psiFile = file.toPsiFile(project) as? PsiJavaFile
+ if (psiFile != null) {
+ javaFiles.add(psiFile)
+ }
+ }
+ }
+ }
+ if (javaFiles.isNotEmpty()) {
+ JavaToKotlinAction.convertFiles(javaFiles, project, false)
+ }
+ break
+ }
+ }
+ }
+
+ private fun showWizard(dataContext: DataContext): Boolean {
+ try {
+ val wizardClass = try {
+ // AS 1.5
+ Class.forName("com.android.tools.idea.wizard.NewAndroidActivityWizard")
+ }
+ catch(e: ClassNotFoundException) {
+ // AS 2.0
+ Class.forName("com.android.tools.idea.npw.NewAndroidActivityWizard")
+ }
+
+ val constructor = wizardClass.getConstructor(Module::class.java, VirtualFile::class.java, File::class.java)
+ val wizard = constructor.newInstance(
+ LangDataKeys.MODULE.getData(dataContext),
+ CommonDataKeys.VIRTUAL_FILE.getData(dataContext),
+ null)
+
+ wizardClass.kotlin.functions.firstOrNull { it.name == "init" }?.call(wizard)
+ return (wizardClass.kotlin.functions.firstOrNull { it.name == "showAndGet" }?.call(wizard) as? Boolean) ?: false
+ }
+ catch(e: Throwable) {
+ LOG.error(e)
+ return false
+ }
+ }
+
+ override fun update(e: AnActionEvent) {
+ val view = LangDataKeys.IDE_VIEW.getData(e.dataContext)
+ val module = LangDataKeys.MODULE.getData(e.dataContext)
+ val facet = if (module != null) AndroidFacet.getInstance(module) else null
+ val presentation = e.presentation
+ val isProjectReady = facet != null && isProjectReady(facet)
+ presentation.text = "Kotlin Activity" + if (isProjectReady) "" else " (Project not ready)"
+ presentation.isVisible = view != null && facet != null && isVisible(facet)
+ }
+
+ private fun isVisible(facet: AndroidFacet): Boolean {
+ try {
+ val shouldSetVisible = AndroidFacet::class.memberFunctions.singleOrNull {
+ it.name == "isGradleProject" || it.name == "requiresAndroidModel"
+ }
+
+ return shouldSetVisible?.call(facet) != null
+ }
+ catch(e: Throwable) {
+ LOG.error(e)
+ return false
+ }
+ }
+
+ private fun isProjectReady(facet: AndroidFacet): Boolean {
+ try {
+ val getAndroidProjectInfoFun = AndroidFacet::class.memberFunctions.singleOrNull {
+ it.name == "getIdeaAndroidProject" || it.name == "getAndroidModel"
+ }
+
+ return getAndroidProjectInfoFun?.call(facet) != null
+ }
+ catch(e: Throwable) {
+ LOG.error(e)
+ return false
+ }
+ }
+
+ override fun hashCode() = 0
+ override fun equals(other: Any?) = other is NewKotlinActivityAction
+}
\ No newline at end of file
diff --git a/idea/kotlin-android-plugin/src/org/jetbrains/kotlin/android/facet/KotlinAndroidStartupManager.kt b/idea/kotlin-android-plugin/src/org/jetbrains/kotlin/android/facet/KotlinAndroidStartupManager.kt
new file mode 100644
index 00000000000..63b52cee05f
--- /dev/null
+++ b/idea/kotlin-android-plugin/src/org/jetbrains/kotlin/android/facet/KotlinAndroidStartupManager.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.android.facet
+
+import com.intellij.openapi.project.Project
+
+class KotlinAndroidStartupManager(private val project: Project) {
+ init {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/src/META-INF/android.xml b/idea/src/META-INF/android.xml
index 98485f2cf97..98b7dd0f913 100644
--- a/idea/src/META-INF/android.xml
+++ b/idea/src/META-INF/android.xml
@@ -24,4 +24,17 @@
+
+
+
+ org.jetbrains.kotlin.android.facet.KotlinAndroidStartupManager
+ org.jetbrains.kotlin.android.facet.KotlinAndroidStartupManager
+
+
+
+
+
+
+
+