initial import from hsyed/rules_kotlin
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..37e64eb
--- /dev/null
+++ b/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/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..c4d8bbd
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,18 @@
+Want to contribute? Great! First, read this page (including the small print at the end).
+
+Before you contribute
+
+Before we can use your code, you must sign the Google Individual Contributor License Agreement (CLA), which you can do online.
+
+The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code. We also need to be sure of various other things — for instance that you'll tell us if you know that your code infringes on other people's patents. You don't have to sign the CLA until after you've submitted your code for review and a member has approved it, but you must do it before we can put your code into our codebase.
+
+The small print
+
+Contributions made by corporations are covered by a different agreement than the one above, the Software Grant and Corporate Contributor License Agreement.
+
+Contribution process
+
+Explain your idea and discuss your plan with members of the team. The best way to do this is to create an issue or comment on an existing issue.
+Prepare a git commit with your change. Don't forget to add tests. Run the existing tests with bazel test //.... Update README.md if appropriate.
+Create a pull request. This will start the code review process. All submissions, including submissions by project members, require review.
+You may be asked to make some changes. You'll also need to sign the CLA at this point, if you haven't done so already. Our continuous integration bots will test your change automatically on supported platforms. Once everything looks good, your change will be merged.
\ No newline at end of file
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
index 0000000..93b927a
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,12 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people.  For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# Names should be added to this file as:
+#     Name <email address>
+
+Hassan Syed <h.a.syed@gmail.com>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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/Makefile b/Makefile
new file mode 100644
index 0000000..7dfada1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,16 @@
+test.smoke:
+	python -B tests/smoke/basic_tests.py
+	bazel test //kotlin/workers:unittests
+
+reformat:
+	buildifier -mode=fix -v kotlin/*.bzl
+	buildifier -mode=fix -v kotlin/rules/*.bzl
+
+docs.regen:
+	bazel build //kotlin:docs
+	unzip -o bazel-bin/kotlin/docs-skydoc.zip -d docs
+
+docs.preview_local:
+	bazel build //kotlin:docs --define local=1
+	unzip -o bazel-bin/kotlin/docs-skydoc.zip -d /tmp/rules_kotlin
+	open /tmp/rules_kotlin/kotlin/kotlin.html
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d40ea1e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+[Skydoc documentation](https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html)
+
+# Overview
+
+These rules were initially forked from [pubref/rules_kotlin](http://github.com/pubref/rules_kotlin). Key changes:
+
+* Replace the macros with three basic rules. `kotlin_binary`, `kotlin_library` and `kotlin_test`.
+* Use a single dep attribute instead of `java_dep` and `dep`.
+* Add support for the following standard java rules attributes:
+  * `data`
+  * `resource_jars`
+  * `runtime_deps`
+  * `resources`
+  * `resources_strip_prefix`
+  * `exports`
+* Persistent worker support.
+* Mixed-Mode compilation (compile Java and Kotlin in one pass).
\ No newline at end of file
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..3a9e6f0
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,35 @@
+# 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.
+workspace(name="io_bazel_rules_kotlin")
+
+git_repository(
+    name = "io_bazel_rules_sass",
+    remote = "https://github.com/bazelbuild/rules_sass.git",
+    tag = "0.0.3",
+)
+load("@io_bazel_rules_sass//sass:sass.bzl", "sass_repositories")
+sass_repositories()
+
+git_repository(
+    name = "io_bazel_skydoc",
+    remote = "https://github.com/bazelbuild/skydoc.git",
+    commit = "b36d22c"
+)
+load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
+skydoc_repositories()
+
+load("//kotlin:kotlin.bzl", "kotlin_repositories")
+kotlin_repositories()
+
+maven_jar(name = "junit_junit",artifact = "junit:junit:jar:4.12")
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..be9b0fd
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,154 @@
+
+
+<!--
+Documentation generated by Skydoc
+-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width initial-scale=1" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+
+    <title>Overview</title>
+
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" type="text/css">
+    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+    <link rel="stylesheet" href="https://code.getmdl.io/1.1.1/material.green-light_blue.min.css">
+    <script defer src="https://code.getmdl.io/1.1.1/material.min.js"></script>
+    <link rel="stylesheet" href="https://hsyed.github.io/rules_kotlin/main.css">
+  </head>
+  <body>
+    <div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer
+      mdl-layout--fixed-header">
+      <header class="mdl-layout__header">
+        <div class="mdl-layout__header-row">
+          <span class="mdl-layout-title">Overview</span>
+        </div>
+      </header>
+      <div class="mdl-layout__drawer">
+        <span class="mdl-layout-title">Bazel</span>
+        <nav class="drawer-nav">
+          <ul class="drawer-nav">
+            
+<li><a href="https://hsyed.github.io/rules_kotlin/index.html">Overview</a></li>
+<li>
+  <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html">Kotlin Rules</a>
+  <ul>
+    <li><a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#overview">Overview</a></li>
+    <li>
+      <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_binary">
+        kotlin_binary
+      </a>
+    </li>
+    <li>
+      <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_library">
+        kotlin_library
+      </a>
+    </li>
+    <li>
+      <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_test">
+        kotlin_test
+      </a>
+    </li>
+  </ul>
+</li>
+
+          </ul>
+        </nav>
+      </div>
+
+      <main class="mdl-layout__content">
+        <div class="page-content">
+<h1>Overview</h1>
+
+
+<nav class="toc">
+  <h2>Rule sets</h2>
+  <ul>
+    <li><a href="#kotlin">Kotlin Rules</a></li>
+  </ul>
+</nav>
+
+<h2><a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html">Kotlin Rules</a></h2>
+
+<h3>Rules</h3>
+<table class="overview-table">
+  <colgroup>
+    <col class="col-name" />
+    <col class="col-description" />
+  </colgroup>
+  <tbody>
+    <tr>
+      <td>
+        <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_binary">
+          <code>kotlin_binary</code>
+        </a>
+      </td>
+      <td>
+        <p>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.</p>
+
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_library">
+          <code>kotlin_library</code>
+        </a>
+      </td>
+      <td>
+        <p>This rule compiles and links Kotlin and Java sources into a .jar file.</p>
+
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_test">
+          <code>kotlin_test</code>
+        </a>
+      </td>
+      <td>
+        <p>Setup a simple kotlin_test.</p>
+
+      </td>
+    </tr>
+  </tbody>
+</table>
+<h3>Macros</h3>
+<table class="overview-table">
+  <colgroup>
+    <col class="col-name" />
+    <col class="col-description" />
+  </colgroup>
+  <tbody>
+    <tr>
+      <td>
+        <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_repositories">
+          <code>kotlin_repositories</code>
+        </a>
+      </td>
+      <td>
+        <p>Call this in the WORKSPACE file to setup the Kotlin rules.</p>
+
+      </td>
+    </tr>
+  </tbody>
+</table>
+
+
+        </div>
+
+        <footer class="mdl-mini-footer">
+          <div class="mdl-mini-footer__left-section">
+            <div class="mdl-logo">Bazel</div>
+            <ul class="mdl-mini-footer__link-list">
+              <li><a href="https://bazel.build">Home</a></li>
+              <li><a href="https://github.com/bazelbuild">GitHub</a></li>
+            </ul>
+          </div>
+        </footer>
+      </main>
+    </div>
+  </body>
+</html>
diff --git a/docs/kotlin/kotlin.html b/docs/kotlin/kotlin.html
new file mode 100644
index 0000000..61c6f5f
--- /dev/null
+++ b/docs/kotlin/kotlin.html
@@ -0,0 +1,418 @@
+
+
+<!--
+Documentation generated by Skydoc
+-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width initial-scale=1" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+
+    <title>Kotlin Rules</title>
+
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" type="text/css">
+    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+    <link rel="stylesheet" href="https://code.getmdl.io/1.1.1/material.green-light_blue.min.css">
+    <script defer src="https://code.getmdl.io/1.1.1/material.min.js"></script>
+    <link rel="stylesheet" href="https://hsyed.github.io/rules_kotlin/main.css">
+  </head>
+  <body>
+    <div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer
+      mdl-layout--fixed-header">
+      <header class="mdl-layout__header">
+        <div class="mdl-layout__header-row">
+          <span class="mdl-layout-title">Kotlin Rules</span>
+        </div>
+      </header>
+      <div class="mdl-layout__drawer">
+        <span class="mdl-layout-title">Bazel</span>
+        <nav class="drawer-nav">
+          <ul class="drawer-nav">
+            
+<li><a href="https://hsyed.github.io/rules_kotlin/index.html">Overview</a></li>
+<li>
+  <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html">Kotlin Rules</a>
+  <ul>
+    <li><a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#overview">Overview</a></li>
+    <li>
+      <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_binary">
+        kotlin_binary
+      </a>
+    </li>
+    <li>
+      <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_library">
+        kotlin_library
+      </a>
+    </li>
+    <li>
+      <a href="https://hsyed.github.io/rules_kotlin/kotlin/kotlin.html#kotlin_test">
+        kotlin_test
+      </a>
+    </li>
+  </ul>
+</li>
+
+          </ul>
+        </nav>
+      </div>
+
+      <main class="mdl-layout__content">
+        <div class="page-content">
+          <h1>Kotlin Rules</h1>
+
+<nav class="toc">
+  <h2><a href="#overview">Overview</a></h2>
+  <h2>Rules</h2>
+  <ul>
+    <li><a href="#kotlin_binary">kotlin_binary</a></li>
+    <li><a href="#kotlin_library">kotlin_library</a></li>
+    <li><a href="#kotlin_test">kotlin_test</a></li>
+  </ul>
+  <h2>Macros</h2>
+  <ul>
+    <li><a href="#kotlin_repositories">kotlin_repositories</a></li>
+  </ul>
+</nav>
+          <hr>
+          <h2 id="overview">Overview</h2>
+          <h3>Setup</h3>
+<p>Add the following snippet to your <code>WORKSPACE</code> file:</p>
+<pre><code class="lang-bzl">git_repository(
+    name = &quot;io_bazel_rules_kotlin&quot;,
+    remote = &quot;https://github.com/bazelbuild/rules_kotlin.git&quot;,
+    commit = &quot;&lt;COMMIT_HASH&gt;&quot;,
+)
+load(&quot;@io_bazel_rules_kotlin//kotlin:kotlin.bzl&quot;, &quot;kotlin_repositories&quot;)
+kotlin_repositories(kotlin_release_version = &quot;1.2.20&quot;)
+</code></pre>
+<p>To enable persistent worker support, add the following to the appropriate <code>bazelrc</code> file:</p>
+<pre><code>build --strategy=KotlinCompile=worker
+test --strategy=KotlinCompile=worker
+</code></pre>
+<h3>Standard Libraries</h3>
+<p>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 <code>com_github_jetbrains_kotlin</code>:</p>
+<ul>
+<li><code>kotlin-test</code>,</li>
+<li><code>kotlin-reflect</code>.</li>
+</ul>
+<p>So if you needed to add reflect as a dep use the following label <code>@com_github_jetbrains_kotlin//:reflect</code>.</p>
+<h3>Caveats</h3>
+<ul>
+<li>The compiler is currently not configurable <a href="https://github.com/hsyed/rules_kotlin/issues/3">issue</a>.</li>
+<li>The compiler is hardwired to target jdk8 and language and api levels "1.2" <a href="https://github.com/hsyed/rules_kotlin/issues/3">issue</a>.</li>
+</ul>
+
+          <hr>
+
+          <h2 id="kotlin_repositories">kotlin_repositories</h2>
+
+          <pre>kotlin_repositories(<a href="#kotlin_repositories.kotlin_release_version">kotlin_release_version</a>)</pre>
+
+          <p>Call this in the WORKSPACE file to setup the Kotlin rules.</p>
+
+
+          <h3 id="kotlin_repositories_args">Attributes</h3>
+
+<table class="params-table">
+  <colgroup>
+    <col class="col-param" />
+    <col class="col-description" />
+  </colgroup>
+  <tbody>
+    <tr id="kotlin_repositories.kotlin_release_version">
+      <td><code>kotlin_release_version</code></td>
+      <td>
+        <p><code>Unknown; Optional</code></p>
+        <p>The kotlin compiler release version. If this is not set the latest release version is
+chosen by default.</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+          <hr>
+
+          <h2 id="kotlin_binary">kotlin_binary</h2>
+
+          <pre>kotlin_binary(<a href="#kotlin_binary.name">name</a>, <a href="#kotlin_binary.deps">deps</a>, <a href="#kotlin_binary.data">data</a>, <a href="#kotlin_binary.resources">resources</a>, <a href="#kotlin_binary.srcs">srcs</a>, <a href="#kotlin_binary.jvm_flags">jvm_flags</a>, <a href="#kotlin_binary.main_class">main_class</a>, <a href="#kotlin_binary.resource_jars">resource_jars</a>, <a href="#kotlin_binary.resource_strip_prefix">resource_strip_prefix</a>, <a href="#kotlin_binary.runtime_deps">runtime_deps</a>)</pre>
+
+          <p>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.</p>
+<p><strong>Note:</strong> This rule does not have all of the features found in <a href="https://docs.bazel.build/versions/master/be/java.html#java_binary"><code>java_binary</code></a>. It is
+appropriate for building workspace utilities. <code>java_binary</code> should be preferred for release artefacts.</p>
+
+
+          <h3 id="kotlin_binary_args">Attributes</h3>
+
+<table class="params-table">
+  <colgroup>
+    <col class="col-param" />
+    <col class="col-description" />
+  </colgroup>
+  <tbody>
+    <tr id="kotlin_binary.name">
+      <td><code>name</code></td>
+      <td>
+        <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+        <p>A unique name for this rule.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.deps">
+      <td><code>deps</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>A list of dependencies of this rule.See general comments about <code>deps</code> at <a href="https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes">Attributes common to all build rules</a>.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.data">
+      <td><code>data</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        
+      </td>
+    </tr>
+    <tr id="kotlin_binary.resources">
+      <td><code>resources</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>A list of data files to include in a Java jar.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.srcs">
+      <td><code>srcs</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>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.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.jvm_flags">
+      <td><code>jvm_flags</code></td>
+      <td>
+        <p><code>List of strings; Optional; Default is []</code></p>
+        <p>A list of flags to embed in the wrapper script generated for running this binary. Note: does not yet support make variable substitution.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.main_class">
+      <td><code>main_class</code></td>
+      <td>
+        <p><code>String; Required</code></p>
+        <p>Name of class with main() method to use as entry point.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.resource_jars">
+      <td><code>resource_jars</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>Set of archives containing Java resources. If specified, the contents of these jars are merged into the output jar.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.resource_strip_prefix">
+      <td><code>resource_strip_prefix</code></td>
+      <td>
+        <p><code>String; Optional; Default is ''</code></p>
+        <p>The path prefix to strip from Java resources, files residing under common prefix such as <code>src/main/resources</code> or <code>src/test/resources</code>
+will have stripping applied by convention.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_binary.runtime_deps">
+      <td><code>runtime_deps</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>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.</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+          <hr>
+
+          <h2 id="kotlin_library">kotlin_library</h2>
+
+          <pre>kotlin_library(<a href="#kotlin_library.name">name</a>, <a href="#kotlin_library.deps">deps</a>, <a href="#kotlin_library.resources">resources</a>, <a href="#kotlin_library.srcs">srcs</a>, <a href="#kotlin_library.exports">exports</a>, <a href="#kotlin_library.resource_jars">resource_jars</a>, <a href="#kotlin_library.resource_strip_prefix">resource_strip_prefix</a>, <a href="#kotlin_library.runtime_deps">runtime_deps</a>)</pre>
+
+          <p>This rule compiles and links Kotlin and Java sources into a .jar file.</p>
+
+
+          <h3 id="kotlin_library_args">Attributes</h3>
+
+<table class="params-table">
+  <colgroup>
+    <col class="col-param" />
+    <col class="col-description" />
+  </colgroup>
+  <tbody>
+    <tr id="kotlin_library.name">
+      <td><code>name</code></td>
+      <td>
+        <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+        <p>A unique name for this rule.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_library.deps">
+      <td><code>deps</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>A list of dependencies of this rule.See general comments about <code>deps</code> at <a href="https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes">Attributes common to all build rules</a>.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_library.resources">
+      <td><code>resources</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>A list of data files to include in a Java jar.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_library.srcs">
+      <td><code>srcs</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>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.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_library.exports">
+      <td><code>exports</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>Exported libraries.</p>
+<p>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.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_library.resource_jars">
+      <td><code>resource_jars</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>Set of archives containing Java resources. If specified, the contents of these jars are merged into the output jar.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_library.resource_strip_prefix">
+      <td><code>resource_strip_prefix</code></td>
+      <td>
+        <p><code>String; Optional; Default is ''</code></p>
+        <p>The path prefix to strip from Java resources, files residing under common prefix such as <code>src/main/resources</code> or <code>src/test/resources</code>
+will have stripping applied by convention.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_library.runtime_deps">
+      <td><code>runtime_deps</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>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.</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+          <hr>
+
+          <h2 id="kotlin_test">kotlin_test</h2>
+
+          <pre>kotlin_test(<a href="#kotlin_test.name">name</a>, <a href="#kotlin_test.deps">deps</a>, <a href="#kotlin_test.data">data</a>, <a href="#kotlin_test.resources">resources</a>, <a href="#kotlin_test.srcs">srcs</a>, <a href="#kotlin_test.jvm_flags">jvm_flags</a>, <a href="#kotlin_test.resource_jars">resource_jars</a>, <a href="#kotlin_test.resource_strip_prefix">resource_strip_prefix</a>, <a href="#kotlin_test.runtime_deps">runtime_deps</a>, <a href="#kotlin_test.test_class">test_class</a>)</pre>
+
+          <p>Setup a simple kotlin_test.</p>
+
+
+          <h3 id="kotlin_test_args">Attributes</h3>
+
+<table class="params-table">
+  <colgroup>
+    <col class="col-param" />
+    <col class="col-description" />
+  </colgroup>
+  <tbody>
+    <tr id="kotlin_test.name">
+      <td><code>name</code></td>
+      <td>
+        <p><code><a href="https://bazel.build/docs/build-ref.html#name">Name</a>; Required</code></p>
+        <p>A unique name for this rule.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.deps">
+      <td><code>deps</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>A list of dependencies of this rule.See general comments about <code>deps</code> at <a href="https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes">Attributes common to all build rules</a>.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.data">
+      <td><code>data</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        
+      </td>
+    </tr>
+    <tr id="kotlin_test.resources">
+      <td><code>resources</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>A list of data files to include in a Java jar.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.srcs">
+      <td><code>srcs</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>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.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.jvm_flags">
+      <td><code>jvm_flags</code></td>
+      <td>
+        <p><code>List of strings; Optional; Default is []</code></p>
+        <p>A list of flags to embed in the wrapper script generated for running this binary. Note: does not yet support make variable substitution.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.resource_jars">
+      <td><code>resource_jars</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>Set of archives containing Java resources. If specified, the contents of these jars are merged into the output jar.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.resource_strip_prefix">
+      <td><code>resource_strip_prefix</code></td>
+      <td>
+        <p><code>String; Optional; Default is ''</code></p>
+        <p>The path prefix to strip from Java resources, files residing under common prefix such as <code>src/main/resources</code> or <code>src/test/resources</code>
+will have stripping applied by convention.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.runtime_deps">
+      <td><code>runtime_deps</code></td>
+      <td>
+        <p><code>List of <a href="https://bazel.build/docs/build-ref.html#labels">labels</a>; Optional; Default is []</code></p>
+        <p>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.</p>
+      </td>
+    </tr>
+    <tr id="kotlin_test.test_class">
+      <td><code>test_class</code></td>
+      <td>
+        <p><code>String; Optional; Default is ''</code></p>
+        <p>The Java class to be loaded by the test runner.</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+
+
+        </div>
+
+        <footer class="mdl-mini-footer">
+          <div class="mdl-mini-footer__left-section">
+            <div class="mdl-logo">Bazel</div>
+            <ul class="mdl-mini-footer__link-list">
+              <li><a href="https://bazel.build">Home</a></li>
+              <li><a href="https://github.com/bazelbuild">GitHub</a></li>
+            </ul>
+          </div>
+        </footer>
+      </main>
+    </div>
+  </body>
+</html>
diff --git a/docs/main.css b/docs/main.css
new file mode 100755
index 0000000..f506e12
--- /dev/null
+++ b/docs/main.css
@@ -0,0 +1,3 @@
+body{background-color:#fafafa}pre,code{font-family:'Liberation Mono', Consolas, Monaco, 'Andale Mono', monospace}pre{background-color:#eee;padding:20px;overflow-x:auto;word-wrap:normal}pre code{overflow-wrap:normal;white-space:pre}code{display:inline-block;font-size:90%;white-space:pre-wrap}.mdl-layout__drawer{background-color:#fff}.mdl-layout__drawer .mdl-layout-title{border-bottom:1px solid #e0e0e0;padding-left:24px}.drawer-nav ul{list-style:none;padding-left:0}.drawer-nav ul li{display:block;padding:0}.drawer-nav ul li ul li a{padding-left:44px;font-weight:400}.drawer-nav ul li a{display:block;flex-shrink:0;padding:15px 0 15px 22px;margin:0;font-weight:600;color:#757575;line-height:1em;text-decoration:none;cursor:pointer}.drawer-nav ul li a:active,.drawer-nav ul li a:hover{background-color:#f0f0f0}.drawer-nav ul li.active a{color:#4caf50;font-weight:500}h1.page-title{font-size:34px;font-weight:400;line-height:40px;margin-bottom:30px;color:#4caf50}p.lead{font-size:20px;line-height:32px}table{border-collapse:collapse;border-spacing:0;background-color:#fff;table-layout:auto}table thead th{background-color:#fafafa;border:1px solid #eee;color:#757575;padding:12px 12px 12px 24px;vertical-align:top}table tbody td{border:1px solid #eee;padding:12px 12px 12px 24px;vertical-align:top}table.params-table{width:100%}table.params-table col.col-param{width:25%}table.params-table col.col-description{width:75%}table.overview-table{width:100%}table.overview-table col.col-name{width:25%}table.overview-table col.col-description{width:75%}table.overview-table td p{margin:0}hr{margin-top:80px;margin-bottom:80px}nav.toc{border-left:5px solid #4caf50;padding-left:20px;margin-bottom:48px}nav.toc h1,nav.toc h2{font-size:15px;line-height:16px;padding-bottom:12px;margin-bottom:0;font-weight:400;color:#757575}nav.toc ul{list-style:none;margin-top:0;padding-left:0}nav.toc ul li{font-size:20px;line-height:40px}nav.toc ul li a{color:#4caf50}.page-content{margin-left:auto;margin-right:auto;padding-top:60px;padding-bottom:60px;width:760px}.page-content a{text-decoration:none}.page-content h1{font-size:34px;font-weight:400;line-height:40px;margin-bottom:30px;color:#4caf50}.page-content h2{font-size:24px;font-weight:400;line-height:32px;margin-bottom:30px;color:#4caf50}.page-content h3{font-size:20px;font-weight:400;line-height:32px;margin-bottom:30px;color:#4caf50}@media (max-width: 768px){.page-content{width:360px}}@media (min-width: 768px){.page-content{width:760px}}@media (min-width: 1476px){.page-content{width:1160px}}.mdl-mini-footer{padding-left:40px}
+
+/*# sourceMappingURL=main.css.map */
\ No newline at end of file
diff --git a/kotlin/BUILD b/kotlin/BUILD
new file mode 100644
index 0000000..3c988f1
--- /dev/null
+++ b/kotlin/BUILD
@@ -0,0 +1,44 @@
+# 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(default_visibility = ["//visibility:private"])
+load("@io_bazel_skydoc//skylark:skylark.bzl", "skylark_doc", "skylark_library" )
+
+skylark_library(
+    name = "doc_public",
+    srcs = [
+        "kotlin.bzl"
+    ],
+    visibility=["//visibility:private"]
+)
+
+skylark_doc(
+    name = "docs",
+    deps = [
+        ":doc_public",
+    ],
+    format = "html",
+    site_root = select({
+        ":local": "/tmp/rules_kotlin",
+        "//conditions:default": "https://hsyed.github.io/rules_kotlin"
+#        "//conditions:default": "https://bazelbuild.github.io/rules_kotlin"
+    }),
+    visibility = ["//visibility:public"]
+)
+
+config_setting(
+    name = "local",
+    values = {
+        "define": "local=1",
+    }
+)
\ No newline at end of file
diff --git a/kotlin/kotlin.bzl b/kotlin/kotlin.bzl
new file mode 100644
index 0000000..f501c8c
--- /dev/null
+++ b/kotlin/kotlin.bzl
@@ -0,0 +1,277 @@
+# 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")
+kotlin_repositories(kotlin_release_version = "1.2.20")
+```
+
+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//:reflect`.
+
+### Caveats
+
+* The compiler is currently not configurable [issue](https://github.com/hsyed/rules_kotlin/issues/3).
+* The compiler is hardwired to target jdk8 and language and api levels "1.2" [issue](https://github.com/hsyed/rules_kotlin/issues/3).
+"""
+# 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/rules:defs.bzl", "KOTLIN_REPO_ROOT")
+
+# The files types that may be passed to the core Kotlin compile rule.
+_kt_compile_filetypes = FileType([
+    ".kt",
+    ".java",
+])
+
+_jar_filetype = FileType([".jar"])
+
+_srcjar_filetype = FileType([
+    ".jar",
+    "-sources.jar",
+])
+
+########################################################################################################################
+# Rule Attributes
+########################################################################################################################
+_implicit_deps = {
+    "_kotlin_compiler_classpath": attr.label_list(
+        allow_files = True,
+        default = [
+            Label("@" + KOTLIN_REPO_ROOT + "//:compiler"),
+            Label("@" + KOTLIN_REPO_ROOT + "//:reflect"),
+            Label("@" + KOTLIN_REPO_ROOT + "//:script-runtime"),
+        ],
+    ),
+    "_kotlinw": attr.label(
+        default = Label("//kotlin/workers:compiler_jvm"),
+        executable = True,
+        cfg = "host",
+    ),
+    # The kotlin runtime
+    "_kotlin_runtime": attr.label(
+        single_file = True,
+        default = Label("@" + KOTLIN_REPO_ROOT + "//:runtime"),
+    ),
+    # The kotlin stdlib
+    "_kotlin_std": attr.label_list(default = [
+        Label("@" + KOTLIN_REPO_ROOT + "//:stdlib"),
+        Label("@" + KOTLIN_REPO_ROOT + "//:stdlib-jdk7"),
+        Label("@" + KOTLIN_REPO_ROOT + "//:stdlib-jdk8"),
+    ]),
+    "_kotlin_reflect": attr.label(
+        single_file = True,
+        default =
+            Label("@" + KOTLIN_REPO_ROOT + "//:reflect"),
+    ),
+    "_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,
+    ),
+    "_jdk": attr.label(
+        default = Label("@bazel_tools//tools/jdk"),
+        cfg = "host",
+        allow_files = True,
+    ),
+    #    "_langtools": attr.label(
+    #        default = Label("@bazel_tools//tools/jdk:langtools"),
+    #        cfg = "host",
+    #        allow_files = True
+    #    ),
+    "_java_stub_template": attr.label(default = Label("@kt_java_stub_template//file")),
+}
+
+_common_attr = dict(_implicit_deps.items() + {
+    "srcs": attr.label_list(
+        default = [],
+        allow_files = _kt_compile_filetypes,
+    ),
+    # only accept deps which are java providers.
+    "deps": attr.label_list(),
+    "runtime_deps": attr.label_list(default = []),
+    # Add debugging info for any rules.
+    #    "verbose": attr.int(default = 0),
+    #    "opts": attr.string_dict(),
+    # Advanced options
+    #    "x_opts": attr.string_list(),
+    # Plugin options
+    #    "plugin_opts": attr.string_dict(),
+    "resources": attr.label_list(
+        default = [],
+        allow_files = True,
+    ),
+    "resource_strip_prefix": attr.string(default = ""),
+    "resource_jars": attr.label_list(default = []),
+    # Other args for the compiler
+}.items())
+
+_runnable_common_attr = dict(_common_attr.items() + {
+    "data": attr.label_list(
+        allow_files = True,
+        cfg = "data",
+    ),
+    "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",
+    srcjar = "%{name}-sources.jar",
+)
+
+_binary_outputs = dict(_common_outputs.items() + {
+    #    "wrapper": "%{name}_wrapper.sh",
+}.items())
+
+########################################################################################################################
+# Repositories
+########################################################################################################################
+load(
+    "//kotlin:kotlin_compiler_repositories.bzl",
+    "KOTLIN_CURRENT_RELEASE",
+    _kotlin_compiler_repository = "kotlin_compiler_repository",
+)
+
+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.
+    """
+    _kotlin_compiler_repository(kotlin_release_version)
+
+########################################################################################################################
+# Simple Rules:
+########################################################################################################################
+load(
+    "//kotlin/rules:rules.bzl",
+    _kotlin_binary_impl = "kotlin_binary_impl",
+    _kotlin_junit_test_impl = "kotlin_junit_test_impl",
+    _kotlin_library_impl = "kotlin_library_impl",
+)
+
+kotlin_library = rule(
+    attrs = dict(_common_attr.items() + {
+        "exports": attr.label_list(default = []),
+    }.items()),
+    outputs = _common_outputs,
+    implementation = _kotlin_library_impl,
+)
+
+"""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).
+"""
+
+kotlin_binary = rule(
+    attrs = dict(_runnable_common_attr.items() + {"main_class": attr.string(mandatory = True)}.items()),
+    executable = True,
+    outputs = _binary_outputs,
+    implementation = _kotlin_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.
+"""
+
+kotlin_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,
+        ),
+        "test_class": attr.string(),
+        #      "main_class": attr.string(),
+    }.items()),
+    executable = True,
+    outputs = _binary_outputs,
+    test = True,
+    implementation = _kotlin_junit_test_impl,
+)
+
+"""Setup a simple kotlin_test.
+Args:
+  test_class: The Java class to be loaded by the test runner.
+"""
diff --git a/kotlin/kotlin_compiler_repositories.bzl b/kotlin/kotlin_compiler_repositories.bzl
new file mode 100644
index 0000000..4b2ec46
--- /dev/null
+++ b/kotlin/kotlin_compiler_repositories.bzl
@@ -0,0 +1,149 @@
+# 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.
+"""
+
+load("//kotlin/rules:defs.bzl", "KOTLIN_REPO_ROOT")
+
+KOTLIN_RELEASES = {
+    "1.2.20": {
+        "version": "1.2.20",
+        "url": "https://github.com/JetBrains/kotlin/releases/download/v1.2.20/kotlin-compiler-1.2.20.zip",
+        "sha256": "fb63d3d9f37b43f37575e3623c058d42a4b5dc8da08479ab065c4994e421a057",
+    },
+    "1.2.10": {
+        "version": "1.2.10",
+        "url": "https://github.com/JetBrains/kotlin/releases/download/v1.2.10/kotlin-compiler-1.2.10.zip",
+        "sha256": "95874568919121acb694bec0d6c92c60bdceea53f4c202e23ab734e94a0c26e3",
+    },
+    "1.2.0": {
+        "version": "1.2.0",
+        "url": "https://github.com/JetBrains/kotlin/releases/download/v1.2.0/kotlin-compiler-1.2.0.zip",
+        "sha256": "895d0f8286db3e4f43d67cd5e09b600af6e0a5017cb74072d1b09c78b697775a",
+    },
+}
+
+KOTLIN_COMPILER_REPO_BUILD_FILE = """
+load("@io_bazel_rules_kotlin//kotlin/rules:bootstrap.bzl", kotlin_stdlib="kotlin_stdlib")
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+    name = "home",
+    srcs = glob(["lib/*.jar"], exclude = ["lib/*-sources.jar"]),
+)
+
+kotlin_stdlib(
+    name = "kotlin-runtime",
+    jars = ["lib/kotlin-runtime.jar"],
+    srcjar = "lib/kotlin-runtime-sources.jar"
+)
+
+kotlin_stdlib(
+    name = "kotlin-stdlib",
+    jars = ["lib/kotlin-stdlib.jar"],
+    srcjar = "lib/kotlin-stdlib-sources.jar"
+)
+
+kotlin_stdlib(
+    name = "kotlin-stdlib-jdk7",
+    jars = ["lib/kotlin-stdlib-jdk7.jar"],
+    srcjar = "lib/kotlin-stdlib-jdk7-sources.jar"
+)
+
+kotlin_stdlib(
+    name = "kotlin-stdlib-jdk8",
+    jars = ["lib/kotlin-stdlib-jdk8.jar"],
+    srcjar = "lib/kotlin-stdlib-jdk8-sources.jar"
+)
+
+kotlin_stdlib(
+    name = "kotlin-reflect",
+    jars = ["lib/kotlin-reflect.jar"],
+    srcjar = "lib/kotlin-reflect-sources.jar"
+)
+
+kotlin_stdlib(
+    name = "kotlin-test",
+    jars = ["lib/kotlin-test.jar"],
+    srcjar = "lib/kotlin-test-sources.jar"
+)
+
+alias(name="runtime", actual="kotlin-runtime")
+alias(name="stdlib", actual="kotlin-stdlib")
+alias(name="stdlib-jdk7", actual="kotlin-stdlib-jdk7")
+alias(name="stdlib-jdk8", actual="kotlin-stdlib-jdk8")
+alias(name="reflect", actual="kotlin-reflect")
+alias(name="test", actual="kotlin-test")
+
+java_import(
+    name = "compiler",
+    jars = ["lib/kotlin-compiler.jar"],
+)
+
+java_import(
+    name = "script-runtime",
+    jars = ["lib/kotlin-script-runtime.jar"],
+)
+
+java_import(
+    name = "preloader",
+    jars = ["lib/kotlin-preloader.jar"],
+)
+
+sh_binary(
+    name = "kotlin",
+    srcs = ["bin/kotlin"],
+)
+
+sh_binary(
+    name = "kotlinc",
+    srcs = ["bin/kotlinc"],
+)
+
+exports_files(["src"])
+"""
+
+KOTLIN_CURRENT_RELEASE = "1.2.20"
+
+_BAZEL_JAVA_LAUNCHER_VERSION = "0.8.1"
+
+def kotlin_compiler_repository(
+    kotlin_release_version=KOTLIN_CURRENT_RELEASE
+):
+    release=KOTLIN_RELEASES[kotlin_release_version]
+    if not release:
+        fail('"%s" not a valid kotlin release, current release is "%s"' % (kotlin_release_version, KOTLIN_CURRENT_RELEASE))
+
+    native.new_http_archive(
+        name = KOTLIN_REPO_ROOT,
+        url = release["url"],
+        sha256 = release["sha256"],
+        build_file_content= KOTLIN_COMPILER_REPO_BUILD_FILE,
+        strip_prefix = "kotlinc",
+    )
+
+    native.maven_jar(
+        name = "io_bazel_rules_kotlin_protobuf_protobuf_java",
+        artifact = "com.google.protobuf:protobuf-java:3.4.0",
+        sha1 = "b32aba0cbe737a4ca953f71688725972e3ee927c",
+    )
+
+    native.http_file(
+        name = "kt_java_stub_template",
+        url = ("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",
+    )
\ No newline at end of file
diff --git a/kotlin/rules/BUILD b/kotlin/rules/BUILD
new file mode 100644
index 0000000..37e64eb
--- /dev/null
+++ b/kotlin/rules/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/rules/bootstrap.bzl b/kotlin/rules/bootstrap.bzl
new file mode 100644
index 0000000..a368b40
--- /dev/null
+++ b/kotlin/rules/bootstrap.bzl
@@ -0,0 +1,58 @@
+# 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/rules:defs.bzl",
+    _KotlinInfo = "KotlinInfo",
+)
+
+def _kotlin_stdlib(ctx):
+    if len(ctx.files.jars) != 1:
+        fail("a jar target must be provided")
+
+    java_info = java_common.create_provider(
+        use_ijar = False,
+        source_jars=[ctx.file.srcjar],
+        compile_time_jars = ctx.files.jars,
+        runtime_jars=ctx.files.jars,
+        transitive_compile_time_jars= ctx.files.jars,
+        transitive_runtime_jars=ctx.files.jars
+    )
+    kotlin_info=_KotlinInfo(
+      outputs = struct(
+          jars = [struct(
+            class_jar = ctx.files.jars[0],
+            source_jar = ctx.file.srcjar,
+            ijar = None,
+          )]
+      )
+    )
+    default_info = DefaultInfo(files=depset(ctx.files.jars))
+    return struct(kt = kotlin_info, providers= [default_info, java_info, kotlin_info])
+
+kotlin_stdlib = rule(
+    attrs = {
+        "jars": attr.label_list(
+            allow_files = True,
+            mandatory = True,
+            cfg = "host",
+        ),
+        "srcjar": attr.label(
+            allow_single_file = True,
+            cfg = "host",
+        ),
+    },
+    implementation = _kotlin_stdlib,
+)
+
+"""Import Kotlin libraries that are part of the compiler release."""
diff --git a/kotlin/rules/compile.bzl b/kotlin/rules/compile.bzl
new file mode 100644
index 0000000..80c591c
--- /dev/null
+++ b/kotlin/rules/compile.bzl
@@ -0,0 +1,211 @@
+# 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/rules:defs.bzl",
+    _KotlinInfo = "KotlinInfo",
+)
+load(
+    "//kotlin/rules:util.bzl",
+    _collect_all_jars = "collect_all_jars",
+    _collect_jars_for_compile = "collect_jars_for_compile",
+    _kotlin_build_resourcejar_action = "kotlin_build_resourcejar_action",
+    _kotlin_fold_jars_action = "kotlin_fold_jars_action",
+    _kotlin_maybe_make_srcs_action = "kotlin_maybe_make_srcs_action",
+)
+
+def _kotlin_do_compile_action(ctx, output_jar, compile_jars, opts):
+    """Internal macro that sets up a Kotlin compile action.
+
+    This macro only supports a single Kotlin compile operation for a rule.
+
+    Args:
+      ctx: the ctx of the rule in scope when this macro is called. The macro will pick up the following entities from
+        the rule ctx:
+          * The `srcs` to compile.
+      output_jar: The jar file that this macro will use as the output of the action -- a hardcoded default output is not
+        setup by this rule as this would close the door to optimizations for simple compile operations.
+      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.
+      opts: struct containing Kotlin compilation options.
+    """
+    args = [
+        "--label", ctx.label,
+        "--output_classjar", output_jar.path,
+        "--output_jdeps", ctx.outputs.jdeps.path,
+        "--classpath", ":".join([f.path for f in compile_jars.to_list()]),
+        "--sources", ":".join([f.path for f in ctx.files.srcs]),
+        # https://github.com/hsyed/rules_kotlin/issues/3.
+        "--kotlin_jvm_target", "1.8", "--kotlin_api_version", "1.2", "--kotlin_language_version", "1.2"
+    ]
+
+    # re-enable compilation options https://github.com/hsyed/rules_kotlin/issues/3.
+#    for k, v in ctx.attr.opts.items():
+#        args + [ "-%s" % k, v]:
+
+    # Advanced options
+#    args += ["-X%s" % opt for opt in ctx.attr.x_opts]
+#
+#
+#    # Plugin options
+#    for k, v in ctx.attr.plugin_opts.items():
+#        args += ["-P"]
+#        args += ["plugin:%s=\"%s\"" % (k, v)]
+
+    # Declare and write out argument file.
+    args_file = ctx.actions.declare_file(ctx.label.name + "-worker.args")
+    ctx.actions.write(args_file, "\n".join(args))
+
+    # When a stratetegy isn't provided for the worker and the workspace is fresh then certain deps are not available under
+    # external/@com_github_jetbrains_kotlin/... that is why the classpath is added explicetly.
+    compile_inputs = (
+      depset([args_file]) +
+      ctx.files.srcs +
+      compile_jars +
+      ctx.files._kotlin_compiler_classpath +
+      ctx.files._jdk)
+
+    ctx.action(
+        mnemonic = "KotlinCompile",
+        inputs = compile_inputs,
+        outputs = [output_jar, ctx.outputs.jdeps],
+        executable = ctx.executable._kotlinw,
+        execution_requirements = {"supports-workers": "1"},
+        arguments = ["@" + args_file.path],
+        progress_message="Compiling %d Kotlin source files to %s" % (len(ctx.files.srcs), output_jar.short_path),
+    )
+
+def _select_compilation_options(ctx):
+  """TODO Stub: setup compilation options"""
+  return struct(
+      # Basic kotlin compile options.
+      opts = {},
+      # Advanced Kotlin compile options.
+      x_opts ={},
+      # Kotlin compiler plugin options.
+      plugin_opts = {}
+  )
+
+def _select_std_libs(ctx):
+    return ctx.files._kotlin_std
+
+def _make_java_provider(ctx, auto_deps=[]):
+    """Creates the java_provider for a Kotlin target.
+
+    This macro is distinct from the kotlin_make_providers as collecting the java_info is useful before the DefaultInfo is
+    created.
+
+    Args:
+    ctx: The ctx of the rule in scope when this macro is called. The macro will pick up the following entities from
+      the rule ctx:
+        * The default output jar.
+        * The `deps` for this provider.
+        * Optionally `exports` (see java rules).
+        * The `_kotlin_runtime` implicit dependency.
+    Returns:
+    A JavaInfo provider.
+    """
+    deps=_collect_all_jars(ctx.attr.deps)
+    exported_deps=_collect_all_jars(getattr(ctx.attr, "exports", []))
+
+    my_compile_jars = exported_deps.compile_jars + [ctx.outputs.jar]
+    my_runtime_jars = exported_deps.runtime_jars + [ctx.outputs.jar]
+
+    my_transitive_compile_jars = my_compile_jars + deps.transitive_compile_time_jars + exported_deps.transitive_compile_time_jars + auto_deps
+    my_transitive_runtime_jars = my_runtime_jars + deps.transitive_runtime_jars + exported_deps.transitive_runtime_jars + [ctx.file._kotlin_runtime] + auto_deps
+
+    # collect the runtime jars from the runtime_deps attribute.
+    for jar in ctx.attr.runtime_deps:
+        my_transitive_runtime_jars += jar[JavaInfo].transitive_runtime_jars
+
+    return java_common.create_provider(
+        use_ijar = False,
+        # A list or set of output source jars that contain the uncompiled source files including the source files
+        # generated by annotation processors if the case.
+        source_jars=_kotlin_maybe_make_srcs_action(ctx),
+        # A list or a set of jars that should be used at compilation for a given target.
+        compile_time_jars = my_compile_jars,
+        # A list or a set of jars that should be used at runtime for a given target.
+        runtime_jars=my_runtime_jars,
+        transitive_compile_time_jars= my_transitive_compile_jars,
+        transitive_runtime_jars=my_transitive_runtime_jars
+    )
+
+def kotlin_make_providers(ctx, java_info, transitive_files=depset(order="default")):
+    kotlin_info=_KotlinInfo(
+        src=ctx.attr.srcs,
+        outputs = struct(
+            jdeps = ctx.outputs.jdeps,
+            jars = [struct(
+              class_jar = ctx.outputs.jar,
+              ijar = None,
+            )]
+        ), # intelij aspect needs this.
+    )
+
+    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 kotlin_compile_action(ctx):
+    """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 + [_kotlin_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
+
+    kotlin_auto_deps=_select_std_libs(ctx)
+
+    # setup the compile action.
+    _kotlin_do_compile_action(
+        ctx,
+        kt_compile_output_jar,
+        _collect_jars_for_compile(ctx.attr.deps) + kotlin_auto_deps,
+        _select_compilation_options(ctx)
+    )
+    # setup the merge action if needed.
+    if len(output_merge_list) > 0:
+        _kotlin_fold_jars_action(ctx, output_jar, output_merge_list)
+
+    # create the java provider but the kotlin and default provider cannot be created here.
+    return _make_java_provider(ctx, kotlin_auto_deps)
\ No newline at end of file
diff --git a/kotlin/rules/defs.bzl b/kotlin/rules/defs.bzl
new file mode 100644
index 0000000..ab197cb
--- /dev/null
+++ b/kotlin/rules/defs.bzl
@@ -0,0 +1,29 @@
+# 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 name of the rules repo. Centralised so it's easy to change.
+REPO_ROOT = "io_bazel_rules_kotlin"
+
+# The name of the Kotlin compiler workspace.
+KOTLIN_REPO_ROOT = "com_github_jetbrains_kotlin"
+
+########################################################################################################################
+# Providers
+########################################################################################################################
+KotlinInfo = provider(
+    fields = {
+        "src": "the source files. [intelij-aspect]",
+        "outputs": "output jars produced by this rule. [intelij-aspect]",
+    },
+)
diff --git a/kotlin/rules/rules.bzl b/kotlin/rules/rules.bzl
new file mode 100644
index 0000000..d8d995c
--- /dev/null
+++ b/kotlin/rules/rules.bzl
@@ -0,0 +1,66 @@
+# 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/rules:compile.bzl",
+    _kotlin_compile_action = "kotlin_compile_action",
+    _kotlin_make_providers = "kotlin_make_providers",
+)
+load(
+    "//kotlin/rules:util.bzl",
+    _kotlin_write_launcher_action = "kotlin_write_launcher_action",
+)
+
+def kotlin_library_impl(ctx):
+  return _kotlin_make_providers(ctx, _kotlin_compile_action(ctx))
+
+def kotlin_binary_impl(ctx):
+    java_info = _kotlin_compile_action(ctx)
+    _kotlin_write_launcher_action(
+        ctx,
+        java_info.transitive_runtime_jars,
+        ctx.attr.main_class,
+        ctx.attr.jvm_flags
+    )
+    return _kotlin_make_providers(
+        ctx,
+        java_info,
+        depset(
+            order = "default",
+            transitive=[java_info.transitive_runtime_jars],
+            direct=[ctx.executable._java]
+        )
+    )
+
+def kotlin_junit_test_impl(ctx):
+    java_info = _kotlin_compile_action(ctx)
+
+    transitive_runtime_jars = java_info.transitive_runtime_jars + ctx.files._bazel_test_runner
+    launcherJvmFlags = ["-ea", "-Dbazel.test_suite=%s"% ctx.attr.test_class]
+
+    _kotlin_write_launcher_action(
+        ctx,
+        transitive_runtime_jars,
+        main_class = "com.google.testing.junit.runner.BazelTestRunner",
+        jvm_flags = launcherJvmFlags + ctx.attr.jvm_flags,
+    )
+    return _kotlin_make_providers(
+        ctx,
+        java_info,
+        depset(
+            order = "default",
+            transitive=[transitive_runtime_jars],
+            direct=[ctx.executable._java]
+        )
+    )
\ No newline at end of file
diff --git a/kotlin/rules/util.bzl b/kotlin/rules/util.bzl
new file mode 100644
index 0000000..7110ae1
--- /dev/null
+++ b/kotlin/rules/util.bzl
@@ -0,0 +1,187 @@
+# 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/rules:defs.bzl", "KotlinInfo")
+
+# DEPSET UTILS #########################################################################################################
+def _select_compile_jars(dep):
+    """selects the correct compile time jar from a java provider"""
+    if not JavaInfo in dep:
+        return []
+    is_kotlin_provider = KotlinInfo in dep
+    java_provider = dep[JavaInfo]
+    if is_kotlin_provider:
+       return java_provider.full_compile_jars
+    elif dep.label.workspace_root == "external/com_github_jetbrains_kotlin":
+         return java_provider.full_compile_jars
+    else:
+        return java_provider.compile_jars
+
+def collect_jars_for_compile(deps):
+    """creates the compile jar depset, this should be strict including only the output jars of the listed dependencies.
+    """
+    compile_jars = depset()
+    for d in deps:
+        compile_jars += _select_compile_jars(d)
+    return compile_jars
+
+def collect_all_jars(deps):
+    """
+    Merges a list of java providers into a struct of depsets.
+    """
+    compile_jars = depset()
+    runtime_jars = depset()
+    transitive_runtime_jars = depset()
+    transitive_compile_time_jars = depset()
+
+    for dep_target in deps:
+        if JavaInfo in dep_target:
+            java_provider = dep_target[JavaInfo]
+            compile_jars += java_provider.compile_jars
+            # the runtime_jar compile_jar seperation is here to support the exports concept.
+            runtime_jars += java_provider.full_compile_jars
+            transitive_compile_time_jars += java_provider.transitive_compile_time_jars
+            transitive_runtime_jars += java_provider.transitive_runtime_jars
+
+    return struct (
+        compile_jars = compile_jars,
+        runtime_jars = runtime_jars,
+        transitive_runtime_jars = transitive_runtime_jars,
+        transitive_compile_time_jars = transitive_compile_time_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 kotlin_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
+
+# SRC JARS #############################################################################################################
+def kotlin_maybe_make_srcs_action(ctx):
+    if len(ctx.files.srcs) > 0:
+        output_srcjar = ctx.actions.declare_file(ctx.label.name + "-sources.jar")
+        args = ["--output", output_srcjar.path]
+        for i in ctx.files.srcs:
+            args += ["--resources", i.path]
+
+        ctx.action(
+            mnemonic = "KotlinPackageSources",
+            inputs = ctx.files.srcs,
+            outputs = [output_srcjar],
+            executable = ctx.executable._singlejar,
+            arguments = args,
+            progress_message="Creating Kotlin srcjar from %d srcs" % len(ctx.files.srcs),
+        )
+        return [output_srcjar]
+    else:
+        return []
+
+# PACKAGE JARS #########################################################################################################
+def kotlin_fold_jars_action(ctx, output_jar, input_jars):
+    args=["--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 kotlin_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.template_action(
+        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 + "/",
+        },
+        executable = True,
+    )
\ No newline at end of file
diff --git a/kotlin/workers/BUILD b/kotlin/workers/BUILD
new file mode 100644
index 0000000..342ddaf
--- /dev/null
+++ b/kotlin/workers/BUILD
@@ -0,0 +1,38 @@
+# 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.
+java_library(
+    name = "lib",
+    srcs = glob(["src/**/*.java"]),
+    deps = [
+        "//kotlin/workers/proto",
+        "@com_github_jetbrains_kotlin//:preloader"
+    ],
+    exports = ["//kotlin/workers/proto"],
+    visibility = ["//visibility:private"]
+)
+
+java_binary(
+    name = "compiler_jvm",
+    main_class = "io.bazel.ruleskotlin.workers.compilers.jvm.KotlinJvmBuilder",
+    visibility = ["//visibility:public"],
+    runtime_deps = ["lib"]
+)
+
+java_test(
+    name = "unittests",
+    test_class = "io.bazel.ruleskotlin.workers.compilers.jvm.utils.JdepsParserTest",
+    srcs = glob(["unittests/**/*.java"]),
+    deps = ["lib"],
+    size = "small"
+)
\ No newline at end of file
diff --git a/kotlin/workers/proto/BUILD b/kotlin/workers/proto/BUILD
new file mode 100644
index 0000000..ebf55a8
--- /dev/null
+++ b/kotlin/workers/proto/BUILD
@@ -0,0 +1,22 @@
+# 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.
+java_import(
+    name = "proto",
+    jars = [
+        "jars/libdeps_proto-speed.jar",
+        "jars/libworker_protocol_proto-speed.jar"
+    ],
+    exports = ["@io_bazel_rules_kotlin_protobuf_protobuf_java//jar"],
+    visibility = ["//kotlin/workers:__subpackages__"]
+)
\ No newline at end of file
diff --git a/kotlin/workers/proto/deps.proto b/kotlin/workers/proto/deps.proto
new file mode 100644
index 0000000..670855d
--- /dev/null
+++ b/kotlin/workers/proto/deps.proto
@@ -0,0 +1,66 @@
+// 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.
+//
+// Definitions for dependency reports.
+
+syntax = "proto2";
+
+package blaze_deps;
+
+option java_package = "com.google.devtools.build.lib.view.proto";
+
+// A specific location within a source file.
+message SourceLocation {
+    required string path = 1;
+    optional int32 line = 2;
+    optional int32 column = 3;
+}
+
+message Dependency {
+
+    enum Kind {
+        // Dependency used explicitly in the source.
+        EXPLICIT = 0;
+        // Dependency that is implicitly loaded and used by the compiler.
+        IMPLICIT = 1;
+        // Unused dependency.
+        UNUSED = 2;
+        // Implicit dependency considered by the compiler but not completed.
+        INCOMPLETE = 3;
+    }
+
+    // Path to the artifact representing this dependency.
+    required string path = 1;
+
+    // Dependency kind
+    required Kind kind = 2;
+
+    // Source file locations: compilers can pinpoint the uses of a dependency.
+    repeated SourceLocation location = 3;
+}
+
+// Top-level message found in .deps artifacts
+message Dependencies {
+    repeated Dependency dependency = 1;
+
+    // Name of the rule being analyzed.
+    optional string rule_label = 2;
+
+    // Whether the action was successful; even when compilation fails, partial
+    // dependency information can be useful.
+    optional bool success = 3;
+
+    // Packages contained in the output jar, sorted alphabetically.
+    repeated string contained_package = 4;
+}
\ No newline at end of file
diff --git a/kotlin/workers/proto/jars/libdeps_proto-speed.jar b/kotlin/workers/proto/jars/libdeps_proto-speed.jar
new file mode 100644
index 0000000..3437167
--- /dev/null
+++ b/kotlin/workers/proto/jars/libdeps_proto-speed.jar
Binary files differ
diff --git a/kotlin/workers/proto/jars/libworker_protocol_proto-speed.jar b/kotlin/workers/proto/jars/libworker_protocol_proto-speed.jar
new file mode 100755
index 0000000..69bc7fc
--- /dev/null
+++ b/kotlin/workers/proto/jars/libworker_protocol_proto-speed.jar
Binary files differ
diff --git a/kotlin/workers/proto/worker_protocol.proto b/kotlin/workers/proto/worker_protocol.proto
new file mode 100644
index 0000000..dd20384
--- /dev/null
+++ b/kotlin/workers/proto/worker_protocol.proto
@@ -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.
+
+syntax = "proto3";
+
+package blaze.worker;
+
+option java_package = "com.google.devtools.build.lib.worker";
+
+// An input file.
+message Input {
+  // The path in the file system where to read this input artifact from. This is
+  // either a path relative to the execution root (the worker process is
+  // launched with the working directory set to the execution root), or an
+  // absolute path.
+  string path = 1;
+
+  // A hash-value of the contents. The format of the contents is unspecified and
+  // the digest should be treated as an opaque token.
+  bytes digest = 2;
+}
+
+// This represents a single work unit that Blaze sends to the worker.
+message WorkRequest {
+  repeated string arguments = 1;
+
+  // The inputs that the worker is allowed to read during execution of this
+  // request.
+  repeated Input inputs = 2;
+}
+
+// The worker sends this message to Blaze when it finished its work on the WorkRequest message.
+message WorkResponse {
+  int32 exit_code = 1;
+
+  // This is printed to the user after the WorkResponse has been received and is supposed to contain
+  // compiler warnings / errors etc. - thus we'll use a string type here, which gives us UTF-8
+  // encoding.
+  string output = 2;
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/BazelWorker.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/BazelWorker.java
new file mode 100644
index 0000000..14b9db3
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/BazelWorker.java
@@ -0,0 +1,146 @@
+/*
+ * 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.ruleskotlin.workers;
+
+
+import com.google.devtools.build.lib.worker.WorkerProtocol;
+import io.bazel.ruleskotlin.workers.compilers.jvm.utils.Utils;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * Bazel worker runner.
+ * <p>
+ * <p>This class adapts a traditional command line program so it can be spawned by Bazel as a
+ * persistent worker process that handles multiple invocations per JVM. It will also be backwards
+ * compatible with being run as a normal single-invocation command.
+ *
+ * @param <T> delegate program type
+ */
+public final class BazelWorker<T extends CommandLineProgram> implements CommandLineProgram {
+    private final CommandLineProgram delegate;
+    private final String mnemonic;
+    private final PrintStream output;
+
+    public BazelWorker(T delegate, PrintStream output, String mnemonic) {
+        this.delegate = delegate;
+        this.output = output;
+        this.mnemonic = mnemonic;
+    }
+
+    @Override
+    public Integer apply(List<String> args) {
+        for (String arg : args) {
+            if (arg.equals("--persistent_worker")) {
+                return runAsPersistentWorker(args);
+            }
+        }
+        return delegate.apply(loadArguments(args, false));
+    }
+
+    @SuppressWarnings("unused")
+    private int runAsPersistentWorker(List<String> ignored) {
+        InputStream realStdIn = System.in;
+        PrintStream realStdOut = System.out;
+        PrintStream realStdErr = System.err;
+        try (InputStream emptyIn = new ByteArrayInputStream(new byte[0]);
+             ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+             PrintStream ps = new PrintStream(buffer)) {
+            System.setIn(emptyIn);
+            System.setOut(ps);
+            System.setErr(ps);
+            while (true) {
+                WorkerProtocol.WorkRequest request = WorkerProtocol.WorkRequest.parseDelimitedFrom(realStdIn);
+                if (request == null) {
+                    return 0;
+                }
+                int exitCode;
+
+                try {
+                    exitCode = delegate.apply(loadArguments(request.getArgumentsList(), true));
+                } catch (RuntimeException e) {
+                    if (wasInterrupted(e)) {
+                        return 0;
+                    }
+                    System.err.println(
+                            "ERROR: Worker threw uncaught exception with args: " +
+                                    request.getArgumentsList().stream().collect(Collectors.joining(" ")));
+                    e.printStackTrace(System.err);
+                    exitCode = 1;
+                }
+                WorkerProtocol.WorkResponse.newBuilder()
+                        .setOutput(buffer.toString())
+                        .setExitCode(exitCode)
+                        .build()
+                        .writeDelimitedTo(realStdOut);
+                realStdOut.flush();
+                buffer.reset();
+                System.gc();  // be a good little worker process and consume less memory when idle
+            }
+        } catch (IOException | RuntimeException e) {
+            if (wasInterrupted(e)) {
+                return 0;
+            }
+            throw new RuntimeException(e);
+        } finally {
+            System.setIn(realStdIn);
+            System.setOut(realStdOut);
+            System.setErr(realStdErr);
+        }
+    }
+
+    private List<String> loadArguments(List<String> args, boolean isWorker) {
+        if (args.size() > 0) {
+            String lastArg = args.get(args.size() - 1);
+
+            if (lastArg.startsWith("@")) {
+                String pathElement = lastArg.substring(1);
+                Path flagFile = Paths.get(pathElement);
+                if ((isWorker && lastArg.startsWith("@@")) || Files.exists(flagFile)) {
+                    if (!isWorker && !mnemonic.isEmpty()) {
+                        output.printf(
+                                "HINT: %s will compile faster if you run: "
+                                        + "echo \"build --strategy=%s=worker\" >>~/.bazelrc\n",
+                                mnemonic, mnemonic);
+                    }
+                    try {
+                        return Files.readAllLines(flagFile, UTF_8);
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+        }
+        return args;
+    }
+
+    private boolean wasInterrupted(Throwable e) {
+        Throwable cause = Utils.getRootCause(e);
+        if (cause instanceof InterruptedException
+                || cause instanceof InterruptedIOException) {
+            output.println("Terminating worker due to interrupt signal");
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/CommandLineProgram.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/CommandLineProgram.java
new file mode 100644
index 0000000..751241f
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/CommandLineProgram.java
@@ -0,0 +1,45 @@
+/*
+ * 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.ruleskotlin.workers;
+
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * Interface for command line programs.
+ * <p>
+ * <p>This is the same thing as a main function, except not static.
+ */
+public interface CommandLineProgram extends Function<List<String>, Integer> {
+
+    /**
+     * Runs blocking program start to finish.
+     * <p>
+     * <p>This function might be called multiple times throughout the life of this object. Output
+     * must be sent to {@link System#out} and {@link System#err}.
+     *
+     * @param args command line arguments
+     * @return program exit code, i.e. 0 for success, non-zero for failure
+     */
+    @Override
+    Integer apply(List<String> args);
+
+    default Integer apply(String[] args) {
+        return apply(Arrays.asList(args));
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Context.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Context.java
new file mode 100644
index 0000000..6ceb27d
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Context.java
@@ -0,0 +1,77 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Context {
+    private final EnumMap<Flag, String> args = new EnumMap<>(Flag.class);
+    private final Map<Meta<?>, Object> meta = new HashMap<>();
+
+    private static final Map<String, Flag> ALL_FIELDS_MAP = Arrays.stream(Flag.values()).collect(Collectors.toMap(x -> x.name, x -> x));
+    private static final Flag[] MANDATORY_FIELDS = Arrays.stream(Flag.values()).filter(x -> x.mandatory).toArray(Flag[]::new);
+
+    private Context(List<String> args) {
+        if (args.size() % 2 != 0) {
+            throw new RuntimeException("args should be k,v pairs");
+        }
+
+        for (int i = 0; i < args.size() / 2; i++) {
+            String flag = args.get(i * 2);
+            String value = args.get((i * 2) + 1);
+            Flag field = ALL_FIELDS_MAP.get(flag);
+            if (field == null) {
+                throw new RuntimeException("unrecognised arg: " + flag);
+            }
+            this.args.put(field, value);
+        }
+
+        for (Flag mandatoryField : MANDATORY_FIELDS) {
+            if (!this.args.containsKey(mandatoryField)) {
+                throw new RuntimeException("mandatory arg missing: " + mandatoryField.name);
+            }
+        }
+    }
+
+    static Context from(List<String> args) {
+        return new Context(args);
+    }
+
+    public EnumMap<Flag, String> copyOfArgsContaining(Flag... fields) {
+        EnumMap<Flag, String> result = new EnumMap<>(Flag.class);
+        for (Flag field : fields) {
+            String value = args.get(field);
+            if (value != null) {
+                result.put(field, value);
+            }
+        }
+        return result;
+    }
+
+    String get(Flag field) {
+        return args.get(field);
+    }
+
+    @SuppressWarnings("unchecked")
+    <T> T get(Meta<T> key) {
+        return (T) meta.get(key);
+    }
+    @SuppressWarnings("unchecked")
+    <T> T putIfAbsent(Meta<T> key, T value) {
+        return (T) meta.putIfAbsent(key, value);
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Flag.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Flag.java
new file mode 100644
index 0000000..f827d1f
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Flag.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm;
+
+public enum Flag {
+    LABEL("--label", null, true),
+    OUTPUT_CLASSJAR("--output_classjar", "-d", true),
+    OUTPUT_JDEPS("--output_jdeps", null, true),
+    CLASSPATH("--classpath", "-cp", true),
+    SOURCES("--sources", null, true),
+    KOTLIN_API_VERSION("--kotlin_api_version", "-api-version", false),
+    KOTLIN_LANGUAGE_VERSION("--kotlin_language_version", "-language-version", false),
+    KOTLIN_JVM_TARGET("--kotlin_jvm_target", "-jvm-target", false);
+
+    public final String name;
+    public final String kotlinFlag;
+    final boolean mandatory;
+
+    Flag(String name, String kotlinName, boolean mandatory) {
+        this.name = name;
+        this.kotlinFlag = kotlinName;
+        this.mandatory = mandatory;
+    }
+
+    public String get(Context context) {
+        return context.get(this);
+    }
+}
\ No newline at end of file
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/KotlinJvmBuilder.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/KotlinJvmBuilder.java
new file mode 100644
index 0000000..71b881e
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/KotlinJvmBuilder.java
@@ -0,0 +1,59 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm;
+
+
+import io.bazel.ruleskotlin.workers.BazelWorker;
+import io.bazel.ruleskotlin.workers.CommandLineProgram;
+import io.bazel.ruleskotlin.workers.compilers.jvm.actions.BuildAction;
+import io.bazel.ruleskotlin.workers.compilers.jvm.actions.GenerateJdepsFile;
+import io.bazel.ruleskotlin.workers.compilers.jvm.actions.KotlinCreateClassJar;
+import io.bazel.ruleskotlin.workers.compilers.jvm.actions.KotlinMainCompile;
+
+import java.util.List;
+
+/**
+ * Bazel Kotlin Compiler worker.
+ */
+public final class KotlinJvmBuilder implements CommandLineProgram {
+    private static final BuildAction[] compileActions = new BuildAction[] {
+            KotlinMainCompile.INSTANCE,
+            KotlinCreateClassJar.INSTANCE,
+            GenerateJdepsFile.INSTANCE,
+    };
+
+    @Override
+    public Integer apply(List<String> args) {
+        Context context = Context.from(args);
+        Integer exitCode = 0;
+        for (BuildAction action : compileActions) {
+            exitCode = action.apply(context);
+            if(exitCode != 0)
+                break;
+        }
+        return exitCode;
+    }
+
+    public static void main(String[] args) {
+        KotlinJvmBuilder kotlinBuilder = new KotlinJvmBuilder();
+        BazelWorker<KotlinJvmBuilder> kotlinCompilerBazelWorker = new BazelWorker<>(
+                kotlinBuilder,
+                System.err,
+                "KotlinCompile"
+        );
+        System.exit(kotlinCompilerBazelWorker.apply(args));
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Locations.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Locations.java
new file mode 100644
index 0000000..f90e031
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Locations.java
@@ -0,0 +1,52 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+public enum Locations {
+        KOTLIN_REPO(Paths.get("external", "com_github_jetbrains_kotlin")),
+        JAVA_HOME(Paths.get("external", "local_jdk"));
+
+        private final Path path;
+
+        Locations(Path path) {
+            this.path = path;
+        }
+
+        public final File resolveVerified(String... parts) {
+            return verified(path.resolve(Paths.get(parts[0], Arrays.copyOfRange(parts, 1, parts.length))));
+        }
+
+        /**
+         * Return a stream of paths that are known to exists relative to this location.
+         */
+        public final Stream<File> verifiedRelativeFiles(Path... paths) {
+            return Stream.of(paths).map(relative -> verified(path.resolve(relative)));
+        }
+
+        private File verified(Path target) {
+            File asFile = target.toFile();
+            if (!asFile.exists()) {
+                throw new RuntimeException("location " + this.name() + " did not have relative path file " + target);
+            }
+            return asFile;
+        }
+    }
\ No newline at end of file
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Meta.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Meta.java
new file mode 100644
index 0000000..f6f0c9c
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/Meta.java
@@ -0,0 +1,43 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm;
+
+import java.io.File;
+import java.util.Optional;
+
+/**
+ * Meta is a key to some compilation state, it is stored in a {@link Context}. A meta is meant for setting up state for other actions.
+ */
+public final class Meta<T> {
+    // if present contains the directory that classes were compiled to.
+    public static final Meta<File> COMPILE_TO_DIRECTORY = new Meta<>("compile_to_jar");
+
+    private final String id;
+
+    private Meta(String id) {
+        this.id = id;
+    }
+
+    public Optional<T> get(Context ctx) {
+        return Optional.ofNullable(ctx.get(this));
+    }
+
+    public void bind(Context ctx, T value) {
+        if (ctx.putIfAbsent(this, value) != null) {
+            throw new RuntimeException("attempting to change bound meta variable " + id);
+        }
+    }
+}
\ No newline at end of file
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/BuildAction.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/BuildAction.java
new file mode 100644
index 0000000..7039fb5
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/BuildAction.java
@@ -0,0 +1,24 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.actions;
+
+import io.bazel.ruleskotlin.workers.compilers.jvm.Context;
+
+import java.util.function.Function;
+
+public interface BuildAction extends Function<Context, Integer> {
+
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/GenerateJdepsFile.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/GenerateJdepsFile.java
new file mode 100644
index 0000000..dfcc204
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/GenerateJdepsFile.java
@@ -0,0 +1,79 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.actions;
+
+import com.google.devtools.build.lib.view.proto.Deps;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Context;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Locations;
+import io.bazel.ruleskotlin.workers.compilers.jvm.utils.JdepsParser;
+import io.bazel.ruleskotlin.workers.compilers.jvm.utils.Utils;
+
+import java.io.FileOutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.function.Predicate;
+
+import static io.bazel.ruleskotlin.workers.compilers.jvm.Flag.*;
+
+public final class GenerateJdepsFile implements BuildAction {
+    private static final String JDEPS_PATH = Locations.JAVA_HOME.resolveVerified("bin", "jdeps").toString();
+
+    private static final Predicate<String> IS_KOTLIN_IMPLICIT = JdepsParser.pathSuffixMatchingPredicate(
+            Paths.get("external", "com_github_jetbrains_kotlin", "lib"),
+            "kotlin-stdlib.jar",
+            "kotlin-stdlib-jdk7.jar",
+            "kotlin-stdlib-jdk8.jar");
+
+    public static final GenerateJdepsFile INSTANCE = new GenerateJdepsFile();
+
+    private GenerateJdepsFile() {
+    }
+
+    @Override
+    public Integer apply(Context ctx) {
+        final String
+                classJar = OUTPUT_CLASSJAR.get(ctx),
+                classPath = CLASSPATH.get(ctx),
+                output = OUTPUT_JDEPS.get(ctx);
+        Deps.Dependencies jdepsContent;
+        try {
+            List<String> jdepLines = Utils.waitForOutput(new String[]{JDEPS_PATH, "-cp", classPath, classJar}, System.err);
+            jdepsContent = JdepsParser.parse(
+                    LABEL.get(ctx),
+                    classJar,
+                    classPath,
+                    jdepLines.stream(),
+                    IS_KOTLIN_IMPLICIT
+            );
+        } catch (Exception e) {
+            throw new RuntimeException("error reading or parsing jdeps file", Utils.getRootCause(e));
+        }
+
+        try {
+            Path outputPath = Paths.get(output);
+            Files.deleteIfExists(outputPath);
+            try (FileOutputStream fileOutputStream = new FileOutputStream(Files.createFile(outputPath).toFile())) {
+                jdepsContent.writeTo(fileOutputStream);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("error writing out jdeps file", Utils.getRootCause(e));
+        }
+
+        return 0;
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/KotlinCreateClassJar.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/KotlinCreateClassJar.java
new file mode 100644
index 0000000..4edc9e9
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/KotlinCreateClassJar.java
@@ -0,0 +1,46 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.actions;
+
+import io.bazel.ruleskotlin.workers.compilers.jvm.Context;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Flag;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Locations;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Meta;
+import io.bazel.ruleskotlin.workers.compilers.jvm.utils.Utils;
+
+/**
+ * If classes for the main artifact were compiled to an intermediate temp directory turn them into a jar and clean up.
+ */
+public final class KotlinCreateClassJar implements BuildAction {
+    public static final KotlinCreateClassJar INSTANCE = new KotlinCreateClassJar();
+    private static final String JAR_TOOL_PATH = Locations.JAVA_HOME.resolveVerified("bin", "jar").toString();
+
+    private KotlinCreateClassJar() {}
+
+    @Override
+    public Integer apply(Context ctx) {
+        Meta.COMPILE_TO_DIRECTORY.get(ctx).ifPresent((classDirectory) -> {
+            try {
+                String classJarPath = Flag.OUTPUT_CLASSJAR.get(ctx);
+                Utils.waitForSuccess(new String[]{JAR_TOOL_PATH, "cf", classJarPath, "-C", classDirectory.toString(), "."}, System.err);
+                Utils.deleteDirectory(classDirectory.toPath());
+            } catch (Exception e) {
+                throw new RuntimeException("unable to create class jar", e);
+            }
+        });
+        return 0;
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/KotlinMainCompile.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/KotlinMainCompile.java
new file mode 100644
index 0000000..6e69f9e
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/actions/KotlinMainCompile.java
@@ -0,0 +1,115 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.actions;
+
+import io.bazel.ruleskotlin.workers.compilers.jvm.Context;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Flag;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Locations;
+import io.bazel.ruleskotlin.workers.compilers.jvm.Meta;
+import io.bazel.ruleskotlin.workers.compilers.jvm.utils.KotlinCompilerOutputProcessor;
+import io.bazel.ruleskotlin.workers.compilers.jvm.utils.KotlinPreloadedCompilerBuilder;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.function.BiFunction;
+
+/**
+ * Either compiles to a jar directly or when performing mixed-mode-compilation compiles to a temp directory first.
+ */
+public final class KotlinMainCompile implements BuildAction {
+    public static final KotlinMainCompile INSTANCE = new KotlinMainCompile(KotlinPreloadedCompilerBuilder.build());
+
+    private static final String
+            JAVAC_PATH = Locations.JAVA_HOME.resolveVerified("bin", "javac").toString();
+
+    private static final String
+            X_COMPILE_JAVA_FLAG = "-Xcompile-java",
+            X_JAVAC_ARGUMENTS_FLAG = "-Xjavac-arguments",
+            X_USE_JAVAC_FLAG = "-Xuse-javac";
+
+    /**
+     * Default fields that are directly mappable to kotlin compiler args.
+     */
+    private static final Flag[] COMPILE_MAPPED_FLAGS = new Flag[]{
+            Flag.OUTPUT_CLASSJAR,
+            Flag.CLASSPATH,
+            Flag.KOTLIN_API_VERSION,
+            Flag.KOTLIN_LANGUAGE_VERSION,
+            Flag.KOTLIN_JVM_TARGET
+    };
+
+    private final BiFunction<String[], PrintStream, Integer> compiler;
+
+    private KotlinMainCompile(BiFunction<String[], PrintStream, Integer> compiler) {
+        this.compiler = compiler;
+    }
+
+    /**
+     * Evaluate the compilation context and add Metadata to the ctx if needed.
+     *
+     * @return The args to pass to the kotlin compile class.
+     */
+    private static String[] setupCompileContext(Context ctx) {
+        List<String> args = new ArrayList<>();
+        EnumMap<Flag, String> compileMappedFields = ctx.copyOfArgsContaining(COMPILE_MAPPED_FLAGS);
+        String[] sources = Flag.SOURCES.get(ctx).split(":");
+
+        for (String source : sources) {
+            if (source.endsWith(".java")) {
+                try {
+                    // Redirect the kotlin and java compilers to a temp directory.
+                    File temporaryClassOutputDirectory = Files.createTempDirectory("kotlinCompile").toFile();
+                    Meta.COMPILE_TO_DIRECTORY.bind(ctx, temporaryClassOutputDirectory);
+                    compileMappedFields.put(Flag.OUTPUT_CLASSJAR, temporaryClassOutputDirectory.toString());
+                    Collections.addAll(args,
+                            X_COMPILE_JAVA_FLAG,
+                            X_USE_JAVAC_FLAG + "=" + JAVAC_PATH,
+                            X_JAVAC_ARGUMENTS_FLAG + "=-d=" + temporaryClassOutputDirectory.toString());
+                    break;
+                } catch (IOException e) {
+                    throw new RuntimeException("could not create temp directory for kotlin compile operation", e);
+                }
+            }
+        }
+        compileMappedFields.forEach((field, arg) -> Collections.addAll(args, field.kotlinFlag, arg));
+        Collections.addAll(args, sources);
+        return args.toArray(new String[args.size()]);
+    }
+
+    @Override
+    public Integer apply(Context ctx) {
+        KotlinCompilerOutputProcessor outputProcessor = KotlinCompilerOutputProcessor.delegatingTo(System.out);
+        try {
+            Integer exitCode = compiler.apply(setupCompileContext(ctx), outputProcessor.getCollector());
+            if (exitCode < 2) {
+                // 1 is a standard compilation error
+                // 2 is an internal error
+                // 3 is the script execution error
+                return exitCode;
+            } else {
+                throw new RuntimeException("KotlinMainCompile returned terminal error code: " + exitCode);
+            }
+        } finally {
+            outputProcessor.process();
+        }
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/JdepsParser.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/JdepsParser.java
new file mode 100644
index 0000000..9d705b8
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/JdepsParser.java
@@ -0,0 +1,144 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.utils;
+
+import com.google.devtools.build.lib.view.proto.Deps;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+public class JdepsParser {
+    private final String filename;
+    private final String packageSuffix;
+    private final Predicate<String> isImplicit;
+
+    private final Map<String, Deps.Dependency.Builder> depMap = new HashMap<>();
+    private final Set<String> packages = new HashSet<>();
+
+    private JdepsParser(String filename, Predicate<String> isImplicit) {
+        this.filename = filename;
+        this.packageSuffix = " (" + filename + ")";
+        this.isImplicit = isImplicit;
+    }
+
+    private void consumeJarLine(String classJarPath, Deps.Dependency.Kind kind) {
+        Path path = Paths.get(classJarPath);
+
+        // ignore absolute files, -- jdk jar paths etc.
+        // only process jar files
+        if (!(path.isAbsolute() || !classJarPath.endsWith(".jar"))) {
+            Deps.Dependency.Builder entry = depMap.computeIfAbsent(classJarPath, (key) -> {
+                Deps.Dependency.Builder depBuilder = Deps.Dependency.newBuilder();
+                depBuilder.setPath(classJarPath);
+                depBuilder.setKind(kind);
+
+                if (isImplicit.test(classJarPath)) {
+                    depBuilder.setKind(Deps.Dependency.Kind.IMPLICIT);
+                }
+                return depBuilder;
+            });
+
+            // don't flip an implicit dep.
+            if (entry.getKind() != Deps.Dependency.Kind.IMPLICIT) {
+                entry.setKind(kind);
+            }
+        }
+    }
+
+    private enum Mode {
+        COLLECT_DEPS,
+        DETERMINE_JDK,
+        COLLECT_PACKAGES_JDK8,
+        COLLECT_PACKAGES_JDK9
+    }
+
+    private Mode mode = Mode.COLLECT_DEPS;
+
+    // maybe simplify this by tokenizing on whitespace and arrows.
+    private void processLine(String line) {
+        String trimmedLine = line.trim();
+        switch (mode) {
+            case COLLECT_DEPS:
+                if (!line.startsWith(" ")) {
+                    String[] parts = line.split(" -> ");
+                    if (parts.length == 2) {
+                        if (!parts[0].equals(filename)) {
+                            throw new RuntimeException("should only get dependencies for dep: " + filename);
+                        }
+                        consumeJarLine(parts[1], Deps.Dependency.Kind.EXPLICIT);
+                    }
+                } else {
+                    mode = Mode.DETERMINE_JDK;
+                    processLine(line);
+                }
+                break;
+            case DETERMINE_JDK:
+                mode = Mode.COLLECT_PACKAGES_JDK8;
+                if (!line.endsWith(packageSuffix)) {
+                    mode = Mode.COLLECT_PACKAGES_JDK9;
+                }
+                processLine(line);
+                break;
+            case COLLECT_PACKAGES_JDK8:
+                if (trimmedLine.endsWith(packageSuffix)) {
+                    packages.add(trimmedLine.substring(0, trimmedLine.length() - packageSuffix.length()));
+                } else if (trimmedLine.startsWith("-> ")) {
+                    // ignore package detail lines, in the jdk8 format these start with arrows.
+                } else throw new RuntimeException("unexpected line while collecting packages: " + line);
+                break;
+            case COLLECT_PACKAGES_JDK9:
+                String[] pkg = trimmedLine.split("\\s+");
+                packages.add(pkg[0]);
+                break;
+        }
+    }
+
+
+    public static Predicate<String> pathSuffixMatchingPredicate(Path directory, String... jars) {
+        String[] suffixes = Stream.of(jars).map(lib -> directory.resolve(lib).toString()).toArray(String[]::new);
+        return (jar) -> {
+            for (String implicitJarsEnding : suffixes) {
+                if (jar.endsWith(implicitJarsEnding)) {
+                    return true;
+                }
+            }
+            return false;
+        };
+    }
+
+    public static Deps.Dependencies parse(String label, String classJar, String classPath, Stream<String> jdepLines, Predicate<String> isImplicit) {
+        String filename = Paths.get(classJar).getFileName().toString();
+        JdepsParser jdepsParser = new JdepsParser(filename, isImplicit);
+        Stream.of(classPath.split(":")).forEach(x -> jdepsParser.consumeJarLine(x, Deps.Dependency.Kind.UNUSED));
+        jdepLines.forEach(jdepsParser::processLine);
+
+        Deps.Dependencies.Builder rootBuilder = Deps.Dependencies.newBuilder();
+        rootBuilder.setSuccess(false);
+        rootBuilder.setRuleLabel(label);
+
+        rootBuilder.addAllContainedPackage(jdepsParser.packages);
+        jdepsParser.depMap.values().forEach(b -> rootBuilder.addDependency(b.build()));
+
+        rootBuilder.setSuccess(true);
+        return rootBuilder.build();
+    }
+}
\ No newline at end of file
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/KotlinCompilerOutputProcessor.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/KotlinCompilerOutputProcessor.java
new file mode 100644
index 0000000..a8c18ba
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/KotlinCompilerOutputProcessor.java
@@ -0,0 +1,53 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.utils;
+
+import java.io.*;
+import java.nio.file.Paths;
+
+
+/**
+ * Utility class to perform common pre-processing on the compiler output before it is passed onto a delegate
+ * PrintStream.
+ */
+// The kotlin compiler produces absolute file paths but the intellij plugin expects workspace root relative paths to
+// render errors.
+public class KotlinCompilerOutputProcessor {
+    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+    // Get the absolute path to ensure the sandbox root is resolved.
+    private final String executionRoot = Paths.get("").toAbsolutePath().toString() + File.separator;
+    private final PrintStream delegate;
+
+
+    private KotlinCompilerOutputProcessor(PrintStream delegate) {
+        this.delegate = delegate;
+    }
+
+    public static KotlinCompilerOutputProcessor delegatingTo(PrintStream delegate) {
+        return new KotlinCompilerOutputProcessor(delegate);
+    }
+
+    public PrintStream getCollector() {
+        return new PrintStream(byteArrayOutputStream);
+    }
+
+    public void process() {
+        new BufferedReader(new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())))
+                .lines()
+                .forEach(line -> delegate.println(line.replace(executionRoot, "")));
+        delegate.flush();
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/KotlinPreloadedCompilerBuilder.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/KotlinPreloadedCompilerBuilder.java
new file mode 100644
index 0000000..f08cf98
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/KotlinPreloadedCompilerBuilder.java
@@ -0,0 +1,72 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.utils;
+
+import io.bazel.ruleskotlin.workers.compilers.jvm.Locations;
+import org.jetbrains.kotlin.preloading.ClassPreloadingUtils;
+import org.jetbrains.kotlin.preloading.Preloader;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public final class KotlinPreloadedCompilerBuilder {
+    private static final Object[] NO_ARGS = new Object[]{};
+
+    private static final List<File> PRELOAD_JARS = Stream.concat(
+            Locations.KOTLIN_REPO.verifiedRelativeFiles(Paths.get("lib", "kotlin-compiler.jar")),
+            Locations.JAVA_HOME.verifiedRelativeFiles(Paths.get("lib", "tools.jar"))
+    ).collect(Collectors.toList());
+
+    /**
+     * Load the Kotlin compiler and the javac tools.jar into a Preloading classloader. The Kotlin compiler is invoked reflectively to eventually allow
+     * toolchain replacement.
+     */
+    public static BiFunction<String[], PrintStream,Integer> build() {
+        try {
+            ClassLoader classLoader = ClassPreloadingUtils.preloadClasses(
+                    PRELOAD_JARS,
+                    Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE,
+                    Thread.currentThread().getContextClassLoader(),
+                    null
+            );
+
+            Class<?> compilerClass = classLoader.loadClass("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler");
+            Class<?> exitCodeClass = classLoader.loadClass("org.jetbrains.kotlin.cli.common.ExitCode");
+
+            Object compiler = compilerClass.newInstance();
+            Method execMethod = compilerClass.getMethod("exec", PrintStream.class, String[].class);
+            Method getCodeMethod = exitCodeClass.getMethod("getCode");
+
+            return (args, stream) -> {
+                final Object exitCodeInstance;
+                try {
+                    exitCodeInstance = execMethod.invoke(compiler, stream, args);
+                    return (Integer) getCodeMethod.invoke(exitCodeInstance, NO_ARGS);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            };
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/Utils.java b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/Utils.java
new file mode 100644
index 0000000..3303d26
--- /dev/null
+++ b/kotlin/workers/src/io/bazel/ruleskotlin/workers/compilers/jvm/utils/Utils.java
@@ -0,0 +1,85 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.utils;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public final class Utils {
+    public static List<String> waitForOutput(String[] command, PrintStream err) {
+        try {
+            ProcessBuilder builder = new ProcessBuilder(command);
+            Process process = builder.start();
+            try (BufferedReader processError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+                 BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+                while (true) {
+                    String line = processError.readLine();
+                    if (line == null)
+                        break;
+                    err.println(line);
+                }
+                if (process.waitFor() != 0) {
+                    throw new RuntimeException("non-zero return: " + process.exitValue());
+                }
+                return output.lines().collect(Collectors.toList());
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void waitForSuccess(String[] command, PrintStream err) {
+        try {
+            ProcessBuilder builder = new ProcessBuilder(command);
+            Process process = builder.start();
+            try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
+                while (true) {
+                    String line = in.readLine();
+                    if (line == null)
+                        break;
+                    err.println(line);
+                }
+                if (process.waitFor() != 0) {
+                    throw new RuntimeException("non-zero return: " + process.exitValue());
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    public static void deleteDirectory(Path directory) throws IOException {
+        Files.walk(directory)
+                .map(Path::toFile)
+                .sorted((o1, o2) -> -o1.compareTo(o2))
+                .forEach(File::delete);
+
+    }
+
+    public static Throwable getRootCause(Throwable e) {
+        Throwable cause;
+        Throwable result = e;
+
+        while (null != (cause = result.getCause()) && (result != cause)) {
+            result = cause;
+        }
+        return result;
+    }
+}
diff --git a/kotlin/workers/unittests/io/bazel/ruleskotlin/workers/compilers/jvm/utils/JdepsParserTest.java b/kotlin/workers/unittests/io/bazel/ruleskotlin/workers/compilers/jvm/utils/JdepsParserTest.java
new file mode 100644
index 0000000..b61377c
--- /dev/null
+++ b/kotlin/workers/unittests/io/bazel/ruleskotlin/workers/compilers/jvm/utils/JdepsParserTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.ruleskotlin.workers.compilers.jvm.utils;
+
+import com.google.devtools.build.lib.view.proto.Deps;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@RunWith(JUnit4.class)
+public class JdepsParserTest {
+    private static final String JDK8_FIXTURE =
+            "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk7.jar\n" +
+                    "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib.jar\n" +
+                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/postgres.jar\n" +
+                    "alt.jar -> bazel-server-cloud/bazel-out/darwin-fastbuild/bin/cloud/qa/integrationtests/pkg/alt/alt.runfiles/__main__/external/org_postgresql_postgresql/jar/postgresql-42.1.1.jar\n" +
+                    "alt.jar -> /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/rt.jar\n" +
+                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/utils/utils.jar\n" +
+                    "   com.axsy.testing.alt (alt.jar)\n" +
+                    "      -> com.axsy.testing.extensions.postgres               postgres.jar\n" +
+                    "      -> com.axsy.testing.pkg.utils                         utils.jar\n" +
+                    "      -> java.io                                            \n" +
+                    "      -> java.lang                                          \n" +
+                    "      -> java.sql                                           \n" +
+                    "      -> javax.sql                                          \n" +
+                    "      -> kotlin                                             kotlin-stdlib.jar\n" +
+                    "      -> kotlin.jdk7                                        kotlin-stdlib-jdk7.jar\n" +
+                    "      -> kotlin.jvm.internal                                kotlin-stdlib.jar\n" +
+                    "      -> org.postgresql.ds                                  postgresql-42.1.1.jar\n" +
+                    "   com.axsy.testing.alt.sub (alt.jar)\n" +
+                    "      -> java.lang                                          \n" +
+                    "      -> kotlin                                             kotlin-stdlib.jar\n";
+
+    private static final String JDK9_FIXTURE =
+            "alt.jar -> java.base\n" +
+                    "alt.jar -> java.sql\n" +
+                    "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk7.jar\n" +
+                    "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib.jar\n" +
+                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/postgres.jar\n" +
+                    "alt.jar -> bazel-server-cloud/bazel-out/darwin-fastbuild/bin/cloud/qa/integrationtests/pkg/alt/alt.runfiles/__main__/external/org_postgresql_postgresql/jar/postgresql-42.1.1.jar\n" +
+                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/utils/utils.jar\n" +
+                    "   com.axsy.testing.alt                               -> com.axsy.testing.extensions.postgres               postgres.jar\n" +
+                    "   com.axsy.testing.alt                               -> com.axsy.testing.pkg.utils                         utils.jar\n" +
+                    "   com.axsy.testing.alt                               -> java.io                                            java.base\n" +
+                    "   com.axsy.testing.alt                               -> java.lang                                          java.base\n" +
+                    "   com.axsy.testing.alt                               -> java.sql                                           java.sql\n" +
+                    "   com.axsy.testing.alt                               -> javax.sql                                          java.sql\n" +
+                    "   com.axsy.testing.alt                               -> kotlin                                             kotlin-stdlib.jar\n" +
+                    "   com.axsy.testing.alt                               -> kotlin.jdk7                                        kotlin-stdlib-jdk7.jar\n" +
+                    "   com.axsy.testing.alt                               -> kotlin.jvm.internal                                kotlin-stdlib.jar\n" +
+                    "   com.axsy.testing.alt                               -> org.postgresql.ds                                  postgresql-42.1.1.jar\n" +
+                    "   com.axsy.testing.alt.sub                           -> java.lang                                          java.base\n" +
+                    "   com.axsy.testing.alt.sub                           -> kotlin                                             kotlin-stdlib.jar\n";
+
+
+    private static final List<String> CLASSPATH = Arrays.asList(
+            "bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/unused.jar",
+            "bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk8.jar",
+            "bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk7.jar",
+            "bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib.jar",
+            "bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/postgres.jar",
+            "bazel-server-cloud/bazel-out/darwin-fastbuild/bin/cloud/qa/integrationtests/pkg/alt/alt.runfiles/__main__/external/org_postgresql_postgresql/jar/postgresql-42.1.1.jar",
+            "bazel-bin/cloud/qa/integrationtests/pkg/utils/utils.jar"
+    );
+
+
+    private static final String LABEL = "//cloud/qa/integrationtests/pkg/alt";
+    private static final String CLASS_JAR = "bazel-bin/something/alt.jar";
+
+    private static final Predicate<String> IS_KOTLIN_IMPLICIT = JdepsParser.pathSuffixMatchingPredicate(
+            Paths.get("external", "com_github_jetbrains_kotlin", "lib"),
+            "kotlin-stdlib.jar",
+            "kotlin-stdlib-jdk7.jar",
+            "kotlin-stdlib-jdk8.jar");
+
+    @Test
+    public void parseJDK8Format() throws IOException {
+        testWithFixture(JDK8_FIXTURE);
+    }
+
+    @Test
+    public void parseJDK9Format() throws IOException {
+        testWithFixture(JDK9_FIXTURE);
+    }
+
+    private void testWithFixture(String fixture) throws IOException {
+        Deps.Dependencies result = JdepsParser.parse(LABEL, CLASS_JAR, CLASSPATH.stream().collect(Collectors.joining(":")), Stream.of(fixture.split("\n")), IS_KOTLIN_IMPLICIT);
+        Assert.assertEquals(LABEL, result.getRuleLabel());
+
+        Assert.assertEquals(7, result.getDependencyCount());
+        Assert.assertEquals(1, depKinds(result, Deps.Dependency.Kind.UNUSED).size());
+        Assert.assertEquals(3, depKinds(result, Deps.Dependency.Kind.IMPLICIT).size());
+        Assert.assertEquals(3, depKinds(result, Deps.Dependency.Kind.EXPLICIT).size());
+
+        Assert.assertEquals(2, result.getContainedPackageCount());
+
+        result.writeTo(System.out);
+        System.out.flush();
+    }
+
+    private List<Deps.Dependency> depKinds(Deps.Dependencies result, Deps.Dependency.Kind kind) {
+        return result.getDependencyList().stream().filter(x -> x.getKind() == kind).collect(Collectors.toList());
+    }
+}
+
diff --git a/tests/smoke/BUILD b/tests/smoke/BUILD
new file mode 100644
index 0000000..794b455
--- /dev/null
+++ b/tests/smoke/BUILD
@@ -0,0 +1,109 @@
+# 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:kotlin.bzl", "kotlin_library", "kotlin_binary", "kotlin_test")
+
+# a test resource library.
+java_library(
+    name = "resourcejar",
+    resources = glob(["resourcejar/**"]),
+    resource_strip_prefix = "tests/smoke/resourcejar"
+)
+
+kotlin_test(
+    name = "junittest",
+    srcs = glob(["junittest/JunitTest.kt"]),
+    test_class="tests.smoke.junittest.JunitTest",
+    size="small",
+    data=glob(["data/*"]),
+    deps = ["@junit_junit//jar"]
+)
+
+kotlin_library(
+    name = "test_merge_resourcesjar",
+    srcs = glob(["testresources/src/*.kt"]),
+    resource_jars = [":resourcejar"],
+)
+
+kotlin_library(
+    name = "test_embed_resources",
+    srcs = glob(["testresources/src/*.kt"]),
+    resources = glob(["testresources/resources/**/*"]),
+    visibility = ["//visibility:public"]
+)
+
+kotlin_library(
+    name = "test_embed_resources_strip_prefix",
+    srcs = glob(["testresources/src/*.kt"]),
+    resources = glob(["testresources/resources/**/*"]),
+    resource_strip_prefix = "tests/smoke/testresources/resources"
+)
+
+kotlin_library(
+    name = "conventional_strip_resources",
+    srcs = glob(["testresources/src/*.kt"]),
+    resources = glob(["conventional_strip_resources/src/main/resources/**/*", "conventional_strip_resources/src/test/resources/**/*"])
+)
+
+kotlin_library(
+    name = "propagation_test_exporter_lib",
+    srcs = ["propagation/Stub.kt"],
+    exports = ["@junit_junit//jar"]
+)
+
+kotlin_library(
+    name = "propagation_test_runtime_lib",
+    srcs = ["propagation/Stub.kt"],
+    runtime_deps = ["@junit_junit//jar"]
+)
+
+java_binary(
+    name = "propagation_ct_consumer",
+    main_class = "testing.CompileTimeDependent",
+    srcs = ["propagation/CompileTimeDependent.java"],
+    deps = [":propagation_test_exporter_lib"]
+)
+
+java_binary(
+    name = "propagation_ct_consumer_fail_on_runtime",
+    main_class = "testing.CompileTimeDependent",
+    srcs = ["propagation/CompileTimeDependent.java"],
+    deps = [":propagation_test_runtime_lib"]
+)
+
+java_binary(
+    name = "propagation_rt_via_export_consumer",
+    main_class = "testing.RuntimeDependent",
+    srcs = ["propagation/RuntimeDependent.java"],
+    deps = [":propagation_test_exporter_lib"]
+)
+
+java_binary(
+    name = "propagation_rt_via_runtime_deps_consumer",
+    main_class = "testing.RuntimeDependent",
+    srcs = ["propagation/RuntimeDependent.java"],
+    deps = [":propagation_test_runtime_lib"]
+)
+
+kotlin_binary(
+    name="helloworld",
+    srcs=glob(["helloworld/Main.kt"]),
+    main_class= "helloworld.Main",
+    data=glob(["data/*"]),
+)
+
+kotlin_binary(
+    name = "hellojava",
+    srcs = ["hellojava/HelloWorld.kt", "hellojava/MessageHolder.java"],
+    main_class = "hellojava.HelloWorldKt"
+)
\ No newline at end of file
diff --git a/tests/smoke/basic_tests.py b/tests/smoke/basic_tests.py
new file mode 100644
index 0000000..610a96c
--- /dev/null
+++ b/tests/smoke/basic_tests.py
@@ -0,0 +1,70 @@
+# 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.
+import unittest
+
+from common import BazelKotlinTestCase
+
+
+class TestRules(BazelKotlinTestCase):
+    def setUp(self):
+        self._pkg = "tests/smoke"
+
+    def test_merge_resource_jar(self):
+        jar = self.buildJarGetZipFile("test_merge_resourcesjar", "jar")
+        self.assertJarContains(jar, "testresources/AClass.class", "testresources/BClass.class")
+        self.assertJarContains(jar, "pkg/file.txt")
+
+    def test_embed_resources(self):
+        jar = self.buildJarGetZipFile("test_embed_resources", "jar")
+        self.assertJarContains(jar, "testresources/AClass.class", "testresources/BClass.class")
+        self.assertJarContains(jar, "tests/smoke/testresources/resources/one/two/aFile.txt", "tests/smoke/testresources/resources/one/alsoAFile.txt")
+
+    def test_embed_resources_strip_prefix(self):
+        jar = self.buildJarGetZipFile("test_embed_resources_strip_prefix", "jar")
+        self.assertJarContains(jar, "testresources/AClass.class", "testresources/BClass.class")
+        self.assertJarContains(jar, "one/two/aFile.txt", "one/alsoAFile.txt")
+
+    def test_test_targets_launch_correctly(self):
+        self.buildLaunchExpectingSuccess("junittest", command="test")
+
+    def test_bin_targets_launch_correctly_with_data(self):
+        self.buildLaunchExpectingSuccess("helloworld")
+
+    def test_conventional_strip_resources(self):
+        jar = self.buildJarGetZipFile("conventional_strip_resources", "jar")
+        self.assertJarContains(jar, "main.txt", "test.txt")
+
+    def test_export_ct_propagation(self):
+        self.buildJar("propagation_ct_consumer")
+
+    def test_export_ct_propagation_fail_on_runtime(self):
+        self.buildJarExpectingFail("propagation_ct_consumer_fail_on_runtime")
+
+    def test_export_rt_propagation(self):
+        self.buildLaunchExpectingSuccess("propagation_rt_via_export_consumer")
+
+    def test_export_rt_propagation_via_dep(self):
+        self.buildLaunchExpectingSuccess("propagation_rt_via_runtime_deps_consumer")
+
+    def test_mixed_mode_compilation(self):
+        self.buildLaunchExpectingSuccess("hellojava")
+
+        # re-enable this test, and ensure the srcjar includes java sources when mixed mode.
+        # def test_srcjar(self):
+        #     jar = self.buildJarGetZipFile("testresources", "srcjar")
+        #     self.assertJarContains(jar, "testresources/AClass.kttestresources/ConsumerLib.kt")
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/smoke/common.py b/tests/smoke/common.py
new file mode 100644
index 0000000..46f541e
--- /dev/null
+++ b/tests/smoke/common.py
@@ -0,0 +1,95 @@
+# 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.
+import os
+import subprocess
+import unittest
+import zipfile
+
+import sys
+
+DEVNULL = open(os.devnull, 'wb')
+
+
+def _do_exec(command, silent=True):
+    out = sys.stdout
+    if silent:
+        out = DEVNULL
+    if subprocess.call(command, stdout=out, stderr=out) != 0:
+        raise Exception("command " + " ".join(command) + " failed")
+
+
+def _do_exec_expect_fail(command, silent=True):
+    out = sys.stdout
+    if silent:
+        out = DEVNULL
+    if subprocess.call(command, stdout=out, stderr=out) == 0:
+        raise Exception("command " + " ".join(command) + " should have failed")
+
+
+class BazelKotlinTestCase(unittest.TestCase):
+    _pkg = None
+
+    def _target(self, target_name):
+        return "//%s:%s" % (self._pkg, target_name)
+
+    def _bazel_bin(self, file):
+        return "bazel-bin/" + self._pkg + "/" + file
+
+    def _open_bazel_bin(self, file):
+        return open(self._bazel_bin(file))
+
+    def _query(self, query, implicits=False):
+        res = []
+        q = ['bazel', 'query', query]
+        if not implicits:
+            q.append('--noimplicit_deps')
+        self._last_command = " ".join(q)
+
+        p = subprocess.Popen(self._last_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        for line in p.stdout.readlines():
+            res.append(line.replace("\n", ""))
+        ret = p.wait()
+        if ret != 0:
+            raise Exception("error (%d) evaluating query: %s" % (ret, self._last_command))
+        else:
+            return res
+
+    def libQuery(self, label, implicits=False):
+        return self._query('\'kind("java_import|.*_library", deps(%s))\'' % label, implicits)
+
+    def assertJarContains(self, jar, *files):
+        curr = ""
+        try:
+            for f in files:
+                curr = f
+                jar.getinfo(f)
+        except Exception as ex:
+            raise Exception("jar does not contain file [%s]" % curr)
+
+    def buildJar(self, target, silent=True):
+        _do_exec(["bazel", "build", self._target(target)], silent)
+
+    def buildJarExpectingFail(self, target, silent=True):
+        _do_exec_expect_fail(["bazel", "build", self._target(target)], silent)
+
+    def buildJarGetZipFile(self, name, extension):
+        jar_file = name + "." + extension
+        self.buildJar(jar_file)
+        return zipfile.ZipFile(self._open_bazel_bin(jar_file))
+
+    def buildLaunchExpectingSuccess(self, target, command="run"):
+        self.buildJar(target, silent=False)
+        res = subprocess.call(["bazel", command, self._target(target)], stdout=sys.stdout, stderr=sys.stdout)
+        if not res == 0:
+            raise Exception("could not launch jar [%s]" % target)
diff --git a/tests/smoke/conventional_strip_resources/src/main/resources/main.txt b/tests/smoke/conventional_strip_resources/src/main/resources/main.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/smoke/conventional_strip_resources/src/main/resources/main.txt
diff --git a/tests/smoke/conventional_strip_resources/src/test/resources/test.txt b/tests/smoke/conventional_strip_resources/src/test/resources/test.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/smoke/conventional_strip_resources/src/test/resources/test.txt
diff --git a/tests/smoke/data/datafile.txt b/tests/smoke/data/datafile.txt
new file mode 100644
index 0000000..2e166c8
--- /dev/null
+++ b/tests/smoke/data/datafile.txt
@@ -0,0 +1 @@
+boom
\ No newline at end of file
diff --git a/tests/smoke/hellojava/Another.java b/tests/smoke/hellojava/Another.java
new file mode 100644
index 0000000..a8c2eda
--- /dev/null
+++ b/tests/smoke/hellojava/Another.java
@@ -0,0 +1,20 @@
+/*
+ * 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 hellojava;
+
+public class Another {
+}
diff --git a/tests/smoke/hellojava/HelloWorld.kt b/tests/smoke/hellojava/HelloWorld.kt
new file mode 100644
index 0000000..3004b28
--- /dev/null
+++ b/tests/smoke/hellojava/HelloWorld.kt
@@ -0,0 +1,20 @@
+/*
+ * 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 hellojava
+
+fun main(args: Array<String>) {
+    println(MessageHolder.message)
+}
diff --git a/tests/smoke/hellojava/MessageHolder.java b/tests/smoke/hellojava/MessageHolder.java
new file mode 100644
index 0000000..510680f
--- /dev/null
+++ b/tests/smoke/hellojava/MessageHolder.java
@@ -0,0 +1,23 @@
+/*
+ * 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 hellojava;
+
+public class MessageHolder {
+    public static final String message = "hello java ";
+    static {
+        System.out.println("boom la  ");
+    }
+}
diff --git a/tests/smoke/helloworld/Main.kt b/tests/smoke/helloworld/Main.kt
new file mode 100644
index 0000000..6a6b65d
--- /dev/null
+++ b/tests/smoke/helloworld/Main.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+@file:JvmName("Main")
+package helloworld
+
+import java.nio.file.Paths
+
+fun main(args :Array<String>) {
+    if(!Paths.get("tests", "smoke", "data" ,"datafile.txt").toFile().exists()) {
+        System.err.println("could not read datafile")
+        System.exit(1)
+    }
+    println("bang bang")
+    System.out.println("boom")
+}
diff --git a/tests/smoke/junittest/JunitTest.kt b/tests/smoke/junittest/JunitTest.kt
new file mode 100644
index 0000000..4a3e1d0
--- /dev/null
+++ b/tests/smoke/junittest/JunitTest.kt
@@ -0,0 +1,38 @@
+/*
+ * 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 tests.smoke.junittest
+
+import org.junit.*
+import org.junit.runner.RunWith
+import org.junit.runners.Suite
+import java.nio.file.Paths
+
+
+//@RunWith(Suite::class)
+class JunitTest {
+    @Test
+    fun dummyTest() {
+        if(!Paths.get("tests", "smoke", "data" ,"datafile.txt").toFile().exists()) {
+            throw RuntimeException("could not read datafile")
+
+        }
+    }
+
+//    @Test
+//    fun failingTest() {
+//        throw RuntimeException("boom")
+//    }
+}
diff --git a/tests/smoke/propagation/CompileTimeDependent.java b/tests/smoke/propagation/CompileTimeDependent.java
new file mode 100644
index 0000000..e505025
--- /dev/null
+++ b/tests/smoke/propagation/CompileTimeDependent.java
@@ -0,0 +1,30 @@
+/*
+ * 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 testing;
+
+import org.junit.Test;
+
+
+public class CompileTimeDependent {
+    @Test
+    public void justSoIcanUseTheTestAnnotation() {
+
+    }
+
+    public static void main(String[] args) {
+        new Stub();
+    }
+}
diff --git a/tests/smoke/propagation/RuntimeDependent.java b/tests/smoke/propagation/RuntimeDependent.java
new file mode 100644
index 0000000..7466c1c
--- /dev/null
+++ b/tests/smoke/propagation/RuntimeDependent.java
@@ -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.
+ */
+package testing;
+
+public class RuntimeDependent {
+    public static void main(String[] args) {
+        try {
+            Class.forName("org.junit.Test");
+        } catch (ClassNotFoundException e) {
+            System.exit(1);
+        }
+        System.exit(0);
+    }
+}
diff --git a/tests/smoke/propagation/Stub.kt b/tests/smoke/propagation/Stub.kt
new file mode 100644
index 0000000..8e1f332
--- /dev/null
+++ b/tests/smoke/propagation/Stub.kt
@@ -0,0 +1,18 @@
+/*
+ * 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 testing
+
+class Stub()
diff --git a/tests/smoke/resourcejar/pkg/file.txt b/tests/smoke/resourcejar/pkg/file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/smoke/resourcejar/pkg/file.txt
diff --git a/tests/smoke/testresources/resources/one/alsoAFile.txt b/tests/smoke/testresources/resources/one/alsoAFile.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/smoke/testresources/resources/one/alsoAFile.txt
diff --git a/tests/smoke/testresources/resources/one/two/aFile.txt b/tests/smoke/testresources/resources/one/two/aFile.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/smoke/testresources/resources/one/two/aFile.txt
diff --git a/tests/smoke/testresources/src/AClass.kt b/tests/smoke/testresources/src/AClass.kt
new file mode 100644
index 0000000..21a2f12
--- /dev/null
+++ b/tests/smoke/testresources/src/AClass.kt
@@ -0,0 +1,24 @@
+/*
+ * 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 testresources
+
+class AClass() {
+
+}
+
+class BClass() {
+
+}