Dissolve top level gitiles-* directories

The current layout of having gitiles-* directories with separate java
source trees dates back to the bad era of Maven, when this specific
layout was necessary to decompose the build into separate pom.xml files.

Moreover, src/{main,test}/java are also Maven artifacts, so that we go
even further and create three top level directories:

* java
* javatests
* resources

Change-Id: I4421096428db1e3de019a9b6c1253217cf7e4fbe
diff --git a/BUILD b/BUILD
index 773eb61..d65fe65 100644
--- a/BUILD
+++ b/BUILD
@@ -2,12 +2,12 @@
 
 pkg_war(
     name = "gitiles",
-    context = ["//gitiles-servlet:webassets"],
+    context = ["//resources/com/google/gitiles:webassets"],
     libs = [
-        "//gitiles-servlet:servlet",
         "//lib/jetty:server",
         "//lib/jetty:servlet",
         "//lib/slf4j:slf4j-simple",
+        "//java/com/google/gitiles:servlet",
     ],
-    web_xml = "//gitiles-war:web_xml",
+    web_xml = "//resources:web_xml",
 )
diff --git a/blame-cache/BUILD b/blame-cache/BUILD
deleted file mode 100644
index 860198a..0000000
--- a/blame-cache/BUILD
+++ /dev/null
@@ -1,27 +0,0 @@
-SRCS = glob(["src/main/java/**/*.java"])
-
-DEPS = [
-    "//lib:guava",
-    "//lib/jgit:jgit",
-]
-
-java_library(
-    name = "blame-cache",
-    srcs = SRCS,
-    visibility = ["//visibility:public"],
-    deps = DEPS,
-)
-
-load("@com_googlesource_gerrit_bazlets//tools:javadoc.bzl", "java_doc")
-
-java_doc(
-    name = "javadoc",
-    libs = [
-        ":blame-cache",
-        "//lib:guava",
-        "//lib/jgit:jgit",
-    ],
-    pkgs = ["com.google.gitiles.blame"],
-    title = "Blame Cache API Documentation",
-    visibility = ["//visibility:public"],
-)
diff --git a/gitiles-servlet/BUILD b/gitiles-servlet/BUILD
deleted file mode 100644
index 142e14c..0000000
--- a/gitiles-servlet/BUILD
+++ /dev/null
@@ -1,108 +0,0 @@
-load(
-    "@com_googlesource_gerrit_bazlets//tools:genrule2.bzl",
-    "genrule2",
-)
-
-DEPS = [
-    "//blame-cache:blame-cache",
-    "//lib:autolink",
-    "//lib:commons-lang3",
-    "//lib:gson",
-    "//lib:guava",
-    "//lib:html-types",
-    "//lib:joda-time",
-    "//lib:jsr305",
-    "//lib:commonmark",
-    "//lib:cm-autolink",
-    "//lib:gfm-tables",
-    "//lib:gfm-strikethrough",
-    "//lib:prettify",
-    "//lib/jgit:jgit",
-    "//lib/jgit:jgit-servlet",
-    "//lib/slf4j:slf4j-api",
-    "//lib/soy:soy",
-]
-
-DEPS_ALL = DEPS + [
-    "//lib/jgit:jgit-archive",
-    "//lib/guice:guice",
-]
-
-java_library(
-    name = "servlet-api",
-    neverlink = 1,
-    exports = ["//lib:servlet-api_2_5"],
-)
-
-java_library(
-    name = "servlet",
-    srcs = glob(["src/main/java/**/*.java"]),
-    resources = glob(["src/main/resources/**/*"]),
-    visibility = ["//visibility:public"],
-    deps = DEPS_ALL + [
-        ":servlet-api",
-    ],
-)
-
-genrule2(
-    name = "webassets",
-    srcs = glob(["src/main/resources/com/google/gitiles/static/**/*"]),
-    outs = ["webassets.zip"],
-    cmd = " && ".join([
-        "o=$$PWD/$@",
-        "tar cf - $(SRCS) | tar -C $$TMP/ --strip-components=2 -xf -",
-        "cd $$TMP/main/resources/com/google/gitiles/",
-        "mv static +static",
-        "zip -qr $$o .",
-    ]),
-    visibility = ["//visibility:public"],
-)
-
-java_library(
-    name = "testutil",
-    srcs = glob(
-        ["src/test/java/**/*.java"],
-        exclude = ["src/test/java/**/*Test.java"],
-    ) + glob(["**/ServletTest.java"]),
-    deps = DEPS + [
-        ":servlet",
-        "//lib:servlet-api_2_5",
-        "//lib:truth",
-        "//lib/jgit:junit",
-        "//lib/junit",
-    ],
-)
-
-load("@com_googlesource_gerrit_bazlets//tools:junit.bzl", "junit_tests")
-
-junit_tests(
-    name = "servlet_tests",
-    srcs = glob(
-        [
-            "src/test/java/**/*Test.java",
-        ],
-        exclude = ["**/ServletTest.java"],
-    ),
-    visibility = ["//visibility:public"],
-    runtime_deps = ["//lib/junit:hamcrest-core"],
-    deps = DEPS + [
-        ":servlet",
-        ":testutil",
-        "//lib:servlet-api_2_5",
-        "//lib:truth",
-        "//lib/jgit:junit",
-        "//lib/junit",
-    ],
-)
-
-load("@com_googlesource_gerrit_bazlets//tools:javadoc.bzl", "java_doc")
-
-java_doc(
-    name = "javadoc",
-    libs = DEPS + [
-        ":servlet",
-    ],
-    pkgs = ["com.google.gitiles"],
-    title = "Gitiles API Documentation",
-    visibility = ["//visibility:public"],
-)
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/AbstractHttpFilter.java b/java/com/google/gitiles/AbstractHttpFilter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/AbstractHttpFilter.java
rename to java/com/google/gitiles/AbstractHttpFilter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ArchiveFormat.java b/java/com/google/gitiles/ArchiveFormat.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/ArchiveFormat.java
rename to java/com/google/gitiles/ArchiveFormat.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ArchiveServlet.java b/java/com/google/gitiles/ArchiveServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/ArchiveServlet.java
rename to java/com/google/gitiles/ArchiveServlet.java
diff --git a/java/com/google/gitiles/BUILD b/java/com/google/gitiles/BUILD
new file mode 100644
index 0000000..fc8d6ec
--- /dev/null
+++ b/java/com/google/gitiles/BUILD
@@ -0,0 +1,89 @@
+# TODO(davido): Move sources that depend on the rest of gitiles
+# out of the blame directory and move this rule into its own BUILD
+# file in blame directory.
+BLAME_CACHE_SRCS = ["blame/" + n for n in [
+    "BlameCache.java",
+    "BlameCacheImpl.java",
+    "Region.java",
+]]
+
+java_library(
+    name = "blame-cache",
+    srcs = BLAME_CACHE_SRCS,
+    visibility = ["//visibility:public"],
+    deps = [
+        "//lib:guava",
+        "//lib/jgit",
+    ],
+)
+
+load("@com_googlesource_gerrit_bazlets//tools:javadoc.bzl", "java_doc")
+
+java_doc(
+    name = "blame-cache-javadoc",
+    libs = [
+        ":blame-cache",
+        "//lib:guava",
+        "//lib/jgit:jgit",
+    ],
+    pkgs = ["com.google.gitiles.blame"],
+    title = "Blame Cache API Documentation",
+    visibility = ["//visibility:public"],
+)
+
+DEPS = [
+    ":blame-cache",
+    "//lib:autolink",
+    "//lib:commons-lang3",
+    "//lib:gson",
+    "//lib:guava",
+    "//lib:html-types",
+    "//lib:joda-time",
+    "//lib:jsr305",
+    "//lib:commonmark",
+    "//lib:cm-autolink",
+    "//lib:gfm-tables",
+    "//lib:gfm-strikethrough",
+    "//lib:prettify",
+    "//lib/jgit:jgit",
+    "//lib/jgit:jgit-servlet",
+    "//lib/slf4j:slf4j-api",
+    "//lib/soy:soy",
+]
+
+DEPS_ALL = DEPS + [
+    "//lib/jgit:jgit-archive",
+    "//lib/guice:guice",
+]
+
+java_library(
+    name = "servlet-api",
+    neverlink = 1,
+    exports = ["//lib:servlet-api_2_5"],
+)
+
+java_library(
+    name = "servlet",
+    srcs = glob(
+        ["**/*.java"],
+        exclude = BLAME_CACHE_SRCS,
+    ),
+    resource_strip_prefix = "resources",
+    resources = ["//resources/com/google/gitiles"],
+    visibility = ["//visibility:public"],
+    deps = DEPS_ALL + [
+        ":servlet-api",
+    ],
+)
+
+load("@com_googlesource_gerrit_bazlets//tools:javadoc.bzl", "java_doc")
+
+java_doc(
+    name = "servlet-javadoc",
+    libs = DEPS + [
+        ":servlet",
+    ],
+    pkgs = ["com.google.gitiles"],
+    title = "Gitiles API Documentation",
+    visibility = ["//visibility:public"],
+)
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java b/java/com/google/gitiles/BaseServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
rename to java/com/google/gitiles/BaseServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/BlobSoyData.java b/java/com/google/gitiles/BlobSoyData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/BlobSoyData.java
rename to java/com/google/gitiles/BlobSoyData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/CommentLinkInfo.java b/java/com/google/gitiles/CommentLinkInfo.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/CommentLinkInfo.java
rename to java/com/google/gitiles/CommentLinkInfo.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/CommitData.java b/java/com/google/gitiles/CommitData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/CommitData.java
rename to java/com/google/gitiles/CommitData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/CommitJsonData.java b/java/com/google/gitiles/CommitJsonData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/CommitJsonData.java
rename to java/com/google/gitiles/CommitJsonData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/CommitSoyData.java b/java/com/google/gitiles/CommitSoyData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/CommitSoyData.java
rename to java/com/google/gitiles/CommitSoyData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ConfigUtil.java b/java/com/google/gitiles/ConfigUtil.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/ConfigUtil.java
rename to java/com/google/gitiles/ConfigUtil.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DateFormatter.java b/java/com/google/gitiles/DateFormatter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/DateFormatter.java
rename to java/com/google/gitiles/DateFormatter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DebugRenderer.java b/java/com/google/gitiles/DebugRenderer.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/DebugRenderer.java
rename to java/com/google/gitiles/DebugRenderer.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DefaultAccess.java b/java/com/google/gitiles/DefaultAccess.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/DefaultAccess.java
rename to java/com/google/gitiles/DefaultAccess.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DefaultRenderer.java b/java/com/google/gitiles/DefaultRenderer.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/DefaultRenderer.java
rename to java/com/google/gitiles/DefaultRenderer.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DefaultUrls.java b/java/com/google/gitiles/DefaultUrls.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/DefaultUrls.java
rename to java/com/google/gitiles/DefaultUrls.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DescribeServlet.java b/java/com/google/gitiles/DescribeServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/DescribeServlet.java
rename to java/com/google/gitiles/DescribeServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java b/java/com/google/gitiles/DiffServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java
rename to java/com/google/gitiles/DiffServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/FileJsonData.java b/java/com/google/gitiles/FileJsonData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/FileJsonData.java
rename to java/com/google/gitiles/FileJsonData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/FormatType.java b/java/com/google/gitiles/FormatType.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/FormatType.java
rename to java/com/google/gitiles/FormatType.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesAccess.java b/java/com/google/gitiles/GitilesAccess.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/GitilesAccess.java
rename to java/com/google/gitiles/GitilesAccess.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesConfig.java b/java/com/google/gitiles/GitilesConfig.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/GitilesConfig.java
rename to java/com/google/gitiles/GitilesConfig.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java b/java/com/google/gitiles/GitilesFilter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java
rename to java/com/google/gitiles/GitilesFilter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesServlet.java b/java/com/google/gitiles/GitilesServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/GitilesServlet.java
rename to java/com/google/gitiles/GitilesServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesUrls.java b/java/com/google/gitiles/GitilesUrls.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/GitilesUrls.java
rename to java/com/google/gitiles/GitilesUrls.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java b/java/com/google/gitiles/GitilesView.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java
rename to java/com/google/gitiles/GitilesView.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitwebRedirectFilter.java b/java/com/google/gitiles/GitwebRedirectFilter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/GitwebRedirectFilter.java
rename to java/com/google/gitiles/GitwebRedirectFilter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java b/java/com/google/gitiles/HostIndexServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
rename to java/com/google/gitiles/HostIndexServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java b/java/com/google/gitiles/HtmlDiffFormatter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java
rename to java/com/google/gitiles/HtmlDiffFormatter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/IdentRevFilter.java b/java/com/google/gitiles/IdentRevFilter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/IdentRevFilter.java
rename to java/com/google/gitiles/IdentRevFilter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/Linkifier.java b/java/com/google/gitiles/Linkifier.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/Linkifier.java
rename to java/com/google/gitiles/Linkifier.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/LogServlet.java b/java/com/google/gitiles/LogServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/LogServlet.java
rename to java/com/google/gitiles/LogServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/LogSoyData.java b/java/com/google/gitiles/LogSoyData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/LogSoyData.java
rename to java/com/google/gitiles/LogSoyData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/MimeTypes.java b/java/com/google/gitiles/MimeTypes.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/MimeTypes.java
rename to java/com/google/gitiles/MimeTypes.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/Paginator.java b/java/com/google/gitiles/Paginator.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/Paginator.java
rename to java/com/google/gitiles/Paginator.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java b/java/com/google/gitiles/PathServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
rename to java/com/google/gitiles/PathServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/PathUtil.java b/java/com/google/gitiles/PathUtil.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/PathUtil.java
rename to java/com/google/gitiles/PathUtil.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ReadmeHelper.java b/java/com/google/gitiles/ReadmeHelper.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/ReadmeHelper.java
rename to java/com/google/gitiles/ReadmeHelper.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RefServlet.java b/java/com/google/gitiles/RefServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/RefServlet.java
rename to java/com/google/gitiles/RefServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/Renderer.java b/java/com/google/gitiles/Renderer.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/Renderer.java
rename to java/com/google/gitiles/Renderer.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryDescription.java b/java/com/google/gitiles/RepositoryDescription.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/RepositoryDescription.java
rename to java/com/google/gitiles/RepositoryDescription.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryFilter.java b/java/com/google/gitiles/RepositoryFilter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/RepositoryFilter.java
rename to java/com/google/gitiles/RepositoryFilter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java b/java/com/google/gitiles/RepositoryIndexServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
rename to java/com/google/gitiles/RepositoryIndexServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/Revision.java b/java/com/google/gitiles/Revision.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/Revision.java
rename to java/com/google/gitiles/Revision.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RevisionParser.java b/java/com/google/gitiles/RevisionParser.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/RevisionParser.java
rename to java/com/google/gitiles/RevisionParser.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RevisionServlet.java b/java/com/google/gitiles/RevisionServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/RevisionServlet.java
rename to java/com/google/gitiles/RevisionServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RootedDocServlet.java b/java/com/google/gitiles/RootedDocServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/RootedDocServlet.java
rename to java/com/google/gitiles/RootedDocServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/TagSoyData.java b/java/com/google/gitiles/TagSoyData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/TagSoyData.java
rename to java/com/google/gitiles/TagSoyData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ThreadSafePrettifyParser.java b/java/com/google/gitiles/ThreadSafePrettifyParser.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/ThreadSafePrettifyParser.java
rename to java/com/google/gitiles/ThreadSafePrettifyParser.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/TimeCache.java b/java/com/google/gitiles/TimeCache.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/TimeCache.java
rename to java/com/google/gitiles/TimeCache.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java b/java/com/google/gitiles/TreeJsonData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java
rename to java/com/google/gitiles/TreeJsonData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/TreeSoyData.java b/java/com/google/gitiles/TreeSoyData.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/TreeSoyData.java
rename to java/com/google/gitiles/TreeSoyData.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ViewFilter.java b/java/com/google/gitiles/ViewFilter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/ViewFilter.java
rename to java/com/google/gitiles/ViewFilter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/VisibilityCache.java b/java/com/google/gitiles/VisibilityCache.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/VisibilityCache.java
rename to java/com/google/gitiles/VisibilityCache.java
diff --git a/blame-cache/src/main/java/com/google/gitiles/blame/BlameCache.java b/java/com/google/gitiles/blame/BlameCache.java
similarity index 100%
rename from blame-cache/src/main/java/com/google/gitiles/blame/BlameCache.java
rename to java/com/google/gitiles/blame/BlameCache.java
diff --git a/blame-cache/src/main/java/com/google/gitiles/blame/BlameCacheImpl.java b/java/com/google/gitiles/blame/BlameCacheImpl.java
similarity index 100%
rename from blame-cache/src/main/java/com/google/gitiles/blame/BlameCacheImpl.java
rename to java/com/google/gitiles/blame/BlameCacheImpl.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/blame/BlameServlet.java b/java/com/google/gitiles/blame/BlameServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/blame/BlameServlet.java
rename to java/com/google/gitiles/blame/BlameServlet.java
diff --git a/blame-cache/src/main/java/com/google/gitiles/blame/Region.java b/java/com/google/gitiles/blame/Region.java
similarity index 100%
rename from blame-cache/src/main/java/com/google/gitiles/blame/Region.java
rename to java/com/google/gitiles/blame/Region.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/blame/RegionAdapter.java b/java/com/google/gitiles/blame/RegionAdapter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/blame/RegionAdapter.java
rename to java/com/google/gitiles/blame/RegionAdapter.java
diff --git a/gitiles-dev/BUILD b/java/com/google/gitiles/dev/BUILD
similarity index 85%
rename from gitiles-dev/BUILD
rename to java/com/google/gitiles/dev/BUILD
index 2552321..f18084c 100644
--- a/gitiles-dev/BUILD
+++ b/java/com/google/gitiles/dev/BUILD
@@ -1,9 +1,9 @@
 java_library(
     name = "lib",
-    srcs = glob(["src/main/java/**/*.java"]),
+    srcs = glob(["**/*.java"]),
     visibility = ["//visibility:public"],
     deps = [
-        "//gitiles-servlet:servlet",
+        "//java/com/google/gitiles:servlet",
         "//lib:guava",
         "//lib:html-types",
         "//lib:servlet-api_3_0",
diff --git a/gitiles-dev/src/main/java/com/google/gitiles/dev/DevServer.java b/java/com/google/gitiles/dev/DevServer.java
similarity index 97%
rename from gitiles-dev/src/main/java/com/google/gitiles/dev/DevServer.java
rename to java/com/google/gitiles/dev/DevServer.java
index 000b0cb..60c353d 100644
--- a/gitiles-dev/src/main/java/com/google/gitiles/dev/DevServer.java
+++ b/java/com/google/gitiles/dev/DevServer.java
@@ -131,7 +131,7 @@
             STATIC_PREFIX,
             Arrays.asList(cfg.getStringList("gitiles", null, "customTemplates")),
             sourceRoot
-                .resolve("gitiles-servlet/src/main/resources/com/google/gitiles/templates")
+                .resolve("resources/com/google/gitiles/templates")
                 .toString(),
             firstNonNull(cfg.getString("gitiles", null, "siteTitle"), "Gitiles"));
 
@@ -151,7 +151,7 @@
 
   private Handler staticHandler() throws IOException {
     Path staticRoot =
-        sourceRoot.resolve("gitiles-servlet/src/main/resources/com/google/gitiles/static");
+        sourceRoot.resolve("resources/com/google/gitiles/static");
     ResourceHandler rh = new ResourceHandler();
     try {
       rh.setBaseResource(new PathResource(staticRoot.toUri().toURL()));
diff --git a/gitiles-dev/src/main/java/com/google/gitiles/dev/Main.java b/java/com/google/gitiles/dev/Main.java
similarity index 100%
rename from gitiles-dev/src/main/java/com/google/gitiles/dev/Main.java
rename to java/com/google/gitiles/dev/Main.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/BlockNote.java b/java/com/google/gitiles/doc/BlockNote.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/BlockNote.java
rename to java/com/google/gitiles/doc/BlockNote.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/BlockNoteExtension.java b/java/com/google/gitiles/doc/BlockNoteExtension.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/BlockNoteExtension.java
rename to java/com/google/gitiles/doc/BlockNoteExtension.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/DocServlet.java b/java/com/google/gitiles/doc/DocServlet.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/DocServlet.java
rename to java/com/google/gitiles/doc/DocServlet.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/GitHubThematicBreakExtension.java b/java/com/google/gitiles/doc/GitHubThematicBreakExtension.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/GitHubThematicBreakExtension.java
rename to java/com/google/gitiles/doc/GitHubThematicBreakExtension.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/GitilesHtmlExtension.java b/java/com/google/gitiles/doc/GitilesHtmlExtension.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/GitilesHtmlExtension.java
rename to java/com/google/gitiles/doc/GitilesHtmlExtension.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/GitilesMarkdown.java b/java/com/google/gitiles/doc/GitilesMarkdown.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/GitilesMarkdown.java
rename to java/com/google/gitiles/doc/GitilesMarkdown.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/HtmlSanitizer.java b/java/com/google/gitiles/doc/HtmlSanitizer.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/HtmlSanitizer.java
rename to java/com/google/gitiles/doc/HtmlSanitizer.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/IframeBlock.java b/java/com/google/gitiles/doc/IframeBlock.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/IframeBlock.java
rename to java/com/google/gitiles/doc/IframeBlock.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/ImageLoader.java b/java/com/google/gitiles/doc/ImageLoader.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/ImageLoader.java
rename to java/com/google/gitiles/doc/ImageLoader.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownConfig.java b/java/com/google/gitiles/doc/MarkdownConfig.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownConfig.java
rename to java/com/google/gitiles/doc/MarkdownConfig.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownToHtml.java b/java/com/google/gitiles/doc/MarkdownToHtml.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownToHtml.java
rename to java/com/google/gitiles/doc/MarkdownToHtml.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownUtil.java b/java/com/google/gitiles/doc/MarkdownUtil.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownUtil.java
rename to java/com/google/gitiles/doc/MarkdownUtil.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MultiColumnBlock.java b/java/com/google/gitiles/doc/MultiColumnBlock.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/MultiColumnBlock.java
rename to java/com/google/gitiles/doc/MultiColumnBlock.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MultiColumnExtension.java b/java/com/google/gitiles/doc/MultiColumnExtension.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/MultiColumnExtension.java
rename to java/com/google/gitiles/doc/MultiColumnExtension.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/NamedAnchor.java b/java/com/google/gitiles/doc/NamedAnchor.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/NamedAnchor.java
rename to java/com/google/gitiles/doc/NamedAnchor.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/NamedAnchorExtension.java b/java/com/google/gitiles/doc/NamedAnchorExtension.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/NamedAnchorExtension.java
rename to java/com/google/gitiles/doc/NamedAnchorExtension.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/Navbar.java b/java/com/google/gitiles/doc/Navbar.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/Navbar.java
rename to java/com/google/gitiles/doc/Navbar.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/PathResolver.java b/java/com/google/gitiles/doc/PathResolver.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/PathResolver.java
rename to java/com/google/gitiles/doc/PathResolver.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/RuntimeIOException.java b/java/com/google/gitiles/doc/RuntimeIOException.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/RuntimeIOException.java
rename to java/com/google/gitiles/doc/RuntimeIOException.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/SmartQuoted.java b/java/com/google/gitiles/doc/SmartQuoted.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/SmartQuoted.java
rename to java/com/google/gitiles/doc/SmartQuoted.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/SmartQuotedExtension.java b/java/com/google/gitiles/doc/SmartQuotedExtension.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/SmartQuotedExtension.java
rename to java/com/google/gitiles/doc/SmartQuotedExtension.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/TocBlock.java b/java/com/google/gitiles/doc/TocBlock.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/TocBlock.java
rename to java/com/google/gitiles/doc/TocBlock.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/TocExtension.java b/java/com/google/gitiles/doc/TocExtension.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/TocExtension.java
rename to java/com/google/gitiles/doc/TocExtension.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/TocFormatter.java b/java/com/google/gitiles/doc/TocFormatter.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/TocFormatter.java
rename to java/com/google/gitiles/doc/TocFormatter.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/html/HtmlBuilder.java b/java/com/google/gitiles/doc/html/HtmlBuilder.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/html/HtmlBuilder.java
rename to java/com/google/gitiles/doc/html/HtmlBuilder.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/html/SoyHtmlBuilder.java b/java/com/google/gitiles/doc/html/SoyHtmlBuilder.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/html/SoyHtmlBuilder.java
rename to java/com/google/gitiles/doc/html/SoyHtmlBuilder.java
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/html/StreamHtmlBuilder.java b/java/com/google/gitiles/doc/html/StreamHtmlBuilder.java
similarity index 100%
rename from gitiles-servlet/src/main/java/com/google/gitiles/doc/html/StreamHtmlBuilder.java
rename to java/com/google/gitiles/doc/html/StreamHtmlBuilder.java
diff --git a/javatests/com/google/gitiles/BUILD b/javatests/com/google/gitiles/BUILD
new file mode 100644
index 0000000..0bb414b
--- /dev/null
+++ b/javatests/com/google/gitiles/BUILD
@@ -0,0 +1,45 @@
+DEPS = [
+    "//lib:gson",
+    "//lib:guava",
+    "//lib/jgit:jgit",
+    "//lib/jgit:jgit-servlet",
+    "//lib:joda-time",
+    "//lib/soy:soy",
+]
+
+java_library(
+    name = "testutil",
+    srcs = glob(
+        ["**/*.java"],
+        exclude = ["**/*Test.java"],
+    ) + glob(["**/ServletTest.java"]),
+    deps = DEPS + [
+        "//java/com/google/gitiles:servlet",
+        "//lib:servlet-api_2_5",
+        "//lib:truth",
+        "//lib/jgit:junit",
+        "//lib/junit",
+    ],
+)
+
+load("@com_googlesource_gerrit_bazlets//tools:junit.bzl", "junit_tests")
+
+junit_tests(
+    name = "servlet_tests",
+    srcs = glob(
+        [
+            "**/*Test.java",
+        ],
+        exclude = ["**/ServletTest.java"],
+    ),
+    visibility = ["//visibility:public"],
+    runtime_deps = ["//lib/junit:hamcrest-core"],
+    deps = DEPS + [
+        "//java/com/google/gitiles:servlet",
+        ":testutil",
+        "//lib:servlet-api_2_5",
+        "//lib:truth",
+        "//lib/jgit:junit",
+        "//lib/junit",
+    ],
+)
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/ConfigUtilTest.java b/javatests/com/google/gitiles/ConfigUtilTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/ConfigUtilTest.java
rename to javatests/com/google/gitiles/ConfigUtilTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/DateFormatterTest.java b/javatests/com/google/gitiles/DateFormatterTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/DateFormatterTest.java
rename to javatests/com/google/gitiles/DateFormatterTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/DiffServletTest.java b/javatests/com/google/gitiles/DiffServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/DiffServletTest.java
rename to javatests/com/google/gitiles/DiffServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/FakeHttpServletRequest.java b/javatests/com/google/gitiles/FakeHttpServletRequest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/FakeHttpServletRequest.java
rename to javatests/com/google/gitiles/FakeHttpServletRequest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/FakeHttpServletResponse.java b/javatests/com/google/gitiles/FakeHttpServletResponse.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/FakeHttpServletResponse.java
rename to javatests/com/google/gitiles/FakeHttpServletResponse.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/GitilesFilterTest.java b/javatests/com/google/gitiles/GitilesFilterTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/GitilesFilterTest.java
rename to javatests/com/google/gitiles/GitilesFilterTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/GitilesUrlsTest.java b/javatests/com/google/gitiles/GitilesUrlsTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/GitilesUrlsTest.java
rename to javatests/com/google/gitiles/GitilesUrlsTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/GitilesViewTest.java b/javatests/com/google/gitiles/GitilesViewTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/GitilesViewTest.java
rename to javatests/com/google/gitiles/GitilesViewTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/GitwebRedirectFilterTest.java b/javatests/com/google/gitiles/GitwebRedirectFilterTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/GitwebRedirectFilterTest.java
rename to javatests/com/google/gitiles/GitwebRedirectFilterTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/HostIndexServletTest.java b/javatests/com/google/gitiles/HostIndexServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/HostIndexServletTest.java
rename to javatests/com/google/gitiles/HostIndexServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/IdentRevFilterTest.java b/javatests/com/google/gitiles/IdentRevFilterTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/IdentRevFilterTest.java
rename to javatests/com/google/gitiles/IdentRevFilterTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/LinkifierTest.java b/javatests/com/google/gitiles/LinkifierTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/LinkifierTest.java
rename to javatests/com/google/gitiles/LinkifierTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/LogServletTest.java b/javatests/com/google/gitiles/LogServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/LogServletTest.java
rename to javatests/com/google/gitiles/LogServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/PaginatorTest.java b/javatests/com/google/gitiles/PaginatorTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/PaginatorTest.java
rename to javatests/com/google/gitiles/PaginatorTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java b/javatests/com/google/gitiles/PathServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java
rename to javatests/com/google/gitiles/PathServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/PathsTest.java b/javatests/com/google/gitiles/PathsTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/PathsTest.java
rename to javatests/com/google/gitiles/PathsTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/RefServletTest.java b/javatests/com/google/gitiles/RefServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/RefServletTest.java
rename to javatests/com/google/gitiles/RefServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/RevisionParserTest.java b/javatests/com/google/gitiles/RevisionParserTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/RevisionParserTest.java
rename to javatests/com/google/gitiles/RevisionParserTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/ServletTest.java b/javatests/com/google/gitiles/ServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/ServletTest.java
rename to javatests/com/google/gitiles/ServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/TestGitilesAccess.java b/javatests/com/google/gitiles/TestGitilesAccess.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/TestGitilesAccess.java
rename to javatests/com/google/gitiles/TestGitilesAccess.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/TestGitilesServlet.java b/javatests/com/google/gitiles/TestGitilesServlet.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/TestGitilesServlet.java
rename to javatests/com/google/gitiles/TestGitilesServlet.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/TestGitilesUrls.java b/javatests/com/google/gitiles/TestGitilesUrls.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/TestGitilesUrls.java
rename to javatests/com/google/gitiles/TestGitilesUrls.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/TestViewFilter.java b/javatests/com/google/gitiles/TestViewFilter.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/TestViewFilter.java
rename to javatests/com/google/gitiles/TestViewFilter.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/TimeCacheTest.java b/javatests/com/google/gitiles/TimeCacheTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/TimeCacheTest.java
rename to javatests/com/google/gitiles/TimeCacheTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/TreeSoyDataTest.java b/javatests/com/google/gitiles/TreeSoyDataTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/TreeSoyDataTest.java
rename to javatests/com/google/gitiles/TreeSoyDataTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/ViewFilterTest.java b/javatests/com/google/gitiles/ViewFilterTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/ViewFilterTest.java
rename to javatests/com/google/gitiles/ViewFilterTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/blame/BlameServletTest.java b/javatests/com/google/gitiles/blame/BlameServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/blame/BlameServletTest.java
rename to javatests/com/google/gitiles/blame/BlameServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/doc/DocServletTest.java b/javatests/com/google/gitiles/doc/DocServletTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/doc/DocServletTest.java
rename to javatests/com/google/gitiles/doc/DocServletTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/doc/LinkTest.java b/javatests/com/google/gitiles/doc/LinkTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/doc/LinkTest.java
rename to javatests/com/google/gitiles/doc/LinkTest.java
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/doc/PathResolverTest.java b/javatests/com/google/gitiles/doc/PathResolverTest.java
similarity index 100%
rename from gitiles-servlet/src/test/java/com/google/gitiles/doc/PathResolverTest.java
rename to javatests/com/google/gitiles/doc/PathResolverTest.java
diff --git a/gitiles-war/BUILD b/resources/BUILD
similarity index 64%
rename from gitiles-war/BUILD
rename to resources/BUILD
index be3000e..020f145 100644
--- a/gitiles-war/BUILD
+++ b/resources/BUILD
@@ -1,5 +1,5 @@
 filegroup(
     name = "web_xml",
-    srcs = ["src/main/resources/web.xml"],
+    srcs = ["web.xml"],
     visibility = ["//visibility:public"],
 )
diff --git a/resources/com/google/gitiles/BUILD b/resources/com/google/gitiles/BUILD
new file mode 100644
index 0000000..c5df3e1
--- /dev/null
+++ b/resources/com/google/gitiles/BUILD
@@ -0,0 +1,27 @@
+load(
+    "@com_googlesource_gerrit_bazlets//tools:genrule2.bzl",
+    "genrule2",
+)
+
+filegroup(
+    name = "gitiles",
+    srcs = glob(
+        ["**/*"],
+        exclude = ["BUILD"],
+    ),
+    visibility = ["//visibility:public"],
+)
+
+genrule2(
+    name = "webassets",
+    srcs = [":gitiles"],
+    outs = ["webassets.zip"],
+    cmd = " && ".join([
+        "o=$$PWD/$@",
+        "tar cf - $(SRCS) | tar -C $$TMP/ --strip-components=1 -xf -",
+        "cd $$TMP/com/google/gitiles/",
+        "mv static +static",
+        "zip -qr $$o .",
+    ]),
+    visibility = ["//visibility:public"],
+)
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/mime-types.properties b/resources/com/google/gitiles/mime-types.properties
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/mime-types.properties
rename to resources/com/google/gitiles/mime-types.properties
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/static/base.css b/resources/com/google/gitiles/static/base.css
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/static/base.css
rename to resources/com/google/gitiles/static/base.css
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/static/doc.css b/resources/com/google/gitiles/static/doc.css
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/static/doc.css
rename to resources/com/google/gitiles/static/doc.css
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/static/prettify/prettify.css b/resources/com/google/gitiles/static/prettify/prettify.css
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/static/prettify/prettify.css
rename to resources/com/google/gitiles/static/prettify/prettify.css
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/BlameDetail.soy b/resources/com/google/gitiles/templates/BlameDetail.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/BlameDetail.soy
rename to resources/com/google/gitiles/templates/BlameDetail.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Common.soy b/resources/com/google/gitiles/templates/Common.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/Common.soy
rename to resources/com/google/gitiles/templates/Common.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy b/resources/com/google/gitiles/templates/DiffDetail.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy
rename to resources/com/google/gitiles/templates/DiffDetail.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Doc.soy b/resources/com/google/gitiles/templates/Doc.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/Doc.soy
rename to resources/com/google/gitiles/templates/Doc.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/HostIndex.soy b/resources/com/google/gitiles/templates/HostIndex.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/HostIndex.soy
rename to resources/com/google/gitiles/templates/HostIndex.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/LogDetail.soy b/resources/com/google/gitiles/templates/LogDetail.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/LogDetail.soy
rename to resources/com/google/gitiles/templates/LogDetail.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/ObjectDetail.soy b/resources/com/google/gitiles/templates/ObjectDetail.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/ObjectDetail.soy
rename to resources/com/google/gitiles/templates/ObjectDetail.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/PathDetail.soy b/resources/com/google/gitiles/templates/PathDetail.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/PathDetail.soy
rename to resources/com/google/gitiles/templates/PathDetail.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RefList.soy b/resources/com/google/gitiles/templates/RefList.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/RefList.soy
rename to resources/com/google/gitiles/templates/RefList.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RepositoryIndex.soy b/resources/com/google/gitiles/templates/RepositoryIndex.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/RepositoryIndex.soy
rename to resources/com/google/gitiles/templates/RepositoryIndex.soy
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RevisionDetail.soy b/resources/com/google/gitiles/templates/RevisionDetail.soy
similarity index 100%
rename from gitiles-servlet/src/main/resources/com/google/gitiles/templates/RevisionDetail.soy
rename to resources/com/google/gitiles/templates/RevisionDetail.soy
diff --git a/gitiles-war/src/main/resources/web.xml b/resources/web.xml
similarity index 100%
rename from gitiles-war/src/main/resources/web.xml
rename to resources/web.xml
diff --git a/tools/bazlets.bzl b/tools/bazlets.bzl
index e14e488..b5c240c 100644
--- a/tools/bazlets.bzl
+++ b/tools/bazlets.bzl
@@ -1,7 +1,7 @@
 NAME = "com_googlesource_gerrit_bazlets"
 
 def load_bazlets(
-    commit,
+    commit = None,
     local_path = None
   ):
   if not local_path:
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
index 45ad493..f6a1b35 100644
--- a/tools/eclipse/BUILD
+++ b/tools/eclipse/BUILD
@@ -2,8 +2,8 @@
 load("@com_googlesource_gerrit_bazlets//tools:py_binary_path.bzl", "py_binary_path")
 
 DEPS = [
-    "//gitiles-servlet:servlet",
-    "//gitiles-dev:lib",
+    "//java/com/google/gitiles:servlet",
+    "//java/com/google/gitiles/dev:lib",
 ]
 
 java_library(
@@ -15,7 +15,7 @@
     name = "main_classpath_collect",
     testonly = 1,
     deps = DEPS + [
-        "//gitiles-servlet:servlet_tests",
+        "//javatests/com/google/gitiles:servlet_tests",
     ],
 )
 
diff --git a/tools/maven/BUILD b/tools/maven/BUILD
index 5efc003..b2d424a 100644
--- a/tools/maven/BUILD
+++ b/tools/maven/BUILD
@@ -3,17 +3,17 @@
 
 maven_package(
     src = {
-        "blame-cache": "//blame-cache:libblame-cache-src.jar",
-        "gitiles-servlet": "//gitiles-servlet:libservlet-src.jar",
+        "blame-cache": "//java/com/google/gitiles:libblame-cache-src.jar",
+        "gitiles-servlet": "//java/com/google/gitiles:libservlet-src.jar",
     },
     doc = {
-        "blame-cache": "//blame-cache:javadoc",
-        "gitiles-servlet": "//gitiles-servlet:javadoc",
+        "blame-cache": "//java/com/google/gitiles:blame-cache-javadoc",
+        "gitiles-servlet": "//java/com/google/gitiles:servlet-javadoc",
     },
     group = "com.google.gitiles",
     jar = {
-        "blame-cache": "//blame-cache:blame-cache",
-        "gitiles-servlet": "//gitiles-servlet:servlet",
+        "blame-cache": "//java/com/google/gitiles:blame-cache",
+        "gitiles-servlet": "//java/com/google/gitiles:servlet",
     },
     repository = "gerrit-maven-repository",
     url = "gs://gerrit-maven",
diff --git a/tools/run_dev.sh b/tools/run_dev.sh
index ce1afa3..497e9d3 100755
--- a/tools/run_dev.sh
+++ b/tools/run_dev.sh
@@ -26,7 +26,7 @@
 
 (
   cd "$ROOT"
-  bazel build gitiles-dev:dev
+  bazel build java/com/google/gitiles/dev
 )
 
-"$ROOT/bazel-bin/gitiles-dev/dev" $PROPERTIES
+"$ROOT/bazel-bin/java/com/google/gitiles/dev/dev" $PROPERTIES