Merge branch 'stable-2.13' into stable-2.14

* stable-2.13:
  Build with API version 2.13.9

Change-Id: Ie2608c64cb3af20f9f01cb8c6408412899ef10d0
diff --git a/.buckconfig b/.buckconfig
deleted file mode 100644
index a73f7b8..0000000
--- a/.buckconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-[alias]
-  plugin = //:delete-project
-
-[java]
-  src_roots = java, resources
-
-[project]
-  ignore = .git, eclipse-out
diff --git a/.gitignore b/.gitignore
index f5b756a..1caf4e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,8 +3,5 @@
 .project
 /.settings/org.maven.ide.eclipse.prefs
 /.settings/org.eclipse.m2e.core.prefs
-.buckd
-.buckversion
-buck-out
-bucklets
-eclipse-out
+/.primary_build_tool
+/bazel-*
diff --git a/BUCK b/BUCK
deleted file mode 100644
index a29218e..0000000
--- a/BUCK
+++ /dev/null
@@ -1,31 +0,0 @@
-include_defs('//bucklets/gerrit_plugin.bucklet')
-
-gerrit_plugin(
-  name = 'delete-project',
-  srcs = glob(['src/main/java/**/*.java']),
-  resources = glob(['src/main/resources/**/*']),
-  manifest_entries = [
-    'Gerrit-PluginName: deleteproject',
-    'Gerrit-Module: com.googlesource.gerrit.plugins.deleteproject.Module',
-    'Gerrit-HttpModule: com.googlesource.gerrit.plugins.deleteproject.HttpModule',
-    'Gerrit-SshModule: com.googlesource.gerrit.plugins.deleteproject.SshModule',
-  ],
-  provided_deps = [
-    '//lib:gson',
-    '//lib/log:log4j',
-  ],
-)
-
-java_library(
-  name = 'classpath',
-  deps = GERRIT_PLUGIN_API + [
-    ':delete-project__plugin',
-  ],
-)
-
-java_test(
-  name = 'delete-project_tests',
-  srcs = glob(['src/test/java/**/*.java']),
-  labels = ['delete-project'],
-  deps = GERRIT_PLUGIN_API + GERRIT_TESTS + [':delete-project__plugin'],
-)
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..89f3d06
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,35 @@
+load("//tools/bzl:junit.bzl", "junit_tests")
+load(
+    "//tools/bzl:plugin.bzl",
+    "gerrit_plugin",
+    "PLUGIN_DEPS",
+    "PLUGIN_TEST_DEPS",
+)
+
+gerrit_plugin(
+    name = "delete-project",
+    srcs = glob(["src/main/java/**/*.java"]),
+    manifest_entries = [
+        "Gerrit-PluginName: delete-project",
+        "Gerrit-Module: com.googlesource.gerrit.plugins.deleteproject.Module",
+        "Gerrit-HttpModule: com.googlesource.gerrit.plugins.deleteproject.HttpModule",
+        "Gerrit-SshModule: com.googlesource.gerrit.plugins.deleteproject.SshModule",
+    ],
+    resources = glob(["src/main/resources/**/*"]),
+)
+
+junit_tests(
+    name = "delete_project_tests",
+    srcs = glob(["src/test/java/**/*.java"]),
+    tags = ["delete-project"],
+    deps = [":delete-project__plugin_test_deps"],
+)
+
+java_library(
+    name = "delete-project__plugin_test_deps",
+    testonly = 1,
+    visibility = ["//visibility:public"],
+    exports = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
+        ":delete-project__plugin",
+    ],
+)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..92bea1f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# Delete project plugin for Gerrit Code Review
+
+A plugin which allows projects to be deleted from Gerrit via an SSH command,
+REST API or the Project settings screen.
+
+[![Build Status](https://gerrit-ci.gerritforge.com/job/plugin-delete-project-bazel-master/badge/icon)
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..83e1afc
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,26 @@
+workspace(name = "delete_project")
+
+load("//:bazlets.bzl", "load_bazlets")
+
+load_bazlets(
+    commit = "e50890188cd63f79d4a8529f90024f56168f9c9a",
+    #    local_path = "/home/<user>/projects/bazlets",
+)
+
+#Snapshot Plugin API
+#load(
+#    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
+#    "gerrit_api_maven_local",
+#)
+
+# Load snapshot Plugin API
+#gerrit_api_maven_local()
+
+# Release Plugin API
+load(
+    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
+    "gerrit_api",
+)
+
+# Load release Plugin API
+gerrit_api()
diff --git a/bazlets.bzl b/bazlets.bzl
new file mode 100644
index 0000000..e14e488
--- /dev/null
+++ b/bazlets.bzl
@@ -0,0 +1,17 @@
+NAME = "com_googlesource_gerrit_bazlets"
+
+def load_bazlets(
+    commit,
+    local_path = None
+  ):
+  if not local_path:
+      native.git_repository(
+          name = NAME,
+          remote = "https://gerrit.googlesource.com/bazlets",
+          commit = commit,
+      )
+  else:
+      native.local_repository(
+          name = NAME,
+          path = local_path,
+      )
diff --git a/lib/BUCK b/lib/BUCK
deleted file mode 100644
index 8892994..0000000
--- a/lib/BUCK
+++ /dev/null
@@ -1,8 +0,0 @@
-include_defs('//bucklets/maven_jar.bucklet')
-
-maven_jar(
-  name = 'gson',
-  id = 'com.google.code.gson:gson:2.1',
-  sha1 = '2e66da15851f9f5b5079228f856c2f090ba98c38',
-  license = 'Apache2.0',
-)
diff --git a/lib/gerrit/BUCK b/lib/gerrit/BUCK
deleted file mode 100644
index d341c07..0000000
--- a/lib/gerrit/BUCK
+++ /dev/null
@@ -1,22 +0,0 @@
-include_defs('//bucklets/maven_jar.bucklet')
-
-VER = '2.13.9'
-REPO = MAVEN_CENTRAL
-
-maven_jar(
-  name = 'plugin-api',
-  id = 'com.google.gerrit:gerrit-plugin-api:' + VER,
-  sha1 = 'a9b00025900f68c1f86036ea07591a2876b10c37',
-  attach_source = False,
-  repository = REPO,
-  license = 'Apache2.0',
-)
-
-maven_jar(
-  name = 'acceptance-framework',
-  id = 'com.google.gerrit:gerrit-acceptance-framework:' + VER,
-  sha1 = '53a6e2baca19303bbf3967b861cf9814323c31f6',
-  license = 'Apache2.0',
-  attach_source = False,
-  repository = REPO,
-)
diff --git a/lib/log/BUCK b/lib/log/BUCK
deleted file mode 100644
index 1ae0c8e..0000000
--- a/lib/log/BUCK
+++ /dev/null
@@ -1,9 +0,0 @@
-include_defs('//bucklets/maven_jar.bucklet')
-
-maven_jar(
-  name = 'log4j',
-  id = 'log4j:log4j:1.2.17',
-  sha1 = '5af35056b4d257e4b64b9e8069c0746e8b08629f',
-  license = 'Apache2.0',
-  exclude = ['META-INF/LICENSE', 'META-INF/NOTICE'],
-)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/CannotDeleteProjectException.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/CannotDeleteProjectException.java
index 6b737ca..3cf3912 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/CannotDeleteProjectException.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/CannotDeleteProjectException.java
@@ -17,10 +17,7 @@
 public class CannotDeleteProjectException extends Exception {
   private static final long serialVersionUID = 1L;
 
-  /**
-   * Thrown when trying to delete a project which can not
-   * be currently deleted.
-   */
+  /** Thrown when trying to delete a project which can not be currently deleted. */
   public CannotDeleteProjectException(String message) {
     super(message);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java
index 44e7ee9..73cad25 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java
@@ -22,16 +22,15 @@
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-
 import com.googlesource.gerrit.plugins.deleteproject.cache.CacheDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.database.DatabaseDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.fs.FilesystemDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.projectconfig.ProjectConfigDeleteHandler;
 
-public class DeleteAction extends DeleteProject implements
-    UiAction<ProjectResource> {
+public class DeleteAction extends DeleteProject implements UiAction<ProjectResource> {
   @Inject
-  DeleteAction(AllProjectsNameProvider allProjectsNameProvider,
+  DeleteAction(
+      AllProjectsNameProvider allProjectsNameProvider,
       DatabaseDeleteHandler dbHandler,
       FilesystemDeleteHandler fsHandler,
       CacheDeleteHandler cacheHandler,
@@ -41,24 +40,32 @@
       DeleteLog deleteLog,
       PluginConfigFactory cfgFactory,
       HideProject hideProject) {
-    super(allProjectsNameProvider, dbHandler, fsHandler, cacheHandler,
-        pcHandler, userProvider, pluginName, deleteLog, cfgFactory, hideProject);
+    super(
+        allProjectsNameProvider,
+        dbHandler,
+        fsHandler,
+        cacheHandler,
+        pcHandler,
+        userProvider,
+        pluginName,
+        deleteLog,
+        cfgFactory,
+        hideProject);
   }
 
   @Override
   public UiAction.Description getDescription(ProjectResource rsrc) {
     return new UiAction.Description()
         .setLabel("Delete...")
-        .setTitle(isAllProjects(rsrc)
-            ? String.format("No deletion of %s project",
-                allProjectsName)
-            : String.format("Delete project %s", rsrc.getName()))
+        .setTitle(
+            isAllProjects(rsrc)
+                ? String.format("No deletion of %s project", allProjectsName)
+                : String.format("Delete project %s", rsrc.getName()))
         .setEnabled(!isAllProjects(rsrc))
         .setVisible(canDelete(rsrc));
   }
 
   private boolean isAllProjects(ProjectResource rsrc) {
-    return (rsrc.getControl().getProject()
-        .getNameKey().equals(allProjectsName));
+    return (rsrc.getControl().getProject().getNameKey().equals(allProjectsName));
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteCommand.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteCommand.java
index 3b77789..e62634a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteCommand.java
@@ -23,12 +23,10 @@
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
-
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.Option;
-
 import java.io.IOException;
 import java.util.Collection;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
 
 @CommandMetaData(name = "delete", description = "Delete specific project")
 public final class DeleteCommand extends SshCommand {
@@ -82,7 +80,7 @@
           msgBuilder.append("There are warnings against deleting ");
           msgBuilder.append(rsrc.getName());
           msgBuilder.append(":\n");
-          for (String warning: warnings) {
+          for (String warning : warnings) {
             msgBuilder.append(" * ");
             msgBuilder.append(warning);
             msgBuilder.append("\n");
@@ -95,8 +93,11 @@
       }
 
       deleteProject.doDelete(rsrc, input);
-    } catch (AuthException | ResourceNotFoundException
-        | ResourceConflictException | OrmException | IOException e) {
+    } catch (AuthException
+        | ResourceNotFoundException
+        | ResourceConflictException
+        | OrmException
+        | IOException e) {
       die(e);
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLog.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLog.java
index 8eca1d3..292d8bd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLog.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLog.java
@@ -14,8 +14,8 @@
 
 package com.googlesource.gerrit.plugins.deleteproject;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.MultimapBuilder;
 import com.google.gerrit.audit.AuditEvent;
 import com.google.gerrit.audit.AuditService;
 import com.google.gerrit.common.TimeUtil;
@@ -27,7 +27,6 @@
 import com.google.gerrit.server.util.SystemLog;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-
 import org.apache.log4j.Level;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
@@ -47,40 +46,38 @@
   private final AuditService auditService;
 
   @Inject
-  public DeleteLog(SystemLog systemLog,
-      ServerInformation serverInfo,
-      AuditService auditService) {
+  public DeleteLog(SystemLog systemLog, ServerInformation serverInfo, AuditService auditService) {
     super(systemLog, serverInfo, DELETE_LOG_NAME, new DeleteLogLayout());
     this.auditService = auditService;
   }
 
-  public void onDelete(IdentifiedUser user, Project.NameKey project,
-      DeleteProject.Input options, Exception ex) {
+  public void onDelete(
+      IdentifiedUser user, Project.NameKey project, DeleteProject.Input options, Exception ex) {
     long ts = TimeUtil.nowMs();
-    LoggingEvent event = new LoggingEvent( //
-        Logger.class.getName(), // fqnOfCategoryClass
-        log, // logger
-        ts, // when
-        ex == null // level
-            ? Level.INFO
-            : Level.ERROR,
-        ex == null // message text
-            ? "OK"
-            : "FAIL",
-        Thread.currentThread().getName(), // thread name
-        null, // exception information
-        null, // current NDC string
-        null, // caller location
-        null // MDC properties
-        );
+    LoggingEvent event =
+        new LoggingEvent( //
+            Logger.class.getName(), // fqnOfCategoryClass
+            log, // logger
+            ts, // when
+            ex == null // level
+                ? Level.INFO
+                : Level.ERROR,
+            ex == null // message text
+                ? "OK"
+                : "FAIL",
+            Thread.currentThread().getName(), // thread name
+            null, // exception information
+            null, // current NDC string
+            null, // caller location
+            null // MDC properties
+            );
 
     event.setProperty(ACCOUNT_ID, user.getAccountId().toString());
     event.setProperty(USER_NAME, user.getUserName());
     event.setProperty(PROJECT_NAME, project.get());
 
     if (options != null) {
-      event.setProperty(OPTIONS,
-          OutputFormat.JSON_COMPACT.newGson().toJson(options));
+      event.setProperty(OPTIONS, OutputFormat.JSON_COMPACT.newGson().toJson(options));
     }
 
     if (ex != null) {
@@ -92,9 +89,13 @@
     audit(user, ts, project, options, ex);
   }
 
-  private void audit(IdentifiedUser user, long ts, Project.NameKey project,
-      DeleteProject.Input options, Exception ex) {
-    Multimap<String, Object> params = HashMultimap.create();
+  private void audit(
+      IdentifiedUser user,
+      long ts,
+      Project.NameKey project,
+      DeleteProject.Input options,
+      Exception ex) {
+    ListMultimap<String, Object> params = MultimapBuilder.hashKeys().arrayListValues().build();
     params.put("class", DeleteLog.class);
     params.put("project", project.get());
     if (options != null) {
@@ -113,7 +114,6 @@
             params, // params
             ex != null // result
                 ? ex.toString()
-                : "OK"
-        ));
+                : "OK"));
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLogLayout.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLogLayout.java
index aba5160..cc4c436 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLogLayout.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteLogLayout.java
@@ -14,14 +14,13 @@
 
 package com.googlesource.gerrit.plugins.deleteproject;
 
-import org.apache.log4j.Layout;
-import org.apache.log4j.spi.LoggingEvent;
-import org.eclipse.jgit.util.QuotedString;
-
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.TimeZone;
+import org.apache.log4j.Layout;
+import org.apache.log4j.spi.LoggingEvent;
+import org.eclipse.jgit.util.QuotedString;
 
 final class DeleteLogLayout extends Layout {
   private final Calendar calendar;
@@ -29,7 +28,7 @@
   private final char[] lastTimeString = new char[20];
   private final char[] timeZone;
 
- public DeleteLogLayout() {
+  public DeleteLogLayout() {
     TimeZone tz = TimeZone.getDefault();
     calendar = Calendar.getInstance(tz);
 
@@ -41,14 +40,12 @@
   /**
    * Formats the events in the delete log.
    *
-   * A successful project deletion will result in a log entry like this:
-   *   [2015-03-05 09:13:28,912 +0100] INFO 1000000 admin OK \
-   *   myProject {"preserve":false,"force":false}
+   * <p>A successful project deletion will result in a log entry like this: [2015-03-05 09:13:28,912
+   * +0100] INFO 1000000 admin OK \ myProject {"preserve":false,"force":false}
    *
-   * The log entry for a failed project deletion will look like this:
-   *   [2015-03-05 12:14:30,180 +0100] ERROR 1000000 admin FAIL \
-   *   myProject {"preserve":false,"force":false} com.google.gwtorm.server.OrmException: \
-   *   Failed to access the database
+   * <p>The log entry for a failed project deletion will look like this: [2015-03-05 12:14:30,180
+   * +0100] ERROR 1000000 admin FAIL \ myProject {"preserve":false,"force":false}
+   * com.google.gwtorm.server.OrmException: \ Failed to access the database
    */
   @Override
   public String format(LoggingEvent event) {
@@ -138,6 +135,5 @@
   }
 
   @Override
-  public void activateOptions() {
-  }
+  public void activateOptions() {}
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java
index db62544..8081cd3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java
@@ -34,17 +34,14 @@
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-
 import com.googlesource.gerrit.plugins.deleteproject.DeleteProject.Input;
 import com.googlesource.gerrit.plugins.deleteproject.cache.CacheDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.database.DatabaseDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.fs.FilesystemDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.projectconfig.ProjectConfigDeleteHandler;
-
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
-
 import java.io.IOException;
 import java.util.Collection;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
 
 class DeleteProject implements RestModifyView<ProjectResource, Input> {
   static class Input {
@@ -64,7 +61,8 @@
   private final HideProject hideProject;
 
   @Inject
-  DeleteProject(AllProjectsNameProvider allProjectsNameProvider,
+  DeleteProject(
+      AllProjectsNameProvider allProjectsNameProvider,
       DatabaseDeleteHandler dbHandler,
       FilesystemDeleteHandler fsHandler,
       CacheDeleteHandler cacheHandler,
@@ -88,16 +86,16 @@
 
   @Override
   public Object apply(ProjectResource rsrc, Input input)
-      throws ResourceNotFoundException, ResourceConflictException,
-      OrmException, IOException, AuthException {
+      throws ResourceNotFoundException, ResourceConflictException, OrmException, IOException,
+          AuthException {
     assertDeletePermission(rsrc);
     assertCanDelete(rsrc, input);
 
     if (input == null || !input.force) {
       Collection<String> warnings = getWarnings(rsrc);
       if (!warnings.isEmpty()) {
-        throw new ResourceConflictException(String.format(
-            "Project %s has open changes", rsrc.getName()));
+        throw new ResourceConflictException(
+            String.format("Project %s has open changes", rsrc.getName()));
       }
     }
 
@@ -105,8 +103,7 @@
     return Response.none();
   }
 
-  public void assertDeletePermission(ProjectResource rsrc)
-      throws AuthException {
+  public void assertDeletePermission(ProjectResource rsrc) throws AuthException {
     if (!canDelete(rsrc)) {
       throw new AuthException("not allowed to delete project");
     }
@@ -116,12 +113,10 @@
     CapabilityControl ctl = userProvider.get().getCapabilities();
     return ctl.canAdministrateServer()
         || ctl.canPerform(pluginName + "-" + DELETE_PROJECT)
-        || (ctl.canPerform(pluginName + "-" + DELETE_OWN_PROJECT)
-            && rsrc.getControl().isOwner());
+        || (ctl.canPerform(pluginName + "-" + DELETE_OWN_PROJECT) && rsrc.getControl().isOwner());
   }
 
-  public void assertCanDelete(ProjectResource rsrc, Input input)
-      throws ResourceConflictException {
+  public void assertCanDelete(ProjectResource rsrc, Input input) throws ResourceConflictException {
     try {
       pcHandler.assertCanDelete(rsrc);
       dbHandler.assertCanDelete(rsrc.getControl().getProject());
@@ -131,19 +126,19 @@
     }
   }
 
-  public Collection<String> getWarnings(ProjectResource rsrc)
-      throws OrmException {
+  public Collection<String> getWarnings(ProjectResource rsrc) throws OrmException {
     return dbHandler.getWarnings(rsrc.getControl().getProject());
   }
 
-  public void doDelete(ProjectResource rsrc, Input input) throws OrmException,
-      IOException, ResourceNotFoundException, ResourceConflictException {
+  public void doDelete(ProjectResource rsrc, Input input)
+      throws OrmException, IOException, ResourceNotFoundException, ResourceConflictException {
     Project project = rsrc.getControl().getProject();
     boolean preserve = input != null && input.preserve;
     Exception ex = null;
     try {
       if (!preserve
-          || !cfgFactory.getFromGerritConfig(pluginName)
+          || !cfgFactory
+              .getFromGerritConfig(pluginName)
               .getBoolean("hideProjectOnPreserve", false)) {
         dbHandler.delete(project);
         try {
@@ -159,8 +154,7 @@
       ex = e;
       throw e;
     } finally {
-      deleteLog.onDelete((IdentifiedUser) userProvider.get(),
-          project.getNameKey(), input, ex);
+      deleteLog.onDelete((IdentifiedUser) userProvider.get(), project.getNameKey(), input, ex);
     }
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
index bc86fc6..6897a29 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
@@ -31,12 +31,10 @@
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-
+import java.io.IOException;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 
-import java.io.IOException;
-
 @Singleton
 class HideProject {
   private static String DEFAULT_PARENT_FOR_DELETED_PROJECTS = "Deleted-Projects";
@@ -61,8 +59,8 @@
     this.pluginName = pluginName;
   }
 
-  public void apply(ProjectResource rsrc) throws ResourceNotFoundException,
-      ResourceConflictException, IOException {
+  public void apply(ProjectResource rsrc)
+      throws ResourceNotFoundException, ResourceConflictException, IOException {
     try {
       MetaDataUpdate md = metaDataUpdateFactory.create(rsrc.getNameKey());
 
@@ -75,8 +73,9 @@
       }
 
       String parentForDeletedProjects =
-          cfgFactory.getFromGerritConfig(pluginName).getString(
-              "parentForDeletedProjects", DEFAULT_PARENT_FOR_DELETED_PROJECTS);
+          cfgFactory
+              .getFromGerritConfig(pluginName)
+              .getString("parentForDeletedProjects", DEFAULT_PARENT_FOR_DELETED_PROJECTS);
       createProjectIfMissing(parentForDeletedProjects);
       p.setParentName(parentForDeletedProjects);
 
@@ -94,12 +93,13 @@
       throws ResourceConflictException, IOException {
     if (projectCache.get(new Project.NameKey(projectName)) == null) {
       try {
-        createProjectFactory.create(projectName).apply(
-            TopLevelResource.INSTANCE, null);
-      } catch (BadRequestException | UnprocessableEntityException
-          | ResourceNotFoundException | ConfigInvalidException e) {
-        throw new ResourceConflictException(String.format(
-            "Failed to create project %s", projectName));
+        createProjectFactory.create(projectName).apply(TopLevelResource.INSTANCE, null);
+      } catch (BadRequestException
+          | UnprocessableEntityException
+          | ResourceNotFoundException
+          | ConfigInvalidException e) {
+        throw new ResourceConflictException(
+            String.format("Failed to create project %s", projectName));
       }
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/Module.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/Module.java
index 3296dfb..857555e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/Module.java
@@ -24,7 +24,6 @@
 import com.google.gerrit.extensions.restapi.RestApiModule;
 import com.google.inject.AbstractModule;
 import com.google.inject.internal.UniqueAnnotations;
-
 import com.googlesource.gerrit.plugins.deleteproject.cache.CacheDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.database.DatabaseDeleteHandler;
 import com.googlesource.gerrit.plugins.deleteproject.fs.DeleteTrashFolders;
@@ -35,9 +34,7 @@
 
   @Override
   protected void configure() {
-    bind(LifecycleListener.class)
-        .annotatedWith(UniqueAnnotations.create())
-        .to(DeleteLog.class);
+    bind(LifecycleListener.class).annotatedWith(UniqueAnnotations.create()).to(DeleteLog.class);
     bind(LifecycleListener.class)
         .annotatedWith(UniqueAnnotations.create())
         .to(DeleteTrashFolders.class);
@@ -51,14 +48,13 @@
     bind(DatabaseDeleteHandler.class);
     bind(FilesystemDeleteHandler.class);
     bind(ProjectConfigDeleteHandler.class);
-    install(new RestApiModule() {
-      @Override
-      protected void configure() {
-        delete(PROJECT_KIND)
-            .to(DeleteProject.class);
-        post(PROJECT_KIND, "delete")
-            .to(DeleteAction.class);
-      }
-    });
+    install(
+        new RestApiModule() {
+          @Override
+          protected void configure() {
+            delete(PROJECT_KIND).to(DeleteProject.class);
+            post(PROJECT_KIND, "delete").to(DeleteAction.class);
+          }
+        });
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/database/DatabaseDeleteHandler.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/database/DatabaseDeleteHandler.java
index d025cd6..26c8710 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/database/DatabaseDeleteHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/database/DatabaseDeleteHandler.java
@@ -14,22 +14,30 @@
 
 package com.googlesource.gerrit.plugins.deleteproject.database;
 
+import static java.util.Collections.singleton;
+
 import com.google.common.collect.Lists;
+import com.google.gerrit.extensions.registration.DynamicItem;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.reviewdb.server.ReviewDbUtil;
 import com.google.gerrit.server.StarredChangesUtil;
+import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.account.WatchConfig;
+import com.google.gerrit.server.account.WatchConfig.Accessor;
+import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
 import com.google.gerrit.server.change.AccountPatchReviewStore;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MergeOpRepoManager;
 import com.google.gerrit.server.git.SubmoduleOp;
 import com.google.gerrit.server.index.change.ChangeIndexer;
 import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.query.account.InternalAccountQuery;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.InternalChangeQuery;
 import com.google.gwtorm.jdbc.JdbcSchema;
@@ -37,27 +45,24 @@
 import com.google.gwtorm.server.ResultSet;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-
 import com.googlesource.gerrit.plugins.deleteproject.CannotDeleteProjectException;
-
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-
 public class DatabaseDeleteHandler {
-  private static final Logger log =
-      LoggerFactory.getLogger(DatabaseDeleteHandler.class);
+  private static final Logger log = LoggerFactory.getLogger(DatabaseDeleteHandler.class);
 
   private final ReviewDb db;
   private final Provider<InternalChangeQuery> queryProvider;
@@ -67,16 +72,23 @@
   private final StarredChangesUtil starredChangesUtil;
   private final DynamicItem<AccountPatchReviewStore> accountPatchReviewStore;
   private final ChangeIndexer indexer;
+  private final Provider<InternalAccountQuery> accountQueryProvider;
+  private final Provider<Accessor> watchConfig;
 
   @Inject
-  public DatabaseDeleteHandler(ReviewDb db,
+  public DatabaseDeleteHandler(
+      ReviewDb db,
       Provider<InternalChangeQuery> queryProvider,
       GitRepositoryManager repoManager,
       SubmoduleOp.Factory subOpFactory,
       Provider<MergeOpRepoManager> ormProvider,
       StarredChangesUtil starredChangesUtil,
       DynamicItem<AccountPatchReviewStore> accountPatchReviewStore,
-      ChangeIndexer indexer) {
+      ChangeIndexer indexer,
+      Provider<InternalAccountQuery> accountQueryProvider,
+      Provider<WatchConfig.Accessor> watchConfig) {
+    this.accountQueryProvider = accountQueryProvider;
+    this.watchConfig = watchConfig;
     this.db = ReviewDbUtil.unwrapDb(db);
     this.queryProvider = queryProvider;
     this.repoManager = repoManager;
@@ -91,8 +103,7 @@
     Collection<String> ret = Lists.newArrayList();
 
     // Warn against open changes
-    List<ChangeData> openChanges =
-        queryProvider.get().byProjectOpen(project.getNameKey());
+    List<ChangeData> openChanges = queryProvider.get().byProjectOpen(project.getNameKey());
     if (openChanges.iterator().hasNext()) {
       ret.add(project.getName() + " has open changes");
     }
@@ -122,8 +133,7 @@
     }
   }
 
-  private final void deleteChanges(List<ChangeData> changeData)
-      throws OrmException {
+  private final void deleteChanges(List<ChangeData> changeData) throws OrmException {
     for (ChangeData cd : changeData) {
       Change.Id id = cd.getId();
       ResultSet<PatchSet> patchSets = null;
@@ -147,53 +157,60 @@
       try {
         indexer.delete(id);
       } catch (IOException e) {
-        log.error(
-            String.format("Failed to delete change %s from index", id), e);
+        log.error(String.format("Failed to delete change %s from index", id), e);
       }
     }
   }
 
-  private final void deleteFromPatchSets(final ResultSet<PatchSet> patchSets)
-      throws OrmException {
+  private final void deleteFromPatchSets(final ResultSet<PatchSet> patchSets) throws OrmException {
     for (PatchSet patchSet : patchSets) {
       accountPatchReviewStore.get().clearReviewed(patchSet.getId());
       db.patchSets().delete(Collections.singleton(patchSet));
     }
   }
 
-  public void assertCanDelete(Project project)
-      throws CannotDeleteProjectException {
+  public void assertCanDelete(Project project) throws CannotDeleteProjectException {
 
     Project.NameKey proj = project.getNameKey();
     try (Repository repo = repoManager.openRepository(proj);
-         MergeOpRepoManager orm = ormProvider.get()) {
+        MergeOpRepoManager orm = ormProvider.get()) {
       Set<Branch.NameKey> branches = new HashSet<>();
-      for (Ref ref : repo.getRefDatabase().getRefs(
-          RefNames.REFS_HEADS).values()) {
+      for (Ref ref : repo.getRefDatabase().getRefs(RefNames.REFS_HEADS).values()) {
         branches.add(new Branch.NameKey(proj, ref.getName()));
       }
       SubmoduleOp sub = subOpFactory.create(branches, orm);
       for (Branch.NameKey b : branches) {
         if (!sub.superProjectSubscriptionsForSubmoduleBranch(b).isEmpty()) {
-          throw new CannotDeleteProjectException(
-              "Project is subscribed by other projects.");
+          throw new CannotDeleteProjectException("Project is subscribed by other projects.");
         }
       }
     } catch (RepositoryNotFoundException e) {
       // we're trying to delete the repository,
       // so this exception should not stop us
     } catch (IOException e) {
-      throw new CannotDeleteProjectException(
-          "Project is subscribed by other projects.");
+      throw new CannotDeleteProjectException("Project is subscribed by other projects.");
     }
   }
 
   public void atomicDelete(Project project) throws OrmException {
-    List<ChangeData> changes =
-        queryProvider.get().byProject(project.getNameKey());
+    List<ChangeData> changes = queryProvider.get().byProject(project.getNameKey());
     deleteChanges(changes);
 
-    db.accountProjectWatches().delete(
-        db.accountProjectWatches().byProject(project.getNameKey()));
+    for (AccountState a : accountQueryProvider.get().byWatchedProject(project.getNameKey())) {
+      Account.Id accountId = a.getAccount().getId();
+      for (ProjectWatchKey watchKey : a.getProjectWatches().keySet()) {
+        if (project.getNameKey().equals(watchKey.project())) {
+          try {
+            watchConfig.get().deleteProjectWatches(accountId, singleton(watchKey));
+          } catch (IOException | ConfigInvalidException e) {
+            log.error(
+                "Removing watch entry for user {} in project {} failed.",
+                a.getUserName(),
+                project.getName(),
+                e);
+          }
+        }
+      }
+    }
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java
index 5b89ec6..96f06cc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java
@@ -13,6 +13,13 @@
 // limitations under the License.
 package com.googlesource.gerrit.plugins.deleteproject.fs;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Sets;
+import com.google.gerrit.extensions.events.LifecycleListener;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.config.RepositoryConfig;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
 import java.io.IOException;
 import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
@@ -21,52 +28,39 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Set;
 import java.util.regex.Pattern;
-
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.RepositoryCache.FileKey;
 import org.eclipse.jgit.util.FS;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Sets;
-import com.google.gerrit.extensions.events.LifecycleListener;
-import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.config.RepositoryConfig;
-import com.google.gerrit.server.config.SitePaths;
-import com.google.inject.Inject;
-
 public class DeleteTrashFolders implements LifecycleListener {
   private static final Logger log = LoggerFactory.getLogger(DeleteTrashFolders.class);
 
   /**
-   * Search for name which ends with a dot, 13 digits and the string
-   * ".deleted". A folder 'f' is renamed to 'f.<currentTimeMillis>.deleted'.
-   * <currentTimeMillis> happens to be exactly 13 digits for commits created
-   * between 2002 (before git was born) and 2285.
+   * Search for name which ends with a dot, 13 digits and the string ".deleted". A folder 'f' is
+   * renamed to 'f.<currentTimeMillis>.deleted'. <currentTimeMillis> happens to be exactly 13 digits
+   * for commits created between 2002 (before git was born) and 2285.
    */
   private static final Pattern TRASH_1 = Pattern.compile(".*\\.\\d{13}.deleted");
 
   /**
-   * New trash folder name format. It adds % chars around the "deleted" string
-   * and keeps the ".git" extension.
+   * New trash folder name format. It adds % chars around the "deleted" string and keeps the ".git"
+   * extension.
    */
   private static final Pattern TRASH_2 = Pattern.compile(".*\\.\\d{13}.%deleted%.git");
 
   @VisibleForTesting
   static final boolean isTrashFolderName(String fName) {
-    return TRASH_1.matcher(fName).matches()
-        || TRASH_2.matcher(fName).matches();
+    return TRASH_1.matcher(fName).matches() || TRASH_2.matcher(fName).matches();
   }
 
   private Set<Path> repoFolders;
 
   @Inject
-  public DeleteTrashFolders(SitePaths site,
-      @GerritServerConfig Config cfg,
-      RepositoryConfig repositoryCfg) {
-    repoFolders = Sets.newHashSet(
-        site.resolve(cfg.getString("gerrit", null, "basePath")));
+  public DeleteTrashFolders(
+      SitePaths site, @GerritServerConfig Config cfg, RepositoryConfig repositoryCfg) {
+    repoFolders = Sets.newHashSet(site.resolve(cfg.getString("gerrit", null, "basePath")));
     repoFolders.addAll(repositoryCfg.getAllBasePaths());
   }
 
@@ -94,51 +88,51 @@
      * @throws IOException
      */
     private void recursiveDelete(Path file) throws IOException {
-      Files.walkFileTree(file, new SimpleFileVisitor<Path>() {
-          @Override
-          public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-              throws IOException {
-            Files.delete(file);
-            return FileVisitResult.CONTINUE;
-          }
-
-          @Override
-          public FileVisitResult postVisitDirectory(Path dir, IOException e)
-              throws IOException {
-            if (e != null) {
-              throw e;
+      Files.walkFileTree(
+          file,
+          new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                throws IOException {
+              Files.delete(file);
+              return FileVisitResult.CONTINUE;
             }
-            Files.delete(dir);
-            return FileVisitResult.CONTINUE;
-          }
-      });
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
+              if (e != null) {
+                throw e;
+              }
+              Files.delete(dir);
+              return FileVisitResult.CONTINUE;
+            }
+          });
     }
   }
 
-
-
   @Override
   public void start() {
-    new Thread(new Runnable() {
-      @Override
-      public void run() {
-        for (Path folder : repoFolders) {
-          if (Files.notExists(folder)) {
-            log.debug("Base path {} does not exist", folder);
-            continue;
-          }
-          try {
-            Files.walkFileTree(folder, new TrashFolderRemover());
-          } catch (IOException e) {
-            log.warn("Exception while trying to delete trash folders", e);
-          }
-        }
-      }
-    }, "DeleteTrashFolders").start();
+    new Thread(
+            new Runnable() {
+              @Override
+              public void run() {
+                for (Path folder : repoFolders) {
+                  if (Files.notExists(folder)) {
+                    log.debug("Base path {} does not exist", folder);
+                    continue;
+                  }
+                  try {
+                    Files.walkFileTree(folder, new TrashFolderRemover());
+                  } catch (IOException e) {
+                    log.warn("Exception while trying to delete trash folders", e);
+                  }
+                }
+              }
+            },
+            "DeleteTrashFolders")
+        .start();
   }
 
   @Override
-  public void stop() {
-  }
+  public void stop() {}
 }
-
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/FilesystemDeleteHandler.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/FilesystemDeleteHandler.java
index f9e45a6..8aac2c1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/FilesystemDeleteHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/FilesystemDeleteHandler.java
@@ -14,23 +14,6 @@
 
 package com.googlesource.gerrit.plugins.deleteproject.fs;
 
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.attribute.BasicFileAttributes;
-
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.RepositoryCache;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.api.changes.NotifyHandling;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
@@ -40,12 +23,25 @@
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.deleteproject.CannotDeleteProjectException;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class FilesystemDeleteHandler {
-  private static final Logger log = LoggerFactory
-      .getLogger(FilesystemDeleteHandler.class);
+  private static final Logger log = LoggerFactory.getLogger(FilesystemDeleteHandler.class);
 
   private final GitRepositoryManager repoManager;
   private final DynamicSet<ProjectDeletedListener> deletedListener;
@@ -53,7 +49,8 @@
   private final String pluginName;
 
   @Inject
-  public FilesystemDeleteHandler(GitRepositoryManager repoManager,
+  public FilesystemDeleteHandler(
+      GitRepositoryManager repoManager,
       DynamicSet<ProjectDeletedListener> deletedListener,
       PluginConfigFactory cfgFactory,
       @PluginName String pluginName) {
@@ -66,8 +63,7 @@
   public void delete(Project project, boolean preserveGitRepository)
       throws IOException, RepositoryNotFoundException {
     // Remove from the jgit cache
-    Repository repository =
-        repoManager.openRepository(project.getNameKey());
+    Repository repository = repoManager.openRepository(project.getNameKey());
     File repoFile = repository.getDirectory();
     cleanCache(repository);
     if (!preserveGitRepository) {
@@ -78,26 +74,26 @@
   public void assertCanDelete(ProjectResource rsrc, boolean preserveGitRepository)
       throws CannotDeleteProjectException {
     if (!preserveGitRepository
-        && !cfgFactory.getFromGerritConfig(pluginName).getBoolean(
-            "allowDeletionOfReposWithTags", true)) {
+        && !cfgFactory
+            .getFromGerritConfig(pluginName)
+            .getBoolean("allowDeletionOfReposWithTags", true)) {
       assertHasNoTags(rsrc);
     }
   }
 
-  private void assertHasNoTags(ProjectResource rsrc)
-      throws CannotDeleteProjectException {
+  private void assertHasNoTags(ProjectResource rsrc) throws CannotDeleteProjectException {
     try (Repository repo = repoManager.openRepository(rsrc.getNameKey())) {
       if (!repo.getRefDatabase().getRefs(Constants.R_TAGS).isEmpty()) {
-        throw new CannotDeleteProjectException(String.format(
-            "Project %s has tags", rsrc.getName()));
+        throw new CannotDeleteProjectException(
+            String.format("Project %s has tags", rsrc.getName()));
       }
     } catch (IOException e) {
       throw new CannotDeleteProjectException(e);
     }
   }
 
-  private void deleteGitRepository(final Project.NameKey project,
-      final File repoFile) throws IOException {
+  private void deleteGitRepository(final Project.NameKey project, final File repoFile)
+      throws IOException {
     // Delete the repository from disk
     Path basePath = getBasePath(repoFile.toPath(), project);
     Path trash = moveToTrash(repoFile.toPath(), basePath, project);
@@ -121,17 +117,18 @@
     }
 
     // Send an event that the repository was deleted
-    ProjectDeletedListener.Event event = new ProjectDeletedListener.Event() {
-      @Override
-      public String getProjectName() {
-        return project.get();
-      }
+    ProjectDeletedListener.Event event =
+        new ProjectDeletedListener.Event() {
+          @Override
+          public String getProjectName() {
+            return project.get();
+          }
 
-      @Override
-      public NotifyHandling getNotify() {
-        return NotifyHandling.NONE;
-      }
-    };
+          @Override
+          public NotifyHandling getNotify() {
+            return NotifyHandling.NONE;
+          }
+        };
     for (ProjectDeletedListener l : deletedListener) {
       try {
         l.onProjectDeleted(event);
@@ -143,14 +140,14 @@
 
   private Path getBasePath(Path repo, Project.NameKey project) {
     Path projectPath = Paths.get(project.get());
-    return repo.getRoot().resolve(
-        repo.subpath(0, repo.getNameCount() - projectPath.getNameCount()));
+    return repo.getRoot()
+        .resolve(repo.subpath(0, repo.getNameCount() - projectPath.getNameCount()));
   }
 
   private Path moveToTrash(Path directory, Path basePath, Project.NameKey nameKey)
       throws IOException {
-    Path trashRepo = basePath.resolve(nameKey.get() + "."
-        + System.currentTimeMillis() + ".%deleted%.git");
+    Path trashRepo =
+        basePath.resolve(nameKey.get() + "." + System.currentTimeMillis() + ".%deleted%.git");
     return Files.move(directory, trashRepo, StandardCopyOption.ATOMIC_MOVE);
   }
 
@@ -165,31 +162,31 @@
    * @throws IOException
    */
   private void recursiveDelete(Path file) throws IOException {
-    Files.walkFileTree(file, new SimpleFileVisitor<Path>() {
-      @Override
-      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-          throws IOException {
-        Files.delete(file);
-        return FileVisitResult.CONTINUE;
-      }
+    Files.walkFileTree(
+        file,
+        new SimpleFileVisitor<Path>() {
+          @Override
+          public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+              throws IOException {
+            Files.delete(file);
+            return FileVisitResult.CONTINUE;
+          }
 
-      @Override
-      public FileVisitResult postVisitDirectory(Path dir, IOException e)
-          throws IOException {
-        if (e != null) {
-          throw e;
-        }
-        Files.delete(dir);
-        return FileVisitResult.CONTINUE;
-      }
-    });
+          @Override
+          public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
+            if (e != null) {
+              throw e;
+            }
+            Files.delete(dir);
+            return FileVisitResult.CONTINUE;
+          }
+        });
   }
 
   /**
-   * Recursively delete the specified file and its parent files until we hit the
-   * file {@code Until} or the parent file is populated. This is used when we
-   * have a tree structure such as a/b/c/d.git and a/b/e.git - if we delete
-   * a/b/c/d.git, we no longer need a/b/c/.
+   * Recursively delete the specified file and its parent files until we hit the file {@code Until}
+   * or the parent file is populated. This is used when we have a tree structure such as a/b/c/d.git
+   * and a/b/e.git - if we delete a/b/c/d.git, we no longer need a/b/c/.
    */
   private void recursiveDeleteParent(File file, File until) throws IOException {
     if (file.equals(until)) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/projectconfig/ProjectConfigDeleteHandler.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/projectconfig/ProjectConfigDeleteHandler.java
index 033a395..21038e2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/projectconfig/ProjectConfigDeleteHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/projectconfig/ProjectConfigDeleteHandler.java
@@ -27,7 +27,6 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.deleteproject.CannotDeleteProjectException;
-
 import java.util.List;
 
 public class ProjectConfigDeleteHandler {
@@ -38,43 +37,43 @@
   private final Provider<ListChildProjects> listChildProjectsProvider;
 
   @Inject
-  public ProjectConfigDeleteHandler(SitePaths site,
+  public ProjectConfigDeleteHandler(
+      SitePaths site,
       AllProjectsNameProvider allProjectsNameProvider,
       Provider<ListChildProjects> listChildProjectsProvider) {
     this.site = site;
     this.allProjectsName = allProjectsNameProvider.get();
     this.listChildProjectsProvider = listChildProjectsProvider;
- }
+  }
 
-  public void assertCanDelete(ProjectResource rsrc)
-      throws CannotDeleteProjectException {
+  public void assertCanDelete(ProjectResource rsrc) throws CannotDeleteProjectException {
     assertIsNotAllProjects(rsrc);
     assertHasNoChildProjects(rsrc);
   }
 
-  private void assertIsNotAllProjects(ProjectResource rsrc)
-      throws CannotDeleteProjectException {
+  private void assertIsNotAllProjects(ProjectResource rsrc) throws CannotDeleteProjectException {
     Project project = rsrc.getControl().getProject();
     if (project.getNameKey().equals(allProjectsName)) {
-      throw new CannotDeleteProjectException("Perhaps you meant to rm -fR "
-          + site.site_path);
+      throw new CannotDeleteProjectException("Perhaps you meant to rm -fR " + site.site_path);
     }
   }
 
-  private void assertHasNoChildProjects(ProjectResource rsrc)
-      throws CannotDeleteProjectException {
+  private void assertHasNoChildProjects(ProjectResource rsrc) throws CannotDeleteProjectException {
     List<ProjectInfo> children = listChildProjectsProvider.get().apply(rsrc);
     if (!children.isEmpty()) {
-      String childrenString = Joiner.on(", ").join(Iterables.transform(
-          children,
-          new Function<ProjectInfo, String>() {
-            @Override
-            public String apply(ProjectInfo info) {
-              return info.name;
-            }
-          }));
-      throw new CannotDeleteProjectException("Cannot delete project because "
-          + "it has children: " + childrenString);
+      String childrenString =
+          Joiner.on(", ")
+              .join(
+                  Iterables.transform(
+                      children,
+                      new Function<ProjectInfo, String>() {
+                        @Override
+                        public String apply(ProjectInfo info) {
+                          return info.name;
+                        }
+                      }));
+      throw new CannotDeleteProjectException(
+          "Cannot delete project because it has children: " + childrenString);
     }
   }
 }
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index 0e0065d..0a6767b 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -1,63 +1,85 @@
 Build
 =====
 
-This plugin is built with Buck.
+This plugin is built with Bazel and two build modes are supported:
 
-Two build modes are supported: Standalone and in Gerrit tree. Standalone
-build mode is recommended, as this mode doesn't require local Gerrit
+* Standalone
+* In Gerrit tree.
+
+Standalone build mode is recommended, as this mode doesn't require local Gerrit
 tree to exist.
 
-Build standalone
-----------------
-
-Clone bucklets library:
-
-```
-  git clone https://gerrit.googlesource.com/bucklets
-
-```
-and link it to delete-project directory:
-
-```
-  cd delete-project && ln -s ../bucklets .
-```
-
-Add link to the .buckversion file:
-
-```
-  cd delete_project && ln -s bucklets/buckversion .buckversion
-```
+## Build standalone
 
 To build the plugin, issue the following command:
 
-
 ```
-  buck build plugin
+  bazel build @PLUGIN@
 ```
 
 The output is created in
 
 ```
-  buck-out/gen/delete-project/delete-project.jar
+  bazel-genfiles/@PLUGIN@.jar
 ```
 
-Build in Gerrit tree
---------------------
+To package the plugin sources run:
+
+```
+  bazel build lib@PLUGIN@__plugin-src.jar
+```
+
+The output is created in:
+
+```
+  bazel-bin/lib@PLUGIN@__plugin-src.jar
+```
+
+To execute the tests run:
+
+```
+  bazel test //...
+```
+
+This project can be imported into the Eclipse IDE. Execute:
+
+```
+  ./tools/eclipse/project.sh
+```
+
+to generate the required files and then import the project.
+
+
+## Build in Gerrit tree
 
 Clone or link this plugin to the plugins directory of Gerrit's source
 tree, and issue the command:
 
 ```
-  buck build plugins/delete-project:delete-project
+  bazel build plugins/@PLUGIN@
 ```
 
 The output is created in
 
 ```
-  buck-out/gen/plugins/delete-project/delete-project.jar
+  bazel-genfiles/plugins/@PLUGIN@/@PLUGIN@.jar
 ```
 
-This project can be imported into the Eclipse IDE:
+To execute the tests run:
+
+```
+  bazel test plugins/@PLUGIN@:delete_project_tests
+```
+
+or filtering using the comma separated tags:
+
+````
+  bazel test --test_tag_filters=@PLUGIN@ //...
+````
+
+This project can be imported into the Eclipse IDE.
+Add the plugin name to the `CUSTOM_PLUGINS` set in
+Gerrit core in `tools/bzl/plugins.bzl`, and execute:
 
 ```
   ./tools/eclipse/project.py
diff --git a/tools/bazel.rc b/tools/bazel.rc
new file mode 100644
index 0000000..4ed16cf
--- /dev/null
+++ b/tools/bazel.rc
@@ -0,0 +1,2 @@
+build --workspace_status_command=./tools/workspace-status.sh
+test --build_tests_only
diff --git a/tools/bzl/BUILD b/tools/bzl/BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/bzl/BUILD
diff --git a/tools/bzl/classpath.bzl b/tools/bzl/classpath.bzl
new file mode 100644
index 0000000..dfcbe9c
--- /dev/null
+++ b/tools/bzl/classpath.bzl
@@ -0,0 +1,2 @@
+load("@com_googlesource_gerrit_bazlets//tools:classpath.bzl",
+     "classpath_collector")
diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl
new file mode 100644
index 0000000..3af7e58
--- /dev/null
+++ b/tools/bzl/junit.bzl
@@ -0,0 +1,4 @@
+load(
+    "@com_googlesource_gerrit_bazlets//tools:junit.bzl",
+    "junit_tests",
+)
diff --git a/tools/bzl/plugin.bzl b/tools/bzl/plugin.bzl
new file mode 100644
index 0000000..a2e438f
--- /dev/null
+++ b/tools/bzl/plugin.bzl
@@ -0,0 +1,6 @@
+load(
+    "@com_googlesource_gerrit_bazlets//:gerrit_plugin.bzl",
+    "gerrit_plugin",
+    "PLUGIN_DEPS",
+    "PLUGIN_TEST_DEPS",
+)
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
new file mode 100644
index 0000000..0ea2557
--- /dev/null
+++ b/tools/eclipse/BUILD
@@ -0,0 +1,17 @@
+load("//tools/bzl:classpath.bzl", "classpath_collector")
+
+java_library(
+    name = "classpath",
+    testonly = 1,
+    runtime_deps = [
+        "//:delete-project__plugin_test_deps",
+    ],
+)
+
+classpath_collector(
+    name = "main_classpath_collect",
+    testonly = 1,
+    deps = [
+        "//:delete-project__plugin_test_deps",
+    ],
+)
diff --git a/tools/eclipse/project.sh b/tools/eclipse/project.sh
new file mode 100755
index 0000000..55713c7
--- /dev/null
+++ b/tools/eclipse/project.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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.
+
+`bazel query @com_googlesource_gerrit_bazlets//tools/eclipse:project --output location | sed s/BUILD:.*//`project.py -n delete-project -r .
diff --git a/tools/workspace-status.sh b/tools/workspace-status.sh
new file mode 100755
index 0000000..3185cae
--- /dev/null
+++ b/tools/workspace-status.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# This script will be run by bazel when the build process starts to
+# generate key-value information that represents the status of the
+# workspace. The output should be like
+#
+# KEY1 VALUE1
+# KEY2 VALUE2
+#
+# If the script exits with non-zero code, it's considered as a failure
+# and the output will be discarded.
+
+function rev() {
+  cd $1; git describe --always --match "v[0-9].*" --dirty
+}
+
+echo STABLE_BUILD_DELETE-PROJECT_LABEL $(rev .)