Merge branch 'stable-2.14'

* stable-2.14:
  Replace additional anonymous classes with lambda expressions
  Replace anonymous classes with lambda expressions
  Remove redundant type argument
  Replace anonymous class with list method
  Use multi catch
  Change project compliance to Java 8
  Remove Buck build
  Add standalone bazel build
  Clean up .gitignore
  Guard against NPE while unboxing possible null Boolean

Change-Id: Icd3e79df864f79ba8ed3c10f48b628f20edad8bb
diff --git a/.gitignore b/.gitignore
index 499784b..4c0afce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
 /.classpath
+/.primary_build_tool
 /.project
-/.settings/org.maven.ide.eclipse.prefs
-/.settings/org.eclipse.m2e.core.prefs
+/.settings
+/bazel-*
+/eclipse-out
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 2a585e4..602b029 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -4,8 +4,8 @@
 org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
 org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
 org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=ignore
 org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
 org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
@@ -85,7 +85,7 @@
 org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
 org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..4c89bfa
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,33 @@
+workspace(name = "importer")
+
+load("//:bazlets.bzl", "load_bazlets")
+
+load_bazlets(
+    commit = "b7514d03a7798905ff1513295b46620e57b8f386",
+    # 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()
+
+load(
+    "@com_googlesource_gerrit_bazlets//:gerrit_gwt.bzl",
+    "gerrit_gwt",
+)
+
+gerrit_gwt()
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/src/main/java/com/googlesource/gerrit/plugins/importer/HttpSession.java b/src/main/java/com/googlesource/gerrit/plugins/importer/HttpSession.java
index 531d176..af7af86 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/HttpSession.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/HttpSession.java
@@ -67,9 +67,7 @@
             new TrustManager[] {new DummyX509TrustManager()};
         context = SSLContext.getInstance("TLS");
         context.init(null, trustAllCerts, null);
-      } catch (KeyManagementException e) {
-        throw new IOException(e.getMessage());
-      } catch (NoSuchAlgorithmException e) {
+      } catch (KeyManagementException | NoSuchAlgorithmException e) {
         throw new IOException(e.getMessage());
       }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
index 1279b56..88df701 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
@@ -126,7 +126,7 @@
     validate(input, groupInfo);
     createGroup(input, groupInfo);
 
-    return Response.<String> ok("OK");
+    return Response.ok("OK");
   }
 
   private void validate(Input input, GroupInfo groupInfo)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
index 5f12110..ec1062c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
@@ -197,7 +197,7 @@
                 c.side == Side.PARENT ? (short) 0 : (short) 1,
                 c.message,
                 serverId,
-                c.unresolved);
+                c.unresolved == null ? false : c.unresolved);
       } else if (parent != null) {
         e.parentUuid = parent;
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
index 7272cd5..c2d20cf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
@@ -40,8 +40,6 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 class ReplayRevisionsStep {
@@ -161,12 +159,7 @@
   }
 
   private static void sortRevisionInfoByNumber(List<RevisionInfo> list) {
-    Collections.sort(list, new Comparator<RevisionInfo>() {
-      @Override
-      public int compare(RevisionInfo a, RevisionInfo b) {
-        return a._number - b._number;
-      }
-    });
+    list.sort((a, b) -> a._number - b._number);
   }
 
   private void updateRef(Repository repo, PatchSet ps)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/CompleteImportDialog.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/CompleteImportDialog.java
index df68a6e..e0339fa 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/CompleteImportDialog.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/CompleteImportDialog.java
@@ -17,8 +17,6 @@
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.NoContent;
 import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.DialogBox;
@@ -43,59 +41,46 @@
 
     completeButton = new Button();
     completeButton.setText("Complete");
-    completeButton.addClickHandler(new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
-        hide();
+    completeButton.addClickHandler(event -> {
+      hide();
 
-        new RestApi("config").id("server")
-            .view(Plugin.get().getName(), "projects").id(project)
-            .delete(new AsyncCallback<NoContent>() {
-              @Override
-              public void onSuccess(NoContent result) {
-                Plugin.get().go("/x/" + Plugin.get().getName() + "/list");
+      new RestApi("config").id("server")
+          .view(Plugin.get().getName(), "projects").id(project)
+          .delete(new AsyncCallback<NoContent>() {
+            @Override
+            public void onSuccess(NoContent result) {
+              Plugin.get().go("/x/" + Plugin.get().getName() + "/list");
 
-                final DialogBox successDialog = new DialogBox();
-                successDialog.setText("Project "
-                    + (copy ? "Copy" : "Import") + " Completed");
-                successDialog.setAnimationEnabled(true);
+              final DialogBox successDialog = new DialogBox();
+              successDialog.setText("Project "
+                  + (copy ? "Copy" : "Import") + " Completed");
+              successDialog.setAnimationEnabled(true);
 
-                Panel p = new VerticalPanel();
-                p.setStyleName("importer-message-panel");
-                p.add(new Label("The project "
-                  + (copy ? "copy" : "import") + " was completed."));
-                Button okButton = new Button("OK");
-                okButton.addClickHandler(new ClickHandler() {
-                  @Override
-                  public void onClick(ClickEvent event) {
-                    successDialog.hide();
-                  }
-                });
+              Panel p = new VerticalPanel();
+              p.setStyleName("importer-message-panel");
+              p.add(new Label("The project "
+                + (copy ? "copy" : "import") + " was completed."));
+              Button okButton = new Button("OK");
+              okButton.addClickHandler(event -> successDialog.hide());
 
-                p.add(okButton);
-                successDialog.add(p);
+              p.add(okButton);
+              successDialog.add(p);
 
-                successDialog.center();
-                successDialog.show();
-              }
+              successDialog.center();
+              successDialog.show();
+            }
 
-              @Override
-              public void onFailure(Throwable caught) {
-              }
-            });
-      }
+            @Override
+            public void onFailure(Throwable caught) {
+            }
+          });
     });
     buttons.add(completeButton);
 
     cancelButton = new Button();
     cancelButton.addStyleName("importer-cancel-button");
     cancelButton.setText("Cancel");
-    cancelButton.addClickHandler(new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
-        hide();
-      }
-    });
+    cancelButton.addClickHandler(event -> hide());
     buttons.add(cancelButton);
 
     FlowPanel center = new FlowPanel();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportActionPanel.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportActionPanel.java
index 212e5cc..2dc3e57 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportActionPanel.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportActionPanel.java
@@ -14,7 +14,6 @@
 
 package com.googlesource.gerrit.plugins.importer.client;
 
-import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.FlowPanel;
@@ -23,17 +22,11 @@
 
   ImportActionPanel(final String project, final boolean copy) {
     setStyleName("importer-action-panel");
-    add(new Button("Resume...", new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
-        (new ResumeImportDialog(project, copy)).center();
-      }
-    }));
-    add(new Button("Complete...", new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
-        (new CompleteImportDialog(project, copy)).center();
-      }
-    }));
+    add(new Button("Resume...",
+        (ClickHandler) event -> (new ResumeImportDialog(project, copy))
+            .center()));
+    add(new Button("Complete...",
+        (ClickHandler) event -> (new CompleteImportDialog(project, copy))
+            .center()));
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportGroupScreen.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportGroupScreen.java
index 6bafec2..a4e9cea 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportGroupScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportGroupScreen.java
@@ -23,8 +23,6 @@
 import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gerrit.plugin.client.screen.Screen;
 import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.CheckBox;
@@ -66,12 +64,7 @@
 
     Button importButton = new Button("Import");
     importButton.addStyleName("importer-importButton");
-    importButton.addClickHandler(new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
-        doImport();
-      }
-    });
+    importButton.addClickHandler(event -> doImport());
     buttons.add(importButton);
     importButton.setEnabled(false);
     new OnEditEnabler(importButton, fromTxt);
@@ -105,12 +98,7 @@
         p.setStyleName("importer-message-panel");
         p.add(new Label("The group was imported."));
         Button okButton = new Button("OK");
-        okButton.addClickHandler(new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            successDialog.hide();
-          }
-        });
+        okButton.addClickHandler(event -> successDialog.hide());
 
         p.add(okButton);
         successDialog.add(p);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
index 7601de4..206f12d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
@@ -21,8 +21,6 @@
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.DialogBox;
@@ -65,12 +63,7 @@
 
     Button importButton = new Button("Import");
     importButton.addStyleName("importer-importButton");
-    importButton.addClickHandler(new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
-        doImport();
-      }
-    });
+    importButton.addClickHandler(event -> doImport());
     buttons.add(importButton);
     importButton.setEnabled(false);
     new OnEditEnabler(importButton, fromTxt);
@@ -107,12 +100,7 @@
         p.add(new Label("The project was imported."));
         p.add(new Label("Created Changes: " + result.numChangesCreated()));
         Button okButton = new Button("OK");
-        okButton.addClickHandler(new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            successDialog.hide();
-          }
-        });
+        okButton.addClickHandler(event -> successDialog.hide());
 
         p.add(okButton);
         successDialog.add(p);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/InputUtil.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/InputUtil.java
index 6edfe44..1f9d55d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/InputUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/InputUtil.java
@@ -15,9 +15,6 @@
 package com.googlesource.gerrit.plugins.importer.client;
 
 import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.CheckBox;
 import com.google.gwt.user.client.ui.HorizontalPanel;
@@ -72,12 +69,7 @@
         }
       };
     }
-    tb.addKeyPressHandler(new KeyPressHandler() {
-      @Override
-      public void onKeyPress(KeyPressEvent event) {
-        event.stopPropagation();
-      }
-    });
+    tb.addKeyPressHandler(event -> event.stopPropagation());
     tb.sinkEvents(Event.ONPASTE);
     tb.setVisibleLength(40);
     return tb;
@@ -85,12 +77,9 @@
 
   private static void handlePaste(final TextBox tb, Event event) {
     if (event.getTypeInt() == Event.ONPASTE) {
-      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-        @Override
-        public void execute() {
-          if (getValue(tb).length() != 0) {
-            tb.setEnabled(true);
-          }
+      Scheduler.get().scheduleDeferred(() -> {
+        if (getValue(tb).length() != 0) {
+          tb.setEnabled(true);
         }
       });
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/OnEditEnabler.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/OnEditEnabler.java
index 81e9fbb..d632652 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/OnEditEnabler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/OnEditEnabler.java
@@ -15,11 +15,8 @@
 package com.googlesource.gerrit.plugins.importer.client;
 
 import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.event.dom.client.ChangeEvent;
 import com.google.gwt.event.dom.client.ChangeHandler;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
 import com.google.gwt.event.dom.client.KeyDownEvent;
 import com.google.gwt.event.dom.client.KeyDownHandler;
 import com.google.gwt.event.dom.client.KeyPressEvent;
@@ -88,12 +85,7 @@
     // up to date with non-user updates of the text (calls to
     // setText()...) and also up to date with user changes which
     // occured after enabling "widget".
-    tb.addFocusHandler(new FocusHandler() {
-        @Override
-        public void onFocus(FocusEvent event) {
-          strings.put(tb, tb.getText().trim());
-        }
-      });
+    tb.addFocusHandler(event -> strings.put(tb, tb.getText().trim()));
 
     // CTRL-V Pastes in Chrome seem only detectable via BrowserEvents or
     // KeyDownEvents, the latter is better.
@@ -144,12 +136,9 @@
         ! ((FocusWidget) e.getSource()).isEnabled() ) {
       if (e.getSource() instanceof ValueBoxBase) {
         final TextBoxBase box = ((TextBoxBase) e.getSource());
-        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-          @Override
-          public void execute() {
-            if (box.getValue().trim().equals(originalValue)) {
-              widget.setEnabled(false);
-            }
+        Scheduler.get().scheduleDeferred(() -> {
+          if (box.getValue().trim().equals(originalValue)) {
+            widget.setEnabled(false);
           }
         });
       }
@@ -168,16 +157,13 @@
 
   private void onTextBoxBase(final TextBoxBase tb) {
     // The text appears to not get updated until the handlers complete.
-    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-      @Override
-      public void execute() {
-        String orig = strings.get(tb);
-        if (orig == null) {
-          orig = "";
-        }
-        if (! orig.equals(tb.getText().trim())) {
-          widget.setEnabled(true);
-        }
+    Scheduler.get().scheduleDeferred(() -> {
+      String orig = strings.get(tb);
+      if (orig == null) {
+        orig = "";
+      }
+      if (! orig.equals(tb.getText().trim())) {
+        widget.setEnabled(true);
       }
     });
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
index 5b25ec4..b56f46d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
@@ -21,8 +21,6 @@
 
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.CheckBox;
@@ -41,7 +39,7 @@
   private final Button resumeButton;
   private TextBox userTxt;
   private TextBox passTxt;
-  private final CheckBox forceCheckBox;
+  private CheckBox forceCheckBox;
 
   public ResumeImportDialog(final String project, final boolean copy) {
     super(/* auto hide */false, /* modal */true);
@@ -52,9 +50,7 @@
 
     resumeButton = new Button();
     resumeButton.setText("Resume");
-    resumeButton.addClickHandler(new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
+    resumeButton.addClickHandler(event -> {
         hide();
 
         RestApi restApi;
@@ -86,12 +82,7 @@
                 p.add(new Label("Created Changes: " + result.numChangesCreated()));
                 p.add(new Label("Updated Changes: " + result.numChangesUpdated()));
                 Button okButton = new Button("OK");
-                okButton.addClickHandler(new ClickHandler() {
-                  @Override
-                  public void onClick(ClickEvent event) {
-                    successDialog.hide();
-                  }
-                });
+                okButton.addClickHandler(event -> successDialog.hide());
 
                 p.add(okButton);
                 successDialog.add(p);
@@ -104,19 +95,13 @@
               public void onFailure(Throwable caught) {
               }
             });
-      }
     });
     buttons.add(resumeButton);
 
     cancelButton = new Button();
     cancelButton.addStyleName("importer-cancel-button");
     cancelButton.setText("Cancel");
-    cancelButton.addClickHandler(new ClickHandler() {
-      @Override
-      public void onClick(ClickEvent event) {
-        hide();
-      }
-    });
+    cancelButton.addClickHandler(event -> hide());
     buttons.add(cancelButton);
 
     FlowPanel center = new FlowPanel();
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index 3c49502..64d5367 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -1,18 +1,58 @@
 Build
 =====
 
-This plugin can be built with Bazel.
+This plugin is built with Bazel and two build modes are supported:
 
-Clone (or link) this plugin to the `plugins` directory of Gerrit's source tree.
+* Standalone
+* In Gerrit tree.
 
-Then issue
+Standalone build mode is recommended, as this mode doesn't require local Gerrit
+tree to exist.
+
+## Build standalone
+
+To build the plugin, issue the following command:
+
+```
+  bazel build @PLUGIN@
+```
+
+The output is created in
+
+```
+  bazel-genfiles/@PLUGIN@.jar
+```
+
+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
+```
+
+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:
 
 ```
   bazel build plugins/@PLUGIN@
 ```
 
-in the root of Gerrit's source tree to build
-
 The output is created in
 
 ```
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/plugin.bzl b/tools/bzl/plugin.bzl
new file mode 100644
index 0000000..74d4ce1
--- /dev/null
+++ b/tools/bzl/plugin.bzl
@@ -0,0 +1,6 @@
+load(
+    "@com_googlesource_gerrit_bazlets//:gerrit_plugin.bzl",
+    "gerrit_plugin",
+    "PLUGIN_DEPS",
+    "GWT_PLUGIN_DEPS",
+)
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
new file mode 100644
index 0000000..9b749e1
--- /dev/null
+++ b/tools/eclipse/BUILD
@@ -0,0 +1,13 @@
+load(
+    "//tools/bzl:plugin.bzl",
+    "PLUGIN_DEPS",
+    "GWT_PLUGIN_DEPS",
+)
+load("//tools/bzl:classpath.bzl", "classpath_collector")
+
+classpath_collector(
+    name = "main_classpath_collect",
+    deps = PLUGIN_DEPS + GWT_PLUGIN_DEPS + [
+        "//:importer__plugin",
+    ],
+)
diff --git a/tools/eclipse/project.sh b/tools/eclipse/project.sh
new file mode 100755
index 0000000..2d40079
--- /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 importer -r .
diff --git a/tools/workspace-status.sh b/tools/workspace-status.sh
new file mode 100755
index 0000000..25fd73a
--- /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_IMPORTER_LABEL "$(rev .)"