reorganize skylark layout to support another aspect
diff --git a/WORKSPACE b/WORKSPACE
index af7d9de..8f7d383 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 workspace(name="io_bazel_rules_kotlin")
-load("//kotlin/internal:bootstrap.bzl",github_archive="github_archive")
+load("//kotlin/internal/repositories:repositories.bzl","github_archive")
 
 github_archive(
     name = "com_google_protobuf",
diff --git a/kotlin/BUILD b/kotlin/BUILD
index e7ab37c..af730cc 100644
--- a/kotlin/BUILD
+++ b/kotlin/BUILD
@@ -13,37 +13,11 @@
 # limitations under the License.
 package(default_visibility = ["//visibility:public"])
 
-load("//kotlin:toolchains.bzl", "define_kt_toolchain")
-load("//kotlin/internal:bootstrap.bzl", "kt_toolchain_ide_info")
-
-config_setting(
-    name = "builder_debug_timings",
-    values = { "define": "kt_timings=1" }
-)
-
-config_setting(
-    name = "builder_debug_trace",
-    values = { "define": "kt_trace=1" }
-)
-
-define_kt_toolchain(
-    name = "default_toolchain",
-    debug=
-        select({
-            "//kotlin:builder_debug_trace": ["trace"],
-            "//conditions:default": []
-        }) +
-        select({
-            "//kotlin:builder_debug_timings": ["timings"],
-            "//conditions:default": []
-        })
-)
+load("//kotlin/internal:toolchains.bzl", "kt_toolchain_ide_info")
 
 toolchain_type(
     name = "kt_toolchain_type",
     visibility = ["//visibility:public"]
 )
 
-kt_toolchain_ide_info(name="kt_toolchain_ide_info")
-
-exports_files(["toolchains.bzl", "kotlin.bzl"], visibility=["//docs:__subpackages__"])
+kt_toolchain_ide_info(name="kt_toolchain_ide_info")
\ No newline at end of file
diff --git a/kotlin/builder/integrationtests/KotlinBuilderActionTests.java b/kotlin/builder/integrationtests/KotlinBuilderActionTests.java
index 257af8b..a8516bf 100644
--- a/kotlin/builder/integrationtests/KotlinBuilderActionTests.java
+++ b/kotlin/builder/integrationtests/KotlinBuilderActionTests.java
@@ -6,7 +6,7 @@
   @Test
   public void testCompileSimple() {
     addSource("AClass.kt", "package something;" + "class AClass{}");
-    component().jvmCompiler().compile(builderCommand());
+    component().jvmTaskExecutor().compileKotlin(builderCommand(), context());
     assertFileExists(DirectoryType.CLASSES, "something/AClass.class");
     assertFileDoesNotExist(outputs().getJar());
   }
diff --git a/kotlin/builder/integrationtests/KotlinBuilderTestCase.java b/kotlin/builder/integrationtests/KotlinBuilderTestCase.java
index 3bfa7db..c5759b5 100644
--- a/kotlin/builder/integrationtests/KotlinBuilderTestCase.java
+++ b/kotlin/builder/integrationtests/KotlinBuilderTestCase.java
@@ -3,6 +3,7 @@
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import io.bazel.kotlin.builder.toolchain.KotlinToolchain;
+import io.bazel.kotlin.builder.utils.CompilationTaskContext;
 import io.bazel.kotlin.model.JvmCompilationTask;
 import io.bazel.kotlin.model.KotlinToolchainInfo;
 import io.bazel.kotlin.model.Platform;
@@ -28,9 +29,7 @@
 
   private final JvmCompilationTask.Builder builder = JvmCompilationTask.newBuilder();
   private final KotlinBuilderComponent component =
-      DaggerKotlinBuilderComponent.builder()
-          .toolchain(KotlinToolchain.createToolchain())
-          .build();
+      DaggerKotlinBuilderComponent.builder().toolchain(KotlinToolchain.createToolchain()).build();
 
   private String label = null;
   private Path inputSourceDir = null;
@@ -56,6 +55,10 @@
     return Paths.get(directories().getClasses());
   }
 
+  protected CompilationTaskContext context() {
+    return new CompilationTaskContext(builder.getInfo(), System.err);
+  }
+
   protected JvmCompilationTask builderCommand() {
     return builder.build();
   }
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderComponent.java b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderComponent.java
index db95f4d..deeedad 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderComponent.java
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderComponent.java
@@ -20,14 +20,12 @@
 import dagger.Provides;
 import io.bazel.kotlin.builder.tasks.BazelWorker;
 import io.bazel.kotlin.builder.tasks.KotlinBuilder;
-import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmCompiler;
 import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor;
 import io.bazel.kotlin.builder.toolchain.KotlinToolchain;
 import io.bazel.kotlin.builder.utils.KotlinCompilerPluginArgsEncoder;
 
 import javax.inject.Singleton;
 import java.io.PrintStream;
-import java.util.function.Supplier;
 
 @Singleton
 @dagger.Component(modules = {KotlinBuilderComponent.Module.class})
@@ -36,8 +34,6 @@
 
   KotlinJvmTaskExecutor jvmTaskExecutor();
 
-  KotlinJvmCompiler jvmCompiler();
-
   BazelWorker worker();
 
   @Component.Builder
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
index c834790..2c7ebfc 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
@@ -71,7 +71,7 @@
 
     private fun buildContext(args: List<String>): Pair<ArgMap, CompilationTaskContext> {
         check(args.isNotEmpty()) { "expected at least a single arg got: ${args.joinToString(" ")}" }
-        val (flagFileName, primaryOutputPath, idx) =
+        val (flagFileName, primaryOutputPath, _) =
                 checkNotNull(FLAGFILE_RE.matchEntire(args[0])) { "invalid flagfile ${args[0]}" }.destructured
         val argMap = Files.readAllLines(Paths.get(flagFileName), StandardCharsets.UTF_8).let(ArgMaps::from)
         val info = buildTaskInfo(argMap).also {
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmCompiler.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmCompiler.kt
deleted file mode 100644
index b4b5bb5..0000000
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmCompiler.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2018 The Bazel Authors. All rights reserved.
- *
- * 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 io.bazel.kotlin.builder.tasks.jvm
-
-import io.bazel.kotlin.builder.toolchain.CompilationStatusException
-import io.bazel.kotlin.builder.toolchain.KotlinToolchain
-import io.bazel.kotlin.builder.utils.CompilationTaskContext
-import io.bazel.kotlin.builder.utils.KotlinCompilerPluginArgsEncoder
-import io.bazel.kotlin.builder.utils.addAll
-import io.bazel.kotlin.builder.utils.joinedClasspath
-import io.bazel.kotlin.model.JvmCompilationTask
-import java.io.ByteArrayInputStream
-import java.io.ByteArrayOutputStream
-import java.io.File
-import java.io.PrintStream
-import javax.inject.Inject
-import javax.inject.Singleton
-
-
-// The Kotlin compiler is not suited for javac compilation as of 1.2.21. The errors are not conveyed directly and would need to be preprocessed, also javac
-// invocations Configured via Kotlin use eager analysis in some corner cases this can result in classpath exceptions from the Java Compiler..
-//
-// 1 is a standard compilation error
-// 2 is an internal error
-// 3 is the script execution error
-@Singleton
-internal class KotlinJvmCompiler @Inject constructor(
-    private val compiler: KotlinToolchain.KotlincInvoker,
-    private val pluginArgsEncoder: KotlinCompilerPluginArgsEncoder
-) {
-    fun runAnnotationProcessor(context: CompilationTaskContext, command: JvmCompilationTask): List<String> {
-        check(command.info.plugins.annotationProcessorsList.isNotEmpty()) {
-            "method called without annotation processors"
-        }
-        return getCommonArgs(command).also {
-            it.addAll(pluginArgsEncoder.encode(context, command))
-            it.addAll(command.inputs.kotlinSourcesList)
-            it.addAll(command.inputs.javaSourcesList)
-        }.let(::invokeCompilePhase)
-    }
-
-    /**
-     * Return a list with the common arguments.
-     */
-    private fun getCommonArgs(command: JvmCompilationTask): MutableList<String> {
-        val args = mutableListOf<String>()
-
-        // use -- for flags not meant for the kotlin compiler
-        args.addAll(
-            "-cp", command.inputs.joinedClasspath,
-            "-api-version", command.info.toolchainInfo.common.apiVersion,
-            "-language-version", command.info.toolchainInfo.common.languageVersion,
-            "-jvm-target", command.info.toolchainInfo.jvm.jvmTarget,
-            // https://github.com/bazelbuild/rules_kotlin/issues/69: remove once jetbrains adds a flag for it.
-            "--friend-paths", command.info.friendPathsList.joinToString(File.pathSeparator)
-        )
-
-        args
-            .addAll("-module-name", command.info.moduleName)
-            .addAll("-d", command.directories.classes)
-
-        command.info.passthroughFlags?.takeIf { it.isNotBlank() }?.also { args.addAll(it.split(" ")) }
-        return args
-    }
-
-    fun compile(command: JvmCompilationTask): List<String> =
-        with(getCommonArgs(command)) {
-            addAll(command.inputs.javaSourcesList)
-            addAll(command.inputs.kotlinSourcesList)
-            invokeCompilePhase(this)
-        }
-
-    private fun invokeCompilePhase(args: List<String>): List<String> {
-        val outputStream = ByteArrayOutputStream()
-        val ps = PrintStream(outputStream)
-        val result = compiler.compile(args.toTypedArray(), ps)
-        val output = ByteArrayInputStream(outputStream.toByteArray()).bufferedReader().readLines()
-        if (result != 0) {
-            throw CompilationStatusException("compile phase failed", result, output)
-        } else {
-            return output
-        }
-    }
-}
\ No newline at end of file
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt
index bac2bcd..4a56c44 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt
@@ -16,6 +16,7 @@
 package io.bazel.kotlin.builder.tasks.jvm
 
 import io.bazel.kotlin.builder.toolchain.CompilationStatusException
+import io.bazel.kotlin.builder.toolchain.KotlinToolchain
 import io.bazel.kotlin.builder.utils.*
 import io.bazel.kotlin.builder.utils.jars.JarCreator
 import io.bazel.kotlin.builder.utils.jars.SourceJarCreator
@@ -29,7 +30,8 @@
 
 @Singleton
 class KotlinJvmTaskExecutor @Inject internal constructor(
-    private val kotlinCompiler: KotlinJvmCompiler,
+    private val compiler: KotlinToolchain.KotlincInvoker,
+    private val pluginArgsEncoder: KotlinCompilerPluginArgsEncoder,
     private val javaCompiler: JavaCompiler,
     private val jDepsGenerator: JDepsGenerator
 ) {
@@ -37,7 +39,7 @@
         // TODO fix error handling
         try {
             val preprocessedTask = task.preprocessingSteps(context)
-            context.execute("compile classes") { preprocessedTask.compileClasses(context) }
+            context.execute("compile classes") { preprocessedTask.compileAll(context) }
             context.execute("create jar") { preprocessedTask.createOutputJar() }
             context.execute("produce src jar") { preprocessedTask.produceSourceJar() }
             context.execute("generate jdeps") { preprocessedTask.generateJDeps() }
@@ -83,6 +85,42 @@
         }
     }
 
+    private fun JvmCompilationTask.runAnnotationProcessor(context: CompilationTaskContext): List<String> {
+        check(info.plugins.annotationProcessorsList.isNotEmpty()) {
+            "method called without annotation processors"
+        }
+        return getCommonArgs().let { args ->
+            args.addAll(pluginArgsEncoder.encode(context, this))
+            args.addAll(inputs.kotlinSourcesList)
+            args.addAll(inputs.javaSourcesList)
+            context.executeCompilerTask(args, false, compiler::compile)
+        }
+    }
+
+    /**
+     * Return a list with the common arguments.
+     */
+    private fun JvmCompilationTask.getCommonArgs(): MutableList<String> {
+        val args = mutableListOf<String>()
+
+        // use -- for flags not meant for the kotlin compiler
+        args.addAll(
+            "-cp", inputs.joinedClasspath,
+            "-api-version", info.toolchainInfo.common.apiVersion,
+            "-language-version", info.toolchainInfo.common.languageVersion,
+            "-jvm-target", info.toolchainInfo.jvm.jvmTarget,
+            // https://github.com/bazelbuild/rules_kotlin/issues/69: remove once jetbrains adds a flag for it.
+            "--friend-paths", info.friendPathsList.joinToString(File.pathSeparator)
+        )
+
+        args
+            .addAll("-module-name", info.moduleName)
+            .addAll("-d", directories.classes)
+
+        info.passthroughFlags?.takeIf { it.isNotBlank() }?.also { args.addAll(it.split(" ")) }
+        return args
+    }
+
     private fun JvmCompilationTask.runAnnotationProcessors(
         context: CompilationTaskContext
     ): JvmCompilationTask =
@@ -90,7 +128,7 @@
             if (info.plugins.annotationProcessorsList.isEmpty()) {
                 this
             } else {
-                val kaptOutput = kotlinCompiler.runAnnotationProcessor(context, this)
+                val kaptOutput = runAnnotationProcessor(context)
                 context.whenTracing { printLines("kapt output", kaptOutput) }
                 expandWithGeneratedSources()
             }
@@ -114,7 +152,7 @@
             it.execute()
         }
 
-    private fun JvmCompilationTask.compileClasses(context: CompilationTaskContext) {
+    private fun JvmCompilationTask.compileAll(context: CompilationTaskContext) {
         ensureDirectories(
             directories.classes
         )
@@ -122,7 +160,7 @@
         var result: List<String>? = null
         context.execute("kotlinc") {
             result = try {
-                kotlinCompiler.compile(this)
+                compileKotlin(context)
             } catch (ex: CompilationStatusException) {
                 kotlinError = ex
                 ex.lines
@@ -139,6 +177,16 @@
     }
 
     /**
+     * Compiles Kotlin sources to classes. Does not compile Java sources.
+     */
+    fun JvmCompilationTask.compileKotlin(context: CompilationTaskContext): List<String> =
+        getCommonArgs().let { args ->
+            args.addAll(inputs.javaSourcesList)
+            args.addAll(inputs.kotlinSourcesList)
+            context.executeCompilerTask(args, false, compiler::compile)
+        }
+
+    /**
      * If any srcjars were provided expand the jars sources and create a new [JvmCompilationTask] with the
      * Java and Kotlin sources merged in.
      */
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt b/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
index 1f39682..3b74053 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
@@ -108,6 +108,10 @@
             getCodeMethod = exitCodeClass.getMethod("getCode")
         }
 
+        // Kotlin error codes:
+        // 1 is a standard compilation error
+        // 2 is an internal error
+        // 3 is the script execution error
         fun compile(args: Array<String>, out: PrintStream): Int {
             val exitCodeInstance = execMethod.invoke(compiler, out, args)
             return getCodeMethod.invoke(exitCodeInstance, *NO_ARGS) as Int
@@ -118,6 +122,11 @@
     class KotlincInvoker @Inject constructor(
         toolchain: KotlinToolchain
     ) : KotlinCliToolInvoker(toolchain, "io.bazel.kotlin.compiler.BazelK2JVMCompiler")
+
+    @Singleton
+    class K2JSCompilerInvoker @Inject constructor(
+        toolchain: KotlinToolchain
+    ) : KotlinCliToolInvoker(toolchain, "org.jetbrains.kotlin.cli.js.K2JSCompiler")
 }
 
 
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/utils/CompilationTaskContext.kt b/kotlin/builder/src/io/bazel/kotlin/builder/utils/CompilationTaskContext.kt
index fc85d0a..8712d88 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/utils/CompilationTaskContext.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/utils/CompilationTaskContext.kt
@@ -18,7 +18,10 @@
 
 import com.google.protobuf.MessageOrBuilder
 import com.google.protobuf.TextFormat
+import io.bazel.kotlin.builder.toolchain.CompilationStatusException
 import io.bazel.kotlin.model.CompilationTaskInfo
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
 import java.io.File
 import java.io.PrintStream
 import java.nio.file.Paths
@@ -35,7 +38,9 @@
         isTracing = debugging.contains("trace")
     }
 
-    fun reportUnhandledException(throwable: Throwable) { throwable.printStackTrace(out) }
+    fun reportUnhandledException(throwable: Throwable) {
+        throwable.printStackTrace(out)
+    }
 
     /**
      * Print a list of debugging lines.
@@ -57,7 +62,9 @@
     }
 
     inline fun <T> whenTracing(block: CompilationTaskContext.() -> T): T? {
-        return if(isTracing) { block() } else null
+        return if (isTracing) {
+            block()
+        } else null
     }
 
     /**
@@ -82,6 +89,31 @@
     }
 
     /**
+     * Execute a compilation task.
+     *
+     * @throws CompilationStatusException if the compiler returns a status of anything but zero.
+     * @param args the compiler command line switches
+     * @param deliverOutput if this is true the output will be printed to out directly.
+     * @param compile the compilation method.
+     */
+    inline fun executeCompilerTask(
+        args: List<String>,
+        deliverOutput: Boolean,
+        compile: (Array<String>, PrintStream) -> Int
+    ): List<String> {
+        val outputStream = ByteArrayOutputStream()
+        val ps = PrintStream(outputStream)
+        val result = compile(args.toTypedArray(), ps)
+        val output = ByteArrayInputStream(outputStream.toByteArray()).bufferedReader().readLines()
+        if (result != 0) {
+            throw CompilationStatusException("compile phase failed", result, output)
+        } else if(deliverOutput) {
+            printCompilerOutput(output)
+        }
+        return output
+    }
+
+    /**
      * Runs a task and records the timings.
      */
     fun <T> execute(name: String, task: () -> T): T {
@@ -104,7 +136,7 @@
      * @param succesfull true if the task finished succesfully.
      */
     fun finalize(succesfull: Boolean) {
-        if(succesfull) {
+        if (succesfull) {
             timings?.also { printLines("Task timings", it, prefix = "  * ") }
         }
     }
diff --git a/kotlin/internal/BUILD b/kotlin/internal/BUILD
index 37e64eb..6561c52 100644
--- a/kotlin/internal/BUILD
+++ b/kotlin/internal/BUILD
@@ -10,4 +10,28 @@
 # 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.
\ No newline at end of file
+# limitations under the License.
+load("//kotlin/internal:toolchains.bzl", "define_kt_toolchain")
+
+config_setting(
+    name = "builder_debug_timings",
+    values = { "define": "kt_timings=1" }
+)
+
+config_setting(
+    name = "builder_debug_trace",
+    values = { "define": "kt_trace=1" }
+)
+
+define_kt_toolchain(
+    name = "default_toolchain",
+    debug=
+        select({
+            ":builder_debug_trace": ["trace"],
+            "//conditions:default": []
+        }) +
+        select({
+            ":builder_debug_timings": ["timings"],
+            "//conditions:default": []
+        })
+)
\ No newline at end of file
diff --git a/kotlin/internal/bootstrap.bzl b/kotlin/internal/bootstrap.bzl
deleted file mode 100644
index 05cbbaf..0000000
--- a/kotlin/internal/bootstrap.bzl
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# 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.
-"""This file contains rules used to bootstrap the compiler repository."""
-
-load("//kotlin/internal:kt.bzl", "kt")
-load("//kotlin/internal:rules.bzl", _kt_jvm_import_impl="kt_jvm_import_impl")
-load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_archive="http_archive")
-
-def _kt_toolchain_ide_info_impl(ctx):
-    tc=ctx.toolchains[kt.defs.TOOLCHAIN_TYPE]
-    info = struct(
-        label = tc.label,
-        common = struct(
-            language_version = tc.language_version,
-            api_version = tc.api_version,
-            coroutines = tc.coroutines
-        ),
-        jvm = struct(
-            jvm_target = tc.jvm_target,
-        )
-    )
-    ctx.actions.write(ctx.outputs.ide_info, info.to_json())
-    return [DefaultInfo(files=depset([ctx.outputs.ide_info]))]
-
-kt_toolchain_ide_info = rule(
-    outputs = {"ide_info": "kt_toolchain_ide_info.json"},
-    toolchains = [kt.defs.TOOLCHAIN_TYPE],
-    implementation = _kt_toolchain_ide_info_impl,
-)
-
-def github_archive(name, repo, commit, build_file_content = None):
-    if build_file_content:
-        _http_archive(
-            name = name,
-            strip_prefix = "%s-%s" % (repo.split("/")[1], commit),
-            url = "https://github.com/%s/archive/%s.zip" % (repo, commit),
-            type = "zip",
-            build_file_content = build_file_content,
-        )
-    else:
-        _http_archive(
-            name = name,
-            strip_prefix = "%s-%s" % (repo.split("/")[1], commit),
-            url = "https://github.com/%s/archive/%s.zip" % (repo, commit),
-            type = "zip",
-        )
diff --git a/kotlin/internal/common/BUILD b/kotlin/internal/common/BUILD
new file mode 100644
index 0000000..9c0f139
--- /dev/null
+++ b/kotlin/internal/common/BUILD
@@ -0,0 +1,13 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
diff --git a/kotlin/internal/common/common.bzl b/kotlin/internal/common/common.bzl
new file mode 100644
index 0000000..ceee057
--- /dev/null
+++ b/kotlin/internal/common/common.bzl
@@ -0,0 +1,49 @@
+load("//kotlin/internal:defs.bzl", _TOOLCHAIN_TYPE="TOOLCHAIN_TYPE")
+
+def _restore_label(l):
+    lbl = l.workspace_root
+    if lbl.startswith("external/"):
+        lbl = lbl.replace("external/", "@")
+    return lbl + "//" + l.package + ":" + l.name
+
+def _derive_module_name(ctx):
+    module_name=getattr(ctx.attr, "module_name", "")
+    if module_name == "":
+        module_name = (ctx.label.package.lstrip("/").replace("/","_") + "-" + ctx.label.name.replace("/", "_"))
+    return module_name
+
+def _init_builder_args(ctx, rule_kind, module_name):
+    toolchain=ctx.toolchains[_TOOLCHAIN_TYPE]
+
+    args = ctx.actions.args()
+    args.set_param_file_format("multiline")
+    args.use_param_file("--flagfile=%s", use_always=True)
+
+    args.add("--target_label", ctx.label)
+    args.add("--rule_kind", rule_kind)
+    args.add("--kotlin_module_name", module_name)
+
+    args.add("--kotlin_jvm_target", toolchain.jvm_target)
+    args.add("--kotlin_api_version", toolchain.api_version)
+    args.add("--kotlin_language_version", toolchain.language_version)
+    args.add("--kotlin_passthrough_flags", "-Xcoroutines=%s" % toolchain.coroutines)
+
+    debug = depset(toolchain.debug)
+    for tag in ctx.attr.tags:
+        if tag == "trace":
+            debug = debug + [tag]
+        if tag == "timings":
+            debug = debug + [tag]
+    args.add("--kotlin_debug", debug)
+
+    return args
+
+def _declare_output_directory(ctx, aspect, dir_name):
+    return ctx.actions.declare_directory("_kotlinc/%s_%s/%s_%s" % (ctx.label.name, aspect, ctx.label.name, dir_name))
+
+common = struct(
+    init_args = _init_builder_args,
+    declare_output_directory = _declare_output_directory,
+    restore_label = _restore_label,
+    derive_module_name = _derive_module_name,
+)
\ No newline at end of file
diff --git a/kotlin/internal/compile.bzl b/kotlin/internal/compile.bzl
deleted file mode 100644
index 47e45a4..0000000
--- a/kotlin/internal/compile.bzl
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# 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.
-load("//kotlin/internal:kt.bzl", "kt")
-load("//kotlin/internal:plugins.bzl", "plugins")
-load("//kotlin/internal:utils.bzl", "utils")
-
-def _declare_output_directory(ctx, aspect, dir_name):
-    return ctx.actions.declare_directory("_kotlinc/%s_%s/%s_%s" % (ctx.label.name, aspect, ctx.label.name, dir_name))
-
-def _common_init_args(ctx, rule_kind, module_name):
-    toolchain=ctx.toolchains[kt.defs.TOOLCHAIN_TYPE]
-
-    args = ctx.actions.args()
-    args.set_param_file_format("multiline")
-    args.use_param_file("--flagfile=%s", use_always=True)
-
-    args.add("--target_label", ctx.label)
-    args.add("--rule_kind", rule_kind)
-    args.add("--kotlin_module_name", module_name)
-
-    args.add("--kotlin_jvm_target", toolchain.jvm_target)
-    args.add("--kotlin_api_version", toolchain.api_version)
-    args.add("--kotlin_language_version", toolchain.language_version)
-    args.add("--kotlin_passthrough_flags", "-Xcoroutines=%s" % toolchain.coroutines)
-
-    debug = depset(toolchain.debug)
-    for tag in ctx.attr.tags:
-        if tag == "trace":
-            debug = debug + [tag]
-        if tag == "timings":
-            debug = debug + [tag]
-    args.add("--kotlin_debug", debug)
-
-    return args
-
-def _kotlin_do_compile_action(ctx, rule_kind, output_jar, compile_jars, module_name, friend_paths, srcs):
-    """This macro performs a compile operation in a single action.
-
-    Args:
-      rule_kind: The rule kind,
-      output_jar: The jar file that this macro will use as the output of the action.
-      module_name: The Kotlin module name, this must be provided and is used by the compiler for symbol mangling in
-         advanced use cases.
-      compile_jars: The compile time jars provided on the classpath for the compile operations -- callers are
-        responsible for preparing the classpath. The stdlib (and jdk7 + jdk8) should generally be added to the classpath
-        by the caller -- kotlin-reflect could be optional.
-      friend_paths: A list of jars paths that this compilation unit should have package private access to.
-      srcs: a struct with the various input sources partitioned.
-    """
-    classes_directory=_declare_output_directory(ctx, "jvm", "classes")
-    generated_classes_directory=_declare_output_directory(ctx, "jvm", "generated_classes")
-    sourcegen_directory=_declare_output_directory(ctx, "jvm", "sourcegenfiles")
-    temp_directory=_declare_output_directory(ctx, "jvm", "temp")
-
-    toolchain=ctx.toolchains[kt.defs.TOOLCHAIN_TYPE]
-    args = _common_init_args(ctx, rule_kind, module_name)
-
-    args.add("--classdir", classes_directory)
-    args.add("--sourcegendir", sourcegen_directory)
-    args.add("--tempdir", temp_directory)
-    args.add("--kotlin_generated_classdir", generated_classes_directory)
-
-    args.add("--output", output_jar)
-    args.add("--kotlin_output_jdeps", ctx.outputs.jdeps)
-    args.add("--kotlin_output_srcjar", ctx.outputs.srcjar)
-
-    args.add("--kotlin_friend_paths", "\n".join(friend_paths.to_list()))
-
-    args.add("--classpath", compile_jars)
-    args.add_all("--sources", srcs.all_srcs, omit_if_empty=True)
-    args.add_all("--source_jars", srcs.src_jars, omit_if_empty=True)
-
-    # Collect and prepare plugin descriptor for the worker.
-    plugin_info=plugins.merge_plugin_infos(ctx.attr.plugins + ctx.attr.deps)
-    if len(plugin_info.annotation_processors) > 0:
-        args.add("--kotlin_plugins", plugin_info.to_json())
-
-    progress_message = "Compiling Kotlin %s { kt: %d, java: %d, srcjars: %d }" % (
-        ctx.label,
-        len(srcs.kt),
-        len(srcs.java),
-        len(srcs.src_jars)
-    )
-
-    inputs, _, input_manifests = ctx.resolve_command(tools = [toolchain.kotlinbuilder])
-    ctx.actions.run(
-        mnemonic = "KotlinCompile",
-        inputs = depset(inputs) + ctx.files.srcs + compile_jars,
-        outputs = [
-            output_jar,
-            ctx.outputs.jdeps,
-            ctx.outputs.srcjar,
-            sourcegen_directory,
-            classes_directory,
-            temp_directory,
-            generated_classes_directory
-        ],
-        executable = toolchain.kotlinbuilder.files_to_run.executable,
-        execution_requirements = {"supports-workers": "1"},
-        arguments = [args],
-        progress_message = progress_message,
-        input_manifests = input_manifests
-    )
-
-def _make_providers(ctx, java_info, module_name, transitive_files=depset(order="default")):
-    kotlin_info=kt.info.KtInfo(
-        srcs=ctx.files.srcs,
-        module_name = module_name,
-        # intelij aspect needs this.
-        outputs = struct(
-            jdeps = ctx.outputs.jdeps,
-            jars = [struct(
-              class_jar = ctx.outputs.jar,
-              ijar = None,
-              source_jars = [ctx.outputs.srcjar]
-            )]
-        ),
-    )
-
-    default_info = DefaultInfo(
-        files=depset([ctx.outputs.jar]),
-        runfiles=ctx.runfiles(
-            transitive_files=transitive_files,
-            collect_default=True
-        ),
-    )
-
-    return struct(
-        kt=kotlin_info,
-        providers=[java_info,default_info,kotlin_info],
-    )
-
-def _compile_action(ctx, rule_kind, module_name, friend_paths=depset(), src_jars=[]):
-    """Setup a kotlin compile action.
-
-    Args:
-        ctx: The rule context.
-    Returns:
-        A JavaInfo struct for the output jar that this macro will build.
-    """
-    # The main output jars
-    output_jar = ctx.outputs.jar
-
-    # The output of the compile step may be combined (folded) with other entities -- e.g., other class files from annotation processing, embedded resources.
-    kt_compile_output_jar=output_jar
-    # the list of jars to merge into the final output, start with the resource jars if any were provided.
-    output_merge_list=ctx.files.resource_jars
-
-    # If this rule has any resources declared setup a zipper action to turn them into a jar and then add the declared zipper output to the merge list.
-    if len(ctx.files.resources) > 0:
-        output_merge_list = output_merge_list + [utils.actions.build_resourcejar(ctx)]
-
-    # If this compile operation requires merging other jars setup the compile operation to go to a intermediate file and add that file to the merge list.
-    if len(output_merge_list) > 0:
-        # Intermediate jar containing the Kotlin compile output.
-        kt_compile_output_jar=ctx.new_file(ctx.label.name + "-ktclass.jar")
-        # If we setup indirection than the first entry in the merge list is the result of the kotlin compile action.
-        output_merge_list=[ kt_compile_output_jar ] + output_merge_list
-
-    srcs = utils.partition_srcs(ctx.files.srcs)
-
-    if (len(srcs.kt) + len(srcs.java) == 0) and len(srcs.src_jars) == 0:
-        fail("no sources provided")
-
-    toolchain=ctx.toolchains[kt.defs.TOOLCHAIN_TYPE]
-
-    deps = [
-        d[JavaInfo]
-        for d in (
-            getattr(ctx.attr, "friends", []) +
-            ctx.attr.deps
-        )
-    ] + [toolchain.jvm_stdlibs]
-
-    # setup the compile action.
-    _kotlin_do_compile_action(
-        ctx,
-        rule_kind = rule_kind,
-        output_jar = kt_compile_output_jar,
-        compile_jars = java_common.merge(deps).compile_jars,
-        module_name = module_name,
-        friend_paths = friend_paths,
-        srcs = srcs
-    )
-
-    # setup the merge action if needed.
-    if len(output_merge_list) > 0:
-        utils.actions.fold_jars(ctx, rule_kind, output_jar, output_merge_list)
-
-    # create the java provider but the kotlin and default provider cannot be created here.
-    return JavaInfo(
-        output_jar = ctx.outputs.jar,
-        compile_jar = ctx.outputs.jar,
-        source_jar = ctx.outputs.srcjar,
-#        jdeps = ctx.outputs.jdeps,
-        deps = deps,
-        runtime_deps = [d[JavaInfo] for d in ctx.attr.runtime_deps],
-        exports = [d[JavaInfo] for d in getattr(ctx.attr, "exports", [])],
-        neverlink = getattr(ctx.attr, "neverlink", False)
-    )
-
-compile = struct(
-    compile_action = _compile_action,
-    make_providers = _make_providers,
-)
diff --git a/kotlin/internal/defs.bzl b/kotlin/internal/defs.bzl
new file mode 100644
index 0000000..e1d23c1
--- /dev/null
+++ b/kotlin/internal/defs.bzl
@@ -0,0 +1,27 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.#
+
+# The Kotlin Toolchain type.
+TOOLCHAIN_TYPE = "@io_bazel_rules_kotlin//kotlin:kt_toolchain_type"
+
+# The name of the Kotlin compiler workspace.
+KT_COMPILER_REPO = "com_github_jetbrains_kotlin"
+
+KtInfo = provider(
+    fields = {
+        "module_name": "the module name",
+        "srcs": "the source files. [intelij-aspect]",
+        "outputs": "output jars produced by this rule. [intelij-aspect]",
+    },
+)
diff --git a/kotlin/internal/jvm/BUILD b/kotlin/internal/jvm/BUILD
new file mode 100644
index 0000000..37e64eb
--- /dev/null
+++ b/kotlin/internal/jvm/BUILD
@@ -0,0 +1,13 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
\ No newline at end of file
diff --git a/kotlin/internal/jvm/compile.bzl b/kotlin/internal/jvm/compile.bzl
new file mode 100644
index 0000000..465c730
--- /dev/null
+++ b/kotlin/internal/jvm/compile.bzl
@@ -0,0 +1,288 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
+load("//kotlin/internal:defs.bzl", "KtInfo", "TOOLCHAIN_TYPE")
+load("//kotlin/internal/jvm:plugins.bzl", "plugins")
+load("//kotlin/internal/common:common.bzl", "common")
+
+# MISC UTILS ###########################################################################################################
+def _partition_srcs(srcs):
+    kt_srcs = []
+    java_srcs = []
+    src_jars = []
+
+    for f in srcs:
+        if f.path.endswith(".kt"):
+            kt_srcs.append(f)
+        elif f.path.endswith(".java"):
+            java_srcs.append(f)
+        elif f.path.endswith(".srcjar"):
+            src_jars.append(f)
+
+    kt = depset(kt_srcs)
+    java = depset(java_srcs)
+
+    return struct (
+        kt = kt,
+        java = java,
+        all_srcs = kt + java,
+        src_jars = depset(src_jars)
+    )
+
+# JAR ACTIONS ##########################################################################################################
+def _fold_jars_action(ctx, rule_kind, output_jar, input_jars):
+    args=[
+        "--normalize",
+        "--compression",
+        "--deploy_manifest_lines",
+            "Target-Label: %s" % str(ctx.label),
+            "Injecting-Rule-Kind: %s" % rule_kind,
+        "--output", output_jar.path
+    ]
+    for i in input_jars:
+        args += ["--sources", i.path]
+    ctx.action(
+        mnemonic = "KotlinFoldOutput",
+        inputs = input_jars,
+        outputs = [output_jar],
+        executable = ctx.executable._singlejar,
+        arguments = args,
+        progress_message="Merging Kotlin output jar " + output_jar.short_path
+    )
+
+_CONVENTIONAL_RESOURCE_PATHS = [
+    "src/main/resources",
+    "src/test/resources",
+]
+
+def _adjust_resources_path_by_strip_prefix(path, resource_strip_prefix):
+    if not path.startswith(resource_strip_prefix):
+      fail("Resource file %s is not under the specified prefix to strip" % path)
+
+    clean_path = path[len(resource_strip_prefix):]
+    return resource_strip_prefix, clean_path
+
+def _adjust_resources_path_by_default_prefixes(path):
+    for cp in _CONVENTIONAL_RESOURCE_PATHS:
+        dir_1, dir_2, rel_path = path.partition(cp)
+        if rel_path:
+            return  dir_1 + dir_2, rel_path
+    return "", path
+
+def _adjust_resources_path(path, resource_strip_prefix):
+    if resource_strip_prefix:
+      return _adjust_resources_path_by_strip_prefix(path,resource_strip_prefix)
+    else:
+      return _adjust_resources_path_by_default_prefixes(path)
+
+def _add_resources_cmd(ctx):
+    res_cmd = []
+    for f in ctx.files.resources:
+        c_dir, res_path = _adjust_resources_path(f.short_path, ctx.attr.resource_strip_prefix)
+        target_path = res_path
+        if target_path[0] == "/":
+            target_path = target_path[1:]
+        line = "{target_path}={c_dir}{res_path}\n".format(
+            res_path=res_path,
+            target_path=target_path,
+            c_dir=c_dir)
+        res_cmd.extend([line])
+    return "".join(res_cmd)
+
+def _build_resourcejar_action(ctx):
+    resources = _add_resources_cmd(ctx)
+    resources_jar_output = ctx.actions.declare_file(ctx.label.name + "-resources.jar")
+    zipper_arg_path = ctx.actions.declare_file("%s_resources_zipper_args" % ctx.label.name)
+    ctx.file_action(zipper_arg_path, resources)
+    cmd = """
+rm -f {resources_jar_output}
+{zipper} c {resources_jar_output} @{path}
+""".format(
+        path=zipper_arg_path.path,
+        resources_jar_output=resources_jar_output.path,
+        zipper=ctx.executable._zipper.path,
+    )
+    ctx.action(
+        mnemonic="KotlinZipResourceJar",
+        inputs=ctx.files.resources + [ctx.executable._zipper,zipper_arg_path],
+        outputs=[resources_jar_output],
+        command=cmd,
+        progress_message="Creating intermediate resource jar %s" % ctx.label,
+        arguments=[]
+    )
+    return resources_jar_output
+
+def kt_jvm_compile_action(ctx, rule_kind, output_jar, srcs):
+    """This macro performs a compile operation in a single action.
+
+    Args:
+      rule_kind: The rule kind,
+      output_jar: The jar file that this macro will use as the output of the action.
+      module_name: The Kotlin module name, this must be provided and is used by the compiler for symbol mangling in
+         advanced use cases.
+      compile_jars: The compile time jars provided on the classpath for the compile operations -- callers are
+        responsible for preparing the classpath. The stdlib (and jdk7 + jdk8) should generally be added to the classpath
+        by the caller -- kotlin-reflect could be optional.
+      friend_paths: A list of jars paths that this compilation unit should have package private access to.
+      srcs: a struct with the various input sources partitioned.
+    """
+    toolchain=ctx.toolchains[TOOLCHAIN_TYPE]
+
+    friends=getattr(ctx.attr, "friends", [])
+    deps = [d[JavaInfo] for d in friends + ctx.attr.deps] + [toolchain.jvm_stdlibs]
+    compile_jars = java_common.merge(deps).compile_jars
+
+    if len(friends) == 0:
+        module_name=common.derive_module_name(ctx)
+        friend_paths=depset()
+    elif len(friends) == 1:
+        if friends[0][KtInfo] == None:
+            fail("only kotlin dependencies can be friends")
+        elif ctx.attr.module_name:
+            fail("if friends has been set then module_name cannot be provided")
+        else:
+            friend_paths=depset([j.path for j in friends[0][JavaInfo].compile_jars])
+            module_name = friends[0][KtInfo].module_name
+    else:
+        fail("only one friend is possible")
+
+    classes_directory=common.declare_output_directory(ctx, "jvm", "classes")
+    generated_classes_directory=common.declare_output_directory(ctx, "jvm", "generated_classes")
+    sourcegen_directory=common.declare_output_directory(ctx, "jvm", "sourcegenfiles")
+    temp_directory=common.declare_output_directory(ctx, "jvm", "temp")
+
+    args = common.init_args(ctx, rule_kind, module_name)
+
+    args.add("--classdir", classes_directory)
+    args.add("--sourcegendir", sourcegen_directory)
+    args.add("--tempdir", temp_directory)
+    args.add("--kotlin_generated_classdir", generated_classes_directory)
+
+    args.add("--output", output_jar)
+    args.add("--kotlin_output_jdeps", ctx.outputs.jdeps)
+    args.add("--kotlin_output_srcjar", ctx.outputs.srcjar)
+
+    args.add("--kotlin_friend_paths", "\n".join(friend_paths.to_list()))
+
+    args.add("--classpath", compile_jars)
+    args.add_all("--sources", srcs.all_srcs, omit_if_empty=True)
+    args.add_all("--source_jars", srcs.src_jars, omit_if_empty=True)
+
+    # Collect and prepare plugin descriptor for the worker.
+    plugin_info=plugins.merge_plugin_infos(ctx.attr.plugins + ctx.attr.deps)
+    if len(plugin_info.annotation_processors) > 0:
+        args.add("--kotlin_plugins", plugin_info.to_json())
+
+    progress_message = "Compiling Kotlin %s { kt: %d, java: %d, srcjars: %d }" % (
+        ctx.label,
+        len(srcs.kt),
+        len(srcs.java),
+        len(srcs.src_jars)
+    )
+
+    inputs, _, input_manifests = ctx.resolve_command(tools = [toolchain.kotlinbuilder])
+    ctx.actions.run(
+        mnemonic = "KotlinCompile",
+        inputs = depset(inputs) + ctx.files.srcs + compile_jars,
+        outputs = [
+            output_jar,
+            ctx.outputs.jdeps,
+            ctx.outputs.srcjar,
+            sourcegen_directory,
+            classes_directory,
+            temp_directory,
+            generated_classes_directory
+        ],
+        executable = toolchain.kotlinbuilder.files_to_run.executable,
+        execution_requirements = {"supports-workers": "1"},
+        arguments = [args],
+        progress_message = progress_message,
+        input_manifests = input_manifests
+    )
+
+    # create the java provider and the kotlin provider. Whilst a struct is being returned, and this is a valid way of
+    # creating a provider, it is intended that the client transforms this into an form.
+    return struct(
+        java=JavaInfo(
+            output_jar = ctx.outputs.jar,
+            compile_jar = ctx.outputs.jar,
+            source_jar = ctx.outputs.srcjar,
+        #  jdeps = ctx.outputs.jdeps,
+            deps = deps,
+            runtime_deps = [d[JavaInfo] for d in ctx.attr.runtime_deps],
+            exports = [d[JavaInfo] for d in getattr(ctx.attr, "exports", [])],
+            neverlink = getattr(ctx.attr, "neverlink", False)
+        ),
+        kt=KtInfo(
+            srcs=ctx.files.srcs,
+            module_name = module_name,
+            # intelij aspect needs this.
+            outputs = struct(
+                jdeps = ctx.outputs.jdeps,
+                jars = [struct(
+                  class_jar = ctx.outputs.jar,
+                  ijar = None,
+                  source_jars = [ctx.outputs.srcjar]
+                )]
+            ),
+        )
+    )
+
+def kt_jvm_produce_jar_actions(ctx, rule_kind, src_jars=[]):
+    """Setup a kotlin compile action. This method takes care of all of the aspects of producing a jar.
+
+    Specifically this action will conditionally set up actions to fold resources and resourcejars and merge them onto a
+    jar compiled by the builder. It indirects the output_jar -- i.e., if no resources or resource jars are present it
+    won't do anything.
+
+    Args:
+        ctx: The rule context.
+    Returns:
+        A JavaInfo struct for the output jar that this macro will build.
+    """
+    # The main output jars
+    output_jar = ctx.outputs.jar
+
+    # The output of the compile step may be combined (folded) with other entities -- e.g., other class files from annotation processing, embedded resources.
+    kt_compile_output_jar=output_jar
+    # the list of jars to merge into the final output, start with the resource jars if any were provided.
+    output_merge_list=ctx.files.resource_jars
+
+    # If this rule has any resources declared setup a zipper action to turn them into a jar and then add the declared zipper output to the merge list.
+    if len(ctx.files.resources) > 0:
+        output_merge_list = output_merge_list + [_build_resourcejar_action(ctx)]
+
+    # If this compile operation requires merging other jars setup the compile operation to go to a intermediate file and add that file to the merge list.
+    if len(output_merge_list) > 0:
+        # Intermediate jar containing the Kotlin compile output.
+        kt_compile_output_jar=ctx.new_file(ctx.label.name + "-ktclass.jar")
+        # If we setup indirection than the first entry in the merge list is the result of the kotlin compile action.
+        output_merge_list=[ kt_compile_output_jar ] + output_merge_list
+
+    srcs = _partition_srcs(ctx.files.srcs)
+
+    if (len(srcs.kt) + len(srcs.java) == 0) and len(srcs.src_jars) == 0:
+        fail("no sources provided")
+
+    # setup the merge action if needed.
+    if len(output_merge_list) > 0:
+        _fold_jars_action(ctx, rule_kind, output_jar, output_merge_list)
+
+    # setup the compile action.
+    return kt_jvm_compile_action(
+        ctx,
+        rule_kind = rule_kind,
+        output_jar = kt_compile_output_jar,
+        srcs = srcs
+    )
+
diff --git a/kotlin/internal/jvm/impl.bzl b/kotlin/internal/jvm/impl.bzl
new file mode 100644
index 0000000..bbc2133
--- /dev/null
+++ b/kotlin/internal/jvm/impl.bzl
@@ -0,0 +1,159 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
+load("//kotlin/internal/jvm:compile.bzl", _kt_jvm_produce_jar_actions="kt_jvm_produce_jar_actions")
+load("//kotlin/internal:defs.bzl", _KtJvmInfo="KtJvmInfo")
+
+def _make_providers(ctx, providers, transitive_files=depset(order="default")):
+    return struct(
+        kt=providers.kt,
+        providers=[
+            providers.java,
+            providers.kt,
+            DefaultInfo(
+                files=depset([ctx.outputs.jar]),
+                runfiles=ctx.runfiles(
+                    transitive_files=transitive_files,
+                    collect_default=True
+                ),
+            )
+        ],
+    )
+
+def _write_launcher_action(ctx, rjars, main_class, jvm_flags, args="", wrapper_preamble=""):
+    """Macro that writes out a launcher script shell script.
+      Args:
+        rjars: All of the runtime jars required to launch this java target.
+        main_class: the main class to launch.
+        jvm_flags: The flags that should be passed to the jvm.
+        args: Args that should be passed to the Binary.
+    """
+    classpath = ":".join(["${RUNPATH}%s" % (j.short_path) for j in rjars.to_list()])
+    jvm_flags = " ".join([ctx.expand_location(f, ctx.attr.data) for f in jvm_flags])
+    template = ctx.attr._java_stub_template.files.to_list()[0]
+
+    ctx.actions.expand_template(
+        template = template,
+        output = ctx.outputs.executable,
+        substitutions = {
+            "%classpath%": classpath,
+            "%java_start_class%": main_class,
+            "%javabin%": "JAVABIN=${RUNPATH}" + ctx.executable._java.short_path,
+            "%jvm_flags%": jvm_flags,
+            "%set_jacoco_metadata%": "",
+            "%workspace_prefix%": ctx.workspace_name + "/",
+        },
+        is_executable = True,
+    )
+
+def kt_jvm_import_impl(ctx):
+    jars = depset()
+    source_jars = depset()
+    runtime_jars = depset()
+    transitive_compile_time_jars = depset()
+    transitive_runtime_jars = depset()
+
+    if ctx.file.srcjar:
+        source_jars += [ctx.file.srcjar]
+
+    if hasattr(ctx.attr, "runtime_deps"):
+        for jar in ctx.attr.runtime_deps:
+            transitive_runtime_jars += jar[JavaInfo].transitive_runtime_jars
+
+    for jar in ctx.attr.jars:
+        if JavaInfo in jar:
+          jars += jar[JavaInfo].full_compile_jars
+          source_jars += jar[JavaInfo].transitive_source_jars
+          transitive_compile_time_jars += jar[JavaInfo].transitive_compile_time_jars
+          transitive_runtime_jars += jar[JavaInfo].transitive_runtime_jars
+        else:
+            for file in jar.files:
+                if file.basename.endswith("-sources.jar"):
+                    source_jars += [file]
+                elif file.basename.endswith(".jar"):
+                    jars += [file]
+                else:
+                    fail("a jar pointing to a filegroup must either end with -sources.jar or .jar")
+
+    runtime_jars += jars
+    transitive_compile_time_jars += jars
+    transitive_runtime_jars += jars
+
+    java_info = java_common.create_provider(
+        use_ijar = False,
+        source_jars=source_jars,
+        compile_time_jars = jars,
+        runtime_jars= runtime_jars,
+        transitive_compile_time_jars=transitive_compile_time_jars,
+        transitive_runtime_jars=transitive_runtime_jars
+    )
+
+    # This is needed for intellij plugin, try to pair up jars with their sources so that the sources are mounted
+    # correctly.
+    source_tally = {}
+    for sj in source_jars.to_list():
+        if sj.basename.endswith("-sources.jar"):
+            source_tally[sj.basename.replace("-sources.jar", ".jar")] = sj
+    artifacts = []
+    for jar in jars.to_list():
+        if jar.basename in source_tally:
+            artifacts += [struct(class_jar=jar, source_jar=source_tally[jar.basename], ijar = None)]
+        else:
+            artifacts += [struct(class_jar=jar, ijar = None)]
+
+    kotlin_info=_KtJvmInfo(outputs=struct(jars=artifacts))
+    default_info = DefaultInfo(files=depset(jars))
+    return struct(kt = kotlin_info, providers= [default_info, java_info, kotlin_info])
+
+def kt_jvm_library_impl(ctx):
+    return _make_providers(
+        ctx,
+        _kt_jvm_produce_jar_actions(ctx, "kt_jvm_library")
+    )
+
+def kt_jvm_binary_impl(ctx):
+    providers = _kt_jvm_produce_jar_actions(ctx, "kt_jvm_binary")
+    _write_launcher_action(
+        ctx,
+        providers.java.transitive_runtime_jars,
+        ctx.attr.main_class,
+        ctx.attr.jvm_flags
+    )
+    return _make_providers(
+        ctx,
+        providers,
+        depset(
+            order = "default",
+            transitive=[providers.java.transitive_runtime_jars],
+            direct=[ctx.executable._java]
+        ),
+    )
+
+def kt_jvm_junit_test_impl(ctx):
+    providers = _kt_jvm_produce_jar_actions(ctx, "kt_jvm_test")
+    runtime_jars=providers.java.transitive_runtime_jars + ctx.files._bazel_test_runner
+    _write_launcher_action(
+        ctx,
+        runtime_jars,
+        main_class = ctx.attr.main_class,
+        jvm_flags = ["-ea", "-Dbazel.test_suite=%s"% ctx.attr.test_class] + ctx.attr.jvm_flags,
+    )
+    return _make_providers(
+        ctx,
+        providers,
+        depset(
+            order = "default",
+            transitive=[runtime_jars],
+            direct=[ctx.executable._java]
+        ),
+    )
\ No newline at end of file
diff --git a/kotlin/internal/jvm/jvm.bzl b/kotlin/internal/jvm/jvm.bzl
new file mode 100644
index 0000000..ad12784
--- /dev/null
+++ b/kotlin/internal/jvm/jvm.bzl
@@ -0,0 +1,355 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
+"""Kotlin Rules
+
+### Setup
+
+Add the following snippet to your `WORKSPACE` file:
+
+```bzl
+git_repository(
+    name = "io_bazel_rules_kotlin",
+    remote = "https://github.com/bazelbuild/rules_kotlin.git",
+    commit = "<COMMIT_HASH>",
+)
+load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains")
+kotlin_repositories(kotlin_release_version = "1.2.21")
+kt_register_toolchains()
+```
+
+To enable persistent worker support, add the following to the appropriate `bazelrc` file:
+
+```
+build --strategy=KotlinCompile=worker
+test --strategy=KotlinCompile=worker
+```
+
+
+### Standard Libraries
+
+The Kotlin libraries that are bundled in a kotlin release should be used with the rules, the mandatory standard libraries are added implicetly. After enabling
+the repository the following Kotlin Libraries are also made available from the workspace `com_github_jetbrains_kotlin`:
+
+* `kotlin-test`,
+* `kotlin-reflect`.
+
+So if you needed to add reflect as a dep use the following label `@com_github_jetbrains_kotlin//:kotlin-reflect`.
+
+### Mixed Mode compilation
+
+The JVM rules can compile both Java and Kotlin sources. The Java compiler wrapper is not optimized or persistent and does not have the features found in the
+native java rules. This mode is usefull for migrating a package to Kotlin over time.
+
+### Annotation Processing
+
+Annotation processing works just as it does in Java, plugins are declared via a [`java_plugin`](https://docs.bazel.build/versions/master/be/java.html#java_plugin)
+and may also be inherited from a `java_library` via the `exported_plugins` attribute. Annotation work in mixed-mode compilation and the Kotlin compiler take
+care of processing both aspects.
+
+An example which can be found under `//examples/dagger`:
+
+```bzl
+java_plugin(
+    name = "dagger_plugin",
+    deps = [
+        "@dagger_compiler//jar",
+        "@guava//jar",
+        "@dagger_producers//jar",
+        "@dagger//jar",
+        "@javax_inject//jar"
+    ],
+    processor_class = "dagger.internal.codegen.ComponentProcessor"
+)
+
+java_library(
+    name = "dagger_lib",
+    exports = [
+        "@javax_inject//jar",
+        "@dagger//jar",
+    ],
+    exported_plugins = ["dagger_plugin"]
+)
+
+kt_jvm_binary(
+    name = "dagger",
+    srcs = glob(["src/**"]),
+    main_class = "coffee.CoffeeApp",
+    deps = [":dagger_lib"],
+)
+```
+"""
+# This file is the main import -- it shouldn't grow out of hand the reason it contains so much allready is due to the limitations of skydoc.
+
+########################################################################################################################
+# Common Definitions
+########################################################################################################################
+load("//kotlin/internal:defs.bzl","KtInfo","TOOLCHAIN_TYPE")
+# struct can't be used till skydoc is removed
+load(
+    "//kotlin/internal/jvm:plugins.bzl",
+    _kt_jvm_plugin_aspect="kt_jvm_plugin_aspect",
+)
+# struct can't be used till skydoc is removed
+load("//kotlin/internal/jvm:impl.bzl",
+    "kt_jvm_binary_impl",
+    "kt_jvm_import_impl",
+    "kt_jvm_junit_test_impl",
+    "kt_jvm_library_impl",
+)
+
+
+########################################################################################################################
+# Rule Attributes
+########################################################################################################################
+_implicit_deps = {
+    "_kotlin_toolchain": attr.label_list(
+        default = [
+            Label("@io_bazel_rules_kotlin//kotlin:kt_toolchain_ide_info"),
+        ],
+        cfg="host",
+        allow_files = False,
+    ),
+    "_singlejar": attr.label(
+        executable = True,
+        cfg = "host",
+        default = Label("@bazel_tools//tools/jdk:singlejar"),
+        allow_files = True,
+    ),
+    "_zipper": attr.label(
+        executable = True,
+        cfg = "host",
+        default = Label("@bazel_tools//tools/zip:zipper"),
+        allow_files = True,
+    ),
+    "_java": attr.label(
+        executable = True,
+        cfg = "host",
+        default = Label("@bazel_tools//tools/jdk:java"),
+        allow_files = True,
+    ),
+    "_java_stub_template": attr.label(
+        cfg = "host",
+        default = Label("@kt_java_stub_template//file"),
+    ),
+}
+
+_common_attr = dict(_implicit_deps.items() + {
+    "srcs": attr.label_list(
+        default = [],
+        allow_files = [".srcjar", ".kt", ".java"],
+    ),
+    "deps": attr.label_list(
+        aspects = [_kt_jvm_plugin_aspect],
+        providers=[
+            [JavaInfo],
+        ],
+        allow_files = False),
+    "runtime_deps": attr.label_list(default = [], allow_files=False),
+    "resources": attr.label_list(
+        default = [],
+        allow_files = True,
+    ),
+    "resource_strip_prefix": attr.string(default = ""),
+    "resource_jars": attr.label_list(default = []),
+    "data": attr.label_list(
+        allow_files = True,
+        cfg = "data",
+    ),
+    "plugins": attr.label_list(
+        default = [],
+        aspects = [_kt_jvm_plugin_aspect],
+    ),
+    "module_name": attr.string(
+        mandatory = False
+    ),
+}.items())
+
+_runnable_common_attr = dict(_common_attr.items() + {
+    "jvm_flags": attr.string_list(
+        default = [],
+    ),
+}.items())
+
+########################################################################################################################
+# Outputs: All the outputs produced by the various rules are modelled here.
+########################################################################################################################
+_common_outputs = dict(
+    jar = "%{name}.jar",
+    jdeps = "%{name}.jdeps",
+    # The params file, declared here so that validate it can be validated for testing.
+#    jar_2_params = "%{name}.jar-2.params",
+    srcjar = "%{name}-sources.jar",
+)
+
+_binary_outputs = dict(_common_outputs.items() + {
+}.items())
+
+
+
+########################################################################################################################
+# Simple Rules:
+########################################################################################################################
+kt_jvm_library = rule(
+    attrs = dict(_common_attr.items() + {
+        "exports": attr.label_list(default = [], providers=[JavaInfo]),
+        "neverlink": attr.bool(default=False),
+    }.items()),
+    outputs = _common_outputs,
+    toolchains = [TOOLCHAIN_TYPE],
+    implementation = kt_jvm_library_impl,
+    provides = [JavaInfo, KtInfo]
+)
+
+"""This rule compiles and links Kotlin and Java sources into a .jar file.
+Args:
+  srcs: The list of source files that are processed to create the target, this can contain both Java and Kotlin files. Java analysis occurs first so Kotlin
+    classes may depend on Java classes in the same compilation unit.
+  exports: Exported libraries.
+
+    Deps listed here will be made available to other rules, as if the parents explicitly depended on these deps.
+    This is not true for regular (non-exported) deps.
+  resources: A list of data files to include in a Java jar.
+  resource_strip_prefix: The path prefix to strip from Java resources, files residing under common prefix such as `src/main/resources` or `src/test/resources`
+    will have stripping applied by convention.
+  resource_jars: Set of archives containing Java resources. If specified, the contents of these jars are merged into the output jar.
+  runtime_deps: Libraries to make available to the final binary or test at runtime only. Like ordinary deps, these will appear on the runtime classpath, but
+    unlike them, not on the compile-time classpath.
+  data: The list of files needed by this rule at runtime. See general comments about `data` at [Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).
+  deps: A list of dependencies of this rule.See general comments about `deps` at [Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).
+  module_name: The name of the module, if not provided the module name is derived from the label. --e.g., `//some/package/path:label_name` is translated to
+    `some_package_path-label_name`.
+  neverlink: If true only use this library for compilation and not at runtime.
+"""
+
+kt_jvm_binary = rule(
+    attrs = dict(_runnable_common_attr.items() + {
+        "main_class": attr.string(mandatory = True)
+    }.items()),
+    executable = True,
+    outputs = _binary_outputs,
+    toolchains = [TOOLCHAIN_TYPE],
+    implementation = kt_jvm_binary_impl,
+)
+
+"""Builds a Java archive ("jar file"), plus a wrapper shell script with the same name as the rule. The wrapper shell script uses a classpath that includes,
+among other things, a jar file for each library on which the binary depends.
+
+**Note:** This rule does not have all of the features found in [`java_binary`](https://docs.bazel.build/versions/master/be/java.html#java_binary). It is
+appropriate for building workspace utilities. `java_binary` should be preferred for release artefacts.
+
+Args:
+  main_class: Name of class with main() method to use as entry point.
+  jvm_flags: A list of flags to embed in the wrapper script generated for running this binary. Note: does not yet support make variable substitution.
+"""
+
+kt_jvm_test = rule(
+    attrs = dict(_runnable_common_attr.items() + {
+        "_bazel_test_runner": attr.label(
+            default = Label("@bazel_tools//tools/jdk:TestRunner_deploy.jar"),
+            allow_files = True,
+        ),
+        "friends": attr.label_list(
+            default = [],
+            providers = [JavaInfo, KtInfo]
+        ),
+        "test_class": attr.string(),
+        "main_class": attr.string(default="com.google.testing.junit.runner.BazelTestRunner"),
+    }.items()),
+    executable = True,
+    outputs = _binary_outputs,
+    test = True,
+    toolchains = [TOOLCHAIN_TYPE],
+    implementation = kt_jvm_junit_test_impl,
+)
+
+"""Setup a simple kotlin_test.
+
+**Notes:**
+* The kotlin test library is not added implicitly, it is available with the label `@com_github_jetbrains_kotlin//:kotlin-test`.
+
+Args:
+  test_class: The Java class to be loaded by the test runner.
+  friends: A single Kotlin dep which allows the test code access to internal members. Currently uses the output jar of
+    the module -- i.e., exported deps won't be included.
+"""
+
+kt_jvm_import = rule(
+    attrs = {
+        "jars": attr.label_list(
+            allow_files = True,
+            mandatory = True,
+            cfg = "target",
+        ),
+        "srcjar": attr.label(
+            allow_single_file = True,
+            cfg = "target",
+        ),
+        "runtime_deps": attr.label_list(
+            default = [],
+            mandatory = False,
+            providers = [JavaInfo]
+        )
+    },
+    implementation = kt_jvm_import_impl,
+    provides = [JavaInfo, KtInfo]
+)
+
+# The pairing of src and class is used by intellij to attatch sources, this is picked up via the kt provider attribute.
+#
+# once current format and semantics are finalized add runtime_deps, exports, data, neverlink, testonly.
+#   * runtime_deps should accept JavaInfo's (this includes KotlinInfo) and maven_jar filegroups.
+#   * exports should only accept JavaInfo's (this include KotlinInfo) but not filegroup. The jars attribute takes care of importing the jars without generating
+#     ijars.
+"""(experimental) Import Kotlin jars.
+
+**Status:** This rule is not a counterpart to `java_import`. The current purpose for this rule is to import a kotlin jar without creating ijars. It will
+eventually [be replaced](https://github.com/bazelbuild/rules_kotlin/issues/4) with `java_import`. If there is a need for expanding this rule we can instead
+create a utility macro that delegates to this.
+
+## examples
+
+```bzl
+# Old style usage -- reference file groups, do not used this.
+kt_jvm_import(
+    name = "kodein",
+    jars = [
+        "@com_github_salomonbrys_kodein_kodein//jar:file",
+        "@com_github_salomonbrys_kodein_kodein_core//jar:file"
+    ]
+)
+
+# This style will pull in the transitive runtime dependencies of the targets as well.
+kt_jvm_import(
+    name = "kodein",
+    jars = [
+        "@com_github_salomonbrys_kodein_kodein//jar",
+        "@com_github_salomonbrys_kodein_kodein_core//jar"
+    ]
+)
+
+# Import a single kotlin jar.
+kt_jvm_import(
+    name = "kotlin-runtime",
+    jars = ["lib/kotlin-runtime.jar"],
+    srcjar = "lib/kotlin-runtime-sources.jar"
+)
+```
+
+Args:
+  jars: The jars listed here are equavalent to an export attribute. The label should be either to a single class jar, or multiple filegroup labels. When the
+    labels is a file_provider it should follow the conventions used in repositories generated by the maven_jar rule  --i.e., the rule expects a file_provider
+    with a single class jar and a single source jar. a source jar is recognized by the suffix `-sources.jar`.
+  srcjar: The sources for the class jar. This should be set when importing a single class jar.
+  runtime_deps: Additional runtime deps.
+"""
diff --git a/kotlin/internal/plugins.bzl b/kotlin/internal/jvm/plugins.bzl
similarity index 77%
rename from kotlin/internal/plugins.bzl
rename to kotlin/internal/jvm/plugins.bzl
index 1a29eae..ab61a6f 100644
--- a/kotlin/internal/plugins.bzl
+++ b/kotlin/internal/jvm/plugins.bzl
@@ -11,7 +11,14 @@
 # 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.
-load("//kotlin/internal:kt.bzl", "kt")
+KtJvmPluginInfo = provider(
+    doc = "This provider contains the plugin info for the JVM aspect",
+    fields = {
+        "annotation_processors": "a serializeable list of structs containing annotation processor definitions",
+    },
+)
+
+_EMPTY_PLUGIN_INFO = [KtJvmPluginInfo(annotation_processors = [])]
 
 def _mk_processor_entry(l,p):
     merged_info=java_common.merge([j[JavaInfo] for j in p.deps])
@@ -27,12 +34,14 @@
 def _merge_plugin_infos(attrs):
     tally={}
     annotation_processors=[]
-    for info in [a[kt.info.KtPluginInfo] for a in attrs]:
+    for info in [a[KtJvmPluginInfo] for a in attrs]:
         for p in info.annotation_processors:
             if p.label not in tally:
                 tally[p.label] = True
                 annotation_processors.append(p)
-    return kt.info.KtPluginInfo(annotation_processors=annotation_processors)
+    return KtJvmPluginInfo(
+        annotation_processors=annotation_processors
+    )
 
 def _restore_label(l):
     lbl = l.workspace_root
@@ -40,11 +49,9 @@
         lbl = lbl.replace("external/", "@")
     return lbl + "//" + l.package + ":" + l.name
 
-_EMPTY_PLUGIN_INFO = [kt.info.KtPluginInfo(annotation_processors = [])]
-
 def _kt_jvm_plugin_aspect_impl(target, ctx):
     if ctx.rule.kind == "java_plugin":
-        return [kt.info.KtPluginInfo(
+        return [KtJvmPluginInfo(
             annotation_processors = [_mk_processor_entry(_restore_label(ctx.label),ctx.rule.attr)]
         )]
     else:
@@ -54,10 +61,13 @@
           return _EMPTY_PLUGIN_INFO
 
 kt_jvm_plugin_aspect = aspect(
+    doc = """This aspect processes collects Java Plugins info so that annotation processors may be configured for a
+rule.""",
     attr_aspects = [
         "plugins",
         "exported_plugins",
     ],
+    provides = [KtJvmPluginInfo],
     implementation = _kt_jvm_plugin_aspect_impl,
 )
 
diff --git a/kotlin/internal/kt.bzl b/kotlin/internal/kt.bzl
deleted file mode 100644
index c660e70..0000000
--- a/kotlin/internal/kt.bzl
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# 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.
-########################################################################################################################
-# Providers
-########################################################################################################################
-_defs = struct(
-    DEFAULT_TOOLCHAIN = "@io_bazel_rules_kotlin//kotlin:default_toolchain",
-    # The name of the Kotlin compiler workspace.
-    KT_COMPILER_REPO = "com_github_jetbrains_kotlin",
-    # The name of the rules repo. Centralised so it's easy to change.
-    REPO_ROOT = "io_bazel_rules_kotlin",
-    TOOLCHAIN_TYPE = "@io_bazel_rules_kotlin//kotlin:kt_toolchain_type",
-)
-
-_KtInfo = provider(
-    fields = {
-        "srcs": "the source files. [intelij-aspect]",
-        "module_name": "the module name",
-        "outputs": "output jars produced by this rule. [intelij-aspect]",
-    },
-)
-
-_KtPluginInfo = provider(
-    fields = {
-        "annotation_processors": "a serializeable list of structs containing an annotation processor definitions",
-    },
-)
-
-kt = struct(
-    defs = _defs,
-    info = struct(
-        KtInfo = _KtInfo,
-        KtPluginInfo = _KtPluginInfo,
-    ),
-)
diff --git a/kotlin/internal/repositories/BUILD b/kotlin/internal/repositories/BUILD
new file mode 100644
index 0000000..37e64eb
--- /dev/null
+++ b/kotlin/internal/repositories/BUILD
@@ -0,0 +1,13 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
\ No newline at end of file
diff --git a/kotlin/BUILD.com_github_jetbrains_kotlin b/kotlin/internal/repositories/BUILD.com_github_jetbrains_kotlin
similarity index 100%
rename from kotlin/BUILD.com_github_jetbrains_kotlin
rename to kotlin/internal/repositories/BUILD.com_github_jetbrains_kotlin
diff --git a/kotlin/kotlin_releases.bzl b/kotlin/internal/repositories/compiler_releases.bzl
similarity index 100%
rename from kotlin/kotlin_releases.bzl
rename to kotlin/internal/repositories/compiler_releases.bzl
diff --git a/kotlin/internal/repositories/repositories.bzl b/kotlin/internal/repositories/repositories.bzl
new file mode 100644
index 0000000..3faa13c
--- /dev/null
+++ b/kotlin/internal/repositories/repositories.bzl
@@ -0,0 +1,78 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
+"""This file contains the Kotlin compiler repository definitions. It should not be loaded directly by client workspaces.
+"""
+load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_file="http_file", _http_archive="http_archive")
+load("//kotlin/internal:defs.bzl", "KT_COMPILER_REPO")
+load("//kotlin/internal/repositories:compiler_releases.bzl", "KOTLIN_COMPILER_RELEASES", "KOTLIN_CURRENT_RELEASE")
+load("//third_party/jvm:workspace.bzl", _maven_dependencies="maven_dependencies")
+
+_BAZEL_JAVA_LAUNCHER_VERSION = "0.8.1"
+
+def github_archive(name, repo, commit, build_file_content = None):
+    if build_file_content:
+        _http_archive(
+            name = name,
+            strip_prefix = "%s-%s" % (repo.split("/")[1], commit),
+            url = "https://github.com/%s/archive/%s.zip" % (repo, commit),
+            type = "zip",
+            build_file_content = build_file_content,
+        )
+    else:
+        _http_archive(
+            name = name,
+            strip_prefix = "%s-%s" % (repo.split("/")[1], commit),
+            url = "https://github.com/%s/archive/%s.zip" % (repo, commit),
+            type = "zip",
+        )
+
+def _compiler_repositories(kotlin_release_version):
+    """
+    Prime the compiler repository.
+
+    This function should not be called directly instead `kotlin_repositories` from `//kotlin:kotlin.bzl` should be
+    called to ensure common deps are loaded.
+    """
+    release=KOTLIN_COMPILER_RELEASES[kotlin_release_version]
+    if not release:
+        fail('"%s" not a valid kotlin release, current release is "%s"' % (kotlin_release_version, KOTLIN_CURRENT_RELEASE))
+
+    _http_archive(
+        name = KT_COMPILER_REPO,
+        url = release["url"],
+        sha256 = release["sha256"],
+        build_file= "@io_bazel_rules_kotlin//kotlin/internal/repositories:BUILD.com_github_jetbrains_kotlin",
+        strip_prefix = "kotlinc",
+    )
+
+    _http_file(
+        name = "kt_java_stub_template",
+        urls = [("https://raw.githubusercontent.com/bazelbuild/bazel/" +
+               _BAZEL_JAVA_LAUNCHER_VERSION +
+           "/src/main/java/com/google/devtools/build/lib/bazel/rules/java/" +
+           "java_stub_template.txt")],
+        sha256 = "86660ee7d5b498ccf611a1e000564f45268dbf301e0b2b08c984dcecc6513f6e",
+    )
+
+def kotlin_repositories(
+    kotlin_release_version=KOTLIN_CURRENT_RELEASE
+):
+    """Call this in the WORKSPACE file to setup the Kotlin rules.
+
+    Args:
+      kotlin_release_version: The kotlin compiler release version. If this is not set the latest release version is
+      chosen by default.
+    """
+    _maven_dependencies()
+    _compiler_repositories(kotlin_release_version)
diff --git a/kotlin/internal/rules.bzl b/kotlin/internal/rules.bzl
deleted file mode 100644
index 79ee8b1..0000000
--- a/kotlin/internal/rules.bzl
+++ /dev/null
@@ -1,140 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# 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.
-
-load("//kotlin/internal:compile.bzl", "compile")
-load("//kotlin/internal:kt.bzl", "kt")
-load("//kotlin/internal:utils.bzl", "utils")
-
-def kt_jvm_import_impl(ctx):
-    jars = depset()
-    source_jars = depset()
-    runtime_jars = depset()
-    transitive_compile_time_jars = depset()
-    transitive_runtime_jars = depset()
-
-    if ctx.file.srcjar:
-        source_jars += [ctx.file.srcjar]
-
-    if hasattr(ctx.attr, "runtime_deps"):
-        for jar in ctx.attr.runtime_deps:
-            transitive_runtime_jars += jar[JavaInfo].transitive_runtime_jars
-
-    for jar in ctx.attr.jars:
-        if JavaInfo in jar:
-          jars += jar[JavaInfo].full_compile_jars
-          source_jars += jar[JavaInfo].transitive_source_jars
-          transitive_compile_time_jars += jar[JavaInfo].transitive_compile_time_jars
-          transitive_runtime_jars += jar[JavaInfo].transitive_runtime_jars
-        else:
-            for file in jar.files:
-                if file.basename.endswith("-sources.jar"):
-                    source_jars += [file]
-                elif file.basename.endswith(".jar"):
-                    jars += [file]
-                else:
-                    fail("a jar pointing to a filegroup must either end with -sources.jar or .jar")
-
-    runtime_jars += jars
-    transitive_compile_time_jars += jars
-    transitive_runtime_jars += jars
-
-    java_info = java_common.create_provider(
-        use_ijar = False,
-        source_jars=source_jars,
-        compile_time_jars = jars,
-        runtime_jars= runtime_jars,
-        transitive_compile_time_jars=transitive_compile_time_jars,
-        transitive_runtime_jars=transitive_runtime_jars
-    )
-
-    # This is needed for intellij plugin, try to pair up jars with their sources so that the sources are mounted
-    # correctly.
-    source_tally = {}
-    for sj in source_jars.to_list():
-        if sj.basename.endswith("-sources.jar"):
-            source_tally[sj.basename.replace("-sources.jar", ".jar")] = sj
-    artifacts = []
-    for jar in jars.to_list():
-        if jar.basename in source_tally:
-            artifacts += [struct(class_jar=jar, source_jar=source_tally[jar.basename], ijar = None)]
-        else:
-            artifacts += [struct(class_jar=jar, ijar = None)]
-
-    kotlin_info=kt.info.KtInfo(outputs=struct(jars=artifacts))
-    default_info = DefaultInfo(files=depset(jars))
-    return struct(kt = kotlin_info, providers= [default_info, java_info, kotlin_info])
-
-def kt_jvm_library_impl(ctx):
-    module_name=utils.derive_module_name(ctx)
-    return compile.make_providers(
-        ctx,
-        compile.compile_action(ctx, "kt_jvm_library", module_name),
-        module_name,
-  )
-
-def kt_jvm_binary_impl(ctx):
-    module_name=utils.derive_module_name(ctx)
-    java_info = compile.compile_action(ctx, "kt_jvm_binary", module_name)
-    utils.actions.write_launcher(
-        ctx,
-        java_info.transitive_runtime_jars,
-        ctx.attr.main_class,
-        ctx.attr.jvm_flags
-    )
-    return compile.make_providers(
-        ctx,
-        java_info,
-        module_name,
-        depset(
-            order = "default",
-            transitive=[java_info.transitive_runtime_jars],
-            direct=[ctx.executable._java]
-        ),
-    )
-
-def kt_jvm_junit_test_impl(ctx):
-    module_name=utils.derive_module_name(ctx)
-    friend_paths=depset()
-
-    friends=getattr(ctx.attr, "friends", [])
-    if len(friends) > 1:
-        fail("only one friend is possible")
-    elif len(friends) == 1:
-        if friends[0][kt.info.KtInfo] == None:
-            fail("only kotlin dependencies can be friends")
-        else:
-            friend_paths += [j.path for j in friends[0][JavaInfo].compile_jars]
-            module_name = friends[0][kt.info.KtInfo].module_name
-
-    java_info = compile.compile_action(ctx, "kt_jvm_test", module_name,friend_paths)
-
-    transitive_runtime_jars = java_info.transitive_runtime_jars + ctx.files._bazel_test_runner
-    launcherJvmFlags = ["-ea", "-Dbazel.test_suite=%s"% ctx.attr.test_class]
-
-    utils.actions.write_launcher(
-        ctx,
-        transitive_runtime_jars,
-        main_class = ctx.attr.main_class,
-        jvm_flags = launcherJvmFlags + ctx.attr.jvm_flags,
-    )
-    return compile.make_providers(
-        ctx,
-        java_info,
-        module_name,
-        depset(
-            order = "default",
-            transitive=[transitive_runtime_jars],
-            direct=[ctx.executable._java]
-        ),
-    )
\ No newline at end of file
diff --git a/kotlin/toolchains.bzl b/kotlin/internal/toolchains.bzl
similarity index 81%
rename from kotlin/toolchains.bzl
rename to kotlin/internal/toolchains.bzl
index c61c8ce..01e07bf 100644
--- a/kotlin/toolchains.bzl
+++ b/kotlin/internal/toolchains.bzl
@@ -11,14 +11,9 @@
 # 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.
-load(
-    "//kotlin/internal:utils.bzl",
-    _utils = "utils",
-)
-load(
-    "//kotlin/internal:kt.bzl",
-    _kt = "kt",
-)
+
+load("//kotlin/internal/common:common.bzl", _common="common")
+load("//kotlin/internal:defs.bzl", _TOOLCHAIN_TYPE="TOOLCHAIN_TYPE", _KT_COMPILER_REPO="KT_COMPILER_REPO")
 
 """Kotlin Toolchains
 
@@ -43,7 +38,7 @@
 ```
 """
 
-_KT_COMPILER_REPO="com_github_jetbrains_kotlin"
+
 
 # The toolchain rules are not made private, at least the jvm ones so that they may be introspected in Intelij.
 _common_attrs = {
@@ -114,7 +109,7 @@
 
 def _kotlin_toolchain_impl(ctx):
     toolchain = dict(
-        label = _utils.restore_label(ctx.label),
+        label = _common.restore_label(ctx.label),
         language_version = ctx.attr.language_version,
         api_version = ctx.attr.api_version,
         coroutines = ctx.attr.coroutines,
@@ -149,6 +144,10 @@
   coroutines: the -Xcoroutines flag, enabled by default as it's considered production ready 1.2.0 onward.
 """
 
+def kt_register_toolchains():
+    """This macro registers all of the default toolchains."""
+    native.register_toolchains("@io_bazel_rules_kotlin//kotlin/internal:default_toolchain")
+
 def define_kt_toolchain(
     name,
     language_version=None,
@@ -172,7 +171,30 @@
     )
     native.toolchain(
         name = name,
-        toolchain_type = _kt.defs.TOOLCHAIN_TYPE,
+        toolchain_type = _TOOLCHAIN_TYPE,
         toolchain = impl_name,
         visibility = ["//visibility:public"]
     )
+
+def _kt_toolchain_ide_info_impl(ctx):
+    tc=ctx.toolchains[_TOOLCHAIN_TYPE]
+    info = struct(
+        label = tc.label,
+        common = struct(
+            language_version = tc.language_version,
+            api_version = tc.api_version,
+            coroutines = tc.coroutines
+        ),
+        jvm = struct(
+            jvm_target = tc.jvm_target,
+        )
+    )
+    ctx.actions.write(ctx.outputs.ide_info, info.to_json())
+    return [DefaultInfo(files=depset([ctx.outputs.ide_info]))]
+
+kt_toolchain_ide_info = rule(
+    outputs = {"ide_info": "kt_toolchain_ide_info.json"},
+    toolchains = [_TOOLCHAIN_TYPE],
+    implementation = _kt_toolchain_ide_info_impl,
+)
+
diff --git a/kotlin/internal/utils.bzl b/kotlin/internal/utils.bzl
deleted file mode 100644
index c141584..0000000
--- a/kotlin/internal/utils.bzl
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# 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.
-
-load(
-    "//kotlin/internal:kt.bzl",
-    kt = "kt",
-)
-
-# MISC UTILS ###################################################################################################################################################
-def _restore_label(l):
-    lbl = l.workspace_root
-    if lbl.startswith("external/"):
-        lbl = lbl.replace("external/", "@")
-    return lbl + "//" + l.package + ":" + l.name
-
-def _derive_module_name(ctx):
-    module_name=getattr(ctx.attr, "module_name", "")
-    if module_name == "":
-        module_name = (ctx.label.package.lstrip("/").replace("/","_") + "-" + ctx.label.name.replace("/", "_"))
-    return module_name
-
-def _partition_srcs(srcs):
-    kt_srcs = []
-    java_srcs = []
-    src_jars = []
-
-    for f in srcs:
-        if f.path.endswith(".kt"):
-            kt_srcs.append(f)
-        elif f.path.endswith(".java"):
-            java_srcs.append(f)
-        elif f.path.endswith(".srcjar"):
-            src_jars.append(f)
-
-    kt = depset(kt_srcs)
-    java = depset(java_srcs)
-
-    return struct (
-        kt = kt,
-        java = java,
-        all_srcs = kt + java,
-        src_jars = depset(src_jars)
-    )
-# RESOURCE JARS ################################################################################################################################################
-_CONVENTIONAL_RESOURCE_PATHS = [
-    "src/main/resources",
-    "src/test/resources",
-]
-
-def _adjust_resources_path_by_strip_prefix(path, resource_strip_prefix):
-    if not path.startswith(resource_strip_prefix):
-      fail("Resource file %s is not under the specified prefix to strip" % path)
-
-    clean_path = path[len(resource_strip_prefix):]
-    return resource_strip_prefix, clean_path
-
-def _adjust_resources_path_by_default_prefixes(path):
-    for cp in _CONVENTIONAL_RESOURCE_PATHS:
-        dir_1, dir_2, rel_path = path.partition(cp)
-        if rel_path:
-            return  dir_1 + dir_2, rel_path
-    return "", path
-
-def _adjust_resources_path(path, resource_strip_prefix):
-    if resource_strip_prefix:
-      return _adjust_resources_path_by_strip_prefix(path,resource_strip_prefix)
-    else:
-      return _adjust_resources_path_by_default_prefixes(path)
-
-def _add_resources_cmd(ctx):
-    res_cmd = []
-    for f in ctx.files.resources:
-        c_dir, res_path = _adjust_resources_path(f.short_path, ctx.attr.resource_strip_prefix)
-        target_path = res_path
-        if target_path[0] == "/":
-            target_path = target_path[1:]
-        line = "{target_path}={c_dir}{res_path}\n".format(
-            res_path=res_path,
-            target_path=target_path,
-            c_dir=c_dir)
-        res_cmd.extend([line])
-    return "".join(res_cmd)
-
-def _build_resourcejar_action(ctx):
-    resources = _add_resources_cmd(ctx)
-    resources_jar_output = ctx.actions.declare_file(ctx.label.name + "-resources.jar")
-    zipper_arg_path = ctx.actions.declare_file("%s_resources_zipper_args" % ctx.label.name)
-    ctx.file_action(zipper_arg_path, resources)
-    cmd = """
-rm -f {resources_jar_output}
-{zipper} c {resources_jar_output} @{path}
-""".format(
-        path=zipper_arg_path.path,
-        resources_jar_output=resources_jar_output.path,
-        zipper=ctx.executable._zipper.path,
-    )
-    ctx.action(
-        mnemonic="KotlinZipResourceJar",
-        inputs=ctx.files.resources + [ctx.executable._zipper,zipper_arg_path],
-        outputs=[resources_jar_output],
-        command=cmd,
-        progress_message="Creating intermediate resource jar %s" % ctx.label,
-        arguments=[]
-    )
-    return resources_jar_output
-# PACKAGE JARS #################################################################################################################################################
-def _fold_jars_action(ctx, rule_kind, output_jar, input_jars):
-    args=[
-        "--normalize",
-        "--compression",
-        "--deploy_manifest_lines",
-            "Target-Label: %s" % str(ctx.label),
-            "Injecting-Rule-Kind: %s" % rule_kind,
-        "--output", output_jar.path
-    ]
-    for i in input_jars:
-        args += ["--sources", i.path]
-    ctx.action(
-        mnemonic = "KotlinFoldOutput",
-        inputs = input_jars,
-        outputs = [output_jar],
-        executable = ctx.executable._singlejar,
-        arguments = args,
-        progress_message="Merging Kotlin output jar " + output_jar.short_path
-    )
-
-# JVM LAUNCH SCRIPTS ###########################################################################################################################################
-def _write_launcher_action(ctx, rjars, main_class, jvm_flags, args="", wrapper_preamble=""):
-    """Macro that writes out a launcher script shell script.
-      Args:
-        rjars: All of the runtime jars required to launch this java target.
-        main_class: the main class to launch.
-        jvm_flags: The flags that should be passed to the jvm.
-        args: Args that should be passed to the Binary.
-    """
-    classpath = ":".join(["${RUNPATH}%s" % (j.short_path) for j in rjars.to_list()])
-    jvm_flags = " ".join([ctx.expand_location(f, ctx.attr.data) for f in jvm_flags])
-    template = ctx.attr._java_stub_template.files.to_list()[0]
-
-    ctx.actions.expand_template(
-        template = template,
-        output = ctx.outputs.executable,
-        substitutions = {
-            "%classpath%": classpath,
-            "%java_start_class%": main_class,
-            "%javabin%": "JAVABIN=${RUNPATH}" + ctx.executable._java.short_path,
-            "%jvm_flags%": jvm_flags,
-            "%set_jacoco_metadata%": "",
-            "%workspace_prefix%": ctx.workspace_name + "/",
-        },
-        is_executable = True,
-    )
-
-# EXPORT #######################################################################################################################################################
-utils = struct(
-    actions = struct(
-        build_resourcejar = _build_resourcejar_action,
-        fold_jars = _fold_jars_action,
-        write_launcher = _write_launcher_action,
-    ),
-    restore_label = _restore_label,
-    derive_module_name = _derive_module_name,
-    partition_srcs = _partition_srcs
-)
diff --git a/kotlin/kotlin.bzl b/kotlin/kotlin.bzl
index f9920af..7bad54c 100644
--- a/kotlin/kotlin.bzl
+++ b/kotlin/kotlin.bzl
@@ -1,4 +1,4 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
+# Copyright 2017 The Bazel Authors. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -11,370 +11,12 @@
 # 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.
-"""Kotlin Rules
+load("//kotlin/internal/repositories:repositories.bzl", "kotlin_repositories")
+load("//kotlin/internal:toolchains.bzl", "kt_register_toolchains")
 
-### Setup
-
-Add the following snippet to your `WORKSPACE` file:
-
-```bzl
-git_repository(
-    name = "io_bazel_rules_kotlin",
-    remote = "https://github.com/bazelbuild/rules_kotlin.git",
-    commit = "<COMMIT_HASH>",
-)
-load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains")
-kotlin_repositories(kotlin_release_version = "1.2.21")
-kt_register_toolchains()
-```
-
-To enable persistent worker support, add the following to the appropriate `bazelrc` file:
-
-```
-build --strategy=KotlinCompile=worker
-test --strategy=KotlinCompile=worker
-```
-
-
-### Standard Libraries
-
-The Kotlin libraries that are bundled in a kotlin release should be used with the rules, the mandatory standard libraries are added implicetly. After enabling
-the repository the following Kotlin Libraries are also made available from the workspace `com_github_jetbrains_kotlin`:
-
-* `kotlin-test`,
-* `kotlin-reflect`.
-
-So if you needed to add reflect as a dep use the following label `@com_github_jetbrains_kotlin//:kotlin-reflect`.
-
-### Mixed Mode compilation
-
-The JVM rules can compile both Java and Kotlin sources. The Java compiler wrapper is not optimized or persistent and does not have the features found in the
-native java rules. This mode is usefull for migrating a package to Kotlin over time.
-
-### Annotation Processing
-
-Annotation processing works just as it does in Java, plugins are declared via a [`java_plugin`](https://docs.bazel.build/versions/master/be/java.html#java_plugin)
-and may also be inherited from a `java_library` via the `exported_plugins` attribute. Annotation work in mixed-mode compilation and the Kotlin compiler take
-care of processing both aspects.
-
-An example which can be found under `//examples/dagger`:
-
-```bzl
-java_plugin(
-    name = "dagger_plugin",
-    deps = [
-        "@dagger_compiler//jar",
-        "@guava//jar",
-        "@dagger_producers//jar",
-        "@dagger//jar",
-        "@javax_inject//jar"
-    ],
-    processor_class = "dagger.internal.codegen.ComponentProcessor"
-)
-
-java_library(
-    name = "dagger_lib",
-    exports = [
-        "@javax_inject//jar",
-        "@dagger//jar",
-    ],
-    exported_plugins = ["dagger_plugin"]
-)
-
-kt_jvm_binary(
-    name = "dagger",
-    srcs = glob(["src/**"]),
-    main_class = "coffee.CoffeeApp",
-    deps = [":dagger_lib"],
-)
-```
-"""
-# This file is the main import -- it shouldn't grow out of hand the reason it contains so much allready is due to the limitations of skydoc.
-
-########################################################################################################################
-# Common Definitions
-########################################################################################################################
-
-load(
-    "//kotlin/internal:kt.bzl",
-    _kt = "kt",
-)
-# struct can't be used till skydoc is removed
-load(
-    "//kotlin/internal:plugins.bzl",
-    _kt_jvm_plugin_aspect="kt_jvm_plugin_aspect",
-)
-# struct can't be used till skydoc is removed
-load(
-    "//kotlin/internal:rules.bzl",
-    _kt_jvm_binary_impl = "kt_jvm_binary_impl",
-    _kt_jvm_import_impl = "kt_jvm_import_impl",
-    _kt_jvm_junit_test_impl = "kt_jvm_junit_test_impl",
-    _kt_jvm_library_impl = "kt_jvm_library_impl",
-)
-load("//kotlin:kotlin_releases.bzl", "KOTLIN_CURRENT_RELEASE")
-load(
-    "//kotlin:kotlin_compiler_repositories.bzl",
-    _kotlin_compiler_repository = "kotlin_compiler_repositories",
-)
-load("//third_party/jvm:workspace.bzl", _maven_dependencies="maven_dependencies")
-
-########################################################################################################################
-# Rule Attributes
-########################################################################################################################
-_implicit_deps = {
-    "_kotlin_toolchain": attr.label_list(
-        default = [
-            Label("@io_bazel_rules_kotlin//kotlin:kt_toolchain_ide_info"),
-        ],
-        cfg="host",
-        allow_files = False,
-    ),
-    "_singlejar": attr.label(
-        executable = True,
-        cfg = "host",
-        default = Label("@bazel_tools//tools/jdk:singlejar"),
-        allow_files = True,
-    ),
-    "_zipper": attr.label(
-        executable = True,
-        cfg = "host",
-        default = Label("@bazel_tools//tools/zip:zipper"),
-        allow_files = True,
-    ),
-    "_java": attr.label(
-        executable = True,
-        cfg = "host",
-        default = Label("@bazel_tools//tools/jdk:java"),
-        allow_files = True,
-    ),
-    "_java_stub_template": attr.label(
-        cfg = "host",
-        default = Label("@kt_java_stub_template//file"),
-    ),
-}
-
-_common_attr = dict(_implicit_deps.items() + {
-    "srcs": attr.label_list(
-        default = [],
-        allow_files = [".srcjar", ".kt", ".java"],
-    ),
-    "deps": attr.label_list(
-        aspects = [_kt_jvm_plugin_aspect],
-        providers=[
-            [JavaInfo],
-        ],
-        allow_files = False),
-    "runtime_deps": attr.label_list(default = [], allow_files=False),
-    "resources": attr.label_list(
-        default = [],
-        allow_files = True,
-    ),
-    "resource_strip_prefix": attr.string(default = ""),
-    "resource_jars": attr.label_list(default = []),
-    "data": attr.label_list(
-        allow_files = True,
-        cfg = "data",
-    ),
-    "plugins": attr.label_list(
-        default = [],
-        aspects = [_kt_jvm_plugin_aspect],
-    ),
-    "module_name": attr.string(),
-}.items())
-
-_runnable_common_attr = dict(_common_attr.items() + {
-    "jvm_flags": attr.string_list(
-        default = [],
-    ),
-}.items())
-
-########################################################################################################################
-# Outputs: All the outputs produced by the various rules are modelled here.
-########################################################################################################################
-_common_outputs = dict(
-    jar = "%{name}.jar",
-    jdeps = "%{name}.jdeps",
-    # The params file, declared here so that validate it can be validated for testing.
-#    jar_2_params = "%{name}.jar-2.params",
-    srcjar = "%{name}-sources.jar",
-)
-
-_binary_outputs = dict(_common_outputs.items() + {
-}.items())
-
-########################################################################################################################
-# Repositories and Toolchains
-########################################################################################################################
-def kotlin_repositories(
-    kotlin_release_version=KOTLIN_CURRENT_RELEASE
-):
-    """Call this in the WORKSPACE file to setup the Kotlin rules.
-
-    Args:
-      kotlin_release_version: The kotlin compiler release version. If this is not set the latest release version is
-      chosen by default.
-    """
-    _maven_dependencies()
-    _kotlin_compiler_repository(kotlin_release_version)
-
-def kt_register_toolchains():
-    """register all default toolchains"""
-    native.register_toolchains(_kt.defs.DEFAULT_TOOLCHAIN)
-
-########################################################################################################################
-# Simple Rules:
-########################################################################################################################
-kt_jvm_library = rule(
-    attrs = dict(_common_attr.items() + {
-        "exports": attr.label_list(default = [], providers=[JavaInfo]),
-        "neverlink": attr.bool(default=False),
-    }.items()),
-    outputs = _common_outputs,
-    toolchains = [_kt.defs.TOOLCHAIN_TYPE],
-    implementation = _kt_jvm_library_impl,
-    provides = [JavaInfo, _kt.info.KtInfo]
-)
-
-"""This rule compiles and links Kotlin and Java sources into a .jar file.
-Args:
-  srcs: The list of source files that are processed to create the target, this can contain both Java and Kotlin files. Java analysis occurs first so Kotlin
-    classes may depend on Java classes in the same compilation unit.
-  exports: Exported libraries.
-
-    Deps listed here will be made available to other rules, as if the parents explicitly depended on these deps.
-    This is not true for regular (non-exported) deps.
-  resources: A list of data files to include in a Java jar.
-  resource_strip_prefix: The path prefix to strip from Java resources, files residing under common prefix such as `src/main/resources` or `src/test/resources`
-    will have stripping applied by convention.
-  resource_jars: Set of archives containing Java resources. If specified, the contents of these jars are merged into the output jar.
-  runtime_deps: Libraries to make available to the final binary or test at runtime only. Like ordinary deps, these will appear on the runtime classpath, but
-    unlike them, not on the compile-time classpath.
-  data: The list of files needed by this rule at runtime. See general comments about `data` at [Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).
-  deps: A list of dependencies of this rule.See general comments about `deps` at [Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).
-  module_name: The name of the module, if not provided the module name is derived from the label. --e.g., `//some/package/path:label_name` is translated to
-    `some_package_path-label_name`.
-  neverlink: If true only use this library for compilation and not at runtime.
-"""
-
-kt_jvm_binary = rule(
-    attrs = dict(_runnable_common_attr.items() + {
-        "main_class": attr.string(mandatory = True)
-    }.items()),
-    executable = True,
-    outputs = _binary_outputs,
-    toolchains = [_kt.defs.TOOLCHAIN_TYPE],
-    implementation = _kt_jvm_binary_impl,
-)
-
-"""Builds a Java archive ("jar file"), plus a wrapper shell script with the same name as the rule. The wrapper shell script uses a classpath that includes,
-among other things, a jar file for each library on which the binary depends.
-
-**Note:** This rule does not have all of the features found in [`java_binary`](https://docs.bazel.build/versions/master/be/java.html#java_binary). It is
-appropriate for building workspace utilities. `java_binary` should be preferred for release artefacts.
-
-Args:
-  main_class: Name of class with main() method to use as entry point.
-  jvm_flags: A list of flags to embed in the wrapper script generated for running this binary. Note: does not yet support make variable substitution.
-"""
-
-kt_jvm_test = rule(
-    attrs = dict(_runnable_common_attr.items() + {
-        "_bazel_test_runner": attr.label(
-            default = Label("@bazel_tools//tools/jdk:TestRunner_deploy.jar"),
-            allow_files = True,
-        ),
-        "friends": attr.label_list(
-            default = [],
-            providers = [JavaInfo]
-        ),
-        "test_class": attr.string(),
-        "main_class": attr.string(default="com.google.testing.junit.runner.BazelTestRunner"),
-    }.items()),
-    executable = True,
-    outputs = _binary_outputs,
-    test = True,
-    toolchains = [_kt.defs.TOOLCHAIN_TYPE],
-    implementation = _kt_jvm_junit_test_impl,
-)
-
-"""Setup a simple kotlin_test.
-
-**Notes:**
-* The kotlin test library is not added implicitly, it is available with the label `@com_github_jetbrains_kotlin//:kotlin-test`.
-
-Args:
-  test_class: The Java class to be loaded by the test runner.
-  friends: A single Kotlin dep which allows the test code access to internal members. Currently uses the output jar of
-    the module -- i.e., exported deps won't be included.
-"""
-
-kt_jvm_import = rule(
-    attrs = {
-        "jars": attr.label_list(
-            allow_files = True,
-            mandatory = True,
-            cfg = "target",
-        ),
-        "srcjar": attr.label(
-            allow_single_file = True,
-            cfg = "target",
-        ),
-        "runtime_deps": attr.label_list(
-            default = [],
-            mandatory = False,
-            providers = [JavaInfo]
-        )
-    },
-    implementation = _kt_jvm_import_impl,
-    provides = [JavaInfo, _kt.info.KtInfo]
-)
-
-# The pairing of src and class is used by intellij to attatch sources, this is picked up via the kt provider attribute.
-#
-# once current format and semantics are finalized add runtime_deps, exports, data, neverlink, testonly.
-#   * runtime_deps should accept JavaInfo's (this includes KotlinInfo) and maven_jar filegroups.
-#   * exports should only accept JavaInfo's (this include KotlinInfo) but not filegroup. The jars attribute takes care of importing the jars without generating
-#     ijars.
-"""(experimental) Import Kotlin jars.
-
-**Status:** This rule is not a counterpart to `java_import`. The current purpose for this rule is to import a kotlin jar without creating ijars. It will
-eventually [be replaced](https://github.com/bazelbuild/rules_kotlin/issues/4) with `java_import`. If there is a need for expanding this rule we can instead
-create a utility macro that delegates to this.
-
-## examples
-
-```bzl
-# Old style usage -- reference file groups, do not used this.
-kt_jvm_import(
-    name = "kodein",
-    jars = [
-        "@com_github_salomonbrys_kodein_kodein//jar:file",
-        "@com_github_salomonbrys_kodein_kodein_core//jar:file"
-    ]
-)
-
-# This style will pull in the transitive runtime dependencies of the targets as well.
-kt_jvm_import(
-    name = "kodein",
-    jars = [
-        "@com_github_salomonbrys_kodein_kodein//jar",
-        "@com_github_salomonbrys_kodein_kodein_core//jar"
-    ]
-)
-
-# Import a single kotlin jar.
-kt_jvm_import(
-    name = "kotlin-runtime",
-    jars = ["lib/kotlin-runtime.jar"],
-    srcjar = "lib/kotlin-runtime-sources.jar"
-)
-```
-
-Args:
-  jars: The jars listed here are equavalent to an export attribute. The label should be either to a single class jar, or multiple filegroup labels. When the
-    labels is a file_provider it should follow the conventions used in repositories generated by the maven_jar rule  --i.e., the rule expects a file_provider
-    with a single class jar and a single source jar. a source jar is recognized by the suffix `-sources.jar`.
-  srcjar: The sources for the class jar. This should be set when importing a single class jar.
-  runtime_deps: Additional runtime deps.
-"""
+load("//kotlin/internal/jvm:jvm.bzl",
+    "kt_jvm_binary",
+    "kt_jvm_library",
+    "kt_jvm_test",
+    "kt_jvm_import",
+)
\ No newline at end of file
diff --git a/kotlin/kotlin_compiler_repositories.bzl b/kotlin/kotlin_compiler_repositories.bzl
deleted file mode 100644
index 6161285..0000000
--- a/kotlin/kotlin_compiler_repositories.bzl
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# 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.
-"""This file contains the Kotlin compiler repository definitions. It should not be loaded directly by client workspaces.
-"""
-load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_file="http_file", _http_archive="http_archive")
-load("//kotlin/internal:kt.bzl", _kt = "kt")
-load("//kotlin:kotlin_releases.bzl",
-    _KOTLIN_COMPILER_RELEASES="KOTLIN_COMPILER_RELEASES",
-    _KOTLIN_CURRENT_RELEASE="KOTLIN_CURRENT_RELEASE"
-)
-
-_BAZEL_JAVA_LAUNCHER_VERSION = "0.8.1"
-
-def kotlin_compiler_repositories(kotlin_release_version):
-    """
-    Prime the compiler repository.
-
-    This function should not be called directly instead `kotlin_repositories` from `//kotlin:kotlin.bzl` should be
-    called to ensure common deps are loaded.
-    """
-    release=_KOTLIN_COMPILER_RELEASES[kotlin_release_version]
-    if not release:
-        fail('"%s" not a valid kotlin release, current release is "%s"' % (kotlin_release_version, _KOTLIN_CURRENT_RELEASE))
-
-    _http_archive(
-        name = _kt.defs.KT_COMPILER_REPO,
-        url = release["url"],
-        sha256 = release["sha256"],
-        build_file= "@io_bazel_rules_kotlin//kotlin:BUILD.com_github_jetbrains_kotlin",
-        strip_prefix = "kotlinc",
-    )
-
-    _http_file(
-        name = "kt_java_stub_template",
-        urls = [("https://raw.githubusercontent.com/bazelbuild/bazel/" +
-               _BAZEL_JAVA_LAUNCHER_VERSION +
-           "/src/main/java/com/google/devtools/build/lib/bazel/rules/java/" +
-           "java_stub_template.txt")],
-        sha256 = "86660ee7d5b498ccf611a1e000564f45268dbf301e0b2b08c984dcecc6513f6e",
-    )