swap guice for dagger and reduce deploy jar to 3.3 mb down from 8
diff --git a/.bazelproject b/.bazelproject
index 0d257c3..ed7ce57 100644
--- a/.bazelproject
+++ b/.bazelproject
@@ -22,7 +22,7 @@
   //examples/...
   # These targets are built for the ide only. Primary purpose is to ensure the builder can build the targets, but it's
   # also a good way of testing the intellij plugin.
-  //kotlin/builder:builder_lib_for_ide
+  //kotlin/builder/src/io/bazel/kotlin/builder:builder_kt_for_ide
   //kotlin/builder:compiler_lib_for_ide
 
 test_sources:
diff --git a/kotlin/BUILD.com_github_jetbrains_kotlin b/kotlin/BUILD.com_github_jetbrains_kotlin
index e5a5b17..a2311f8 100644
--- a/kotlin/BUILD.com_github_jetbrains_kotlin
+++ b/kotlin/BUILD.com_github_jetbrains_kotlin
@@ -44,6 +44,12 @@
     ]
 ]
 
+# Kotlin annotations jar. Contains annotations like NotNull.
+java_import(
+    name = "annotations",
+    jars = ["lib/annotations-13.0.jar"],
+)
+
 load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_import")
 
 #  The Kotlin standard libraries. These should be setup in a Toolchain.
diff --git a/kotlin/builder/BUILD b/kotlin/builder/BUILD
index 6114a98..5e7417f 100644
--- a/kotlin/builder/BUILD
+++ b/kotlin/builder/BUILD
@@ -25,37 +25,13 @@
     ],
 )
 
-kt_bootstrap_library(
-    name = "builder_lib",
-    srcs = glob(["src/io/bazel/kotlin/builder/**/*.kt"]),
-    runtime_deps = [
-        "@com_github_jetbrains_kotlin//:kotlin-reflect",
-        "@com_github_jetbrains_kotlin//:kotlin-stdlib-jdk7",
-        "@com_github_jetbrains_kotlin//:kotlin-stdlib-jdk8",
-        "@io_bazel_rules_kotlin_aopalliance_aopalliance//jar",
-        "@io_bazel_rules_kotlin_com_google_code_gson_gson//jar",
-    ],
-    deps = [
-        "@io_bazel_rules_kotlin_com_google_guava_guava//jar",
-        "@com_github_jetbrains_kotlin//:kotlin-stdlib",
-        "@com_github_jetbrains_kotlin//:kotlin-preloader",
-        "@io_bazel_rules_kotlin//kotlin/builder/proto:kotlin_model",
-        "@io_bazel_rules_kotlin//kotlin/builder/proto:deps",
-        "@io_bazel_rules_kotlin//kotlin/builder/proto:worker",
-        "@io_bazel_rules_kotlin_com_google_inject_guice//jar",
-        "@io_bazel_rules_kotlin_com_google_protobuf_protobuf_java//jar",
-        "@io_bazel_rules_kotlin_com_google_protobuf_protobuf_java_util//jar",
-        "@io_bazel_rules_kotlin_javax_inject_javax_inject//jar",
-    ],
-)
-
 # The builder artifact.
 java_binary(
     name = "builder",
     data = [":compiler_lib.jar"],
-    main_class = "io.bazel.kotlin.builder.KotlinBuilder",
+    main_class = "io.bazel.kotlin.builder.KotlinBuilderMain",
     visibility = ["//visibility:public"],
-    runtime_deps = [":builder_lib"],
+    runtime_deps = ["//kotlin/builder/src/io/bazel/kotlin/builder"],
 )
 
 filegroup(
@@ -74,18 +50,17 @@
     name = "builder_lib_for_tests",
     runtime_deps = [
         "@com_github_jetbrains_kotlin//:kotlin-reflect",
-        "@io_bazel_rules_kotlin_aopalliance_aopalliance//jar",
+        "@com_github_jetbrains_kotlin//:kotlin-stdlib",
     ],
     testonly = 1,
     data = [":data_for_tests"],
     exports = [
-        ":builder_lib",
+        "//kotlin/builder/src/io/bazel/kotlin/builder",
         "//third_party/jvm/com/google/truth",
         "//third_party/jvm/junit",
         "@io_bazel_rules_kotlin//kotlin/builder/proto:deps",
         "@io_bazel_rules_kotlin//kotlin/builder/proto:kotlin_model",
         "@io_bazel_rules_kotlin_com_google_guava_guava//jar",
-        "@io_bazel_rules_kotlin_com_google_inject_guice//jar",
         "@io_bazel_rules_kotlin_com_google_protobuf_protobuf_java//jar",
     ],
     visibility = [
diff --git a/kotlin/builder/bootstrap.bzl b/kotlin/builder/bootstrap.bzl
index ebfeeaa..fc3ed89 100644
--- a/kotlin/builder/bootstrap.bzl
+++ b/kotlin/builder/bootstrap.bzl
@@ -16,7 +16,7 @@
 _BOOTSTRAP_LIB_ARGS=["-jvm-target","1.8"]
 
 def _resolve_dep_label(d):
-    if d.startswith("//kotlin/builder/src/io/bazel/kotlin/builder") and not d.endswith("_for_ide"):
+    if d.startswith("//kotlin/builder/src/io/bazel/kotlin") and not d.endswith("_for_ide"):
         prefix, _, target = d.rpartition(":")
         if target == None:
             # untested
diff --git a/kotlin/builder/integrationtests/KotlinBuilderActionTests.java b/kotlin/builder/integrationtests/KotlinBuilderActionTests.java
index 6e27646..257af8b 100644
--- a/kotlin/builder/integrationtests/KotlinBuilderActionTests.java
+++ b/kotlin/builder/integrationtests/KotlinBuilderActionTests.java
@@ -1,13 +1,12 @@
 package io.bazel.kotlin.builder;
 
-import io.bazel.kotlin.builder.tasks.jvm.KotlinCompiler;
 import org.junit.Test;
 
 public class KotlinBuilderActionTests extends KotlinBuilderTestCase {
   @Test
   public void testCompileSimple() {
     addSource("AClass.kt", "package something;" + "class AClass{}");
-    instance(KotlinCompiler.class).compile(builderCommand());
+    component().jvmCompiler().compile(builderCommand());
     assertFileExists(DirectoryType.CLASSES, "something/AClass.class");
     assertFileDoesNotExist(outputs().getJar());
   }
diff --git a/kotlin/builder/integrationtests/KotlinBuilderTestCase.java b/kotlin/builder/integrationtests/KotlinBuilderTestCase.java
index 5fe32c7..c4a7367 100644
--- a/kotlin/builder/integrationtests/KotlinBuilderTestCase.java
+++ b/kotlin/builder/integrationtests/KotlinBuilderTestCase.java
@@ -2,7 +2,7 @@
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
-import com.google.inject.Injector;
+import io.bazel.kotlin.builder.toolchain.KotlinToolchain;
 import io.bazel.kotlin.model.KotlinModel;
 import org.junit.Before;
 
@@ -25,7 +25,12 @@
 
   private final KotlinModel.CompilationTask.Builder builder =
       KotlinModel.CompilationTask.newBuilder();
-  private final Injector injector = KotlinToolchain.createInjector(() -> System.out, null);
+  private final KotlinBuilderComponent component =
+      DaggerKotlinBuilderComponent.builder()
+          .out(System.err)
+          .toolchain(KotlinToolchain.createToolchain())
+          .build();
+
   private String label = null;
   private Path inputSourceDir = null;
 
@@ -54,8 +59,8 @@
     return builder.build();
   }
 
-  protected <T> T instance(Class<T> clazz) {
-    return injector.getInstance(clazz);
+  protected KotlinBuilderComponent component() {
+    return component;
   }
 
   protected void addSource(String filename, String... lines) {
@@ -85,19 +90,20 @@
     inputSourceDir = Paths.get(createTestOuputDirectory(prefixPath.resolve("input_sources")));
 
     builder.clear();
-    builder.getInfoBuilder()
-            .setLabel("//some/bogus:" + label)
-            .setModuleName("some_bogus_module")
-            .setPlatform(KotlinModel.CompilationTask.Info.Platform.JVM)
-            .setRuleKind(KotlinModel.CompilationTask.Info.RuleKind.LIBRARY)
-            .setToolchainInfo(
-                KotlinModel.KotlinToolchainInfo.newBuilder()
-                    .setCommon(
-                        KotlinModel.KotlinToolchainInfo.Common.newBuilder()
-                            .setApiVersion("1.2")
-                            .setCoroutines("enabled")
-                            .setLanguageVersion("1.2"))
-                    .setJvm(KotlinModel.KotlinToolchainInfo.Jvm.newBuilder().setJvmTarget("1.8")));
+    builder
+        .getInfoBuilder()
+        .setLabel("//some/bogus:" + label)
+        .setModuleName("some_bogus_module")
+        .setPlatform(KotlinModel.CompilationTask.Info.Platform.JVM)
+        .setRuleKind(KotlinModel.CompilationTask.Info.RuleKind.LIBRARY)
+        .setToolchainInfo(
+            KotlinModel.KotlinToolchainInfo.newBuilder()
+                .setCommon(
+                    KotlinModel.KotlinToolchainInfo.Common.newBuilder()
+                        .setApiVersion("1.2")
+                        .setCoroutines("enabled")
+                        .setLanguageVersion("1.2"))
+                .setJvm(KotlinModel.KotlinToolchainInfo.Jvm.newBuilder().setJvmTarget("1.8")));
     builder
         .getDirectoriesBuilder()
         .setClasses(prefixPath.resolve("classes").toAbsolutePath().toString())
diff --git a/kotlin/builder/integrationtests/KotlinBuilderTests.java b/kotlin/builder/integrationtests/KotlinBuilderTests.java
index e046fed..7c0dd1a 100644
--- a/kotlin/builder/integrationtests/KotlinBuilderTests.java
+++ b/kotlin/builder/integrationtests/KotlinBuilderTests.java
@@ -2,8 +2,6 @@
 
 import com.google.common.truth.Truth;
 import com.google.devtools.build.lib.view.proto.Deps;
-
-import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor;
 import io.bazel.kotlin.model.KotlinModel;
 import org.junit.Test;
 
@@ -46,9 +44,9 @@
       }
     }
     int timeoutSeconds = 10;
-    KotlinJvmTaskExecutor executor = instance(KotlinJvmTaskExecutor.class);
+//    KotlinJvmTaskExecutor executor = instance(KotlinJvmTaskExecutor.class);
     try {
-      CompletableFuture.runAsync(() -> executor.compile(command))
+      CompletableFuture.runAsync(() -> component().jvmTaskExecutor().compile(command))
           .get(timeoutSeconds, TimeUnit.SECONDS);
     } catch (TimeoutException e) {
       throw new AssertionError("did not complete in: " + timeoutSeconds);
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/BUILD b/kotlin/builder/src/io/bazel/kotlin/builder/BUILD
new file mode 100644
index 0000000..f76b592
--- /dev/null
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/BUILD
@@ -0,0 +1,51 @@
+# 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/builder:bootstrap.bzl", "kt_bootstrap_library")
+
+kt_bootstrap_library(
+    name = "builder_kt",
+    srcs = glob([
+        "toolchain/*.kt",
+        "tasks/**/*.kt",
+        "utils/**/*.kt",
+    ]),
+    deps = [
+        "@com_github_jetbrains_kotlin//:kotlin-preloader",
+        "@io_bazel_rules_kotlin//kotlin/builder/proto:deps",
+        "@io_bazel_rules_kotlin//kotlin/builder/proto:kotlin_model",
+        "@io_bazel_rules_kotlin//kotlin/builder/proto:worker",
+        "@io_bazel_rules_kotlin_com_google_protobuf_protobuf_java//jar",
+        "@io_bazel_rules_kotlin_com_google_protobuf_protobuf_java_util//jar",
+        "@io_bazel_rules_kotlin_javax_inject_javax_inject//jar",
+    ],
+)
+
+java_library(
+    name = "builder",
+    srcs = glob(["*.java"]),
+    visibility = ["//kotlin/builder:__subpackages__"],
+    exports = [":builder_kt"],
+    deps = [
+        ":builder_kt",
+        "//kotlin/builder/proto:kotlin_model",
+        "//third_party:dagger",
+        "@com_github_jetbrains_kotlin//:annotations",
+    ],
+    runtime_deps = [
+        "@com_github_jetbrains_kotlin//:kotlin-stdlib",
+        "@com_github_jetbrains_kotlin//:kotlin-stdlib-jdk7",
+        "@com_github_jetbrains_kotlin//:kotlin-stdlib-jdk8",
+        "@io_bazel_rules_kotlin_com_google_code_gson_gson//jar",
+    ]
+)
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderComponent.java b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderComponent.java
new file mode 100644
index 0000000..73e187a
--- /dev/null
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderComponent.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+import dagger.BindsInstance;
+import dagger.Component;
+import dagger.Provides;
+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.tasks.BazelWorker;
+import io.bazel.kotlin.builder.utils.KotlinCompilerPluginArgsEncoder;
+
+import javax.inject.Singleton;
+import java.io.PrintStream;
+
+@Singleton
+@dagger.Component(modules = {KotlinBuilderComponent.Module.class})
+public interface KotlinBuilderComponent {
+  KotlinToolchain toolchain();
+  KotlinJvmTaskExecutor jvmTaskExecutor();
+  KotlinJvmCompiler jvmCompiler();
+  BazelWorker worker();
+
+  @Component.Builder
+  interface Builder {
+    @BindsInstance
+    KotlinBuilderComponent.Builder toolchain(KotlinToolchain toolchain);
+
+    @BindsInstance
+    KotlinBuilderComponent.Builder out(PrintStream out);
+
+    KotlinBuilderComponent build();
+  }
+
+  @dagger.Module
+  class Module {
+    @Provides
+    public KotlinCompilerPluginArgsEncoder providePluginArgEncoder(KotlinToolchain toolchain) {
+      return new KotlinCompilerPluginArgsEncoder(
+          toolchain.getKapt3Plugin().getJarPath(), toolchain.getKapt3Plugin().getId());
+    }
+
+    @Provides
+    public BazelWorker provideWorker(KotlinBuilder builder) {
+      return new BazelWorker(builder, System.err, "KotlinCompile");
+    }
+  }
+}
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderMain.java b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderMain.java
new file mode 100644
index 0000000..c7182da
--- /dev/null
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilderMain.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+import io.bazel.kotlin.builder.toolchain.KotlinToolchain;
+
+import java.util.Arrays;
+
+public class KotlinBuilderMain {
+  public static void main(String[] args) {
+    KotlinBuilderComponent component =
+        DaggerKotlinBuilderComponent.builder()
+            .toolchain(KotlinToolchain.createToolchain())
+            .out(System.err)
+            .build();
+    System.exit(component.worker().apply(Arrays.asList(args)));
+  }
+}
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinToolchain.kt b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinToolchain.kt
deleted file mode 100644
index 22424a1..0000000
--- a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinToolchain.kt
+++ /dev/null
@@ -1,115 +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
-
-import com.google.inject.*
-import com.google.inject.util.Modules
-import io.bazel.kotlin.builder.utils.resolveVerified
-import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
-import org.jetbrains.kotlin.preloading.Preloader
-import java.io.File
-import java.io.PrintStream
-import java.io.PrintWriter
-import java.nio.file.Path
-import java.nio.file.Paths
-import javax.inject.Qualifier
-
-class KotlinToolchain private constructor(
-    internal val javaHome: Path,
-    val kotlinHome: Path,
-    internal val classLoader: ClassLoader,
-    val kotlinStandardLibraries: List<String> = listOf(
-        "kotlin-stdlib.jar",
-        "kotlin-stdlib-jdk7.jar",
-        "kotlin-stdlib-jdk8.jar"
-    )
-) {
-    companion object {
-        internal val NO_ARGS = arrayOf<Any>()
-
-        private val isJdk9OrNewer = !System.getProperty("java.version").startsWith("1.")
-        private val javaRunfiles get() = Paths.get(System.getenv("JAVA_RUNFILES"))
-
-        private fun createClassLoader(javaHome: Path, kotlinHome: Path): ClassLoader {
-            val preloadJars = mutableListOf<File>().also {
-                it += kotlinHome.resolveVerified("lib", "kotlin-compiler.jar")
-                it += javaRunfiles.resolveVerified("io_bazel_rules_kotlin", "kotlin", "builder", "compiler_lib.jar")
-                if (!isJdk9OrNewer) {
-                    it += javaHome.resolveVerified("lib", "tools.jar")
-                }
-            }
-            return ClassPreloadingUtils.preloadClasses(
-                preloadJars,
-                Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE,
-                ClassLoader.getSystemClassLoader(),
-                null
-            )
-        }
-
-        private fun createToolchain(): KotlinToolchain {
-            val kotlinHome = Paths.get("external", "com_github_jetbrains_kotlin")
-            val javaHome = Paths.get(System.getProperty("java.home")).let {
-                it.takeIf { !it.endsWith(Paths.get("jre")) } ?: it.parent
-            }
-            return KotlinToolchain(
-                javaHome,
-                kotlinHome,
-                createClassLoader(javaHome, kotlinHome)
-            )
-        }
-
-        /**
-         * @param outputProvider A provider for the output stream to write to. A provider is used here as the System.err
-         * gets rebound when the worker is executing.
-         */
-        @JvmStatic
-        fun createInjector(outputProvider: Provider<PrintStream>, overrides: Module? = null): Injector {
-            val toolchain = createToolchain()
-            val module = object : AbstractModule() {
-                override fun configure() {
-                    bind(KotlinToolchain::class.java).toInstance(toolchain)
-                    bind(PrintStream::class.java).toProvider(outputProvider)
-                    install(KotlinToolchainModule)
-                }
-            }
-            return Guice.createInjector(
-                overrides?.let { Modules.override(module).with(it) } ?: module
-            )
-        }
-    }
-
-    data class CompilerPlugin(val jarPath: String, val id: String) {
-        @Qualifier
-        annotation class Kapt3
-    }
-
-    interface JavacInvoker {
-        fun compile(args: Array<String>): Int
-        fun compile(args: Array<String>, out: PrintWriter): Int
-    }
-
-
-    interface JDepsInvoker {
-        fun run(args: Array<String>, out: PrintWriter): Int
-    }
-
-
-    interface KotlincInvoker {
-        fun compile(args: Array<String>, out: PrintStream): Int
-    }
-}
-
-
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinToolchainModule.kt b/kotlin/builder/src/io/bazel/kotlin/builder/KotlinToolchainModule.kt
deleted file mode 100644
index 5bb5cc1..0000000
--- a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinToolchainModule.kt
+++ /dev/null
@@ -1,70 +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
-
-import com.google.inject.AbstractModule
-import com.google.inject.Provides
-import io.bazel.kotlin.builder.KotlinToolchain.Companion.NO_ARGS
-import io.bazel.kotlin.builder.utils.resolveVerified
-import java.io.PrintStream
-import java.io.PrintWriter
-
-internal object KotlinToolchainModule : AbstractModule() {
-    @Provides
-    fun javacInvoker(toolchain: KotlinToolchain): KotlinToolchain.JavacInvoker = object : KotlinToolchain.JavacInvoker {
-        val c = toolchain.classLoader.loadClass("com.sun.tools.javac.Main")
-        val m = c.getMethod("compile", Array<String>::class.java)
-        val mPw = c.getMethod("compile", Array<String>::class.java, PrintWriter::class.java)
-        override fun compile(args: Array<String>) = m.invoke(c, args) as Int
-        override fun compile(args: Array<String>, out: PrintWriter) = mPw.invoke(c, args, out) as Int
-    }
-
-    @Provides
-    fun jdepsInvoker(toolchain: KotlinToolchain): KotlinToolchain.JDepsInvoker = object : KotlinToolchain.JDepsInvoker {
-        val clazz = toolchain.classLoader.loadClass("com.sun.tools.jdeps.Main")
-        val method = clazz.getMethod("run", Array<String>::class.java, PrintWriter::class.java)
-        override fun run(args: Array<String>, out: PrintWriter): Int = method.invoke(clazz, args, out) as Int
-    }
-
-    @Provides
-    fun kotlincInvoker(toolchain: KotlinToolchain): KotlinToolchain.KotlincInvoker =
-        object : KotlinToolchain.KotlincInvoker {
-            val compilerClass = toolchain.classLoader.loadClass("io.bazel.kotlin.compiler.BazelK2JVMCompiler")
-            val exitCodeClass = toolchain.classLoader.loadClass("org.jetbrains.kotlin.cli.common.ExitCode")
-
-            val compiler = compilerClass.getConstructor().newInstance()
-            val execMethod = compilerClass.getMethod("exec", PrintStream::class.java, Array<String>::class.java)
-            val getCodeMethod = exitCodeClass.getMethod("getCode")
-
-
-            override fun compile(args: Array<String>, out: PrintStream): Int {
-                val exitCodeInstance = execMethod.invoke(compiler, out, args)
-                return getCodeMethod.invoke(exitCodeInstance, *NO_ARGS) as Int
-            }
-        }
-
-    @Provides
-    @KotlinToolchain.CompilerPlugin.Kapt3
-    fun provideKapt3(toolchain: KotlinToolchain): KotlinToolchain.CompilerPlugin =
-        KotlinToolchain.CompilerPlugin(
-            toolchain.kotlinHome.resolveVerified("lib", "kotlin-annotation-processing.jar").absolutePath,
-            "org.jetbrains.kotlin.kapt3"
-        )
-
-    @Provides
-    fun provideBazelWorker(kotlinBuilder: KotlinBuilder, output: PrintStream): BazelWorker =
-        BazelWorker(kotlinBuilder, output, "KotlinCompile")
-}
\ No newline at end of file
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/BazelWorker.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/BazelWorker.kt
similarity index 93%
rename from kotlin/builder/src/io/bazel/kotlin/builder/BazelWorker.kt
rename to kotlin/builder/src/io/bazel/kotlin/builder/tasks/BazelWorker.kt
index 19c2a7f..94bf289 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/BazelWorker.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/BazelWorker.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.bazel.kotlin.builder
+package io.bazel.kotlin.builder.tasks
 
 
 import com.google.devtools.build.lib.worker.WorkerProtocol
@@ -24,21 +24,6 @@
 import java.nio.file.Paths
 import java.util.stream.Collectors
 
-sealed class ToolException(
-    msg: String,
-    ex: Throwable? = null
-) : RuntimeException(msg, ex)
-
-class CompilationException(msg: String, cause: Throwable? = null) :
-    ToolException(msg, cause)
-
-class CompilationStatusException(
-    msg: String,
-    val status: Int,
-    val lines: List<String> = emptyList()
-) : ToolException("$msg:${lines.joinToString("\n", "\n")}")
-
-
 /**
  * Interface for command line programs.
  *
@@ -161,7 +146,6 @@
                     } catch (e: IOException) {
                         throw RuntimeException(e)
                     }
-
                 }
             }
         }
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilder.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
similarity index 83%
rename from kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilder.kt
rename to kotlin/builder/src/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
index b56b8dd..74a6153 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinBuilder.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
@@ -13,28 +13,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.bazel.kotlin.builder
+package io.bazel.kotlin.builder.tasks
 
-import com.google.inject.Inject
-import com.google.inject.Provider
-import com.google.inject.Singleton
 import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor
+import io.bazel.kotlin.builder.toolchain.CompilationStatusException
 import io.bazel.kotlin.builder.utils.*
-import io.bazel.kotlin.builder.utils.jars.SourceJarExtractor
 import io.bazel.kotlin.model.KotlinModel
+import io.bazel.kotlin.builder.utils.jars.SourceJarExtractor
 import java.nio.file.Paths
+import javax.inject.Inject
+import javax.inject.Singleton
 
 @Singleton
 @Suppress("MemberVisibilityCanBePrivate")
 class KotlinBuilder @Inject internal constructor(
-    private val commandBuilder: TaskBuilder,
+    private val taskBuilder: TaskBuilder,
     private val jvmTaskExecutor: KotlinJvmTaskExecutor
 ) : CommandLineProgram {
     fun execute(args: List<String>): Int =
         ArgMaps.from(args).let { execute(it) }
 
     fun execute(args: ArgMap): Int =
-        commandBuilder.fromInput(args).let { execute(it) }
+        taskBuilder.fromInput(args).let { execute(it) }
 
     fun execute(command: KotlinModel.CompilationTask): Int {
         ensureDirectories(
@@ -74,12 +74,4 @@
     override fun apply(args: List<String>): Int {
         return execute(args)
     }
-
-    companion object {
-        @JvmStatic
-        fun main(args: Array<String>) {
-            val worker = KotlinToolchain.createInjector(Provider { System.err }).getInstance(BazelWorker::class.java)
-            System.exit(worker.apply(args.toList()))
-        }
-    }
 }
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/TaskBuilder.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/TaskBuilder.kt
similarity index 99%
rename from kotlin/builder/src/io/bazel/kotlin/builder/TaskBuilder.kt
rename to kotlin/builder/src/io/bazel/kotlin/builder/tasks/TaskBuilder.kt
index 204d623..0ee3eff 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/TaskBuilder.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/TaskBuilder.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.bazel.kotlin.builder
+package io.bazel.kotlin.builder.tasks
 
 import com.google.protobuf.util.JsonFormat
 import io.bazel.kotlin.builder.utils.ArgMap
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JDepsGenerator.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JDepsGenerator.kt
index ddbab12..a6197a7 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JDepsGenerator.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JDepsGenerator.kt
@@ -16,33 +16,29 @@
 package io.bazel.kotlin.builder.tasks.jvm
 
 import com.google.devtools.build.lib.view.proto.Deps
-import com.google.inject.ImplementedBy
-import com.google.inject.Inject
-import io.bazel.kotlin.builder.CompilationException
-import io.bazel.kotlin.builder.CompilationStatusException
-import io.bazel.kotlin.builder.KotlinToolchain
+import io.bazel.kotlin.builder.toolchain.CompilationException
+import io.bazel.kotlin.builder.toolchain.CompilationStatusException
+import io.bazel.kotlin.builder.toolchain.KotlinToolchain
+import io.bazel.kotlin.model.KotlinModel
 import io.bazel.kotlin.builder.utils.joinedClasspath
 import io.bazel.kotlin.builder.utils.resolveVerified
 import io.bazel.kotlin.builder.utils.rootCause
-import io.bazel.kotlin.model.KotlinModel
 import java.io.ByteArrayOutputStream
 import java.io.FileOutputStream
 import java.io.PrintWriter
 import java.nio.file.Files
 import java.nio.file.Paths
+import javax.inject.Inject
+import javax.inject.Singleton
 
-@ImplementedBy(DefaultJDepsGenerator::class)
-interface JDepsGenerator {
-    fun generateJDeps(command: KotlinModel.CompilationTask)
-}
-
-private class DefaultJDepsGenerator @Inject constructor(
+@Singleton
+internal class JDepsGenerator  @Inject constructor(
     toolchain: KotlinToolchain,
-    val invoker: KotlinToolchain.JDepsInvoker
-) : JDepsGenerator {
+    private val invoker: KotlinToolchain.JDepsInvoker
+) {
     private val isKotlinImplicit = JdepsParser.pathSuffixMatchingPredicate(
         toolchain.kotlinHome.resolveVerified("lib").toPath(), *toolchain.kotlinStandardLibraries.toTypedArray())
-    override fun generateJDeps(command: KotlinModel.CompilationTask) {
+    fun generateJDeps(command: KotlinModel.CompilationTask) {
         val jdepsContent =
             if (command.inputs.classpathList.isEmpty()) {
                 Deps.Dependencies.newBuilder().let {
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt
index 1fa912e..d260143 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt
@@ -15,23 +15,19 @@
  */
 package io.bazel.kotlin.builder.tasks.jvm
 
-import com.google.inject.ImplementedBy
-import com.google.inject.Inject
-import io.bazel.kotlin.builder.CompilationStatusException
-import io.bazel.kotlin.builder.KotlinToolchain
+import io.bazel.kotlin.builder.toolchain.CompilationStatusException
+import io.bazel.kotlin.builder.toolchain.KotlinToolchain
+import io.bazel.kotlin.model.KotlinModel.CompilationTask
 import io.bazel.kotlin.builder.utils.addAll
 import io.bazel.kotlin.builder.utils.joinedClasspath
-import io.bazel.kotlin.model.KotlinModel.CompilationTask
+import javax.inject.Inject
+import javax.inject.Singleton
 
-@ImplementedBy(DefaultJavaCompiler::class)
-interface JavaCompiler {
-    fun compile(command: CompilationTask)
-}
-
-private class DefaultJavaCompiler @Inject constructor(
-    val javacInvoker: KotlinToolchain.JavacInvoker
-) : JavaCompiler {
-    override fun compile(command: CompilationTask) {
+@Singleton
+internal class JavaCompiler @Inject constructor(
+    private val javacInvoker: KotlinToolchain.JavacInvoker
+) {
+   fun compile(command: CompilationTask) {
         val i = command.inputs
         val d = command.directories
         if (i.javaSourcesList.isNotEmpty()) {
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JdepsParser.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JdepsParser.kt
index 5614add..0c923e6 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JdepsParser.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/JdepsParser.kt
@@ -20,9 +20,8 @@
 import java.nio.file.Paths
 import java.util.*
 import java.util.function.Predicate
-import java.util.stream.Stream
 
-class JdepsParser private constructor(private val filename: String, private val isImplicit: Predicate<String>) {
+internal class JdepsParser private constructor(private val filename: String, private val isImplicit: Predicate<String>) {
     private val packageSuffix: String = " ($filename)"
 
     private val depMap = HashMap<String, Deps.Dependency.Builder>()
@@ -120,7 +119,7 @@
         ): Deps.Dependencies {
             val filename = Paths.get(classJar).fileName.toString()
             val jdepsParser = JdepsParser(filename, isImplicit)
-            Stream.of(*classPath.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
+            classPath.split(":".toRegex()).dropLastWhile { it.isEmpty() }.stream()
                 .forEach { x -> jdepsParser.consumeJarLine(x, Deps.Dependency.Kind.UNUSED) }
             jdepLines.forEach { jdepsParser.processLine(it) }
 
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinCompilerOutputSink.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinCompilerOutputSink.kt
index c72628c..9b7a594 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinCompilerOutputSink.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinCompilerOutputSink.kt
@@ -15,16 +15,17 @@
  */
 package io.bazel.kotlin.builder.tasks.jvm
 
-import com.google.inject.Inject
-import com.google.inject.Provider
-import com.google.inject.Singleton
+
 import java.io.File
 import java.io.PrintStream
 import java.nio.file.Paths
+import javax.inject.Inject
+import javax.inject.Provider
+import javax.inject.Singleton
 
 @Singleton
-class KotlinCompilerOutputSink @Inject constructor(
-    val streamProvider: Provider<PrintStream>
+internal class KotlinCompilerOutputSink @Inject constructor(
+    private val streamProvider: Provider<PrintStream>
 ) {
     private val executionRoot: String = Paths.get("").toAbsolutePath().toString() + File.separator
 
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinCompiler.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmCompiler.kt
similarity index 83%
rename from kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinCompiler.kt
rename to kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmCompiler.kt
index 0c7ec10..d5cf108 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinCompiler.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmCompiler.kt
@@ -15,11 +15,9 @@
  */
 package io.bazel.kotlin.builder.tasks.jvm
 
-import com.google.inject.ImplementedBy
-import com.google.inject.Inject
-import io.bazel.kotlin.builder.CompilationStatusException
-import io.bazel.kotlin.builder.KotlinCompilerPluginArgsEncoder
-import io.bazel.kotlin.builder.KotlinToolchain
+import io.bazel.kotlin.builder.toolchain.CompilationStatusException
+import io.bazel.kotlin.builder.utils.KotlinCompilerPluginArgsEncoder
+import io.bazel.kotlin.builder.toolchain.KotlinToolchain
 import io.bazel.kotlin.builder.utils.addAll
 import io.bazel.kotlin.builder.utils.joinedClasspath
 import io.bazel.kotlin.model.KotlinModel
@@ -27,12 +25,9 @@
 import java.io.ByteArrayOutputStream
 import java.io.File
 import java.io.PrintStream
+import javax.inject.Inject
+import javax.inject.Singleton
 
-@ImplementedBy(DefaultKotlinCompiler::class)
-interface KotlinCompiler {
-    fun runAnnotationProcessor(command: KotlinModel.CompilationTask): List<String>
-    fun compile(command: KotlinModel.CompilationTask): List<String>
-}
 
 // 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..
@@ -40,11 +35,12 @@
 // 1 is a standard compilation error
 // 2 is an internal error
 // 3 is the script execution error
-private class DefaultKotlinCompiler @Inject constructor(
-    val compiler: KotlinToolchain.KotlincInvoker,
-    val pluginArgsEncoder: KotlinCompilerPluginArgsEncoder
-) : KotlinCompiler {
-    override fun runAnnotationProcessor(command: KotlinModel.CompilationTask): List<String> {
+@Singleton
+internal class KotlinJvmCompiler @Inject constructor(
+    private val compiler: KotlinToolchain.KotlincInvoker,
+    private val pluginArgsEncoder: KotlinCompilerPluginArgsEncoder
+) {
+    fun runAnnotationProcessor(command: KotlinModel.CompilationTask): List<String> {
         check(command.info.plugins.annotationProcessorsList.isNotEmpty()) {
             "method called without annotation processors"
         }
@@ -79,7 +75,7 @@
         return args
     }
 
-    override fun compile(command: KotlinModel.CompilationTask): List<String> =
+    fun compile(command: KotlinModel.CompilationTask): List<String> =
         with(getCommonArgs(command)) {
             addAll(command.inputs.javaSourcesList)
             addAll(command.inputs.kotlinSourcesList)
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 e152033..16b358a 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
@@ -15,24 +15,23 @@
  */
 package io.bazel.kotlin.builder.tasks.jvm
 
-import com.google.common.base.Stopwatch
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import io.bazel.kotlin.builder.CompilationStatusException
-import io.bazel.kotlin.builder.utils.expandWithSources
-import io.bazel.kotlin.model.KotlinModel.CompilationTask
-import java.io.File
-import java.util.concurrent.TimeUnit
 
+import io.bazel.kotlin.builder.toolchain.CompilationStatusException
+import io.bazel.kotlin.model.KotlinModel.CompilationTask
+import io.bazel.kotlin.builder.utils.expandWithSources
+import java.io.File
+import javax.inject.Inject
+import javax.inject.Singleton
 
 @Singleton
 class KotlinJvmTaskExecutor @Inject internal constructor(
-    private val kotlinCompiler: KotlinCompiler,
+    private val kotlinCompiler: KotlinJvmCompiler,
     private val outputSink: KotlinCompilerOutputSink,
     private val javaCompiler: JavaCompiler,
     private val jDepsGenerator: JDepsGenerator,
     private val outputJarCreator: OutputJarCreator
 ) {
+    @Suppress("unused")
     class Result(val timings: List<String>, val command: CompilationTask)
 
     fun compile(command: CompilationTask): Result {
@@ -90,15 +89,13 @@
 
     internal class Context {
         val timings = mutableListOf<String>()
-        val sw: Stopwatch = Stopwatch.createUnstarted()
         inline fun <T> execute(name: String, task: () -> T): T {
-            sw.start()
+            val start = System.currentTimeMillis()
             return try {
                 task()
             } finally {
-                sw.stop()
-                timings += "$name: ${sw.elapsed(TimeUnit.MILLISECONDS)} ms"
-                sw.reset()
+                val stop = System.currentTimeMillis()
+                timings += "$name: ${stop - start} ms"
             }
         }
     }
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/OutputJarCreator.kt b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/OutputJarCreator.kt
index 15c3be1..ff6c075 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/OutputJarCreator.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/tasks/jvm/OutputJarCreator.kt
@@ -15,19 +15,16 @@
  */
 package io.bazel.kotlin.builder.tasks.jvm
 
-import com.google.inject.ImplementedBy
+import io.bazel.kotlin.model.KotlinModel
 import io.bazel.kotlin.builder.utils.bazelRuleKind
 import io.bazel.kotlin.builder.utils.jars.JarCreator
-import io.bazel.kotlin.model.KotlinModel
 import java.nio.file.Paths
+import javax.inject.Inject
+import javax.inject.Singleton
 
-@ImplementedBy(DefaultOutputJarCreator::class)
-interface OutputJarCreator {
-    fun createOutputJar(command: KotlinModel.CompilationTask)
-}
-
-private class DefaultOutputJarCreator : OutputJarCreator {
-    override fun createOutputJar(command: KotlinModel.CompilationTask) {
+@Singleton
+internal class OutputJarCreator @Inject constructor() {
+    fun createOutputJar(command: KotlinModel.CompilationTask) {
         JarCreator(
             path = Paths.get(command.outputs.jar),
             normalize = true,
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolException.kt b/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolException.kt
new file mode 100644
index 0000000..50702e8
--- /dev/null
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolException.kt
@@ -0,0 +1,15 @@
+package io.bazel.kotlin.builder.toolchain
+
+sealed class KotlinToolException(
+    msg: String,
+    ex: Throwable? = null
+) : RuntimeException(msg, ex)
+
+class CompilationException(msg: String, cause: Throwable? = null) :
+    KotlinToolException(msg, cause)
+
+class CompilationStatusException(
+    msg: String,
+    val status: Int,
+    val lines: List<String> = emptyList()
+) : KotlinToolException("$msg:${lines.joinToString("\n", "\n")}")
\ No newline at end of file
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt b/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
new file mode 100644
index 0000000..d087b5c
--- /dev/null
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.toolchain
+
+import io.bazel.kotlin.builder.utils.resolveVerified
+import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
+import org.jetbrains.kotlin.preloading.Preloader
+import java.io.File
+import java.io.PrintStream
+import java.io.PrintWriter
+import java.nio.file.Path
+import java.nio.file.Paths
+import javax.inject.Inject
+import javax.inject.Singleton
+
+class KotlinToolchain private constructor(
+    internal val javaHome: Path,
+    val kotlinHome: Path,
+    val classLoader: ClassLoader,
+    val kotlinStandardLibraries: List<String> = listOf(
+        "kotlin-stdlib.jar",
+        "kotlin-stdlib-jdk7.jar",
+        "kotlin-stdlib-jdk8.jar"
+    ),
+    val kapt3Plugin: KotlinToolchain.CompilerPlugin = KotlinToolchain.CompilerPlugin(
+        kotlinHome.resolveVerified("lib", "kotlin-annotation-processing.jar").absolutePath,
+        "org.jetbrains.kotlin.kapt3"
+    )
+) {
+
+    companion object {
+        internal val NO_ARGS = arrayOf<Any>()
+
+        private val isJdk9OrNewer = !System.getProperty("java.version").startsWith("1.")
+        private val javaRunfiles get() = Paths.get(System.getenv("JAVA_RUNFILES"))
+
+        private fun createClassLoader(javaHome: Path, kotlinHome: Path): ClassLoader {
+            val preloadJars = mutableListOf<File>().also {
+                it += kotlinHome.resolveVerified("lib", "kotlin-compiler.jar")
+                it += javaRunfiles.resolveVerified("io_bazel_rules_kotlin", "kotlin", "builder", "compiler_lib.jar")
+                if (!isJdk9OrNewer) {
+                    it += javaHome.resolveVerified("lib", "tools.jar")
+                }
+            }
+            return ClassPreloadingUtils.preloadClasses(
+                preloadJars,
+                Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE,
+                ClassLoader.getSystemClassLoader(),
+                null
+            )
+        }
+
+        @JvmStatic
+        fun createToolchain(): KotlinToolchain {
+            val kotlinHome = Paths.get("external", "com_github_jetbrains_kotlin")
+            val javaHome = Paths.get(System.getProperty("java.home")).let {
+                it.takeIf { !it.endsWith(Paths.get("jre")) } ?: it.parent
+            }
+            return KotlinToolchain(
+                javaHome,
+                kotlinHome,
+                createClassLoader(javaHome, kotlinHome)
+            )
+        }
+
+//        @JvmStatic
+//        fun createToolchainModule(outputProvider: Provider<PrintStream>): Module {
+//            val toolchain = createToolchain()
+//            return object : AbstractModule() {
+//                override fun configure() {
+//                    bind(PrintStream::class.java).toProvider(outputProvider)
+//                    bind(KotlinToolchain::class.java).toInstance(toolchain)
+//                    install(KotlinToolchainModule)
+//                }
+//            }
+//        }
+    }
+
+    data class CompilerPlugin(val jarPath: String, val id: String)
+
+    @Singleton
+    class JavacInvoker @Inject constructor(toolchain: KotlinToolchain) {
+        private val c = toolchain.classLoader.loadClass("com.sun.tools.javac.Main")
+        private val m = c.getMethod("compile", Array<String>::class.java)
+        private val mPw = c.getMethod("compile", Array<String>::class.java, PrintWriter::class.java)
+        fun compile(args: Array<String>) = m.invoke(c, args) as Int
+        fun compile(args: Array<String>, out: PrintWriter) = mPw.invoke(c, args, out) as Int
+    }
+
+    @Singleton
+    class JDepsInvoker @Inject constructor(toolchain: KotlinToolchain) {
+        private val clazz = toolchain.classLoader.loadClass("com.sun.tools.jdeps.Main")
+        private val method = clazz.getMethod("run", Array<String>::class.java, PrintWriter::class.java)
+        fun run(args: Array<String>, out: PrintWriter): Int = method.invoke(clazz, args, out) as Int
+    }
+
+    @Singleton
+    class KotlincInvoker @Inject constructor(toolchain: KotlinToolchain) {
+        private val compilerClass = toolchain.classLoader.loadClass("io.bazel.kotlin.compiler.BazelK2JVMCompiler")
+        private val exitCodeClass = toolchain.classLoader.loadClass("org.jetbrains.kotlin.cli.common.ExitCode")
+
+        private val compiler = compilerClass.getConstructor().newInstance()
+        private val execMethod = compilerClass.getMethod("exec", PrintStream::class.java, Array<String>::class.java)
+        private val getCodeMethod = exitCodeClass.getMethod("getCode")
+
+        fun compile(args: Array<String>, out: PrintStream): Int {
+            val exitCodeInstance = execMethod.invoke(compiler, out, args)
+            return getCodeMethod.invoke(exitCodeInstance, *NO_ARGS) as Int
+        }
+    }
+}
+
+
diff --git a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinCompilerPluginArgsEncoder.kt b/kotlin/builder/src/io/bazel/kotlin/builder/utils/KotlinCompilerPluginArgsEncoder.kt
similarity index 90%
rename from kotlin/builder/src/io/bazel/kotlin/builder/KotlinCompilerPluginArgsEncoder.kt
rename to kotlin/builder/src/io/bazel/kotlin/builder/utils/KotlinCompilerPluginArgsEncoder.kt
index e67c1ae..77f2227 100644
--- a/kotlin/builder/src/io/bazel/kotlin/builder/KotlinCompilerPluginArgsEncoder.kt
+++ b/kotlin/builder/src/io/bazel/kotlin/builder/utils/KotlinCompilerPluginArgsEncoder.kt
@@ -13,21 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.bazel.kotlin.builder
+package io.bazel.kotlin.builder.utils
 
 
-import io.bazel.kotlin.builder.KotlinToolchain.CompilerPlugin
 import io.bazel.kotlin.model.KotlinModel
 import java.io.ByteArrayOutputStream
 import java.io.ObjectOutputStream
 import java.util.*
-import javax.inject.Inject
-import javax.inject.Singleton
 
-@Singleton
-internal class KotlinCompilerPluginArgsEncoder @Inject constructor(
-    @CompilerPlugin.Kapt3
-    private val kapt3: CompilerPlugin
+class KotlinCompilerPluginArgsEncoder(
+    private val jarPath: String,
+    private val pluginId: String
 ) {
     companion object {
         private fun encodeMap(options: Map<String, String>): String {
@@ -82,8 +78,8 @@
         // passed to kotlinc.
         fun encode(): List<String> =
             listOf(
-                "-Xplugin=${kapt3.jarPath}",
-                "-P", "plugin:${kapt3.id}:configuration=${encodeMultiMap(
+                "-Xplugin=$jarPath",
+                "-P", "plugin:$pluginId:configuration=${encodeMultiMap(
                     tally
                 )}"
             )
diff --git a/kotlin/builder/unittests/BUILD b/kotlin/builder/unittests/BUILD
index 37f6237..494de37 100644
--- a/kotlin/builder/unittests/BUILD
+++ b/kotlin/builder/unittests/BUILD
@@ -15,7 +15,7 @@
     name = "unittests",
     size = "small",
     srcs = glob(["**/*.java"]),
-    test_class = "io.bazel.kotlin.builder.mode.jvm.utils.JdepsParserTest",
+    test_class = "io.bazel.kotlin.builder.tasks.jvm.JdepsParserTest",
     deps = [
         "//kotlin/builder:builder_lib_for_tests",
         "@com_github_jetbrains_kotlin//:kotlin-stdlib",
diff --git a/kotlin/builder/unittests/io/bazel/kotlin/workers/mode/jvm/utils/JdepsParserTest.java b/kotlin/builder/unittests/io/bazel/kotlin/workers/tasks/jvm/JdepsParserTest.java
similarity index 98%
rename from kotlin/builder/unittests/io/bazel/kotlin/workers/mode/jvm/utils/JdepsParserTest.java
rename to kotlin/builder/unittests/io/bazel/kotlin/workers/tasks/jvm/JdepsParserTest.java
index 8bf24ec..f18a9c0 100644
--- a/kotlin/builder/unittests/io/bazel/kotlin/workers/mode/jvm/utils/JdepsParserTest.java
+++ b/kotlin/builder/unittests/io/bazel/kotlin/workers/tasks/jvm/JdepsParserTest.java
@@ -13,10 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.bazel.kotlin.builder.mode.jvm.utils;
+package io.bazel.kotlin.builder.tasks.jvm;
 
 import com.google.devtools.build.lib.view.proto.Deps;
-import io.bazel.kotlin.builder.tasks.jvm.JdepsParser;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -29,6 +28,7 @@
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
+@SuppressWarnings("KotlinInternalInJava")
 @RunWith(JUnit4.class)
 public class JdepsParserTest {
   private static final String JDK8_FIXTURE =
diff --git a/third_party/BUILD b/third_party/BUILD
index 0746542..d1ef82b 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -25,4 +25,23 @@
     jars = [
         "@io_bazel_rules_kotlin_org_jetbrains_kotlinx_kotlinx_coroutines_core//jar",
     ],
+)
+
+java_plugin(
+    name = "dagger_component_plugin",
+    generates_api = 1,
+    processor_class = "dagger.internal.codegen.ComponentProcessor",
+    deps = [
+        "//third_party/jvm/com/google/dagger:dagger_compiler",
+    ],
+    visibility = ["//visibility:private"]
+)
+
+java_library(
+    name = "dagger",
+    exported_plugins = [":dagger_component_plugin"],
+    exports = [
+        "//third_party/jvm/com/google/dagger",
+        "//third_party/jvm/javax/inject:javax_inject",
+    ],
 )
\ No newline at end of file
diff --git a/third_party/dependencies.yaml b/third_party/dependencies.yaml
index fbfb498..6414939 100644
--- a/third_party/dependencies.yaml
+++ b/third_party/dependencies.yaml
@@ -15,10 +15,6 @@
     junit:
       lang: "java"
       version: "4.12"
-  com.google.inject:
-    guice:
-      lang: "java"
-      version: "4.2.0"
   com.google.protobuf:
     protobuf:
       modules: ["java", "java-util"]
diff --git a/third_party/jvm/aopalliance/BUILD b/third_party/jvm/aopalliance/BUILD
deleted file mode 100644
index 15ee13b..0000000
--- a/third_party/jvm/aopalliance/BUILD
+++ /dev/null
@@ -1,12 +0,0 @@
-licenses(["notice"])
-java_library(
-    name = "aopalliance",
-    exports = [
-        "//external:jar/io_bazel_rules_kotlin_aopalliance/aopalliance"
-    ],
-    visibility = [
-        "//third_party/jvm:__subpackages__"
-    ]
-)
-
-
diff --git a/third_party/jvm/com/google/inject/BUILD b/third_party/jvm/com/google/inject/BUILD
deleted file mode 100644
index d2857fc..0000000
--- a/third_party/jvm/com/google/inject/BUILD
+++ /dev/null
@@ -1,17 +0,0 @@
-licenses(["notice"])
-java_library(
-    name = "guice",
-    exports = [
-        "//external:jar/io_bazel_rules_kotlin_com/google/inject/guice"
-    ],
-    runtime_deps = [
-        "//third_party/jvm/aopalliance:aopalliance",
-        "//third_party/jvm/com/google/guava:guava",
-        "//third_party/jvm/javax/inject:javax_inject"
-    ],
-    visibility = [
-        "//visibility:public"
-    ]
-)
-
-
diff --git a/third_party/jvm/workspace.bzl b/third_party/jvm/workspace.bzl
index a7318b8..e0ae5a3 100644
--- a/third_party/jvm/workspace.bzl
+++ b/third_party/jvm/workspace.bzl
@@ -66,7 +66,6 @@
 
 def list_dependencies():
     return [
-    {"artifact": "aopalliance:aopalliance:1.0", "lang": "java", "sha1": "0235ba8b489512805ac13a8f9ea77a1ca5ebe3e8", "sha256": "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/aopalliance/aopalliance/1.0/aopalliance-1.0.jar", "source": {"sha1": "4a4b6d692e17846a9f3da036438a7ac491d3c814", "sha256": "e6ef91d439ada9045f419c77543ebe0416c3cdfc5b063448343417a3e4a72123", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"} , "name": "io_bazel_rules_kotlin_aopalliance_aopalliance", "actual": "@io_bazel_rules_kotlin_aopalliance_aopalliance//jar", "bind": "jar/io_bazel_rules_kotlin_aopalliance/aopalliance"},
     {"artifact": "com.google.auto.service:auto-service:1.0-rc4", "lang": "java", "sha1": "44954d465f3b9065388bbd2fc08a3eb8fd07917c", "sha256": "e422d49c312fd2031222e7306e8108c1b4118eb9c049f1b51eca280bed87e924", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/auto/service/auto-service/1.0-rc4/auto-service-1.0-rc4.jar", "source": {"sha1": "4e0285a57f33a9139e203687a617d7c98104b73a", "sha256": "285a6d4bc111255b5c99f5393b833f8b9156c4acb4e6c3f7cdde8493e888dd27", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/auto/service/auto-service/1.0-rc4/auto-service-1.0-rc4-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_auto_service_auto_service", "actual": "@io_bazel_rules_kotlin_com_google_auto_service_auto_service//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/auto/service/auto_service"},
     {"artifact": "com.google.auto.value:auto-value:1.5.3", "lang": "java", "sha1": "514df6a7c7938de35c7f68dc8b8f22df86037f38", "sha256": "238d3b7535096d782d08576d1e42f79480713ff0794f511ff2cc147363ec072d", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value/1.5.3/auto-value-1.5.3.jar", "source": {"sha1": "1bb4def82e18be0b6a58ab089fba288d712db6cb", "sha256": "7c9adb9f49a4f07e226778951e087da85759a9ab53ac375f9d076de6dc84ca2b", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value/1.5.3/auto-value-1.5.3-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_auto_value_auto_value", "actual": "@io_bazel_rules_kotlin_com_google_auto_value_auto_value//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/auto/value/auto_value"},
     {"artifact": "com.google.auto:auto-common:0.8", "lang": "java", "sha1": "c6f7af0e57b9d69d81b05434ef9f3c5610d498c4", "sha256": "97db1709f57b91b32edacb596ef4641872f227b7d99ad90e467f0d77f5ba134a", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/auto/auto-common/0.8/auto-common-0.8.jar", "source": {"sha1": "24705cafc9997c5eb6ae3270bd6234fdf9912bad", "sha256": "1e258bc08963dc8ffdcf22efa04b9fea6886761e077fc126ebacf92d11c9abec", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/auto/auto-common/0.8/auto-common-0.8-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_auto_auto_common", "actual": "@io_bazel_rules_kotlin_com_google_auto_auto_common//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/auto/auto_common"},
@@ -86,11 +85,9 @@
 # - com.google.dagger:dagger-producers:2.16 wanted version 23.3-jre
 # - com.google.dagger:dagger-spi:2.16 wanted version 23.3-jre
 # - com.google.googlejavaformat:google-java-format:1.4 wanted version 19.0
-# - com.google.inject:guice:4.2.0 wanted version 23.6-android
 # - com.google.protobuf:protobuf-java-util:3.6.0 wanted version 19.0
 # - com.google.truth:truth:0.40 wanted version 23.4-android
     {"artifact": "com.google.guava:guava:25.0-jre", "lang": "java", "sha1": "7319c34fa5866a85b6bad445adad69d402323129", "sha256": "3fd4341776428c7e0e5c18a7c10de129475b69ab9d30aeafbb5c277bb6074fa9", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/guava/guava/25.0-jre/guava-25.0-jre.jar", "source": {"sha1": "030ade485699e7782cc2369b0e5d3d8e0bfc317c", "sha256": "386e429ab4f9e511630038e7b7a331d3dca3931564f592e412ba47995fefd89b", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/guava/guava/25.0-jre/guava-25.0-jre-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_guava_guava", "actual": "@io_bazel_rules_kotlin_com_google_guava_guava//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/guava/guava"},
-    {"artifact": "com.google.inject:guice:4.2.0", "lang": "java", "sha1": "25e1f4c1d528a1cffabcca0d432f634f3132f6c8", "sha256": "2865a82693f0b97f1ef3305a06f0aae3bfc3e63d71b33363af5ec2eed598acb8", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/inject/guice/4.2.0/guice-4.2.0.jar", "source": {"sha1": "6e7f63430060b8589f90165bccf179db41a29dc1", "sha256": "276bffcce41f9144445d67f3b7d35db38ea0c88c05795bfbd851ac9e39c91045", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/inject/guice/4.2.0/guice-4.2.0-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_inject_guice", "actual": "@io_bazel_rules_kotlin_com_google_inject_guice//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/inject/guice"},
     {"artifact": "com.google.j2objc:j2objc-annotations:1.1", "lang": "java", "sha1": "ed28ded51a8b1c6b112568def5f4b455e6809019", "sha256": "2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar", "source": {"sha1": "1efdf5b737b02f9b72ebdec4f72c37ec411302ff", "sha256": "2cd9022a77151d0b574887635cdfcdf3b78155b602abc89d7f8e62aba55cfb4f", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_j2objc_j2objc_annotations", "actual": "@io_bazel_rules_kotlin_com_google_j2objc_j2objc_annotations//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/j2objc/j2objc_annotations"},
     {"artifact": "com.google.protobuf:protobuf-java-util:3.6.0", "lang": "java", "sha1": "3680d0042d4fe0b95ada844ff24da0698a7f0773", "sha256": "ad7f8d67674906ce88077fbb233b427b7068991a61af42ce9301990bdf8f3605", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java-util/3.6.0/protobuf-java-util-3.6.0.jar", "source": {"sha1": "1ac9d14befa9c98d382529dafa562a2dd4650011", "sha256": "a2959842caed6f0b1dbecfaf0e73ef03117416f967c0532c32d092b6e2b98d60", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java-util/3.6.0/protobuf-java-util-3.6.0-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_protobuf_protobuf_java_util", "actual": "@io_bazel_rules_kotlin_com_google_protobuf_protobuf_java_util//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/protobuf/protobuf_java_util"},
     {"artifact": "com.google.protobuf:protobuf-java:3.6.0", "lang": "java", "sha1": "5333f7e422744d76840c08a106e28e519fbe3acd", "sha256": "8c8a65be83e75ccdcaa21417e303025f1708ea01e8c0a05d6c770e64b6c09ea1", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.6.0/protobuf-java-3.6.0.jar", "source": {"sha1": "6013b3453e0c102a8bd330d37f8e6918ce431882", "sha256": "88411bb0333725b27bf53ed4d95785f6f4b541e22e1e27c60c2be8b3115fc5c4", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.6.0/protobuf-java-3.6.0-sources.jar"} , "name": "io_bazel_rules_kotlin_com_google_protobuf_protobuf_java", "actual": "@io_bazel_rules_kotlin_com_google_protobuf_protobuf_java//jar", "bind": "jar/io_bazel_rules_kotlin_com/google/protobuf/protobuf_java"},