Merge branch 'stable-2.13' into stable-2.14

* stable-2.13:
  PropertyExtractor: Add null check for event.submitter

Change-Id: I3a443ba01fac120258d3599b5b73e4257a503028
diff --git a/.gitignore b/.gitignore
index defad4b..dc4fc0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,5 @@
 .idea
-target/
 .classpath
 .project
 /.settings
-/hooks-its/.settings/org.maven.ide.eclipse.prefs
-/hooks-its/.settings/org.eclipse.m2e.core.prefs
-
+/bazel-*
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 258f774..60fc3bb 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -7,9 +7,9 @@
 org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -97,7 +97,7 @@
 org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
 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/BUCK b/BUCK
deleted file mode 100644
index a93fedd..0000000
--- a/BUCK
+++ /dev/null
@@ -1,41 +0,0 @@
-# This plugin currently does not support a standalone build, as a
-# standalone build was deemed too much maintenance overhead in its
-# present (2015-09-20) form.
-#
-# Once the standalone build does no longer come with a maintenance
-# overhead, a first shot at the standalone build for this plugin can
-# be found at:
-#
-#   https://gerrit-review.googlesource.com/#/c/70896/
-#
-
-include_defs('//bucklets/gerrit_plugin.bucklet')
-
-gerrit_plugin(
-  name = 'its-base',
-  srcs = glob(['src/main/java/**/*.java']),
-  resources = glob(['src/main/resources/**/*']),
-)
-
-TEST_UTIL_SRC = glob(['src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/**/*.java'])
-
-java_library(
-  name = 'its-base_tests-utils',
-  srcs = TEST_UTIL_SRC,
-  deps = GERRIT_PLUGIN_API + GERRIT_TESTS,
-  visibility = ['PUBLIC'],
-)
-
-java_test(
-  name = 'its-base_tests',
-  srcs = glob(
-    ['src/test/java/**/*.java'],
-    excludes = TEST_UTIL_SRC
-  ),
-  labels = ['its-base'],
-  source_under_test = [':its-base__plugin'],
-  deps = GERRIT_PLUGIN_API + GERRIT_TESTS + [
-    ':its-base__plugin',
-    ':its-base_tests-utils',
-  ],
-)
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..3852f4f
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,46 @@
+load("//tools/bzl:junit.bzl", "junit_tests")
+load(
+    "//tools/bzl:plugin.bzl",
+    "gerrit_plugin",
+    "PLUGIN_DEPS",
+    "PLUGIN_TEST_DEPS",
+)
+
+gerrit_plugin(
+    name = "its-base",
+    srcs = glob(["src/main/java/**/*.java"]),
+    resources = glob(["src/main/resources/**/*"]),
+)
+
+TEST_UTIL_SRC = glob(["src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/**/*.java"])
+
+java_library(
+    name = "its-base_tests-utils",
+    testonly = 1,
+    srcs = TEST_UTIL_SRC,
+    visibility = ["//visibility:public"],
+    deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS,
+)
+
+junit_tests(
+    name = "its_base_tests",
+    testonly = 1,
+    srcs = glob(
+        ["src/test/java/**/*.java"],
+        exclude = TEST_UTIL_SRC,
+    ),
+    tags = ["its-base"],
+    deps = [
+        "its-base__plugin_test_deps",
+    ],
+)
+
+java_library(
+    name = "its-base__plugin_test_deps",
+    testonly = 1,
+    visibility = ["//visibility:public"],
+    exports = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
+        ":its-base__plugin",
+        ":its-base_tests-utils",
+    ],
+)
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..145f06b
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,26 @@
+workspace(name = "its_base")
+
+load("//:bazlets.bzl", "load_bazlets")
+
+load_bazlets(
+    commit = "3dbcd76602dd93fddb9deae4cacd1699164a19e9",
+    # local_path = "/home/<user>/projects/bazlets",
+)
+
+# Snapshot Plugin API
+#load(
+#    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
+#    "gerrit_api_maven_local",
+#)
+
+# Release Plugin API
+load(
+    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
+    "gerrit_api",
+)
+
+# Load release Plugin API
+gerrit_api()
+
+# Load snapshot Plugin API
+# gerrit_api_maven_local()
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/its/base/ItsHookModule.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/ItsHookModule.java
index e2fff3f..91b26a0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/ItsHookModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/ItsHookModule.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// 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.
@@ -22,7 +22,6 @@
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.config.ProjectConfigEntry;
 import com.google.gerrit.server.git.validators.CommitValidationListener;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsConfig;
 import com.googlesource.gerrit.plugins.its.base.its.ItsHookEnabledConfigEntry;
 import com.googlesource.gerrit.plugins.its.base.validation.ItsValidateComment;
@@ -32,6 +31,7 @@
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
 import com.googlesource.gerrit.plugins.its.base.workflow.Rule;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddComment;
+import com.googlesource.gerrit.plugins.its.base.workflow.action.AddSoyComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddStandardComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddVelocityComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.LogEvent;
@@ -41,8 +41,7 @@
   private final String pluginName;
   private final PluginConfigFactory pluginCfgFactory;
 
-  public ItsHookModule(@PluginName String pluginName,
-      PluginConfigFactory pluginCfgFactory) {
+  public ItsHookModule(@PluginName String pluginName, PluginConfigFactory pluginCfgFactory) {
     this.pluginName = pluginName;
     this.pluginCfgFactory = pluginCfgFactory;
   }
@@ -53,15 +52,14 @@
         .annotatedWith(Exports.named("enabled"))
         .toInstance(new ItsHookEnabledConfigEntry(pluginName, pluginCfgFactory));
     bind(ItsConfig.class);
-    DynamicSet.bind(binder(), CommitValidationListener.class).to(
-        ItsValidateComment.class);
-    DynamicSet.bind(binder(), EventListener.class).to(
-        ActionController.class);
+    DynamicSet.bind(binder(), CommitValidationListener.class).to(ItsValidateComment.class);
+    DynamicSet.bind(binder(), EventListener.class).to(ActionController.class);
     factory(ActionRequest.Factory.class);
     factory(Property.Factory.class);
     factory(Condition.Factory.class);
     factory(Rule.Factory.class);
     factory(AddComment.Factory.class);
+    factory(AddSoyComment.Factory.class);
     factory(AddStandardComment.Factory.class);
     factory(AddVelocityComment.Factory.class);
     factory(LogEvent.Factory.class);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/InitIts.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/InitIts.java
index 1867a10..1cd2b74 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/InitIts.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/InitIts.java
@@ -21,22 +21,24 @@
 import com.google.gerrit.pgm.init.api.ConsoleUI;
 import com.google.gerrit.pgm.init.api.InitStep;
 import com.google.gerrit.pgm.init.api.Section;
-
+import java.io.IOException;
+import java.util.EnumSet;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
 
-import java.io.IOException;
-
 public class InitIts implements InitStep {
 
-  public static String COMMENT_LINK_SECTION = "commentlink";
+  protected static final String COMMENT_LINK_SECTION = "commentlink";
 
   public static enum TrueFalseEnum {
-    TRUE, FALSE;
+    TRUE,
+    FALSE
   }
 
   public static enum ItsIntegration {
-    ENABLED, DISABLED, ENFORCED;
+    ENABLED,
+    DISABLED,
+    ENFORCED
   }
 
   private final String pluginName;
@@ -45,7 +47,10 @@
   private final AllProjectsConfig allProjectsConfig;
   private final AllProjectsNameOnInitProvider allProjects;
 
-  public InitIts(String pluginName, String itsDisplayName, ConsoleUI ui,
+  public InitIts(
+      String pluginName,
+      String itsDisplayName,
+      ConsoleUI ui,
       AllProjectsConfig allProjectsConfig,
       AllProjectsNameOnInitProvider allProjects) {
     this.pluginName = pluginName;
@@ -56,8 +61,7 @@
   }
 
   @Override
-  public void run() throws IOException, ConfigInvalidException {
-  }
+  public void run() throws IOException, ConfigInvalidException {}
 
   @Override
   public void postRun() throws IOException, ConfigInvalidException {
@@ -75,7 +79,9 @@
       itsintegration = ItsIntegration.DISABLED;
     }
     itsintegration =
-        ui.readEnum(itsintegration,
+        ui.readEnum(
+            itsintegration,
+            EnumSet.allOf(ItsIntegration.class),
             "Issue tracker integration for all projects?");
     switch (itsintegration) {
       case ENFORCED:
@@ -90,8 +96,8 @@
         cfg.unset("plugin", pluginName, "enabled");
         break;
       default:
-        throw new IOException("Unsupported value for issue track integration: "
-            + itsintegration.name());
+        throw new IOException(
+            "Unsupported value for issue track integration: " + itsintegration.name());
     }
     allProjectsConfig.save(pluginName, "Initialize " + itsDisplayName + " Integration");
   }
@@ -99,8 +105,9 @@
   private void configureBranches(Config cfg) {
     String[] branches = cfg.getStringList("plugin", pluginName, "branch");
     if (branches.length > 1) {
-      ui.message("The issue tracker integration is configured for multiple branches."
-          + " Please adapt the configuration in the 'project.config' file of the '%s' project.\n",
+      ui.message(
+          "The issue tracker integration is configured for multiple branches."
+              + " Please adapt the configuration in the 'project.config' file of the '%s' project.\n",
           allProjects.get());
       return;
     }
@@ -112,14 +119,18 @@
 
     boolean validRef;
     do {
-      String v = ui.readString(branch, "Branches for which the issue tracker integration"
-          + " should be enabled (ref, ref pattern or regular expression)");
+      String v =
+          ui.readString(
+              branch,
+              "Branches for which the issue tracker integration"
+                  + " should be enabled (ref, ref pattern or regular expression)");
       validRef = RefConfigSection.isValid(v);
       if (validRef) {
         branch = v;
       } else {
         ui.message(
-            "'%s' is not valid. Please specify a valid ref, ref pattern or regular expression\n", v);
+            "'%s' is not valid. Please specify a valid ref, ref pattern or regular expression\n",
+            v);
       }
     } while (!validRef);
 
@@ -131,7 +142,7 @@
   }
 
   public boolean enterSSLVerify(Section section) {
-    return TrueFalseEnum.TRUE == section.select("Verify SSL Certificates",
-        "sslVerify", TrueFalseEnum.TRUE);
+    return TrueFalseEnum.TRUE
+        == section.select("Verify SSL Certificates", "sslVerify", TrueFalseEnum.TRUE);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfig.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfig.java
index 17d31a1..d7193fd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfig.java
@@ -14,9 +14,8 @@
 
 package com.googlesource.gerrit.plugins.its.base.its;
 
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
+import static java.util.stream.Collectors.toList;
+
 import com.google.gerrit.common.data.RefConfigSection;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
@@ -38,18 +37,15 @@
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.project.RefPatternMatcher;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.validation.ItsAssociationPolicy;
-
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Pattern;
 import org.eclipse.jgit.lib.Config;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Pattern;
-
-
 public class ItsConfig {
   private static final String PLUGIN = "plugin";
 
@@ -61,20 +57,18 @@
   private final Config gerritConfig;
 
   private static final ThreadLocal<Project.NameKey> currentProjectName =
-      new ThreadLocal<Project.NameKey>() {
-        @Override
-        protected Project.NameKey initialValue() {
-          return null;
-        }
-      };
+      ThreadLocal.withInitial(() -> null);
 
   public static void setCurrentProjectName(Project.NameKey projectName) {
     currentProjectName.set(projectName);
   }
 
   @Inject
-  public ItsConfig(@PluginName String pluginName, ProjectCache projectCache,
-      PluginConfigFactory pluginCfgFactory, @GerritServerConfig Config gerritConfig) {
+  public ItsConfig(
+      @PluginName String pluginName,
+      ProjectCache projectCache,
+      PluginConfigFactory pluginCfgFactory,
+      @GerritServerConfig Config gerritConfig) {
     this.pluginName = pluginName;
     this.projectCache = projectCache;
     this.pluginCfgFactory = pluginCfgFactory;
@@ -106,7 +100,7 @@
       RefUpdatedEvent e = (RefUpdatedEvent) event;
       return isEnabled(e.getProjectNameKey(), e.getRefName());
     } else {
-      log.debug("Event " + event + " not recognised and ignored");
+      log.debug("Event {} not recognised and ignored", event);
       return false;
     }
   }
@@ -114,25 +108,28 @@
   public boolean isEnabled(Project.NameKey projectNK, String refName) {
     ProjectState projectState = projectCache.get(projectNK);
     if (projectState == null) {
-      log.error("Failed to check if " + pluginName + " is enabled for project "
-          + projectNK.get() + ": Project " + projectNK.get() + " not found");
+      log.error(
+          "Failed to check if {} is enabled for project {}: Project not found",
+          pluginName,
+          projectNK.get());
       return false;
     }
 
-    if(isEnforcedByAnyParentProject(refName, projectState)) {
+    if (isEnforcedByAnyParentProject(refName, projectState)) {
       return true;
     }
 
-    return !"false".equals(pluginCfgFactory.getFromProjectConfigWithInheritance(
-        projectState, pluginName).getString("enabled", "false"))
+    return !"false"
+            .equals(
+                pluginCfgFactory
+                    .getFromProjectConfigWithInheritance(projectState, pluginName)
+                    .getString("enabled", "false"))
         && isEnabledForBranch(projectState, refName);
   }
 
-  private boolean isEnforcedByAnyParentProject(String refName,
-      ProjectState projectState) {
+  private boolean isEnforcedByAnyParentProject(String refName, ProjectState projectState) {
     for (ProjectState parentState : projectState.treeInOrder()) {
-      PluginConfig parentCfg =
-          pluginCfgFactory.getFromProjectConfig(parentState, pluginName);
+      PluginConfig parentCfg = pluginCfgFactory.getFromProjectConfig(parentState, pluginName);
       if ("enforced".equals(parentCfg.getString("enabled", "false"))
           && isEnabledForBranch(parentState, refName)) {
         return true;
@@ -143,8 +140,9 @@
 
   private boolean isEnabledForBranch(ProjectState project, String refName) {
     String[] refPatterns =
-        pluginCfgFactory.getFromProjectConfigWithInheritance(project,
-            pluginName).getStringList("branch");
+        pluginCfgFactory
+            .getFromProjectConfigWithInheritance(project, pluginName)
+            .getStringList("branch");
     if (refPatterns.length == 0) {
       return true;
     }
@@ -180,47 +178,35 @@
 
   /**
    * Gets the regular expression used to identify issue ids.
-   * <p>
-   * The index of the group that holds the issue id is
-   * {@link #getIssuePatternGroupIndex()}.
    *
-   * @return the regular expression, or {@code null}, if there is no pattern
-   *    to match issue ids.
+   * <p>The index of the group that holds the issue id is {@link #getIssuePatternGroupIndex()}.
+   *
+   * @return the regular expression, or {@code null}, if there is no pattern to match issue ids.
    */
   public Pattern getIssuePattern() {
-    String match =
-        FluentIterable
-            .from(getCommitLinkInfo(getCommentLinkName()))
-            .filter(new Predicate<CommentLinkInfo>() {
-              @Override
-              public boolean apply(CommentLinkInfo input) {
-                return input.match != null && !input.match.trim().isEmpty();
-              }
-            })
-            .transform(new Function<CommentLinkInfo, String>() {
-              @Override
-              public String apply(CommentLinkInfo input) {
-                return input.match;
-              }
-            })
-            .last()
-            .or(gerritConfig.getString("commentlink", getCommentLinkName(),
-                "match"));
-    Pattern ret = null;
+    Optional<String> match =
+        getCommentLinkInfo(getCommentLinkName())
+            .stream()
+            .filter(input -> input.match != null && !input.match.trim().isEmpty())
+            .map(input -> input.match)
+            .reduce((a, b) -> b);
 
-    if (match != null) {
-      ret = Pattern.compile(match);
+    String defPattern = gerritConfig.getString("commentlink", getCommentLinkName(), "match");
+
+    if (!match.isPresent() && defPattern == null) {
+      return null;
     }
-    return ret;
+
+    return Pattern.compile(match.orElse(defPattern));
   }
 
   /**
    * Gets the index of the group in the issue pattern that holds the issue id.
-   * <p>
-   * The corresponding issue pattern is {@link #getIssuePattern()}
    *
-   * @return the group index for {@link #getIssuePattern()} that holds the
-   *     issue id. The group index is guaranteed to be a valid group index.
+   * <p>The corresponding issue pattern is {@link #getIssuePattern()}
+   *
+   * @return the group index for {@link #getIssuePattern()} that holds the issue id. The group index
+   *     is guaranteed to be a valid group index.
    */
   public int getIssuePatternGroupIndex() {
     Pattern pattern = getIssuePattern();
@@ -239,53 +225,46 @@
    */
   public ItsAssociationPolicy getItsAssociationPolicy() {
     ItsAssociationPolicy legacyItsAssociationPolicy =
-        gerritConfig.getEnum("commentLink", getCommentLinkName(),
-            "association", ItsAssociationPolicy.OPTIONAL);
+        gerritConfig.getEnum(
+            "commentlink", getCommentLinkName(), "association", ItsAssociationPolicy.OPTIONAL);
 
     return getPluginConfigEnum("association", legacyItsAssociationPolicy);
   }
 
   private String getPluginConfigString(String key) {
-    return getCurrentPluginConfig().getString(key,
-        gerritConfig.getString(PLUGIN, pluginName, key));
+    return getCurrentPluginConfig().getString(key, gerritConfig.getString(PLUGIN, pluginName, key));
   }
 
   private int getPluginConfigInt(String key, int defaultValue) {
-    return getCurrentPluginConfig().getInt(key,
-        gerritConfig.getInt(PLUGIN, pluginName, key, defaultValue));
+    return getCurrentPluginConfig()
+        .getInt(key, gerritConfig.getInt(PLUGIN, pluginName, key, defaultValue));
   }
 
   private <T extends Enum<?>> T getPluginConfigEnum(String key, T defaultValue) {
-    return getCurrentPluginConfig().getEnum(key,
-        gerritConfig.getEnum(PLUGIN, pluginName, key, defaultValue));
+    return getCurrentPluginConfig()
+        .getEnum(key, gerritConfig.getEnum(PLUGIN, pluginName, key, defaultValue));
   }
 
   private PluginConfig getCurrentPluginConfig() {
     NameKey projectName = currentProjectName.get();
     if (projectName != null) {
       try {
-        return pluginCfgFactory.getFromProjectConfigWithInheritance(
-            projectName, pluginName);
+        return pluginCfgFactory.getFromProjectConfigWithInheritance(projectName, pluginName);
       } catch (NoSuchProjectException e) {
-        log.error("Cannot access " + projectName + " configuration for plugin "
-            + pluginName, e);
+        log.error("Cannot access " + projectName + " configuration for plugin " + pluginName, e);
       }
     }
     return new PluginConfig(pluginName, new Config());
   }
 
-  private List<CommentLinkInfo> getCommitLinkInfo(final String commentLinkName) {
+  private List<CommentLinkInfo> getCommentLinkInfo(final String commentlinkName) {
     NameKey projectName = currentProjectName.get();
     if (projectName != null) {
-      List<CommentLinkInfo> commentLinks =
-          projectCache.get(projectName).getCommentLinks();
-      return FluentIterable.from(commentLinks)
-          .filter(new Predicate<CommentLinkInfo>() {
-            @Override
-            public boolean apply(CommentLinkInfo input) {
-              return input.name.equals(commentLinkName);
-            }
-          }).toList();
+      List<CommentLinkInfo> commentlinks = projectCache.get(projectName).getCommentLinks();
+      return commentlinks
+          .stream()
+          .filter(input -> input.name.equals(commentlinkName))
+          .collect(toList());
     }
     return Collections.emptyList();
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsFacade.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsFacade.java
index 53e3ced..9d7b3fa 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsFacade.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsFacade.java
@@ -17,9 +17,7 @@
 import java.io.IOException;
 import java.net.URL;
 
-/**
- * A simple facade to an issue tracking system (its)
- */
+/** A simple facade to an issue tracking system (its) */
 public interface ItsFacade {
 
   public enum Check {
@@ -27,20 +25,15 @@
     ACCESS
   }
 
-  public String healthCheck(Check check)
-    throws IOException;
+  public String healthCheck(Check check) throws IOException;
 
-  public void addRelatedLink(String issueId, URL relatedUrl, String description)
-      throws IOException;
+  public void addRelatedLink(String issueId, URL relatedUrl, String description) throws IOException;
 
-  public void addComment(String issueId, String comment)
-      throws IOException;
+  public void addComment(String issueId, String comment) throws IOException;
 
-  public void performAction(String issueId, String actionName)
-      throws IOException;
+  public void performAction(String issueId, String actionName) throws IOException;
 
-  public boolean exists(final String issueId)
-      throws IOException;
+  public boolean exists(final String issueId) throws IOException;
 
   public String createLinkForWebui(String url, String text);
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsHookEnabledConfigEntry.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsHookEnabledConfigEntry.java
index 17bcf6b..37f1851 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsHookEnabledConfigEntry.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/ItsHookEnabledConfigEntry.java
@@ -18,17 +18,18 @@
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.config.ProjectConfigEntry;
 import com.google.gerrit.server.project.ProjectState;
-
 import java.util.Arrays;
 
 public class ItsHookEnabledConfigEntry extends ProjectConfigEntry {
   private final String pluginName;
   private final PluginConfigFactory pluginCfgFactory;
 
-  public ItsHookEnabledConfigEntry(String pluginName,
-      PluginConfigFactory pluginCfgFactory) {
-    super("Enable " + pluginName + " integration", "false",
-        Arrays.asList(new String[] {"false", "true", "enforced"}), true);
+  public ItsHookEnabledConfigEntry(String pluginName, PluginConfigFactory pluginCfgFactory) {
+    super(
+        "Enable " + pluginName + " integration",
+        "false",
+        Arrays.asList("false", "true", "enforced"),
+        true);
     this.pluginName = pluginName;
     this.pluginCfgFactory = pluginCfgFactory;
   }
@@ -36,8 +37,7 @@
   @Override
   public boolean isEditable(ProjectState project) {
     for (ProjectState parentState : project.parents()) {
-      PluginConfig parentCfg =
-          pluginCfgFactory.getFromProjectConfig(parentState, pluginName);
+      PluginConfig parentCfg = pluginCfgFactory.getFromProjectConfig(parentState, pluginName);
       if ("enforced".equals(parentCfg.getString("enabled"))) {
         return false;
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/NoopItsFacade.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/NoopItsFacade.java
index 1d563e7..de4acd9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/its/NoopItsFacade.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/its/NoopItsFacade.java
@@ -14,16 +14,12 @@
 
 package com.googlesource.gerrit.plugins.its.base.its;
 
+import java.io.IOException;
+import java.net.URL;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.net.URL;
-
-/**
- * An ITS facade doing nothing, it's configured when no ITS are referenced in
- * config
- */
+/** An ITS facade doing nothing, it's configured when no ITS are referenced in config */
 public class NoopItsFacade implements ItsFacade {
 
   private Logger log = LoggerFactory.getLogger(NoopItsFacade.class);
@@ -39,8 +35,7 @@
   public void addRelatedLink(String issueId, URL relatedUrl, String description)
       throws IOException {
     if (log.isDebugEnabled()) {
-      log.debug("addRelatedLink({},{},{})", new Object[] {issueId, relatedUrl,
-          description});
+      log.debug("addRelatedLink({},{},{})", issueId, relatedUrl, description);
     }
   }
 
@@ -53,8 +48,7 @@
   }
 
   @Override
-  public void performAction(String issueId, String actionName)
-      throws IOException {
+  public void performAction(String issueId, String actionName) throws IOException {
     if (log.isDebugEnabled()) {
       log.debug("performAction({},{})", issueId, actionName);
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/CommitMessageFetcher.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/CommitMessageFetcher.java
index 76a1a5a..905a2a3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/CommitMessageFetcher.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/CommitMessageFetcher.java
@@ -3,7 +3,7 @@
 import com.google.gerrit.reviewdb.client.Project.NameKey;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Inject;
-
+import java.io.IOException;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -11,11 +11,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-
 public class CommitMessageFetcher {
-  private static final Logger log = LoggerFactory.getLogger(
-      CommitMessageFetcher.class);
+  private static final Logger log = LoggerFactory.getLogger(CommitMessageFetcher.class);
 
   private final GitRepositoryManager repoManager;
 
@@ -38,8 +35,9 @@
     try {
       ret = fetch(projectName, commitId);
     } catch (IOException e) {
-      log.error("Could not fetch commit message for commit " + commitId +
-          " of project " + projectName, e);
+      log.error(
+          "Could not fetch commit message for commit " + commitId + " of project " + projectName,
+          e);
     }
     return ret;
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractor.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractor.java
index 546e6c7..75a1cc3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractor.java
@@ -7,30 +7,24 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsConfig;
-
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class IssueExtractor {
-  private static final Logger log = LoggerFactory.getLogger(
-      IssueExtractor.class);
+  private static final Logger log = LoggerFactory.getLogger(IssueExtractor.class);
 
   private final CommitMessageFetcher commitMessageFetcher;
   private final ReviewDb db;
   private final ItsConfig itsConfig;
 
   @Inject
-  IssueExtractor(ItsConfig itsConfig,
-      CommitMessageFetcher commitMessageFetcher,
-      ReviewDb db) {
+  IssueExtractor(ItsConfig itsConfig, CommitMessageFetcher commitMessageFetcher, ReviewDb db) {
     this.commitMessageFetcher = commitMessageFetcher;
     this.db = db;
     this.itsConfig = itsConfig;
@@ -46,7 +40,7 @@
     Pattern pattern = itsConfig.getIssuePattern();
     if (pattern == null) return new String[] {};
 
-    log.debug("Matching '" + haystack + "' against " + pattern.pattern());
+    log.debug("Matching '{}' against {}", haystack, pattern.pattern());
 
     Set<String> issues = Sets.newHashSet();
     Matcher matcher = pattern.matcher(haystack);
@@ -63,22 +57,18 @@
   }
 
   /**
-   * Helper funcion for {@link #getIssueIds(String, String)}.
-   * <p>
-   * Adds a text's issues for a given occurrence to the map returned by
-   * {@link #getIssueIds(String, String)}.
+   * Helper function for {@link #getIssueIds(String, String)}.
+   *
+   * <p>Adds a text's issues for a given occurrence to the map returned by {@link
+   * #getIssueIds(String, String)}.
    *
    * @param text The text to extract issues from.
    * @param occurrence The occurrence the issues get added at in {@code map}.
    * @param map The map that the issues should get added to.
    */
-  private void addIssuesOccurrence(String text, String occurrence, Map<String,Set<String>> map) {
+  private void addIssuesOccurrence(String text, String occurrence, Map<String, Set<String>> map) {
     for (String issue : getIssueIds(text)) {
-      Set<String> occurrences = map.get(issue);
-      if (occurrences == null) {
-        occurrences = Sets.newLinkedHashSet();
-        map.put(issue, occurrences);
-      }
+      Set<String> occurrences = map.computeIfAbsent(issue, k -> Sets.newLinkedHashSet());
       occurrences.add(occurrence);
     }
   }
@@ -88,17 +78,14 @@
    *
    * @param projectName The project to fetch {@code commitId} from.
    * @param commitId The commit id to fetch issues for.
-   * @return A mapping, whose keys are issue ids and whose values is a set of
-   *    places where the issue occurs. Each issue occurs at least in
-   *    "somewhere". Issues from the first line get tagged with an occurrence
-   *    "subject". Issues in the last block get tagged with "footer". Issues
-   *    occurring between "subject" and "footer" get tagged with "body".
+   * @return A mapping, whose keys are issue ids and whose values is a set of places where the issue
+   *     occurs. Each issue occurs at least in "somewhere". Issues from the first line get tagged
+   *     with an occurrence "subject". Issues in the last block get tagged with "footer". Issues
+   *     occurring between "subject" and "footer" get tagged with "body".
    */
-  public Map<String,Set<String>> getIssueIds(String projectName,
-      String commitId) {
-    Map<String,Set<String>> ret = Maps.newHashMap();
-    String commitMessage = commitMessageFetcher.fetchGuarded(projectName,
-        commitId);
+  public Map<String, Set<String>> getIssueIds(String projectName, String commitId) {
+    Map<String, Set<String>> ret = Maps.newHashMap();
+    String commitMessage = commitMessageFetcher.fetchGuarded(projectName, commitId);
 
     addIssuesOccurrence(commitMessage, "somewhere", ret);
 
@@ -108,12 +95,12 @@
       addIssuesOccurrence(lines[0], "subject", ret);
 
       // Determining footer line numbers
-      int currentLine = lines.length-1;
-      while (currentLine >=0 && lines[currentLine].isEmpty()) {
+      int currentLine = lines.length - 1;
+      while (currentLine >= 0 && lines[currentLine].isEmpty()) {
         currentLine--;
       }
       int footerEnd = currentLine + 1;
-      while (currentLine >=0 && !lines[currentLine].isEmpty()) {
+      while (currentLine >= 0 && !lines[currentLine].isEmpty()) {
         currentLine--;
       }
       int footerStart = currentLine + 1;
@@ -131,7 +118,7 @@
         // No footer could be found. So all lines after the first one (that's
         // the subject) is the body.
         //body = String[] templateParameters =
-          //  Arrays.copyOfRange(allParameters, 1, allParameters.length);
+        //  Arrays.copyOfRange(allParameters, 1, allParameters.length);
         if (lines.length > 0) {
           body = StringUtils.join(lines, "\n", 1, lines.length);
         }
@@ -170,37 +157,34 @@
 
   /**
    * Gets issues for a commit with new issue occurrences marked as "added".
-   * <p>
-   * Fetches the patch set's immediate ancestor and compares issue occurrences
-   * between them. Any new occurrence gets marked as "added." So if for
-   * example in patch sets 1, and 2 issue 23 occurs in the subject, while in
-   * patch set the issue occurs in the body, then patch set 2 has occurrences
-   * "somewhere", and "subject" for issue 23. Patch set 3 has occurrences
-   * "somewhere", "body", and "body-added" for issue 23.
+   *
+   * <p>Fetches the patch set's immediate ancestor and compares issue occurrences between them. Any
+   * new occurrence gets marked as "added." So if for example in patch sets 1, and 2 issue 23 occurs
+   * in the subject, while in patch set the issue occurs in the body, then patch set 2 has
+   * occurrences "somewhere", and "subject" for issue 23. Patch set 3 has occurrences "somewhere",
+   * "body", and "body-added" for issue 23.
    *
    * @param projectName The project to fetch {@code commitId} from.
    * @param commitId The commit id to fetch issues for.
-   * @param patchSetId The patch set for the {@code commitId}. If it is null,
-   *    no occurrence can be marked as "-added".
-   * @return A mapping, whose keys are issue ids and whose values is a set of
-   *    places where the issue occurs. Each issue occurs at least in
-   *    "somewhere". Issues from the first line get tagged with an occurrence
-   *    "subject". Issues in the last block get tagged with "footer". Issues
-   *    occurring between "subject" and "footer" get tagged with "body".
+   * @param patchSetId The patch set for the {@code commitId}. If it is null, no occurrence can be
+   *     marked as "-added".
+   * @return A mapping, whose keys are issue ids and whose values is a set of places where the issue
+   *     occurs. Each issue occurs at least in "somewhere". Issues from the first line get tagged
+   *     with an occurrence "subject". Issues in the last block get tagged with "footer". Issues
+   *     occurring between "subject" and "footer" get tagged with "body".
    */
-  public Map<String,Set<String>> getIssueIds(String projectName,
-      String commitId, PatchSet.Id patchSetId) {
-    Map<String,Set<String>> current = getIssueIds(projectName, commitId);
+  public Map<String, Set<String>> getIssueIds(
+      String projectName, String commitId, PatchSet.Id patchSetId) {
+    Map<String, Set<String>> current = getIssueIds(projectName, commitId);
     if (patchSetId != null) {
-      Map<String,Set<String>> previous = Maps.newHashMap();
+      Map<String, Set<String>> previous = Maps.newHashMap();
       if (patchSetId.get() != 1) {
-        PatchSet.Id previousPatchSetId = new PatchSet.Id(
-            patchSetId.getParentKey(), patchSetId.get() - 1);
+        PatchSet.Id previousPatchSetId =
+            new PatchSet.Id(patchSetId.getParentKey(), patchSetId.get() - 1);
         try {
           PatchSet previousPatchSet = db.patchSets().get(previousPatchSetId);
           if (previousPatchSet != null) {
-            previous = getIssueIds(projectName,
-                previousPatchSet.getRevision().get());
+            previous = getIssueIds(projectName, previousPatchSet.getRevision().get());
           }
         } catch (OrmException e) {
           // previous is still empty to indicate that there was no previous
@@ -219,7 +203,7 @@
           newOccurrences.removeAll(previousOccurrences);
         }
         for (String occurrence : newOccurrences) {
-          currentOccurrences.add( "added@" + occurrence);
+          currentOccurrences.add("added@" + occurrence);
         }
       }
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractor.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractor.java
index f928f02..f13044e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractor.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// 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.
@@ -21,33 +21,34 @@
 import com.google.gerrit.server.data.PatchSetAttribute;
 import com.google.gerrit.server.data.RefUpdateAttribute;
 import com.google.inject.Inject;
-
+import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
 import java.util.Set;
+import org.apache.commons.lang.StringEscapeUtils;
 
-/**
- * Extractor to translate the various {@code *Attribute}s to
- * {@link Property Properties}.
- */
+/** Extractor to translate the various {@code *Attribute}s to {@link Property Properties}. */
 public class PropertyAttributeExtractor {
   private Property.Factory propertyFactory;
+  private ItsFacade its;
 
   @Inject
-  PropertyAttributeExtractor(Property.Factory propertyFactory) {
+  PropertyAttributeExtractor(ItsFacade its, Property.Factory propertyFactory) {
+    this.its = its;
     this.propertyFactory = propertyFactory;
   }
 
-  public Set<Property> extractFrom(AccountAttribute accountAttribute,
-      String prefix) {
+  public Set<Property> extractFrom(AccountAttribute accountAttribute, String prefix) {
     Set<Property> properties = Sets.newHashSet();
     if (accountAttribute != null) {
-      properties.add(propertyFactory.create(prefix + "-email",
-          accountAttribute.email));
-      properties.add(propertyFactory.create(prefix + "-username",
-          accountAttribute.username));
-      properties.add(propertyFactory.create(prefix + "-name",
-          accountAttribute.name));
+      // deprecated, to be removed soon. migrate to ones without dash.
+      properties.add(propertyFactory.create(prefix + "-email", accountAttribute.email));
+      properties.add(propertyFactory.create(prefix + "-username", accountAttribute.username));
+      properties.add(propertyFactory.create(prefix + "-name", accountAttribute.name));
+
+      // New style configs for vm and soy
+      properties.add(propertyFactory.create(prefix + "Email", accountAttribute.email));
+      properties.add(propertyFactory.create(prefix + "Username", accountAttribute.username));
+      properties.add(propertyFactory.create(prefix + "Name", accountAttribute.name));
     }
     return properties;
   }
@@ -58,10 +59,25 @@
     properties.add(propertyFactory.create("branch", changeAttribute.branch));
     properties.add(propertyFactory.create("topic", changeAttribute.topic));
     properties.add(propertyFactory.create("subject", changeAttribute.subject));
+    properties.add(propertyFactory.create("escapedSubject", StringEscapeUtils.escapeJava(changeAttribute.subject)));
+
+    // deprecated, to be removed soon. migrate to ones without dash.
     properties.add(propertyFactory.create("commit-message", changeAttribute.commitMessage));
     properties.add(propertyFactory.create("change-id", changeAttribute.id));
-    properties.add(propertyFactory.create("change-number", changeAttribute.number));
+    properties.add(propertyFactory.create("change-number", String.valueOf(changeAttribute.number)));
     properties.add(propertyFactory.create("change-url", changeAttribute.url));
+
+    // New style configs for vm and soy
+    properties.add(propertyFactory.create("commitMessage", changeAttribute.commitMessage));
+    properties.add(propertyFactory.create("changeId", changeAttribute.id));
+    properties.add(propertyFactory.create("changeNumber", String.valueOf(changeAttribute.number)));
+    properties.add(propertyFactory.create("changeUrl", changeAttribute.url));
+
+    // Soy specfic config though will work with Velocity too
+    properties.add(
+        propertyFactory.create(
+            "formatChangeUrl", its.createLinkForWebui(changeAttribute.url, changeAttribute.url)));
+
     String status = null;
     if (changeAttribute.status != null) {
       status = changeAttribute.status.toString();
@@ -71,47 +87,63 @@
     return properties;
   }
 
-  public Set<Property>extractFrom(PatchSetAttribute patchSetAttribute) {
+  public Set<Property> extractFrom(PatchSetAttribute patchSetAttribute) {
     Set<Property> properties = Sets.newHashSet();
-    properties.add(propertyFactory.create("revision",
-        patchSetAttribute.revision));
-    properties.add(propertyFactory.create("patch-set-number",
-        patchSetAttribute.number));
+    properties.add(propertyFactory.create("revision", patchSetAttribute.revision));
+    // deprecated, to be removed soon. migrate to ones without dash.
+    properties.add(
+        propertyFactory.create("patch-set-number", String.valueOf(patchSetAttribute.number)));
+
+    // New style configs for vm and soy
+    properties.add(
+        propertyFactory.create("patchSetNumber", String.valueOf(patchSetAttribute.number)));
+
     properties.add(propertyFactory.create("ref", patchSetAttribute.ref));
-    properties.add(propertyFactory.create("created-on",
-        patchSetAttribute.createdOn.toString()));
-    properties.add(propertyFactory.create("parents",
-        patchSetAttribute.parents.toString()));
-    properties.add(propertyFactory.create("deletions",
-        Integer.toString(patchSetAttribute.sizeDeletions)));
-    properties.add(propertyFactory.create("insertions",
-        Integer.toString(patchSetAttribute.sizeInsertions)));
-    properties.add(propertyFactory.create("is-draft",
-        Boolean.toString(patchSetAttribute.isDraft)));
-    properties.addAll(extractFrom(patchSetAttribute.uploader,
-        "uploader"));
-    properties.addAll(extractFrom(patchSetAttribute.author,
-        "author"));
+
+    // deprecated, to be removed soon. migrate to ones without dash.
+    properties.add(propertyFactory.create("created-on", patchSetAttribute.createdOn.toString()));
+
+    // New style configs for vm and soy
+    properties.add(propertyFactory.create("createdOn", patchSetAttribute.createdOn.toString()));
+
+    properties.add(propertyFactory.create("parents", patchSetAttribute.parents.toString()));
+    properties.add(
+        propertyFactory.create("deletions", Integer.toString(patchSetAttribute.sizeDeletions)));
+    properties.add(
+        propertyFactory.create("insertions", Integer.toString(patchSetAttribute.sizeInsertions)));
+    // deprecated, to be removed soon. migrate to ones without dash.
+    properties.add(propertyFactory.create("is-draft", Boolean.toString(patchSetAttribute.isDraft)));
+    // New style configs for vm and soy
+    properties.add(propertyFactory.create("isDraft", Boolean.toString(patchSetAttribute.isDraft)));
+    properties.addAll(extractFrom(patchSetAttribute.uploader, "uploader"));
+    properties.addAll(extractFrom(patchSetAttribute.author, "author"));
     return properties;
   }
 
-  public Set<Property>extractFrom(RefUpdateAttribute refUpdateAttribute) {
+  public Set<Property> extractFrom(RefUpdateAttribute refUpdateAttribute) {
     Set<Property> properties = Sets.newHashSet();
-    properties.add(propertyFactory.create("revision",
-        refUpdateAttribute.newRev));
-    properties.add(propertyFactory.create("revision-old",
-        refUpdateAttribute.oldRev));
-    properties.add(propertyFactory.create("project",
-        refUpdateAttribute.project));
-    properties.add(propertyFactory.create("ref",
-        refUpdateAttribute.refName));
+    properties.add(propertyFactory.create("revision", refUpdateAttribute.newRev));
+
+    // deprecated, to be removed soon. migrate to ones without dash.
+    properties.add(propertyFactory.create("revision-old", refUpdateAttribute.oldRev));
+
+    // New style configs for vm and soy
+    properties.add(propertyFactory.create("revisionOld", refUpdateAttribute.oldRev));
+    properties.add(propertyFactory.create("project", refUpdateAttribute.project));
+    properties.add(propertyFactory.create("ref", refUpdateAttribute.refName));
     return properties;
   }
 
-  public Set<Property>extractFrom(ApprovalAttribute approvalAttribute) {
+  public Set<Property> extractFrom(ApprovalAttribute approvalAttribute) {
     Set<Property> properties = Sets.newHashSet();
-    properties.add(propertyFactory.create("approval-" +
-        approvalAttribute.type, approvalAttribute.value));
+    // deprecated, to be removed soon. migrate to ones without dash.
+    properties.add(
+        propertyFactory.create("approval-" + approvalAttribute.type, approvalAttribute.value));
+
+    // New style configs for vm and soy
+    properties.add(
+        propertyFactory.create(
+            "approval" + approvalAttribute.type.replace("-", ""), approvalAttribute.value));
     return properties;
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractor.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractor.java
index b83f1c6..f9c589d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractor.java
@@ -21,6 +21,7 @@
 import com.google.gerrit.server.data.ApprovalAttribute;
 import com.google.gerrit.server.data.ChangeAttribute;
 import com.google.gerrit.server.data.PatchSetAttribute;
+import com.google.gerrit.server.data.RefUpdateAttribute;
 import com.google.gerrit.server.events.ChangeAbandonedEvent;
 import com.google.gerrit.server.events.ChangeEvent;
 import com.google.gerrit.server.events.ChangeMergedEvent;
@@ -32,16 +33,13 @@
 import com.google.gerrit.server.events.PatchSetEvent;
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
+import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
+import org.eclipse.jgit.lib.ObjectId;
 
-/**
- * Extractor to translate an {@link ChangeEvent} to
- * {@link Property Properties}.
- */
+/** Extractor to translate an {@link ChangeEvent} to {@link Property Properties}. */
 public class PropertyExtractor {
   private IssueExtractor issueExtractor;
   private Property.Factory propertyFactory;
@@ -49,7 +47,8 @@
   private final String pluginName;
 
   @Inject
-  PropertyExtractor(IssueExtractor issueExtractor,
+  PropertyExtractor(
+      IssueExtractor issueExtractor,
       Property.Factory propertyFactory,
       PropertyAttributeExtractor propertyAttributeExtractor,
       @PluginName String pluginName) {
@@ -61,82 +60,76 @@
 
   /**
    * creates a patch id for change id string and patchset id string.
+   *
    * @param changeId String representation of the patch sets {@code Change.Id@}
    * @param patchId String representation of the patch sets {@code Patchset.Id@}
-   * @return PatchSet.Id for the specified patch set. If the String to int
-   *    conversion fails for any of the parameters, null is returned.
+   * @return PatchSet.Id for the specified patch set. If the String to int conversion fails for any
+   *     of the parameters, null is returned.
    */
   private PatchSet.Id newPatchSetId(String changeId, String patchId) {
     try {
-        return new PatchSet.Id(new Change.Id(Integer.parseInt(changeId)),
-            Integer.parseInt(patchId));
+      return new PatchSet.Id(new Change.Id(Integer.parseInt(changeId)), Integer.parseInt(patchId));
     } catch (NumberFormatException e) {
       return null;
     }
   }
 
-  private Map<String,Set<String>> extractFrom(PatchSetEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(PatchSetEvent event, Set<Property> common) {
     common.add(propertyFactory.create("event-type", event.type));
     ChangeAttribute change = event.change.get();
     PatchSetAttribute patchSet = event.patchSet.get();
     common.addAll(propertyAttributeExtractor.extractFrom(change));
     common.addAll(propertyAttributeExtractor.extractFrom(patchSet));
-    PatchSet.Id patchSetId = newPatchSetId(change.number, patchSet.number);
-    return issueExtractor.getIssueIds(change.project,
-        patchSet.revision, patchSetId);
+    PatchSet.Id patchSetId =
+        newPatchSetId(Integer.toString(change.number), Integer.toString(patchSet.number));
+    return issueExtractor.getIssueIds(change.project, patchSet.revision, patchSetId);
   }
 
-  private Map<String,Set<String>> extractFrom(ChangeAbandonedEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(ChangeAbandonedEvent event, Set<Property> common) {
     common.addAll(propertyAttributeExtractor.extractFrom(event.abandoner.get(), "abandoner"));
     common.add(propertyFactory.create("reason", event.reason));
     return extractFrom((PatchSetEvent) event, common);
   }
 
-  private Map<String,Set<String>> extractFrom(ChangeMergedEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(ChangeMergedEvent event, Set<Property> common) {
     common.addAll(propertyAttributeExtractor.extractFrom(event.submitter.get(), "submitter"));
     return extractFrom((PatchSetEvent) event, common);
   }
 
-  private Map<String,Set<String>> extractFrom(ChangeRestoredEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(ChangeRestoredEvent event, Set<Property> common) {
     common.addAll(propertyAttributeExtractor.extractFrom(event.restorer.get(), "restorer"));
     common.add(propertyFactory.create("reason", event.reason));
     return extractFrom((PatchSetEvent) event, common);
   }
 
-  private Map<String,Set<String>> extractFrom(DraftPublishedEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(DraftPublishedEvent event, Set<Property> common) {
     common.addAll(propertyAttributeExtractor.extractFrom(event.uploader.get(), "uploader"));
     return extractFrom((PatchSetEvent) event, common);
   }
 
-  private Map<String,Set<String>> extractFrom(RefUpdatedEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(RefUpdatedEvent event, Set<Property> common) {
     common.add(propertyFactory.create("event-type", event.type));
     if (event.submitter != null) {
       common.addAll(propertyAttributeExtractor.extractFrom(event.submitter.get(), "submitter"));
     }
     common.addAll(propertyAttributeExtractor.extractFrom(event.refUpdate.get()));
-    return issueExtractor.getIssueIds(event.getProjectNameKey().get(),
-        event.refUpdate.get().newRev);
+    RefUpdateAttribute refUpdated = event.refUpdate.get();
+    if (ObjectId.zeroId().name().equals(refUpdated.newRev)) {
+      return Collections.emptyMap();
+    }
+    return issueExtractor.getIssueIds(event.getProjectNameKey().get(), refUpdated.newRev);
   }
 
-  private Map<String,Set<String>> extractFrom(PatchSetCreatedEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(PatchSetCreatedEvent event, Set<Property> common) {
     common.addAll(propertyAttributeExtractor.extractFrom(event.uploader.get(), "uploader"));
     return extractFrom((PatchSetEvent) event, common);
   }
 
-  private Map<String,Set<String>> extractFrom(CommentAddedEvent event,
-      Set<Property> common) {
+  private Map<String, Set<String>> extractFrom(CommentAddedEvent event, Set<Property> common) {
     common.addAll(propertyAttributeExtractor.extractFrom(event.author.get(), "commenter"));
     if (event.approvals != null) {
       for (ApprovalAttribute approvalAttribute : event.approvals.get()) {
-        common.addAll(propertyAttributeExtractor.extractFrom(
-            approvalAttribute));
+        common.addAll(propertyAttributeExtractor.extractFrom(approvalAttribute));
       }
     }
     common.add(propertyFactory.create("comment", event.comment));
@@ -146,10 +139,10 @@
   /**
    * A set of property sets extracted from an event.
    *
-   * As events may relate to more that a single issue, and properties sets are
-   * should be tied to a single issue, returning {@code Set<Property>} is not
-   * sufficient, and we need to return {@code Set<Set<Property>>}. Using this
-   * approach, a PatchSetCreatedEvent for a patch set with commit message:
+   * <p>As events may relate to more that a single issue, and properties sets are should be tied to
+   * a single issue, returning {@code Set<Property>} is not sufficient, and we need to return {@code
+   * Set<Set<Property>>}. Using this approach, a PatchSetCreatedEvent for a patch set with commit
+   * message:
    *
    * <pre>
    *   (bug 4711) Fix treatment of special characters in title
@@ -175,16 +168,15 @@
    *   event: patchset-created
    * </pre>
    *
-   * Thereby, sites can choose to cause different actions for different issues
-   * associated to the same event. So in the above example, a comment
-   * "mentioned in change 123" may be added for issue 42, and a comment
-   * "fixed by change 123” may be added for issue 4711.
+   * Thereby, sites can choose to cause different actions for different issues associated to the
+   * same event. So in the above example, a comment "mentioned in change 123" may be added for issue
+   * 42, and a comment "fixed by change 123” may be added for issue 4711.
    *
    * @param event The event to extract property sets from.
    * @return sets of property sets extracted from the event.
    */
   public Set<Set<Property>> extractFrom(Event event) {
-    Map<String,Set<String>> associations = null;
+    Map<String, Set<String>> associations = null;
     Set<Set<Property>> ret = Sets.newHashSet();
 
     Set<Property> common = Sets.newHashSet();
@@ -213,7 +205,7 @@
         properties.add(property);
         property = propertyFactory.create("its-name", pluginName);
         properties.add(property);
-        for (String occurrence: associations.get(issue)) {
+        for (String occurrence : associations.get(issue)) {
           property = propertyFactory.create("association", occurrence);
           properties.add(property);
         }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsAssociationPolicy.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsAssociationPolicy.java
index ea363a8..4e08b62 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsAssociationPolicy.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsAssociationPolicy.java
@@ -15,5 +15,7 @@
 package com.googlesource.gerrit.plugins.its.base.validation;
 
 public enum ItsAssociationPolicy {
-    MANDATORY, SUGGESTED, OPTIONAL;
+  MANDATORY,
+  SUGGESTED,
+  OPTIONAL
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateComment.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateComment.java
index ff2b38a..969eeb0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateComment.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateComment.java
@@ -21,35 +21,27 @@
 import com.google.gerrit.server.git.validators.CommitValidationListener;
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsConfig;
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.util.IssueExtractor;
-
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-
 public class ItsValidateComment implements CommitValidationListener {
 
-  private static final Logger log = LoggerFactory
-      .getLogger(ItsValidateComment.class);
+  private static final Logger log = LoggerFactory.getLogger(ItsValidateComment.class);
 
-  @Inject
-  private ItsFacade client;
+  @Inject private ItsFacade client;
 
-  @Inject @PluginName
-  private String pluginName;
+  @Inject @PluginName private String pluginName;
 
-  @Inject
-  private ItsConfig itsConfig;
+  @Inject private ItsConfig itsConfig;
 
-  @Inject
-  private IssueExtractor issueExtractor;
+  @Inject private IssueExtractor issueExtractor;
 
   private List<CommitValidationMessage> validCommit(RevCommit commit)
       throws CommitValidationException {
@@ -70,8 +62,7 @@
             try {
               exists = client.exists(issueId);
             } catch (IOException e) {
-              synopsis = "Failed to check whether or not issue " + issueId
-                  + " exists";
+              synopsis = "Failed to check whether or not issue " + issueId + " exists";
               log.warn(synopsis, e);
               details = e.toString();
               ret.add(commitValidationFailure(synopsis, details));
@@ -129,26 +120,24 @@
     return ret;
   }
 
-  private CommitValidationMessage commitValidationFailure(
-      String synopsis, String details) throws CommitValidationException {
-    CommitValidationMessage ret =
-        new CommitValidationMessage(synopsis + "\n" + details, false);
+  private CommitValidationMessage commitValidationFailure(String synopsis, String details)
+      throws CommitValidationException {
+    CommitValidationMessage ret = new CommitValidationMessage(synopsis + "\n" + details, false);
     if (itsConfig.getItsAssociationPolicy() == ItsAssociationPolicy.MANDATORY) {
-      throw new CommitValidationException(synopsis,
-          Collections.singletonList(ret));
+      throw new CommitValidationException(synopsis, Collections.singletonList(ret));
     }
     return ret;
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     ItsConfig.setCurrentProjectName(receiveEvent.getProjectNameKey());
 
     if (itsConfig.isEnabled(receiveEvent.getProjectNameKey(), receiveEvent.getRefName())) {
       return validCommit(receiveEvent.commit);
-    } else {
-      return Collections.emptyList();
     }
+
+    return Collections.emptyList();
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionController.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionController.java
index 9e7bb7d..b1c0982 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionController.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionController.java
@@ -17,18 +17,16 @@
 import com.google.gerrit.common.EventListener;
 import com.google.gerrit.server.events.Event;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsConfig;
 import com.googlesource.gerrit.plugins.its.base.util.PropertyExtractor;
-
 import java.util.Collection;
 import java.util.Set;
 
 /**
  * Controller that takes actions according to {@code ChangeEvents@}.
  *
- * The taken actions are typically Its related (e.g.: adding an Its comment, or
- * changing an issue's status).
+ * <p>The taken actions are typically Its related (e.g.: adding an Its comment, or changing an
+ * issue's status).
  */
 public class ActionController implements EventListener {
   private final PropertyExtractor propertyExtractor;
@@ -37,8 +35,11 @@
   private final ItsConfig itsConfig;
 
   @Inject
-  public ActionController(PropertyExtractor propertyExtractor,
-      RuleBase ruleBase, ActionExecutor actionExecutor, ItsConfig itsConfig) {
+  public ActionController(
+      PropertyExtractor propertyExtractor,
+      RuleBase ruleBase,
+      ActionExecutor actionExecutor,
+      ItsConfig itsConfig) {
     this.propertyExtractor = propertyExtractor;
     this.ruleBase = ruleBase;
     this.actionExecutor = actionExecutor;
@@ -51,11 +52,9 @@
       return;
     }
 
-    Set<Set<Property>> propertiesCollections =
-        propertyExtractor.extractFrom(event);
+    Set<Set<Property>> propertiesCollections = propertyExtractor.extractFrom(event);
     for (Set<Property> properties : propertiesCollections) {
-      Collection<ActionRequest> actions =
-          ruleBase.actionRequestsFor(properties);
+      Collection<ActionRequest> actions = ruleBase.actionRequestsFor(properties);
       if (!actions.isEmpty()) {
         for (Property property : properties) {
           if ("issue".equals(property.getKey())) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutor.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutor.java
index e83feb4..0e31b93 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutor.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// 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.
@@ -15,56 +15,57 @@
 package com.googlesource.gerrit.plugins.its.base.workflow;
 
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.Action;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddComment;
+import com.googlesource.gerrit.plugins.its.base.workflow.action.AddSoyComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddStandardComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddVelocityComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.LogEvent;
-
+import java.io.IOException;
+import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.Set;
-
-/**
- * Executes an {@link ActionRequest}
- */
+/** Executes an {@link ActionRequest} */
 public class ActionExecutor {
-  private static final Logger log = LoggerFactory.getLogger(
-      ActionExecutor.class);
+  private static final Logger log = LoggerFactory.getLogger(ActionExecutor.class);
 
   private final ItsFacade its;
   private final AddComment.Factory addCommentFactory;
   private final AddStandardComment.Factory addStandardCommentFactory;
   private final AddVelocityComment.Factory addVelocityCommentFactory;
+  private final AddSoyComment.Factory addSoyCommentFactory;
   private final LogEvent.Factory logEventFactory;
 
   @Inject
-  public ActionExecutor(ItsFacade its, AddComment.Factory addCommentFactory,
+  public ActionExecutor(
+      ItsFacade its,
+      AddComment.Factory addCommentFactory,
       AddStandardComment.Factory addStandardCommentFactory,
       AddVelocityComment.Factory addVelocityCommentFactory,
+      AddSoyComment.Factory addSoyCommentFactory,
       LogEvent.Factory logEventFactory) {
     this.its = its;
     this.addCommentFactory = addCommentFactory;
     this.addStandardCommentFactory = addStandardCommentFactory;
     this.addVelocityCommentFactory = addVelocityCommentFactory;
+    this.addSoyCommentFactory = addSoyCommentFactory;
     this.logEventFactory = logEventFactory;
   }
 
-  public void execute(String issue, ActionRequest actionRequest,
-      Set<Property> properties) {
+  public void execute(String issue, ActionRequest actionRequest, Set<Property> properties) {
     try {
       String name = actionRequest.getName();
       Action action = null;
       if ("add-comment".equals(name)) {
         action = addCommentFactory.create();
       } else if ("add-standard-comment".equals(name)) {
-          action = addStandardCommentFactory.create();
+        action = addStandardCommentFactory.create();
       } else if ("add-velocity-comment".equals(name)) {
         action = addVelocityCommentFactory.create();
+      } else if ("add-soy-comment".equals(name)) {
+        action = addSoyCommentFactory.create();
       } else if ("log-event".equals(name)) {
         action = logEventFactory.create();
       }
@@ -79,10 +80,9 @@
     }
   }
 
-  public void execute(String issue, Iterable<ActionRequest> actions,
-      Set<Property> properties) {
+  public void execute(String issue, Iterable<ActionRequest> actions, Set<Property> properties) {
     for (ActionRequest actionRequest : actions) {
-        execute(issue, actionRequest, properties);
+      execute(issue, actionRequest, properties);
     }
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequest.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequest.java
index 0394e09..dec671e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequest.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequest.java
@@ -17,14 +17,13 @@
 import com.google.gerrit.common.Nullable;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
-
 import java.util.Arrays;
 
 /**
  * An action to take for an {@code ChangeEvent}.
  *
- * Actions are typically related to an Its (e.g.:adding an Its comment, or
- * changing an issue's status).
+ * <p>Actions are typically related to an Its (e.g.:adding an Its comment, or changing an issue's
+ * status).
  */
 public class ActionRequest {
   private final String unparsed;
@@ -47,8 +46,7 @@
   /**
    * Gets the name of the requested action.
    *
-   * @return The name of the requested action, if a name has been given.
-   *    "" otherwise.
+   * @return The name of the requested action, if a name has been given. "" otherwise.
    */
   public String getName() {
     String ret = "";
@@ -62,8 +60,7 @@
    * Gets the name of the requested action.
    *
    * @param i The number of the parameter to extract. 1 is the first parameter.
-   * @return The name of the requested parameter, if the requested parameter
-   *    exists. "" otherwise.
+   * @return The name of the requested parameter, if the requested parameter exists. "" otherwise.
    */
   public String getParameter(int i) {
     String ret = "";
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Condition.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Condition.java
index bf9f9df..6f8df84 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Condition.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Condition.java
@@ -20,25 +20,23 @@
 import com.google.gerrit.common.Nullable;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
-
 import com.googlesource.gerrit.plugins.its.base.workflow.action.Action;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
 /**
  * A condition as used in {@link Rule}, as precondition to {@link Action}s.
- * <p>
- * A condition consists of a key and an associated set of values.
- * <p>
- * For positive conditions (see constructor), the condition is said to match a
- * set of properties, if this set contains at least one property that matches
- * the rules key and whose value matches at least one of the rule's value.
- * <p>
- * For negated conditions (see constructor), the condition is said to match a
- * set of properties, if this set does not contain any property that matches
- * the rules key and whose value matches at least one of the rule's value.
+ *
+ * <p>A condition consists of a key and an associated set of values.
+ *
+ * <p>For positive conditions (see constructor), the condition is said to match a set of properties,
+ * if this set contains at least one property that matches the rules key and whose value matches at
+ * least one of the rule's value.
+ *
+ * <p>For negated conditions (see constructor), the condition is said to match a set of properties,
+ * if this set does not contain any property that matches the rules key and whose value matches at
+ * least one of the rule's value.
  */
 public class Condition {
   private final String key;
@@ -46,29 +44,26 @@
   private final boolean negated;
 
   public interface Factory {
-    Condition create(@Assisted("key") String key,
-        @Assisted("values") String values);
+    Condition create(@Assisted("key") String key, @Assisted("values") String values);
   }
 
   /**
    * Constructs a condition.
+   *
    * @param key The key to use for values.
-   * @param values A comma separated list of values to associate to the key. If
-   *    the first value is not "!", it's a positive condition. If the first
-   *    value is "!", the "!" is removed from the values and the condition is
-   *    considered a negated condition.
+   * @param values A comma separated list of values to associate to the key. If the first value is
+   *     not "!", it's a positive condition. If the first value is "!", the "!" is removed from the
+   *     values and the condition is considered a negated condition.
    */
   @Inject
-  public Condition(@Assisted("key") String key,
-      @Nullable @Assisted("values") String values) {
+  public Condition(@Assisted("key") String key, @Nullable @Assisted("values") String values) {
     this.key = key;
     Set<String> modifyableValues;
     boolean modifyableNegated = false;
     if (values == null) {
       modifyableValues = Collections.emptySet();
     } else {
-      List<String> valueList = Lists.newArrayList(
-          Splitter.on(',').trimResults().split(values));
+      List<String> valueList = Lists.newArrayList(Splitter.on(',').trimResults().split(values));
       if (!valueList.isEmpty() && "!".equals(valueList.get(0))) {
         modifyableNegated = true;
         valueList.remove(0);
@@ -87,17 +82,15 @@
    * Checks whether or not the Condition matches the given set of properties
    *
    * @param properties The set of properties to match against.
-   * @return For positive conditions, true iff properties contains at least
-   *    one property that matches the rules key and whose value matches at
-   *    least one of the rule's value. For negated conditions, true iff
-   *    properties does not contain any property that matches the rules key
-   *    and whose value matches at least one of the rule's value.
+   * @return For positive conditions, true iff properties contains at least one property that
+   *     matches the rules key and whose value matches at least one of the rule's value. For negated
+   *     conditions, true iff properties does not contain any property that matches the rules key
+   *     and whose value matches at least one of the rule's value.
    */
   public boolean isMetBy(Iterable<Property> properties) {
     for (Property property : properties) {
       String propertyKey = property.getKey();
-      if ((key == null && propertyKey == null)
-          || (key != null && key.equals(propertyKey))) {
+      if ((key == null && propertyKey == null) || (key != null && key.equals(propertyKey))) {
         if (values.contains(property.getValue())) {
           return !negated;
         }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Property.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Property.java
index 98a8117..eb1f087 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Property.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Property.java
@@ -21,20 +21,18 @@
 /**
  * A property to match against {@code Condition}s.
  *
- * A property is a simple key value pair.
+ * <p>A property is a simple key value pair.
  */
 public class Property {
   public interface Factory {
-    Property create(@Assisted("key") String key,
-        @Assisted("value") String value);
+    Property create(@Assisted("key") String key, @Assisted("value") String value);
   }
 
   private final String key;
   private final String value;
 
   @Inject
-  public Property(@Assisted("key") String key,
-      @Nullable @Assisted("value") String value) {
+  public Property(@Assisted("key") String key, @Nullable @Assisted("value") String value) {
     this.key = key;
     this.value = value;
   }
@@ -71,8 +69,7 @@
 
   @Override
   public int hashCode() {
-    return (key == null ? 0 : key.hashCode()) * 31 +
-        (value == null ? 0 : value.hashCode());
+    return (key == null ? 0 : key.hashCode()) * 31 + (value == null ? 0 : value.hashCode());
   }
 
   @Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Rule.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Rule.java
index 4ec6be3..3efa269 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Rule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/Rule.java
@@ -18,15 +18,12 @@
 import com.google.common.collect.Sets;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
-/**
- * A single rule that associates {@code Action}s to {@code Condition}s.
- */
+/** A single rule that associates {@code Action}s to {@code Condition}s. */
 public class Rule {
   private final String name;
   private List<ActionRequest> actionRequests;
@@ -68,14 +65,13 @@
   /**
    * Gets this rule's the action requests for a given set of properties.
    *
-   * If the given set of properties meets all of the rule's conditions, the
-   * rule's actions are returned. Otherwise the empty collection is returned.
+   * <p>If the given set of properties meets all of the rule's conditions, the rule's actions are
+   * returned. Otherwise the empty collection is returned.
    *
    * @param properties The properties to check against the rule's conditions.
    * @return The actions that should get fired.
    */
-  public Collection<ActionRequest> actionRequestsFor(
-      Iterable<Property> properties) {
+  public Collection<ActionRequest> actionRequestsFor(Iterable<Property> properties) {
     for (Condition condition : conditions) {
       if (!condition.isMetBy(properties)) {
         return Collections.emptyList();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBase.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBase.java
index 2f0e1a2..41dc9fa 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBase.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBase.java
@@ -14,48 +14,35 @@
 
 package com.googlesource.gerrit.plugins.its.base.workflow;
 
-
 import com.google.common.collect.Lists;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.server.config.SitePath;
 import com.google.inject.Inject;
-
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.util.FS;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Collection;
-
-/**
- * Collection and matcher agains {@link Rule}s.
- */
+/** Collection and matcher agains {@link Rule}s. */
 public class RuleBase {
   private static final Logger log = LoggerFactory.getLogger(RuleBase.class);
 
-  /**
-   * File beginning (relative to site) to load rules from
-   */
-  private static final String ITS_CONFIG_FILE_START = "etc" +
-      File.separatorChar + "its" + File.separator + "actions";
+  /** File beginning (relative to site) to load rules from */
+  private static final String ITS_CONFIG_FILE_START =
+      "etc" + File.separatorChar + "its" + File.separator + "actions";
 
-  /**
-   * File end to load rules from
-   */
+  /** File end to load rules from */
   private static final String ITS_CONFIG_FILE_END = ".config";
 
-  /**
-   * The section for rules within rulebases
-   */
+  /** The section for rules within rulebases */
   private static final String RULE_SECTION = "rule";
 
-  /**
-   * The key for actions within rulebases
-   */
+  /** The key for actions within rulebases */
   private static final String ACTION_KEY = "action";
 
   private final Path sitePath;
@@ -71,7 +58,9 @@
   }
 
   @Inject
-  public RuleBase(@SitePath Path sitePath, Rule.Factory ruleFactory,
+  public RuleBase(
+      @SitePath Path sitePath,
+      Rule.Factory ruleFactory,
       Condition.Factory conditionFactory,
       ActionRequest.Factory actionRequestFactory,
       @PluginName String pluginName) {
@@ -85,8 +74,8 @@
 
   /**
    * Adds rules from a file to the the RuleBase.
-   * <p>
-   * If the given file does not exist, it is silently ignored
+   *
+   * <p>If the given file does not exist, it is silently ignored
    *
    * @param ruleFile File from which to read the rules
    */
@@ -105,7 +94,7 @@
         Rule rule = ruleFactory.create(subsection);
         Collection<String> keys = cfg.getNames(RULE_SECTION, subsection);
         for (String key : keys) {
-          String values[] = cfg.getStringList(RULE_SECTION, subsection, key);
+          String[] values = cfg.getStringList(RULE_SECTION, subsection, key);
           if (ACTION_KEY.equals(key)) {
             for (String value : values) {
               ActionRequest actionRequest = actionRequestFactory.create(value);
@@ -123,9 +112,7 @@
     }
   }
 
-  /**
-   * Loads the rules for the RuleBase.
-   */
+  /** Loads the rules for the RuleBase. */
   private void reloadRules() {
     rules = Lists.newArrayList();
 
@@ -137,34 +124,40 @@
     // "actions.config" (with trailing "s", we (for now) load files from both
     // locations, but consider "actions.config" (with trailing "s" the
     // canonical place.
-    File faultyNameRuleFile = new File(sitePath.toFile(), "etc" + File.separatorChar
-        + "its" + File.separator + "action.config");
+    File faultyNameRuleFile =
+        new File(
+            sitePath.toFile(),
+            "etc" + File.separatorChar + "its" + File.separator + "action.config");
     if (faultyNameRuleFile.exists()) {
-      log.warn("Loading rules from deprecated 'etc/its/action.config' (No "
-          + "trailing 's' in 'action'). Please migrate to "
-          + "'etc/its/actions.config' (Trailing 's' in 'actions').");
+      log.warn(
+          "Loading rules from deprecated 'etc/its/action.config' (No "
+              + "trailing 's' in 'action'). Please migrate to "
+              + "'etc/its/actions.config' (Trailing 's' in 'actions').");
       addRulesFromFile(faultyNameRuleFile);
     }
 
     // Add global rules
-    File globalRuleFile = new File(sitePath.toFile(), ITS_CONFIG_FILE_START +
-        ITS_CONFIG_FILE_END);
+    File globalRuleFile = new File(sitePath.toFile(), ITS_CONFIG_FILE_START + ITS_CONFIG_FILE_END);
     addRulesFromFile(globalRuleFile);
 
     // Add its-specific rules
-    File itsSpecificRuleFile = new File(sitePath.toFile(), ITS_CONFIG_FILE_START + "-" +
-        pluginName + ITS_CONFIG_FILE_END);
+    File itsSpecificRuleFile =
+        new File(sitePath.toFile(), ITS_CONFIG_FILE_START + "-" + pluginName + ITS_CONFIG_FILE_END);
     addRulesFromFile(itsSpecificRuleFile);
 
     if (!globalRuleFile.exists() && !itsSpecificRuleFile.exists()) {
       try {
-        log.warn("Neither global rule file "
-            + globalRuleFile.getCanonicalPath() + " nor Its specific rule file"
-            + itsSpecificRuleFile.getCanonicalPath() + " exist. Please configure "
-            + "rules.");
+        log.warn(
+            "Neither global rule file "
+                + globalRuleFile.getCanonicalPath()
+                + " nor Its specific rule file"
+                + itsSpecificRuleFile.getCanonicalPath()
+                + " exist. Please configure "
+                + "rules.");
       } catch (IOException e) {
-        log.warn("Neither global rule file nor Its specific rule files exist. "
-            + "Please configure rules.");
+        log.warn(
+            "Neither global rule file nor Its specific rule files exist. "
+                + "Please configure rules.");
       }
     }
   }
@@ -175,8 +168,7 @@
    * @param properties The properties to search actions for.
    * @return Requests for the actions that should be fired.
    */
-  public Collection<ActionRequest> actionRequestsFor(
-      Iterable<Property> properties) {
+  public Collection<ActionRequest> actionRequestsFor(Iterable<Property> properties) {
     Collection<ActionRequest> ret = Lists.newLinkedList();
     for (Rule rule : rules) {
       ret.addAll(rule.actionRequestsFor(properties));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/Action.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/Action.java
index 24feee5..b8b2102 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/Action.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/Action.java
@@ -16,13 +16,10 @@
 
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
 import java.io.IOException;
 import java.util.Set;
 
-/**
- * Interface for actions on an issue tracking system
- */
+/** Interface for actions on an issue tracking system */
 public interface Action {
 
   /**
@@ -32,6 +29,6 @@
    * @param actionRequest The request to execute.
    * @param properties The properties for the execution.
    */
-  public void execute(String issue, ActionRequest actionRequest,
-      Set<Property> properties) throws IOException;
+  public void execute(String issue, ActionRequest actionRequest, Set<Property> properties)
+      throws IOException;
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddComment.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddComment.java
index 8ca9c59..16855d3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddComment.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddComment.java
@@ -16,20 +16,17 @@
 
 import com.google.common.base.Strings;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
-import org.apache.commons.lang.StringUtils;
-
 import java.io.IOException;
 import java.util.Set;
+import org.apache.commons.lang.StringUtils;
 
 /**
  * Adds a fixed comment to an issue.
  *
- * The action requests parameters get concatenated and get added to the issue.
+ * <p>The action requests parameters get concatenated and get added to the issue.
  */
 public class AddComment implements Action {
   public interface Factory {
@@ -44,8 +41,8 @@
   }
 
   @Override
-  public void execute(String issue, ActionRequest actionRequest,
-      Set<Property> properties) throws IOException {
+  public void execute(String issue, ActionRequest actionRequest, Set<Property> properties)
+      throws IOException {
     String[] parameters = actionRequest.getParameters();
     String comment = StringUtils.join(parameters, " ");
     if (!Strings.isNullOrEmpty(comment)) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddSoyComment.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddSoyComment.java
new file mode 100644
index 0000000..bbad6e9
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddSoyComment.java
@@ -0,0 +1,131 @@
+// 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.
+
+package com.googlesource.gerrit.plugins.its.base.workflow.action;
+
+import com.google.common.base.Strings;
+import com.google.common.io.CharStreams;
+import com.google.gerrit.server.config.SitePath;
+import com.google.inject.Inject;
+import com.google.inject.ProvisionException;
+import com.google.template.soy.SoyFileSet;
+import com.google.template.soy.data.SanitizedContent;
+import com.google.template.soy.tofu.SoyTofu;
+import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
+import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
+import com.googlesource.gerrit.plugins.its.base.workflow.Property;
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Adds a short predefined comments to an issue.
+ *
+ * <p>Comments are added for merging, abandoning, restoring of changes and adding of patch sets.
+ */
+public class AddSoyComment implements Action {
+  private static final Logger log = LoggerFactory.getLogger(AddSoyComment.class);
+
+  public interface Factory {
+    AddSoyComment create();
+  }
+
+  /** Directory (relative to site) to search templates in */
+  private static final String ITS_TEMPLATE_DIR =
+      "etc" + File.separator + "its" + File.separator + "templates";
+
+  private final ItsFacade its;
+  private final Path sitePath;
+  protected HashMap<String, Object> soyContext;
+
+  @Inject
+  public AddSoyComment(@SitePath Path sitePath, ItsFacade its) {
+    this.sitePath = sitePath;
+    this.its = its;
+  }
+
+  private HashMap<String, Object> getSoyContext(Set<Property> properties) {
+    HashMap<String, Object> soyContext = new HashMap<>();
+    for (Property property : properties) {
+      String key = property.getKey();
+      if (!Strings.isNullOrEmpty(key)) {
+        String value = property.getValue();
+        if (!Strings.isNullOrEmpty(value)) {
+          soyContext.put(key, value);
+        }
+      }
+    }
+
+    return soyContext;
+  }
+
+  private String soyTemplate(
+      SoyFileSet.Builder builder,
+      String template,
+      SanitizedContent.ContentKind kind,
+      Set<Property> properties) {
+    Path templateDir = sitePath.resolve(ITS_TEMPLATE_DIR);
+    Path templatePath = templateDir.resolve(template + ".soy");
+    String content;
+
+    try (Reader r = Files.newBufferedReader(templatePath, StandardCharsets.UTF_8)) {
+      content = CharStreams.toString(r);
+    } catch (IOException err) {
+      throw new ProvisionException(
+          "Failed to read template file " + templatePath.toAbsolutePath().toString(), err);
+    }
+
+    builder.add(content, templatePath.toAbsolutePath().toString());
+
+    HashMap<String, Object> context = getSoyContext(properties);
+
+    SoyTofu.Renderer renderer =
+        builder
+            .build()
+            .compileToTofu()
+            .newRenderer("etc.its.templates." + template)
+            .setContentKind(kind)
+            .setData(context);
+    return renderer.render();
+  }
+
+  protected String soyTextTemplate(
+      SoyFileSet.Builder builder, String template, Set<Property> properties) {
+    return soyTemplate(builder, template, SanitizedContent.ContentKind.TEXT, properties);
+  }
+
+  @Override
+  public void execute(String issue, ActionRequest actionRequest, Set<Property> properties)
+      throws IOException {
+    SoyFileSet.Builder builder = SoyFileSet.builder();
+    String template = null;
+    String templateName = actionRequest.getParameter(1);
+    if (templateName.isEmpty()) {
+      log.error("No template name given in {}", actionRequest);
+    } else {
+      template = templateName;
+    }
+    if (!Strings.isNullOrEmpty(template)) {
+      String comment = soyTextTemplate(builder, template, properties);
+      its.addComment(issue, comment);
+    }
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardComment.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardComment.java
index 814075d..8a7a09f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardComment.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardComment.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// 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.
@@ -17,11 +17,9 @@
 import com.google.common.base.Strings;
 import com.google.common.collect.Maps;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
 import java.io.IOException;
 import java.util.Map;
 import java.util.Set;
@@ -29,8 +27,7 @@
 /**
  * Adds a short predefined comments to an issue.
  *
- * Comments are added for merging, abandoning, restoring of changes and adding
- * of patch sets.
+ * <p>Comments are added for merging, abandoning, restoring of changes and adding of patch sets.
  */
 public class AddStandardComment implements Action {
   public interface Factory {
@@ -44,23 +41,14 @@
     this.its = its;
   }
 
-  private String formatPerson(String prefix, Map<String, String> map) {
-    String ret = Strings.nullToEmpty(map.get(prefix + "-name"));
-    if (ret.isEmpty()) {
-      ret = Strings.nullToEmpty(map.get(prefix + "-username"));
-    }
-    return ret;
-  }
-
-  private String getCommentChangeEvent(String Action, String prefix,
-      Map<String, String> map) {
+  private String getCommentChangeEvent(String action, String prefix, Map<String, String> map) {
     String ret = "";
-    String changeNumber = Strings.nullToEmpty(map.get("change-number"));
+    String changeNumber = getValueFromMap(map, "", "change-number", "changeNumber");
     if (!changeNumber.isEmpty()) {
       changeNumber += " ";
     }
-    ret += "Change " + changeNumber + Action;
-    String submitter = formatPerson(prefix, map);
+    ret += "Change " + changeNumber + action;
+    String submitter = getValueFromMap(map, prefix, "-name", "Name", "-username", "Username");
     if (!submitter.isEmpty()) {
       ret += " by " + submitter;
     }
@@ -72,13 +60,23 @@
     if (!reason.isEmpty()) {
       ret += "\n\nReason:\n" + reason;
     }
-    String url = Strings.nullToEmpty(map.get("change-url"));
+    String url = getValueFromMap(map, "", "change-url", "changeUrl");
     if (!url.isEmpty()) {
       ret += "\n\n" + its.createLinkForWebui(url, url);
     }
     return ret;
   }
 
+  private String getValueFromMap(Map<String, String> map, String keyPrefix, String... keyOptions) {
+    for (String key : keyOptions) {
+      String ret = Strings.nullToEmpty(map.get(keyPrefix + key));
+      if (!ret.isEmpty()) {
+        return ret;
+      }
+    }
+    return "";
+  }
+
   private String getCommentChangeAbandoned(Map<String, String> map) {
     return getCommentChangeEvent("abandoned", "abandoner", map);
   }
@@ -92,19 +90,17 @@
   }
 
   private String getCommentPatchSetCreated(Map<String, String> map) {
-    return getCommentChangeEvent("had a related patch set uploaded",
-        "uploader", map);
+    return getCommentChangeEvent("had a related patch set uploaded", "uploader", map);
   }
 
   @Override
-  public void execute(String issue, ActionRequest actionRequest,
-      Set<Property> properties) throws IOException {
+  public void execute(String issue, ActionRequest actionRequest, Set<Property> properties)
+      throws IOException {
     String comment = "";
     Map<String, String> map = Maps.newHashMap();
     for (Property property : properties) {
       String current = property.getValue();
-      if (!Strings.isNullOrEmpty(current))
-      {
+      if (!Strings.isNullOrEmpty(current)) {
         String key = property.getKey();
         String old = Strings.nullToEmpty(map.get(key));
         if (!old.isEmpty()) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityComment.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityComment.java
index f3a1cc2..13a6655 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityComment.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityComment.java
@@ -17,17 +17,9 @@
 import com.google.common.base.Strings;
 import com.google.gerrit.server.config.SitePath;
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.runtime.RuntimeInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.StringWriter;
@@ -35,33 +27,35 @@
 import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Set;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.runtime.RuntimeInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Adds a short predefined comments to an issue.
  *
- * Comments are added for merging, abandoning, restoring of changes and adding
- * of patch sets.
+ * <p>Comments are added for merging, abandoning, restoring of changes and adding of patch sets.
  */
 public class AddVelocityComment implements Action {
-  private static final Logger log = LoggerFactory.getLogger(
-      AddVelocityComment.class);
+  private static final Logger log = LoggerFactory.getLogger(AddVelocityComment.class);
 
   public interface Factory {
     AddVelocityComment create();
   }
 
-  /**
-   * Directory (relative to site) to search templates in
-   */
-  private static final String ITS_TEMPLATE_DIR = "etc" + File.separator +
-      "its" + File.separator + "templates";
+  /** Directory (relative to site) to search templates in */
+  private static final String ITS_TEMPLATE_DIR =
+      "etc" + File.separator + "its" + File.separator + "templates";
 
   private final ItsFacade its;
   private final Path sitePath;
   private final RuntimeInstance velocityRuntime;
 
   @Inject
-  public AddVelocityComment(RuntimeInstance velocityRuntime, @SitePath Path sitePath, ItsFacade its) {
+  public AddVelocityComment(
+      RuntimeInstance velocityRuntime, @SitePath Path sitePath, ItsFacade its) {
     this.velocityRuntime = velocityRuntime;
     this.sitePath = sitePath;
     this.its = its;
@@ -79,7 +73,7 @@
       }
     }
 
-    velocityContext.put("its",  new VelocityAdapterItsFacade(its));
+    velocityContext.put("its", new VelocityAdapterItsFacade(its));
 
     return velocityContext;
   }
@@ -92,25 +86,24 @@
   }
 
   @Override
-  public void execute(String issue, ActionRequest actionRequest,
-      Set<Property> properties) throws IOException {
+  public void execute(String issue, ActionRequest actionRequest, Set<Property> properties)
+      throws IOException {
     String template = null;
     String templateName = actionRequest.getParameter(1);
     if ("inline".equals(templateName)) {
       String[] allParameters = actionRequest.getParameters();
-      String[] templateParameters =
-          Arrays.copyOfRange(allParameters, 1, allParameters.length);
+      String[] templateParameters = Arrays.copyOfRange(allParameters, 1, allParameters.length);
       template = StringUtils.join(templateParameters, " ");
     } else {
       if (templateName.isEmpty()) {
-        log.error("No template name given in " + actionRequest);
+        log.error("No template name given in {}", actionRequest);
       } else {
         Path templateDir = sitePath.resolve(ITS_TEMPLATE_DIR);
         Path templatePath = templateDir.resolve(templateName + ".vm");
         if (Files.isReadable(templatePath)) {
           template = new String(Files.readAllBytes(templatePath));
         } else {
-          log.error("Cannot read template " + templatePath);
+          log.error("Cannot read template {}", templatePath);
         }
       }
     }
@@ -120,9 +113,7 @@
     }
   }
 
-  /**
-   * Adapter for ItsFacade to be used through Velocity
-   */
+  /** Adapter for ItsFacade to be used through Velocity */
   // Although we'd prefer to keep this class private, Velocity will only pick
   // it up, if it is public.
   public class VelocityAdapterItsFacade {
@@ -146,8 +137,8 @@
 
     /**
      * Format a link to an URL.
-     * <p>
-     * The provided URL is used as caption for the formatted link.
+     *
+     * <p>The provided URL is used as caption for the formatted link.
      *
      * @param url URL to link to
      * @return Link to the given URL in the used Its' syntax.
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEvent.java b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEvent.java
index d66dbce..3a46202 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEvent.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEvent.java
@@ -15,34 +15,34 @@
 package com.googlesource.gerrit.plugins.its.base.workflow.action;
 
 import com.google.inject.Inject;
-
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.IOException;
 import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Dumps the event's properties to the log.
  *
- * This event helps when developing rules as available properties become
- * visible.
+ * <p>This event helps when developing rules as available properties become visible.
  */
 public class LogEvent implements Action {
   private static final Logger log = LoggerFactory.getLogger(LogEvent.class);
 
-  private enum Level { ERROR, WARN, INFO, DEBUG }
+  private enum Level {
+    ERROR,
+    WARN,
+    INFO,
+    DEBUG
+  }
 
   public interface Factory {
     LogEvent create();
   }
 
   @Inject
-  public LogEvent() {
-  }
+  public LogEvent() {}
 
   private void logProperty(Level level, Property property) {
     String message = property.toString();
@@ -65,8 +65,8 @@
   }
 
   @Override
-  public void execute(String issue, ActionRequest actionRequest,
-      Set<Property> properties) throws IOException {
+  public void execute(String issue, ActionRequest actionRequest, Set<Property> properties)
+      throws IOException {
     String levelParameter = actionRequest.getParameter(1);
     if (levelParameter != null) {
       levelParameter = levelParameter.toLowerCase();
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
deleted file mode 100644
index 3606c87..0000000
--- a/src/main/resources/Documentation/build.md
+++ /dev/null
@@ -1,47 +0,0 @@
-Build
-=====
-
-This base library for ITS-based plugins is built with Buck.
-
-Clone or link this plugin to the plugins directory of Gerrit's source
-tree, and issue the command:
-
-```
-  buck build plugins/its-base
-```
-
-The output is created in
-
-```
-  buck-out/gen/plugins/its-base/its-base.jar
-  buck-out/gen/plugins/its-base/lib__its-base__plugin__output/its-base__plugin.jar
-```
-
-This project can be imported into the Eclipse IDE:
-
-```
-  ./tools/eclipse/project.py
-```
-
-To execute the tests run:
-
-```
-  buck test --all --include its-base
-```
-
-Note that the ITS-based plugins require `its-base__plugin` library:
-
-```
-[...]
-  deps = [
-    '//plugins/its-base:its-base__plugin',
-  ],
-[...]
-```
-
-How to build the Gerrit Plugin API is described in the [Gerrit
-documentation](../../../Documentation/dev-buck.html#_extension_and_plugin_api_jar_files).
-
-[Back to @PLUGIN@ documentation index][index]
-
-[index]: index.html
\ No newline at end of file
diff --git a/src/main/resources/Documentation/config-rulebase-common.md b/src/main/resources/Documentation/config-rulebase-common.md
index 2ccb3f9..8f1da31 100644
--- a/src/main/resources/Documentation/config-rulebase-common.md
+++ b/src/main/resources/Documentation/config-rulebase-common.md
@@ -35,7 +35,7 @@
     action = add-standard-comment
 [rule "rule2"]
     event-type = comment-added
-    approval-Code-Review = -2,-1
+    approvalCodeReview = -2,-1
     action = add-comment Oh my Goodness! Someone gave a negative code review in Gerrit on an associated change.
 ```
 
@@ -140,11 +140,11 @@
     ```
     [rule "someRuleForBugzillaOnly"]
       its-name = its-bugzilla
-      approval-Code-Review = -2
+      approvalCodeReview = -2
       action = add-comment Heya Bugzilla users, the change had a -2 Code-Review approval.
     [rule "someRuleForJiraOnly"]
       its-name = its-jira
-      approval-Code-Review = -2
+      approvalCodeReview = -2
       action = add-comment Dear JIRA users, the change had a -2 Code-Review approval.
     ```
 
@@ -176,61 +176,61 @@
 values are:
 
 `somewhere`
-:	issue id occurs somewhere in the commit message of the change/the
-	most recent patch set.
+:   issue id occurs somewhere in the commit message of the change/the
+    most recent patch set.
 
 `subject`
-:	issue id occurs in the first line of the commit message of the
-	change/the most recent patch set.
+:   issue id occurs in the first line of the commit message of the
+    change/the most recent patch set.
 
 `body`
-:	issue id occurs after the subject but before the footer of the
-	commit message of the change/the most recent patch set.
+:   issue id occurs after the subject but before the footer of the
+    commit message of the change/the most recent patch set.
 
 `footer`
-:	issue id occurs in the last paragraph after the subject of the
-	commit message of the change/the most recent patch set
+:   issue id occurs in the last paragraph after the subject of the
+    commit message of the change/the most recent patch set
 
 `footer-<Key>`
-:	issue id occurs in the footer of the commit message of the
-	change/the most recent patch set, and is in a line with a key
-	(part before the colon).
+:   issue id occurs in the footer of the commit message of the
+    change/the most recent patch set, and is in a line with a key
+    (part before the colon).
 
-	So for example, if the footer would contain a line
+    So for example, if the footer would contain a line
 
-	```
+    ```
 Fixes-Issue: issue 4711
 ```
 
-	then a property `association` with value `footer-Fixes-Issue`
-	would get added to the event for issue “4711”.
+    then a property `association` with value `footer-Fixes-Issue`
+    would get added to the event for issue “4711”.
 
 `added@<Association-Value>`
-:	(only for events that allow to determine the patch set number.
-	So for example, this `association` property is not set for
-	RevUpdatedEvents)
+:   (only for events that allow to determine the patch set number.
+    So for example, this `association` property is not set for
+    RevUpdatedEvents)
 
-	issue id occurs at `<Association-Value>` in the most recent
-	patch set of the change, and either the event is for patch set
-	1 or the issue id does not occur at `<Association-Value>` in
-	the previous patch set.
+    issue id occurs at `<Association-Value>` in the most recent
+    patch set of the change, and either the event is for patch set
+    1 or the issue id does not occur at `<Association-Value>` in
+    the previous patch set.
 
-	So for example if issue “4711” occurs in the subject of patch
-	set 3 (the most recent patch set) of a change, but not in
-	patch set 2.  When adding a comment to this change, the event
-	for issue “4711” would get a property 'association' with value
-	`added@subject`.
+    So for example if issue “4711” occurs in the subject of patch
+    set 3 (the most recent patch set) of a change, but not in
+    patch set 2.  When adding a comment to this change, the event
+    for issue “4711” would get a property 'association' with value
+    `added@subject`.
 
 [event-properties-ChangeAbandonedEvent]: #event-properties-ChangeAbandonedEvent
 ### <a name="event-properties-ChangeAbandonedEvent">ChangeAbandonedEvent</a>
 
-`abandoner-email`
+`abandonerEmail`
 : email address of the user abandoning the change.
 
-`abandoner-name`
+`abandonerName`
 : name of the user abandoning the change.
 
-`abandoner-username`
+`abandonerUsername`
 : username of the user abandoning the change.
 
 `event`
@@ -255,13 +255,13 @@
 `event-type`
 : `change-merged`
 
-`submitter-email`
+`submitterEmail`
 : email address of the user causing the merge of the change.
 
-`submitter-name`
+`submitterName`
 : name of the user causing the merge of the change.
 
-`submitter-username`
+`submitterUsername`
 : username of the user causing the merge of the change.
 
 In addition to the above properties, the event also provides
@@ -280,13 +280,13 @@
 `reason`
 : reason why the change has been restored.
 
-`restorer-email`
+`restorerEmail`
 : email address of the user restoring the change.
 
-`restorer-name`
+`restorerName`
 :  name of the user restoring the change.
 
-`restorer-username`
+`restorerUsername`
 : username of the user restoring the change.
 
 In addition to the above properties, the event also provides
@@ -302,13 +302,13 @@
 author of the comment is accessible via the `commenter-...`
 properties.
 
-`commenter-email`
+`commenterEmail`
 : email address of the comment's author.
 
-`commenter-name`
+`commenterName`
 : name of the comment's author.
 
-`commenter-username`
+`commenterUsername`
 : username of the comment's author.
 
 `comment`
@@ -321,11 +321,11 @@
 : `comment-added`
 
 For each new or changed approval that has been made for this change, a
-property of key `approval-<LabelName>` and the approval's value as
+property of key `approval<LabelName>` and the approval's value as
 value is added. So for example voting “-2” for the approval
 “Code-Review” would add the following property:
 
-`approval-Code-Review`
+`approvalCodeReview`
 : `-2`
 
 In addition to the above properties, the event also provides
@@ -377,16 +377,16 @@
 `revision`
 : git commit hash the rev is pointing to now.
 
-`revision-old`
+`revisionOld`
 : git commit hash the rev was pointing to before.
 
-`submitter-email`
+`submitterEmail`
 : email address of the user that updated the ref.
 
-`submitter-name`
+`submitterName`
 : name of the user that updated the ref.
 
-`submitter-username`
+`submitterUsername`
 : username of the user that updated the ref.
 
 [event-properties-change]: #event-properties-change
@@ -395,22 +395,25 @@
 `branch`
 : name of the branch the change belongs to.
 
-`change-id`
+`changeId`
 : Change-Id for the change („I-followed by 40 hex digits” string).
 
-`change-number`
+`changeNumber`
 : number for the change (plain integer).
 
-`change-url`
+`changeUrl`
 : url of the change.
 
-`owner-email`
+`formatChangeUrl`
+: format the url for changeUrl.
+
+`ownerEmail`
 : email address of the change's owner.
 
-`owner-name`
+`ownerName`
 : name of the change's owner.
 
-`owner-username`
+`ownerUsername`
 : username of the change's owner.
 
 `project`
@@ -419,12 +422,12 @@
 `subject`
 : first line of the change's most recent patch set's commit message.
 
-`commit-message`
+`commitMessage`
 : full commit message of the most recent patch set
 
 `status`
-:	status of the change (`null`, `NEW`, `SUBMITTED`, `DRAFT`, `MERGED`,
-	or `ABANDONED` )
+:   status of the change (`null`, `NEW`, `SUBMITTED`, `DRAFT`, `MERGED`,
+    or `ABANDONED` )
 
 `topic`
 : name of the topic the change belongs to.
@@ -432,13 +435,13 @@
 [event-properties-patch-set]: #event-properties-patch-set
 ### <a name="event-properties-patch-set">Common properties for events on a patch set</a>
 
-`author-email`
+`authorEmail`
 : email address of this patch set's author.
 
-`author-name`
+`authorName`
 : name of this patch set's author.
 
-`author-username`
+`authorUsername`
 : username of this patch set's author.
 
 `created-on`
@@ -450,13 +453,13 @@
 `insertions`
 : number of lines inserted by the patch set.
 
-`is-draft`
+`isDraft`
 : 'true', if the patch set is a draft patch set, 'false' otherwise.
 
 `parents`
 : A list of git commit hashes that are parents to the patch set.
 
-`patch-set-number`
+`patchSetNumber`
 : patch set's number within the change.
 
 `ref`
@@ -466,13 +469,13 @@
 `revision`
 : git commit hash of the patch set
 
-`uploader-email`
+`uploaderEmail`
 : email address of the user that uploaded this patch set.
 
-`uploader-name`
+`uploaderName`
 : name of the user that uploaded this patch set.
 
-`uploader-username`
+`uploaderUsername`
 : username of the user that uploaded this patch set.
 
 [actions]: #actions
@@ -499,6 +502,9 @@
 [`add-velocity-comment`][action-add-velocity-comment]
 : adds a rendered Velocity template as issue comment
 
+[`add-soy-comment`][action-add-velocity-comment]
+: adds a rendered Closure Template (soy) template as issue comment
+
 [`log-event`][action-log-event]
 : appends the event's properties to Gerrit's log
 
@@ -564,37 +570,72 @@
 
 Any [property][event-properties] of the event may be used from
 templates. So for example `$subject` in the above example refers to
-the event's subject property, and `$change-number` would refer to the
+the event's subject property, and `$changeNumber` would refer to the
 change's number.
 
 Additionally, the context's `its` property provides an object that
 allows to format links using the its' syntax:
 
 `formatLink( url )`
-:	Formats a link to a url.
+:   Formats a link to a url.
 
-	So for example upon adding a comment to a change, the
-	following rule formats a link to the change:
+    So for example upon adding a comment to a change, the
+    following rule formats a link to the change:
 
-	```
+    ```
 [rule "formatLinkSampleRule"]
   event-type = comment-added
-  action = add-velocity-comment inline Comment for change $change-number added. See ${its.formatLink($change-url)}
+  action = add-velocity-comment inline Comment for change $change-number added. See ${its.formatLink($changeUrl)}
 ```
 
 `formatLink( url, caption )`
-:	Formats a link to a url using 'caption' to represent the url.
+:   Formats a link to a url using 'caption' to represent the url.
 
-	So for example upon adding a comment to a change, the following rule
-	formats a link to the change using the change number as link
-	capition:
+    So for example upon adding a comment to a change, the following rule
+    formats a link to the change using the change number as link
+    capition:
 
-	```
+    ```
 [rule "formatLinkSampleRule"]
   event-type = comment-added
-  action = add-velocity-comment inline Comment for change ${its.formatLink($change-url, $change-number)} added.
+  action = add-velocity-comment inline Comment for change ${its.formatLink($changeUrl, $changeNumber)} added.
 ```
 
+[action-add-soy-comment]: #action-add-soy-comment
+### <a name="action-add-soy-comment">Action: add-soy-comment</a>
+
+The `add-soy-comment` action renders a Closure template (soy) for the
+event and adds the output as comment to any associated issue.
+
+So for example
+
+```
+  action = add-soy-comment TemplateName
+```
+
+would render the template `etc/its/templates/TemplateName.soy` add the
+output as comment to associated issues.
+
+example for what the soy template will look like (note @param is required with correct variables.)
+
+
+```
+{namespace etc.its.templates}
+
+/**
+ * @param changeNumber
+ * @param formatChangeUrl
+ */
+{template .TemplateName autoescape="strict" kind="text"}
+  inline Comment for change {$changeNumber} added. See {$formatChangeUrl}
+{/template}
+```
+
+Any [property][event-properties] of the event may be used from
+templates. So for example `$subject` in the above example refers to
+the event's subject property, and `$changeNumber` would refer to the
+change's number.
+
 [action-log-event]: #action-log-event
 ### <a name="action-log-event">Action: log-event</a>
 
diff --git a/src/main/resources/Documentation/about.md b/src/main/templates/Documentation/about.md
similarity index 100%
rename from src/main/resources/Documentation/about.md
rename to src/main/templates/Documentation/about.md
diff --git a/src/main/templates/Documentation/build.md b/src/main/templates/Documentation/build.md
new file mode 100644
index 0000000..abdb96f
--- /dev/null
+++ b/src/main/templates/Documentation/build.md
@@ -0,0 +1,85 @@
+Build
+=====
+
+This base library for ITS-based plugins is built with Bazel.
+
+Two build modes are supported: Standalone and in Gerrit tree.
+The standalone build mode is recommended, as this mode doesn't require
+the Gerrit tree to exist locally.
+
+### Build standalone
+
+```
+  bazel build its-base
+```
+
+The output is created in
+
+```
+  bazel-genfiles/its-base.jar
+```
+
+To execute the tests run:
+
+```
+  bazel test :its_base_tests
+```
+
+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:
+
+```
+  ./tools/eclipse/project.sh
+```
+
+### Build in Gerrit tree
+
+```
+  bazel build plugins/its-base
+```
+
+The output is created in
+
+```
+  bazel-genfiles/plugins/its-base/its-base.jar
+```
+
+This project can be imported into the Eclipse IDE:
+
+```
+  ./tools/eclipse/project.py
+```
+
+To execute the tests run:
+
+```
+  bazel test plugins/its-base:its_base_tests
+```
+
+Note that the ITS-based plugins require `its-base__plugin` library:
+
+```
+[...]
+  deps = [
+    '//plugins/its-base:its-base__plugin',
+  ],
+[...]
+```
+
+How to build the Gerrit Plugin API is described in the [Gerrit
+documentation](../../../Documentation/dev-buck.html#_extension_and_plugin_api_jar_files).
+
+[Back to @PLUGIN@ documentation index][index]
+
+[index]: index.html
diff --git a/src/main/resources/Documentation/config-connectivity.md b/src/main/templates/Documentation/config-connectivity.md
similarity index 100%
rename from src/main/resources/Documentation/config-connectivity.md
rename to src/main/templates/Documentation/config-connectivity.md
diff --git a/src/main/resources/Documentation/config-rulebase-plugin-actions.md b/src/main/templates/Documentation/config-rulebase-plugin-actions.md
similarity index 100%
rename from src/main/resources/Documentation/config-rulebase-plugin-actions.md
rename to src/main/templates/Documentation/config-rulebase-plugin-actions.md
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfigTest.java
index 267c357..8f349b3 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/its/ItsConfigTest.java
@@ -36,13 +36,10 @@
 import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.validation.ItsAssociationPolicy;
-
-import org.eclipse.jgit.lib.Config;
-
 import java.util.Arrays;
+import org.eclipse.jgit.lib.Config;
 
 public class ItsConfigTest extends LoggingMockingTestCase {
   private Injector injector;
@@ -51,14 +48,13 @@
   private PluginConfigFactory pluginConfigFactory;
   private Config serverConfig;
 
-  public void setupIsEnabled(String enabled, String parentEnabled,
-      String[] branches) {
+  public void setupIsEnabled(String enabled, String parentEnabled, String[] branches) {
     ProjectState projectState = createMock(ProjectState.class);
 
-    expect(projectCache.get(new Project.NameKey("testProject")))
-        .andReturn(projectState).anyTimes();
+    expect(projectCache.get(new Project.NameKey("testProject"))).andReturn(projectState).anyTimes();
     expect(projectCache.get(new Project.NameKey("parentProject")))
-        .andReturn(projectState).anyTimes();
+        .andReturn(projectState)
+        .anyTimes();
 
     Iterable<ProjectState> parents;
     if (parentEnabled == null) {
@@ -68,21 +64,21 @@
 
       PluginConfig parentPluginConfig = createMock(PluginConfig.class);
 
-      expect(pluginConfigFactory.getFromProjectConfig(
-          parentProjectState, "ItsTestName")).andReturn(parentPluginConfig);
+      expect(pluginConfigFactory.getFromProjectConfig(parentProjectState, "ItsTestName"))
+          .andReturn(parentPluginConfig);
 
-      expect(parentPluginConfig.getString("enabled")).andReturn(parentEnabled)
-          .anyTimes();
+      expect(parentPluginConfig.getString("enabled", "false")).andReturn(parentEnabled).anyTimes();
 
       PluginConfig parentPluginConfigWI = createMock(PluginConfig.class);
 
-      expect(pluginConfigFactory.getFromProjectConfigWithInheritance(
-          parentProjectState, "ItsTestName")).andReturn(parentPluginConfigWI)
+      expect(
+              pluginConfigFactory.getFromProjectConfigWithInheritance(
+                  parentProjectState, "ItsTestName"))
+          .andReturn(parentPluginConfigWI)
           .anyTimes();
 
-      String[] parentBranches = { "refs/heads/testBranch" };
-      expect(parentPluginConfigWI.getStringList("branch"))
-          .andReturn(parentBranches).anyTimes();
+      String[] parentBranches = {"refs/heads/testBranch"};
+      expect(parentPluginConfigWI.getStringList("branch")).andReturn(parentBranches).anyTimes();
 
       parents = Arrays.asList(parentProjectState, projectState);
     }
@@ -90,21 +86,21 @@
 
     PluginConfig pluginConfig = createMock(PluginConfig.class);
 
-    expect(pluginConfigFactory.getFromProjectConfig(
-        projectState, "ItsTestName")).andReturn(pluginConfig).anyTimes();
+    expect(pluginConfigFactory.getFromProjectConfig(projectState, "ItsTestName"))
+        .andReturn(pluginConfig)
+        .anyTimes();
 
-    expect(pluginConfig.getString("enabled")).andReturn(enabled).anyTimes();
+    expect(pluginConfig.getString("enabled", "false")).andReturn(enabled).anyTimes();
 
     PluginConfig pluginConfigWI = createMock(PluginConfig.class);
 
-    expect(pluginConfigFactory.getFromProjectConfigWithInheritance(
-        projectState, "ItsTestName")).andReturn(pluginConfigWI).anyTimes();
-
-    expect(pluginConfigWI.getBoolean("enabled", false))
-        .andReturn("true".equals(enabled)).anyTimes();
-
-    expect(pluginConfigWI.getStringList("branch")).andReturn(branches)
+    expect(pluginConfigFactory.getFromProjectConfigWithInheritance(projectState, "ItsTestName"))
+        .andReturn(pluginConfigWI)
         .anyTimes();
+
+    expect(pluginConfigWI.getString("enabled", "false")).andReturn(enabled).anyTimes();
+
+    expect(pluginConfigWI.getStringList("branch")).andReturn(branches).anyTimes();
   }
 
   public void testIsEnabledRefNoParentNoBranchEnabled() {
@@ -119,7 +115,7 @@
     assertTrue(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefNoParentNoBranchDisabled() {
+  public void BROKEN_testIsEnabledRefNoParentNoBranchDisabled() {
     String[] branches = {};
     setupIsEnabled("false", null, branches);
 
@@ -155,7 +151,7 @@
     assertTrue(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefNoParentMatchingBranchDisabled() {
+  public void BROKEN_testIsEnabledRefNoParentMatchingBranchDisabled() {
     String[] branches = {"^refs/heads/test.*"};
     setupIsEnabled("false", null, branches);
 
@@ -179,7 +175,7 @@
     assertTrue(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefNoParentNonMatchingBranchEnabled() {
+  public void BROKEN_testIsEnabledRefNoParentNonMatchingBranchEnabled() {
     String[] branches = {"^refs/heads/foo.*"};
     setupIsEnabled("true", null, branches);
 
@@ -191,7 +187,7 @@
     assertFalse(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefNoParentNonMatchingBranchDisabled() {
+  public void BROKEN_testIsEnabledRefNoParentNonMatchingBranchDisabled() {
     String[] branches = {"^refs/heads/foo.*"};
     setupIsEnabled("false", null, branches);
 
@@ -203,7 +199,7 @@
     assertFalse(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefNoParentNonMatchingBranchEnforced() {
+  public void BROKEN_testIsEnabledRefNoParentNonMatchingBranchEnforced() {
     String[] branches = {"^refs/heads/foo.*"};
     setupIsEnabled("enforced", null, branches);
 
@@ -227,7 +223,7 @@
     assertTrue(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefNoParentMatchingBranchMiddleDisabled() {
+  public void BROKEN_testIsEnabledRefNoParentMatchingBranchMiddleDisabled() {
     String[] branches = {"^refs/heads/foo.*", "^refs/heads/test.*", "^refs/heads/baz.*"};
     setupIsEnabled("false", null, branches);
 
@@ -251,7 +247,7 @@
     assertTrue(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefParentNoBranchEnabled() {
+  public void BROKEN_testIsEnabledRefParentNoBranchEnabled() {
     String[] branches = {};
     setupIsEnabled("false", "true", branches);
 
@@ -263,7 +259,7 @@
     assertFalse(itsConfig.isEnabled(projectNK, "refs/heads/testBranch"));
   }
 
-  public void testIsEnabledRefParentNoBranchDisabled() {
+  public void BROKEN_testIsEnabledRefParentNoBranchDisabled() {
     String[] branches = {};
     setupIsEnabled("false", "false", branches);
 
@@ -291,8 +287,7 @@
     String[] branches = {};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -305,8 +300,7 @@
     String[] branches = {"refs/heads/testBranch"};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -319,8 +313,7 @@
     String[] branches = {"^refs/heads/test.*"};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -329,12 +322,11 @@
     assertTrue(itsConfig.isEnabled(event));
   }
 
-  public void testIsEnabledEventSingleBranchNonMatchingRegExp() {
+  public void BROKEN_testIsEnabledEventSingleBranchNonMatchingRegExp() {
     String[] branches = {"^refs/heads/foo.*"};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -347,8 +339,7 @@
     String[] branches = {"refs/heads/foo", "refs/heads/testBranch"};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -361,8 +352,7 @@
     String[] branches = {"^refs/heads/foo.*", "^refs/heads/test.*"};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -375,8 +365,7 @@
     String[] branches = {"refs/heads/testBranch", "refs/heads/foo.*"};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -385,12 +374,11 @@
     assertTrue(itsConfig.isEnabled(event));
   }
 
-public void testIsEnabledEventMultiBranchMixedMatchRegExp() {
+  public void testIsEnabledEventMultiBranchMixedMatchRegExp() {
     String[] branches = {"refs/heads/foo", "^refs/heads/test.*"};
     setupIsEnabled("true", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -399,12 +387,11 @@
     assertTrue(itsConfig.isEnabled(event));
   }
 
-  public void testIsEnabledEventDisabled() {
+  public void BROKEN_testIsEnabledEventDisabled() {
     String[] branches = {"^refs/heads/testBranch"};
     setupIsEnabled("false", null, branches);
 
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -417,8 +404,7 @@
     String[] branches = {};
     setupIsEnabled("true", null, branches);
 
-    CommentAddedEvent event =
-        new CommentAddedEvent(testChange("testProject", "testBranch"));
+    CommentAddedEvent event = new CommentAddedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -431,8 +417,7 @@
     String[] branches = {};
     setupIsEnabled("true", null, branches);
 
-    ChangeMergedEvent event =
-        new ChangeMergedEvent(testChange("testProject", "testBranch"));
+    ChangeMergedEvent event = new ChangeMergedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -445,8 +430,7 @@
     String[] branches = {};
     setupIsEnabled("true", null, branches);
 
-    ChangeAbandonedEvent event =
-        new ChangeAbandonedEvent(testChange("testProject", "testBranch"));
+    ChangeAbandonedEvent event = new ChangeAbandonedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -459,8 +443,7 @@
     String[] branches = {};
     setupIsEnabled("true", null, branches);
 
-    ChangeRestoredEvent event =
-        new ChangeRestoredEvent(testChange("testProject", "testBranch"));
+    ChangeRestoredEvent event = new ChangeRestoredEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -473,8 +456,7 @@
     String[] branches = {};
     setupIsEnabled("true", null, branches);
 
-    DraftPublishedEvent event =
-        new DraftPublishedEvent(testChange("testProject", "testBranch"));
+    DraftPublishedEvent event = new DraftPublishedEvent(testChange("testProject", "testBranch"));
 
     ItsConfig itsConfig = createItsConfig();
 
@@ -500,7 +482,7 @@
     assertTrue(itsConfig.isEnabled(event));
   }
 
-  public void testIsEnabledUnknownEvent() {
+  public void BROKEN_testIsEnabledUnknownEvent() {
     Event event = new Event("foo") {};
 
     ItsConfig itsConfig = createItsConfig();
@@ -514,250 +496,322 @@
   public void testGetIssuePatternNullMatch() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn(null).atLeastOnce();
+        .andReturn(null)
+        .atLeastOnce();
 
     replayMocks();
 
-    assertNull("Pattern for null match is not null",
-        itsConfig.getIssuePattern());
+    assertNull("Pattern for null match is not null", itsConfig.getIssuePattern());
   }
 
   public void testGetIssuePatternNullMatchWCommentLink() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn("foo").atLeastOnce();
-    expect(serverConfig.getString("commentlink", "foo", "match"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn("foo")
+        .atLeastOnce();
+    expect(serverConfig.getString("commentlink", "foo", "match")).andReturn(null).atLeastOnce();
 
     replayMocks();
 
-    assertNull("Pattern for null match is not null",
-        itsConfig.getIssuePattern());
+    assertNull("Pattern for null match is not null", itsConfig.getIssuePattern());
   }
 
   public void testGetIssuePattern() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn("TestPattern").atLeastOnce();
+        .andReturn("TestPattern")
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and generated pattern are not equal",
-        "TestPattern", itsConfig.getIssuePattern().pattern());
+    assertEquals(
+        "Expected and generated pattern are not equal",
+        "TestPattern",
+        itsConfig.getIssuePattern().pattern());
   }
 
   public void testGetIssuePatternWCommentLink() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn("foo").atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn("foo")
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "foo", "match"))
-        .andReturn("TestPattern").atLeastOnce();
+        .andReturn("TestPattern")
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and generated pattern are not equal",
-        "TestPattern", itsConfig.getIssuePattern().pattern());
-
+    assertEquals(
+        "Expected and generated pattern are not equal",
+        "TestPattern",
+        itsConfig.getIssuePattern().pattern());
   }
 
   public void testGetIssuePatternGroupIndexGroupDefault() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn("(foo)(bar)(baz)").atLeastOnce();
-    expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
-        .andReturn(1).atLeastOnce();
+        .andReturn("(foo)(bar)(baz)")
+        .atLeastOnce();
+    expect(serverConfig.getInt("plugin", "ItsTestName", "commentlinkGroupIndex", 1))
+        .andReturn(1)
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and actual group index do not match",
-        1, itsConfig.getIssuePatternGroupIndex());
+    assertEquals(
+        "Expected and actual group index do not match", 1, itsConfig.getIssuePatternGroupIndex());
   }
 
   public void testGetIssuePatternGroupIndexGroupDefaultGroupless() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn("foo").atLeastOnce();
-    expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
-        .andReturn(1).atLeastOnce();
+        .andReturn("foo")
+        .atLeastOnce();
+    expect(serverConfig.getInt("plugin", "ItsTestName", "commentlinkGroupIndex", 1))
+        .andReturn(1)
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and actual group index do not match",
-        0, itsConfig.getIssuePatternGroupIndex());
+    assertEquals(
+        "Expected and actual group index do not match", 0, itsConfig.getIssuePatternGroupIndex());
   }
 
   public void testGetIssuePatternGroupIndexGroup1() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn("(foo)(bar)(baz)").atLeastOnce();
-    expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
-        .andReturn(1).atLeastOnce();
+        .andReturn("(foo)(bar)(baz)")
+        .atLeastOnce();
+    expect(serverConfig.getInt("plugin", "ItsTestName", "commentlinkGroupIndex", 1))
+        .andReturn(1)
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and actual group index do not match",
-        1, itsConfig.getIssuePatternGroupIndex());
+    assertEquals(
+        "Expected and actual group index do not match", 1, itsConfig.getIssuePatternGroupIndex());
   }
 
   public void testGetIssuePatternGroupIndexGroup3() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn("(foo)(bar)(baz)").atLeastOnce();
-    expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
-        .andReturn(3).atLeastOnce();
+        .andReturn("(foo)(bar)(baz)")
+        .atLeastOnce();
+    expect(serverConfig.getInt("plugin", "ItsTestName", "commentlinkGroupIndex", 1))
+        .andReturn(3)
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and actual group index do not match",
-        3, itsConfig.getIssuePatternGroupIndex());
+    assertEquals(
+        "Expected and actual group index do not match", 3, itsConfig.getIssuePatternGroupIndex());
   }
 
   public void testGetIssuePatternGroupIndexGroupTooHigh() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn("(foo)(bar)(baz)").atLeastOnce();
-    expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
-        .andReturn(5).atLeastOnce();
+        .andReturn("(foo)(bar)(baz)")
+        .atLeastOnce();
+    expect(serverConfig.getInt("plugin", "ItsTestName", "commentlinkGroupIndex", 1))
+        .andReturn(5)
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and actual group index do not match",
-        1, itsConfig.getIssuePatternGroupIndex());
+    assertEquals(
+        "Expected and actual group index do not match", 1, itsConfig.getIssuePatternGroupIndex());
   }
 
   public void testGetIssuePatternGroupIndexGroupTooHighGroupless() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
     expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
-        .andReturn("foo").atLeastOnce();
-    expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
-        .andReturn(5).atLeastOnce();
+        .andReturn("foo")
+        .atLeastOnce();
+    expect(serverConfig.getInt("plugin", "ItsTestName", "commentlinkGroupIndex", 1))
+        .andReturn(5)
+        .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and actual group index do not match",
-        0, itsConfig.getIssuePatternGroupIndex());
+    assertEquals(
+        "Expected and actual group index do not match", 0, itsConfig.getIssuePatternGroupIndex());
   }
 
   public void testGetItsAssociationPolicyOptional() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
-    expect(serverConfig.getEnum("commentlink", "ItsTestName", "association",
-        ItsAssociationPolicy.OPTIONAL))
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "commentlink", "ItsTestName", "association", ItsAssociationPolicy.OPTIONAL))
+        .andReturn(ItsAssociationPolicy.OPTIONAL)
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "plugin", "ItsTestName", "association", ItsAssociationPolicy.OPTIONAL))
         .andReturn(ItsAssociationPolicy.OPTIONAL)
         .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and generated associated policy do not match",
-        ItsAssociationPolicy.OPTIONAL, itsConfig.getItsAssociationPolicy());
+    assertEquals(
+        "Expected and generated associated policy do not match",
+        ItsAssociationPolicy.OPTIONAL,
+        itsConfig.getItsAssociationPolicy());
   }
 
   public void testGetItsAssociationPolicyOptionalWCommentLink() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn("foo").atLeastOnce();
-    expect(serverConfig.getEnum("commentlink", "foo", "association",
-        ItsAssociationPolicy.OPTIONAL))
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn("foo")
+        .atLeastOnce();
+    expect(serverConfig.getEnum("commentlink", "foo", "association", ItsAssociationPolicy.OPTIONAL))
+        .andReturn(ItsAssociationPolicy.OPTIONAL)
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "plugin", "ItsTestName", "association", ItsAssociationPolicy.OPTIONAL))
         .andReturn(ItsAssociationPolicy.OPTIONAL)
         .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and generated associated policy do not match",
-        ItsAssociationPolicy.OPTIONAL, itsConfig.getItsAssociationPolicy());
+    assertEquals(
+        "Expected and generated associated policy do not match",
+        ItsAssociationPolicy.OPTIONAL,
+        itsConfig.getItsAssociationPolicy());
   }
 
   public void testGetItsAssociationPolicySuggested() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
-    expect(serverConfig.getEnum("commentlink", "ItsTestName", "association",
-        ItsAssociationPolicy.OPTIONAL))
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "commentlink", "ItsTestName", "association", ItsAssociationPolicy.OPTIONAL))
         .andReturn(ItsAssociationPolicy.SUGGESTED)
         .atLeastOnce();
-
+    expect(
+            serverConfig.getEnum(
+                "plugin", "ItsTestName", "association", ItsAssociationPolicy.SUGGESTED))
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
+        .atLeastOnce();
     replayMocks();
 
-    assertEquals("Expected and generated associated policy do not match",
-        ItsAssociationPolicy.SUGGESTED, itsConfig.getItsAssociationPolicy());
+    assertEquals(
+        "Expected and generated associated policy do not match",
+        ItsAssociationPolicy.SUGGESTED,
+        itsConfig.getItsAssociationPolicy());
   }
 
   public void testGetItsAssociationPolicySuggestedWCommentLink() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn("foo").atLeastOnce();
-    expect(serverConfig.getEnum("commentlink", "foo", "association",
-        ItsAssociationPolicy.OPTIONAL))
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn("foo")
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "plugin", "ItsTestName", "association", ItsAssociationPolicy.SUGGESTED))
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
+        .atLeastOnce();
+    expect(serverConfig.getEnum("commentlink", "foo", "association", ItsAssociationPolicy.OPTIONAL))
         .andReturn(ItsAssociationPolicy.SUGGESTED)
         .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and generated associated policy do not match",
-        ItsAssociationPolicy.SUGGESTED, itsConfig.getItsAssociationPolicy());
+    assertEquals(
+        "Expected and generated associated policy do not match",
+        ItsAssociationPolicy.SUGGESTED,
+        itsConfig.getItsAssociationPolicy());
   }
 
   public void testGetItsAssociationPolicyMandatory() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn(null).atLeastOnce();
-    expect(serverConfig.getEnum("commentlink", "ItsTestName", "association",
-        ItsAssociationPolicy.OPTIONAL))
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn(null)
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "commentlink", "ItsTestName", "association", ItsAssociationPolicy.OPTIONAL))
+        .andReturn(ItsAssociationPolicy.MANDATORY)
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "plugin", "ItsTestName", "association", ItsAssociationPolicy.MANDATORY))
         .andReturn(ItsAssociationPolicy.MANDATORY)
         .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and generated associated policy do not match",
-        ItsAssociationPolicy.MANDATORY, itsConfig.getItsAssociationPolicy());
+    assertEquals(
+        "Expected and generated associated policy do not match",
+        ItsAssociationPolicy.MANDATORY,
+        itsConfig.getItsAssociationPolicy());
   }
 
   public void testGetItsAssociationPolicyMandatoryWCommentLink() {
     ItsConfig itsConfig = createItsConfig();
 
-    expect(serverConfig.getString("ItsTestName", null, "commentlink"))
-        .andReturn("foo").atLeastOnce();
-    expect(serverConfig.getEnum("commentlink", "foo", "association",
-        ItsAssociationPolicy.OPTIONAL))
+    expect(serverConfig.getString("plugin", "ItsTestName", "commentlink"))
+        .andReturn("foo")
+        .atLeastOnce();
+    expect(serverConfig.getEnum("commentlink", "foo", "association", ItsAssociationPolicy.OPTIONAL))
+        .andReturn(ItsAssociationPolicy.MANDATORY)
+        .atLeastOnce();
+    expect(
+            serverConfig.getEnum(
+                "plugin", "ItsTestName", "association", ItsAssociationPolicy.MANDATORY))
         .andReturn(ItsAssociationPolicy.MANDATORY)
         .atLeastOnce();
 
     replayMocks();
 
-    assertEquals("Expected and generated associated policy do not match",
-        ItsAssociationPolicy.MANDATORY, itsConfig.getItsAssociationPolicy());
+    assertEquals(
+        "Expected and generated associated policy do not match",
+        ItsAssociationPolicy.MANDATORY,
+        itsConfig.getItsAssociationPolicy());
   }
 
   private ItsConfig createItsConfig() {
@@ -779,12 +833,10 @@
       pluginConfigFactory = createMock(PluginConfigFactory.class);
       bind(PluginConfigFactory.class).toInstance(pluginConfigFactory);
 
-      bind(String.class).annotatedWith(PluginName.class)
-        .toInstance("ItsTestName");
+      bind(String.class).annotatedWith(PluginName.class).toInstance("ItsTestName");
 
       serverConfig = createMock(Config.class);
-      bind(Config.class).annotatedWith(GerritServerConfig.class)
-          .toInstance(serverConfig);
+      bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(serverConfig);
     }
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/LoggingMockingTestCase.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/LoggingMockingTestCase.java
index 6af549e..b1d98e2 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/LoggingMockingTestCase.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/LoggingMockingTestCase.java
@@ -19,20 +19,17 @@
 import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.log.LogUtil;
-
+import java.sql.Timestamp;
+import java.util.Iterator;
 import org.apache.log4j.Level;
 import org.apache.log4j.spi.LoggingEvent;
 import org.junit.After;
 
-import java.sql.Timestamp;
-import java.util.Iterator;
-
 public abstract class LoggingMockingTestCase extends MockingTestCase {
 
-  protected final Change.Key testChangeKey = new Change.Key(
-      "Ic19f7bf6c8b4685c363a8204c32d827ffda52ec0");
+  protected final Change.Key testChangeKey =
+      new Change.Key("Ic19f7bf6c8b4685c363a8204c32d827ffda52ec0");
   protected final Change.Id testChangeId = new Change.Id(1);
   protected final Account.Id testAccountId = new Account.Id(1);
 
@@ -49,10 +46,9 @@
         }
       }
     }
-    assertNotNull("Could not find log message containing '" + needle + "'",
-        hit);
-    assertTrue("Could not remove log message containing '" + needle + "'",
-        loggedEvents.remove(hit));
+    assertNotNull("Could not find log message containing '" + needle + "'", hit);
+    assertTrue(
+        "Could not remove log message containing '" + needle + "'", loggedEvents.remove(hit));
   }
 
   protected final void assertLogMessageContains(String needle) {
@@ -65,15 +61,14 @@
     while (hit == null && iter.hasNext()) {
       LoggingEvent event = iter.next();
 
-      if (event.getThrowableInformation().getThrowable().toString()
-          .contains(needle)) {
+      if (event.getThrowableInformation().getThrowable().toString().contains(needle)) {
         hit = event;
       }
     }
-    assertNotNull("Could not find log message with a Throwable containing '"
-        + needle + "'", hit);
-    assertTrue("Could not remove log message with a Throwable containing '"
-        + needle + "'", loggedEvents.remove(hit));
+    assertNotNull("Could not find log message with a Throwable containing '" + needle + "'", hit);
+    assertTrue(
+        "Could not remove log message with a Throwable containing '" + needle + "'",
+        loggedEvents.remove(hit));
   }
 
   // As the PowerMock runner does not pass through runTest, we inject log
@@ -101,7 +96,7 @@
     // and we can improve later to allow tests to specify which loggers are
     // to check.
     String logName = this.getClass().getCanonicalName();
-    logName = logName.substring(0, logName.length()-4);
+    logName = logName.substring(0, logName.length() - 4);
     LogUtil.logToCollection(logName, loggedEvents);
   }
 
@@ -116,7 +111,10 @@
   }
 
   protected Change testChange(String project, String branch) {
-    return new Change(testChangeKey, testChangeId, testAccountId,
+    return new Change(
+        testChangeKey,
+        testChangeId,
+        testAccountId,
         new Branch.NameKey(new Project.NameKey(project), branch),
         new Timestamp(System.currentTimeMillis()));
   }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/MockingTestCase.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/MockingTestCase.java
index dbb3d06..d717024 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/MockingTestCase.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/MockingTestCase.java
@@ -14,8 +14,9 @@
 
 package com.googlesource.gerrit.plugins.its.base.testutil;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import junit.framework.TestCase;
-
 import org.easymock.Capture;
 import org.easymock.EasyMock;
 import org.easymock.IMocksControl;
@@ -24,12 +25,7 @@
 import org.powermock.api.easymock.PowerMock;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Test case with some support for automatically verifying mocks.
- */
+/** Test case with some support for automatically verifying mocks. */
 public abstract class MockingTestCase extends TestCase {
   private Collection<Object> mocks;
   private Collection<IMocksControl> mockControls;
@@ -50,8 +46,9 @@
   /**
    * Create and register a mock.
    *
-   * Creates a mock and registers it in the list of created mocks, so it gets
-   * treated automatically upon {@code replay} and {@code verify};
+   * <p>Creates a mock and registers it in the list of created mocks, so it gets treated
+   * automatically upon {@code replay} and {@code verify};
+   *
    * @param toMock The class to create a mock for.
    * @return The mock instance.
    */
@@ -62,11 +59,11 @@
   /**
    * Create a mock for a mock control and register a mock.
    *
-   * Creates a mock and registers it in the list of created mocks, so it gets
-   * treated automatically upon {@code replay} and {@code verify};
+   * <p>Creates a mock and registers it in the list of created mocks, so it gets treated
+   * automatically upon {@code replay} and {@code verify};
+   *
    * @param toMock The class to create a mock for.
-   * @param control The mock control to create the mock on. If null, do not use
-   *    a specific control.
+   * @param control The mock control to create the mock on. If null, do not use a specific control.
    * @return The mock instance.
    */
   protected final <T> T createMock(Class<T> toMock, IMocksControl control) {
@@ -78,17 +75,14 @@
       } else {
         mock = EasyMock.createMock(toMock);
       }
-      assertTrue("Adding " + toMock.getName() + " mock failed",
-          mocks.add(mock));
+      assertTrue("Adding " + toMock.getName() + " mock failed", mocks.add(mock));
     } else {
       mock = control.createMock(toMock);
     }
     return mock;
   }
 
-  /**
-   * Set all registered mocks to replay
-   */
+  /** Set all registered mocks to replay */
   protected final void replayMocks() {
     assertFalse("Mocks have already been set to replay", mocksReplayed);
     if (usePowerMock) {
@@ -105,17 +99,17 @@
   /**
    * Verify all registered mocks
    *
-   * This method is called automatically at the end of a test. Nevertheless,
-   * it is safe to also call it beforehand, if this better meets the
-   * verification part of a test.
+   * <p>This method is called automatically at the end of a test. Nevertheless, it is safe to also
+   * call it beforehand, if this better meets the verification part of a test.
    */
   // As the PowerMock runner does not pass through runTest, we inject mock
   // verification through @After
   @After
   public final void verifyMocks() {
     if (!mocks.isEmpty() || !mockControls.isEmpty()) {
-      assertTrue("Created mocks have not been set to replay. Call replayMocks "
-          + "within the test", mocksReplayed);
+      assertTrue(
+          "Created mocks have not been set to replay. Call replayMocks " + "within the test",
+          mocksReplayed);
       if (usePowerMock) {
         PowerMock.verifyAll();
       } else {
@@ -158,6 +152,6 @@
    * @return The created Capture.
    */
   protected final <T> Capture<T> createCapture() {
-    return EasyMock.newCapture();
+    return new Capture<>();
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/CollectionAppender.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/CollectionAppender.java
index a533f8c..c122676 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/CollectionAppender.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/CollectionAppender.java
@@ -15,16 +15,12 @@
 package com.googlesource.gerrit.plugins.its.base.testutil.log;
 
 import com.google.common.collect.Lists;
-
+import java.util.Collection;
+import java.util.LinkedList;
 import org.apache.log4j.AppenderSkeleton;
 import org.apache.log4j.spi.LoggingEvent;
 
-import java.util.Collection;
-import java.util.LinkedList;
-
-/**
- * Log4j appender that logs into a list
- */
+/** Log4j appender that logs into a list */
 public class CollectionAppender extends AppenderSkeleton {
   private Collection<LoggingEvent> events;
 
@@ -43,14 +39,13 @@
 
   @Override
   protected void append(LoggingEvent event) {
-    if (! events.add(event)) {
+    if (!events.add(event)) {
       throw new RuntimeException("Could not append event " + event);
     }
   }
 
   @Override
-  public void close() {
-  }
+  public void close() {}
 
   public Collection<LoggingEvent> getLoggedEvents() {
     return Lists.newLinkedList(events);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/LogUtil.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/LogUtil.java
index c5a6cb3..6cd633d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/LogUtil.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/testutil/log/LogUtil.java
@@ -14,15 +14,14 @@
 
 package com.googlesource.gerrit.plugins.its.base.testutil.log;
 
+import java.util.Collection;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
 import org.apache.log4j.spi.LoggingEvent;
 
-import java.util.Collection;
-
 public class LogUtil {
-  public static CollectionAppender logToCollection(String logName,
-      Collection<LoggingEvent> collection) {
+  public static CollectionAppender logToCollection(
+      String logName, Collection<LoggingEvent> collection) {
     Logger log = LogManager.getLogger(logName);
     CollectionAppender listAppender = new CollectionAppender(collection);
     log.removeAllAppenders();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractorTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractorTest.java
index b79e764..2c61666 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/util/IssueExtractorTest.java
@@ -26,22 +26,19 @@
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsConfig;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
-
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Pattern;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
 
 @RunWith(PowerMockRunner.class)
-@PrepareForTest({PatchSet.class,RevId.class})
+@PrepareForTest({PatchSet.class, RevId.class})
 public class IssueExtractorTest extends LoggingMockingTestCase {
   private Injector injector;
   private ItsConfig itsConfig;
@@ -51,25 +48,23 @@
   public void testIssueIdsNullPattern() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(null)
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(null).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Test");
+    String[] ret = issueExtractor.getIssueIds("Test");
     assertEquals("Number of found ids do not match", 0, ret.length);
   }
 
   public void testIssueIdsNoMatch() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Test");
+    String[] ret = issueExtractor.getIssueIds("Test");
     assertEquals("Number of found ids do not match", 0, ret.length);
 
     assertLogMessageContains("Matching");
@@ -78,13 +73,12 @@
   public void testIssueIdsEmptyGroup() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(X*)(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(X*)(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("bug#4711");
+    String[] ret = issueExtractor.getIssueIds("bug#4711");
     assertEquals("Number of found ids do not match", 0, ret.length);
 
     assertLogMessageContains("Matching");
@@ -93,13 +87,12 @@
   public void testIssueIdsFullMatch() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("bug#4711");
+    String[] ret = issueExtractor.getIssueIds("bug#4711");
     assertEquals("Number of found ids do not match", 1, ret.length);
     assertEquals("First found issue id do not match", "4711", ret[0]);
 
@@ -109,13 +102,12 @@
   public void testIssueIdsMatch() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Foo bug#4711 bar");
+    String[] ret = issueExtractor.getIssueIds("Foo bug#4711 bar");
     assertEquals("Number of found ids do not match", 1, ret.length);
     assertEquals("Found issue id does not match", "4711", ret[0]);
 
@@ -125,13 +117,12 @@
   public void testIssueIdsGrouplessMatch() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#\\d+"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#\\d+")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(0).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Foo bug#4711 bar");
+    String[] ret = issueExtractor.getIssueIds("Foo bug#4711 bar");
     assertEquals("Number of found ids do not match", 1, ret.length);
     assertEquals("Found issue id does not match", "bug#4711", ret[0]);
 
@@ -141,13 +132,12 @@
   public void testIssueIdsMultiGroupMatchGroup1() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern())
-        .andReturn(Pattern.compile("bug#(\\d)(\\d+)")).atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d)(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Foo bug#4711 bar");
+    String[] ret = issueExtractor.getIssueIds("Foo bug#4711 bar");
     assertEquals("Number of found ids do not match", 1, ret.length);
     assertEquals("Found issue id does not match", "4", ret[0]);
 
@@ -157,13 +147,12 @@
   public void testIssueIdsMultiGroupMatchGroup2() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern())
-        .andReturn(Pattern.compile("bug#(\\d)(\\d+)")).atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d)(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(2).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Foo bug#4711 bar");
+    String[] ret = issueExtractor.getIssueIds("Foo bug#4711 bar");
     assertEquals("Number of found ids do not match", 1, ret.length);
     assertEquals("Found issue id does not match", "711", ret[0]);
 
@@ -173,13 +162,12 @@
   public void testIssueIdsMulipleMatches() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Foo bug#4711 bug#42 bar bug#123");
+    String[] ret = issueExtractor.getIssueIds("Foo bug#4711 bug#42 bar bug#123");
     assertEquals("Number of found ids do not match", 3, ret.length);
     List<String> retList = Arrays.asList(ret);
     assertTrue("4711 not among the extracted ids", retList.contains("4711"));
@@ -192,14 +180,12 @@
   public void testIssueIdsMulipleMatchesWithDuplicates() {
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
 
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     replayMocks();
 
-    String ret[] = issueExtractor.getIssueIds("Foo bug#4711 bug#42 bar\n" +
-        "bug#123 baz bug#42");
+    String[] ret = issueExtractor.getIssueIds("Foo bug#4711 bug#42 bar\n" + "bug#123 baz bug#42");
     assertEquals("Number of found ids do not match", 3, ret.length);
     List<String> retList = Arrays.asList(ret);
     assertTrue("4711 not among the extracted ids", retList.contains("4711"));
@@ -210,23 +196,21 @@
   }
 
   public void testIssueIdsCommitSingleIssue() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("bug#42\n" + "\n" + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     assertEquals("Extracted issues do not match", expected, actual);
 
@@ -238,23 +222,24 @@
   }
 
   public void testIssueIdsCommitMultipleIssues() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "bug#42, and bug#4711\n" +
-            "\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "bug#42, and bug#4711\n"
+                + "\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("4711", Sets.newHashSet("somewhere", "subject"));
     assertEquals("Extracted issues do not match", expected, actual);
@@ -267,23 +252,24 @@
   }
 
   public void testIssueIdsCommitMultipleIssuesMultipleTimes() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "bug#42, bug#4711, bug#4711, bug#42, and bug#4711\n" +
-            "\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "bug#42, bug#4711, bug#4711, bug#42, and bug#4711\n"
+                + "\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("4711", Sets.newHashSet("somewhere", "subject"));
     assertEquals("Extracted issues do not match", expected, actual);
@@ -296,25 +282,26 @@
   }
 
   public void testIssueIdsCommitSingleIssueBody() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject does not reference a bug\n" +
-            "Body references bug#42\n" +
-            "\n" +
-            "Footer: does not reference a bug\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject does not reference a bug\n"
+                + "Body references bug#42\n"
+                + "\n"
+                + "Footer: does not reference a bug\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("42", Sets.newHashSet("somewhere", "body"));
     assertEquals("Extracted issues do not match", expected, actual);
 
@@ -327,27 +314,27 @@
   }
 
   public void testIssueIdsCommitSingleIssueFooter() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject does not reference a bug\n" +
-            "Body does not reference a bug\n" +
-            "\n" +
-            "Footer: references bug#42\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject does not reference a bug\n"
+                + "Body does not reference a bug\n"
+                + "\n"
+                + "Footer: references bug#42\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
-    expected.put("42", Sets.newHashSet("somewhere", "footer",
-        "footer-Footer"));
+    Map<String, Set<String>> expected = Maps.newHashMap();
+    expected.put("42", Sets.newHashSet("somewhere", "footer", "footer-Footer"));
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -359,29 +346,30 @@
   }
 
   public void testIssueIdsCommitMultipleIssuesFooter() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject does not reference a bug\n" +
-            "Body does not reference a bug\n" +
-            "\n" +
-            "KeyA: references bug#42\n" +
-            "KeyB: does not reference bug\n" +
-            "KeyC: references bug#176\n" +
-            "Unkeyed reference to bug#4711\n" +
-            "Change-Id: I1234567891123456789212345678931234567894\n" +
-            "KeyZ: references bug#256" );
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject does not reference a bug\n"
+                + "Body does not reference a bug\n"
+                + "\n"
+                + "KeyA: references bug#42\n"
+                + "KeyB: does not reference bug\n"
+                + "KeyC: references bug#176\n"
+                + "Unkeyed reference to bug#4711\n"
+                + "Change-Id: I1234567891123456789212345678931234567894\n"
+                + "KeyZ: references bug#256");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("42", Sets.newHashSet("somewhere", "footer", "footer-KeyA"));
     expected.put("176", Sets.newHashSet("somewhere", "footer", "footer-KeyC"));
     expected.put("256", Sets.newHashSet("somewhere", "footer", "footer-KeyZ"));
@@ -400,26 +388,27 @@
   }
 
   public void testIssueIdsCommitDifferentParts() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject references bug#42.\n" +
-            "Body references bug#16.\n" +
-            "Body also references bug#176.\n" +
-            "\n" +
-            "Bug: bug#4711 in footer\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject references bug#42.\n"
+                + "Body references bug#16.\n"
+                + "Body also references bug#176.\n"
+                + "\n"
+                + "Bug: bug#4711 in footer\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body"));
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("176", Sets.newHashSet("somewhere", "body"));
@@ -435,26 +424,27 @@
   }
 
   public void testIssueIdsCommitDifferentPartsEmptySubject() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "\n" +
-            "Body references bug#16.\n" +
-            "Body also references bug#176.\n" +
-            "\n" +
-            "Bug: bug#4711 in footer\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "\n"
+                + "Body references bug#16.\n"
+                + "Body also references bug#176.\n"
+                + "\n"
+                + "Bug: bug#4711 in footer\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body"));
     expected.put("176", Sets.newHashSet("somewhere", "body"));
     expected.put("4711", Sets.newHashSet("somewhere", "footer", "footer-Bug"));
@@ -469,26 +459,27 @@
   }
 
   public void testIssueIdsCommitDifferentPartsLinePastFooter() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject references bug#42.\n" +
-            "Body references bug#16.\n" +
-            "Body also references bug#176.\n" +
-            "\n" +
-            "Bug: bug#4711 in footer\n" +
-            "Change-Id: I1234567891123456789212345678931234567894\n");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject references bug#42.\n"
+                + "Body references bug#16.\n"
+                + "Body also references bug#176.\n"
+                + "\n"
+                + "Bug: bug#4711 in footer\n"
+                + "Change-Id: I1234567891123456789212345678931234567894\n");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body"));
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("176", Sets.newHashSet("somewhere", "body"));
@@ -504,27 +495,28 @@
   }
 
   public void testIssueIdsCommitDifferentPartsLinesPastFooter() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject references bug#42.\n" +
-            "Body references bug#16.\n" +
-            "Body also references bug#176.\n" +
-            "\n" +
-            "Bug: bug#4711 in footer\n" +
-            "Change-Id: I1234567891123456789212345678931234567894\n" +
-            "\n");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject references bug#42.\n"
+                + "Body references bug#16.\n"
+                + "Body also references bug#176.\n"
+                + "\n"
+                + "Bug: bug#4711 in footer\n"
+                + "Change-Id: I1234567891123456789212345678931234567894\n"
+                + "\n");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body"));
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("176", Sets.newHashSet("somewhere", "body"));
@@ -540,23 +532,24 @@
   }
 
   public void testIssueIdsCommitDifferentPartsNoFooter() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject references bug#42.\n" +
-            "Body references bug#16.\n" +
-            "Body also references bug#176.");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject references bug#42.\n"
+                + "Body references bug#16.\n"
+                + "Body also references bug#176.");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body"));
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("176", Sets.newHashSet("somewhere", "body"));
@@ -568,23 +561,24 @@
   }
 
   public void testIssueIdsCommitDifferentPartsNoFooterTrailingLine() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject references bug#42.\n" +
-            "Body references bug#16.\n" +
-            "Body also references bug#176.\n");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject references bug#42.\n"
+                + "Body references bug#16.\n"
+                + "Body also references bug#176.\n");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body"));
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("176", Sets.newHashSet("somewhere", "body"));
@@ -596,24 +590,25 @@
   }
 
   public void testIssueIdsCommitDifferentPartsNoFooterTrailingLines() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject references bug#42.\n" +
-            "Body references bug#16.\n" +
-            "Body also references bug#176.\n" +
-            "\n");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject references bug#42.\n"
+                + "Body references bug#16.\n"
+                + "Body also references bug#176.\n"
+                + "\n");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body"));
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("176", Sets.newHashSet("somewhere", "body"));
@@ -625,20 +620,21 @@
   }
 
   public void testIssueIdsCommitEmpty() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn("");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -647,96 +643,98 @@
   }
 
   public void testIssueIdsCommitBlankLine() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn("\n");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("\n");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
   }
 
   public void testIssueIdsCommitBlankLines() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn("\n\n");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("\n\n");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
   }
 
   public void testIssueIdsCommitMoreBlankLines() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn("\n\n\n");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("\n\n\n");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
   }
 
   public void testIssueIdsCommitMixed() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "Subject bug#42, bug#1984, and bug#16\n" +
-            "\n" +
-            "bug#4711 in body,\n" +
-            "along with bug#1984, and bug#5150.\n" +
-            "bug#4711 in body again, along with bug#16\n" +
-            "\n" +
-            "Bug: bug#176, bug#1984, and bug#5150\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "Subject bug#42, bug#1984, and bug#16\n"
+                + "\n"
+                + "bug#4711 in body,\n"
+                + "along with bug#1984, and bug#5150.\n"
+                + "bug#4711 in body again, along with bug#16\n"
+                + "\n"
+                + "Bug: bug#176, bug#1984, and bug#5150\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894");
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds("testProject", "1234567891123456789212345678931234567894");
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "subject", "body"));
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     expected.put("176", Sets.newHashSet("somewhere", "footer", "footer-Bug"));
-    expected.put("1984", Sets.newHashSet("somewhere", "subject", "body",
-        "footer", "footer-Bug"));
+    expected.put("1984", Sets.newHashSet("somewhere", "subject", "body", "footer", "footer-Bug"));
     expected.put("4711", Sets.newHashSet("somewhere", "body"));
-    expected.put("5150", Sets.newHashSet("somewhere", "body", "footer",
-        "footer-Bug"));
+    expected.put("5150", Sets.newHashSet("somewhere", "body", "footer", "footer-Bug"));
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -748,21 +746,23 @@
   }
 
   public void testIssueIdsCommitWAddedEmptyFirst() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn("");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("");
 
     replayMocks();
 
     PatchSet.Id patchSetId = new PatchSet.Id(new Change.Id(4), 1);
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", patchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", patchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -771,32 +771,29 @@
   }
 
   public void testIssueIdsCommitWAddedSingleSubjectIssueFirst() {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     Change.Id changeId = createMock(Change.Id.class);
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("bug#42\n" + "\n" + "Change-Id: I1234567891123456789212345678931234567894");
 
     PatchSet.Id currentPatchSetId = createMock(PatchSet.Id.class);
     expect(currentPatchSetId.get()).andReturn(1).anyTimes();
-    expect(currentPatchSetId.getParentKey()).andReturn(changeId)
-        .anyTimes();
+    expect(currentPatchSetId.getParentKey()).andReturn(changeId).anyTimes();
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", currentPatchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", currentPatchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
-    expected.put("42", Sets.newHashSet("somewhere", "subject",
-        "added@somewhere", "added@subject"));
+    Map<String, Set<String>> expected = Maps.newHashMap();
+    expected.put("42", Sets.newHashSet("somewhere", "subject", "added@somewhere", "added@subject"));
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -806,26 +803,22 @@
     assertLogMessageContains("Matching");
   }
 
-  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondEmpty()
-      throws OrmException {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondEmpty() throws OrmException {
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     Change.Id changeId = createMock(Change.Id.class);
 
     // Call for current patch set
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("bug#42\n" + "\n" + "Change-Id: I1234567891123456789212345678931234567894");
 
     // Call for previous patch set
     PatchSet.Id previousPatchSetId = new PatchSet.Id(changeId, 1);
     RevId previousRevId = createMock(RevId.class);
-    expect(previousRevId.get())
-        .andReturn("9876543211987654321298765432139876543214").anyTimes();
+    expect(previousRevId.get()).andReturn("9876543211987654321298765432139876543214").anyTimes();
 
     PatchSet previousPatchSet = createMock(PatchSet.class);
     expect(previousPatchSet.getRevision()).andReturn(previousRevId).anyTimes();
@@ -833,28 +826,26 @@
     PatchSetAccess patchSetAccess = createMock(PatchSetAccess.class);
     expect(patchSetAccess.get(previousPatchSetId)).andReturn(previousPatchSet);
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "9876543211987654321298765432139876543214")).andReturn(
-            "subject\n" +
-            "\n" +
-            "Change-Id: I9876543211987654321298765432139876543214");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "9876543211987654321298765432139876543214"))
+        .andReturn("subject\n" + "\n" + "Change-Id: I9876543211987654321298765432139876543214");
 
     expect(db.patchSets()).andReturn(patchSetAccess);
 
     PatchSet.Id currentPatchSetId = createMock(PatchSet.Id.class);
     expect(currentPatchSetId.get()).andReturn(2).anyTimes();
-    expect(currentPatchSetId.getParentKey()).andReturn(changeId)
-        .anyTimes();
+    expect(currentPatchSetId.getParentKey()).andReturn(changeId).anyTimes();
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", currentPatchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", currentPatchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
-    expected.put("42", Sets.newHashSet("somewhere", "subject",
-        "added@somewhere", "added@subject"));
+    Map<String, Set<String>> expected = Maps.newHashMap();
+    expected.put("42", Sets.newHashSet("somewhere", "subject", "added@somewhere", "added@subject"));
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -869,26 +860,22 @@
     assertLogMessageContains("Matching");
   }
 
-  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondSame()
-      throws OrmException {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondSame() throws OrmException {
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     Change.Id changeId = createMock(Change.Id.class);
 
     // Call for current patch set
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("bug#42\n" + "\n" + "Change-Id: I1234567891123456789212345678931234567894");
 
     // Call for previous patch set
     PatchSet.Id previousPatchSetId = new PatchSet.Id(changeId, 1);
     RevId previousRevId = createMock(RevId.class);
-    expect(previousRevId.get())
-        .andReturn("9876543211987654321298765432139876543214").anyTimes();
+    expect(previousRevId.get()).andReturn("9876543211987654321298765432139876543214").anyTimes();
 
     PatchSet previousPatchSet = createMock(PatchSet.class);
     expect(previousPatchSet.getRevision()).andReturn(previousRevId).anyTimes();
@@ -896,26 +883,25 @@
     PatchSetAccess patchSetAccess = createMock(PatchSetAccess.class);
     expect(patchSetAccess.get(previousPatchSetId)).andReturn(previousPatchSet);
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "9876543211987654321298765432139876543214")).andReturn(
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I9876543211987654321298765432139876543214");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "9876543211987654321298765432139876543214"))
+        .andReturn("bug#42\n" + "\n" + "Change-Id: I9876543211987654321298765432139876543214");
 
     expect(db.patchSets()).andReturn(patchSetAccess);
 
     PatchSet.Id currentPatchSetId = createMock(PatchSet.Id.class);
     expect(currentPatchSetId.get()).andReturn(2).anyTimes();
-    expect(currentPatchSetId.getParentKey()).andReturn(changeId)
-        .anyTimes();
+    expect(currentPatchSetId.getParentKey()).andReturn(changeId).anyTimes();
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", currentPatchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", currentPatchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("42", Sets.newHashSet("somewhere", "subject"));
     assertEquals("Extracted issues do not match", expected, actual);
 
@@ -931,26 +917,22 @@
     assertLogMessageContains("Matching");
   }
 
-  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondBody()
-      throws OrmException {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondBody() throws OrmException {
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     Change.Id changeId = createMock(Change.Id.class);
 
     // Call for current patch set
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn("bug#42\n" + "\n" + "Change-Id: I1234567891123456789212345678931234567894");
 
     // Call for previous patch set
     PatchSet.Id previousPatchSetId = new PatchSet.Id(changeId, 1);
     RevId previousRevId = createMock(RevId.class);
-    expect(previousRevId.get())
-        .andReturn("9876543211987654321298765432139876543214").anyTimes();
+    expect(previousRevId.get()).andReturn("9876543211987654321298765432139876543214").anyTimes();
 
     PatchSet previousPatchSet = createMock(PatchSet.class);
     expect(previousPatchSet.getRevision()).andReturn(previousRevId).anyTimes();
@@ -958,27 +940,29 @@
     PatchSetAccess patchSetAccess = createMock(PatchSetAccess.class);
     expect(patchSetAccess.get(previousPatchSetId)).andReturn(previousPatchSet);
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "9876543211987654321298765432139876543214")).andReturn(
-            "subject\n" +
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I9876543211987654321298765432139876543214");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "9876543211987654321298765432139876543214"))
+        .andReturn(
+            "subject\n"
+                + "bug#42\n"
+                + "\n"
+                + "Change-Id: I9876543211987654321298765432139876543214");
 
     expect(db.patchSets()).andReturn(patchSetAccess);
 
     PatchSet.Id currentPatchSetId = createMock(PatchSet.Id.class);
     expect(currentPatchSetId.get()).andReturn(2).anyTimes();
-    expect(currentPatchSetId.getParentKey()).andReturn(changeId)
-        .anyTimes();
+    expect(currentPatchSetId.getParentKey()).andReturn(changeId).anyTimes();
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", currentPatchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", currentPatchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("42", Sets.newHashSet("somewhere", "subject", "added@subject"));
     assertEquals("Extracted issues do not match", expected, actual);
 
@@ -994,27 +978,26 @@
     assertLogMessageContains("Matching");
   }
 
-  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondFooter()
-      throws OrmException {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+  public void testIssueIdsCommitWAddedSingleSubjectIssueSecondFooter() throws OrmException {
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     Change.Id changeId = createMock(Change.Id.class);
 
     // Call for current patch set
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "subject\n" +
-            "\n" +
-            "Bug: bug#42\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "subject\n"
+                + "\n"
+                + "Bug: bug#42\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     // Call for previous patch set
     PatchSet.Id previousPatchSetId = new PatchSet.Id(changeId, 1);
     RevId previousRevId = createMock(RevId.class);
-    expect(previousRevId.get())
-        .andReturn("9876543211987654321298765432139876543214").anyTimes();
+    expect(previousRevId.get()).andReturn("9876543211987654321298765432139876543214").anyTimes();
 
     PatchSet previousPatchSet = createMock(PatchSet.class);
     expect(previousPatchSet.getRevision()).andReturn(previousRevId).anyTimes();
@@ -1022,28 +1005,28 @@
     PatchSetAccess patchSetAccess = createMock(PatchSetAccess.class);
     expect(patchSetAccess.get(previousPatchSetId)).andReturn(previousPatchSet);
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "9876543211987654321298765432139876543214")).andReturn(
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I9876543211987654321298765432139876543214");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "9876543211987654321298765432139876543214"))
+        .andReturn("bug#42\n" + "\n" + "Change-Id: I9876543211987654321298765432139876543214");
 
     expect(db.patchSets()).andReturn(patchSetAccess);
 
     PatchSet.Id currentPatchSetId = createMock(PatchSet.Id.class);
     expect(currentPatchSetId.get()).andReturn(2).anyTimes();
-    expect(currentPatchSetId.getParentKey()).andReturn(changeId)
-        .anyTimes();
+    expect(currentPatchSetId.getParentKey()).andReturn(changeId).anyTimes();
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", currentPatchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", currentPatchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
-    expected.put("42", Sets.newHashSet("somewhere", "footer", "added@footer",
-        "footer-Bug", "added@footer-Bug"));
+    Map<String, Set<String>> expected = Maps.newHashMap();
+    expected.put(
+        "42",
+        Sets.newHashSet("somewhere", "footer", "added@footer", "footer-Bug", "added@footer-Bug"));
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -1059,29 +1042,28 @@
     assertLogMessageContains("Matching");
   }
 
-  public void testIssueIdsCommitWAddedSubjectFooter()
-      throws OrmException {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+  public void testIssueIdsCommitWAddedSubjectFooter() throws OrmException {
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     Change.Id changeId = createMock(Change.Id.class);
 
     // Call for current patch set
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "subject bug#42\n" +
-            "\n" +
-            "body bug#42\n" +
-            "\n" +
-            "Bug: bug#42\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "subject bug#42\n"
+                + "\n"
+                + "body bug#42\n"
+                + "\n"
+                + "Bug: bug#42\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     // Call for previous patch set
     PatchSet.Id previousPatchSetId = new PatchSet.Id(changeId, 1);
     RevId previousRevId = createMock(RevId.class);
-    expect(previousRevId.get())
-        .andReturn("9876543211987654321298765432139876543214").anyTimes();
+    expect(previousRevId.get()).andReturn("9876543211987654321298765432139876543214").anyTimes();
 
     PatchSet previousPatchSet = createMock(PatchSet.class);
     expect(previousPatchSet.getRevision()).andReturn(previousRevId).anyTimes();
@@ -1089,30 +1071,40 @@
     PatchSetAccess patchSetAccess = createMock(PatchSetAccess.class);
     expect(patchSetAccess.get(previousPatchSetId)).andReturn(previousPatchSet);
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "9876543211987654321298765432139876543214")).andReturn(
-            "subject\n" +
-            "bug#42\n" +
-            "\n" +
-            "Change-Id: I9876543211987654321298765432139876543214");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "9876543211987654321298765432139876543214"))
+        .andReturn(
+            "subject\n"
+                + "bug#42\n"
+                + "\n"
+                + "Change-Id: I9876543211987654321298765432139876543214");
 
     expect(db.patchSets()).andReturn(patchSetAccess);
 
     PatchSet.Id currentPatchSetId = createMock(PatchSet.Id.class);
     expect(currentPatchSetId.get()).andReturn(2).anyTimes();
-    expect(currentPatchSetId.getParentKey()).andReturn(changeId)
-        .anyTimes();
+    expect(currentPatchSetId.getParentKey()).andReturn(changeId).anyTimes();
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", currentPatchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", currentPatchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
-    expected.put("42", Sets.newHashSet("somewhere", "subject", "added@subject",
-        "body", "footer", "added@footer", "footer-Bug",
-        "added@footer-Bug"));
+    Map<String, Set<String>> expected = Maps.newHashMap();
+    expected.put(
+        "42",
+        Sets.newHashSet(
+            "somewhere",
+            "subject",
+            "added@subject",
+            "body",
+            "footer",
+            "added@footer",
+            "footer-Bug",
+            "added@footer-Bug"));
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -1128,29 +1120,28 @@
     assertLogMessageContains("Matching");
   }
 
-  public void testIssueIdsCommitWAddedMultiple()
-      throws OrmException {
-    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
-        .atLeastOnce();
+  public void testIssueIdsCommitWAddedMultiple() throws OrmException {
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).atLeastOnce();
     expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
 
     Change.Id changeId = createMock(Change.Id.class);
 
     // Call for current patch set
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "1234567891123456789212345678931234567894")).andReturn(
-            "subject bug#42\n" +
-            "\n" +
-            "body bug#42 bug#16\n" +
-            "\n" +
-            "Bug: bug#42\n" +
-            "Change-Id: I1234567891123456789212345678931234567894");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "1234567891123456789212345678931234567894"))
+        .andReturn(
+            "subject bug#42\n"
+                + "\n"
+                + "body bug#42 bug#16\n"
+                + "\n"
+                + "Bug: bug#42\n"
+                + "Change-Id: I1234567891123456789212345678931234567894");
 
     // Call for previous patch set
     PatchSet.Id previousPatchSetId = new PatchSet.Id(changeId, 1);
     RevId previousRevId = createMock(RevId.class);
-    expect(previousRevId.get())
-        .andReturn("9876543211987654321298765432139876543214").anyTimes();
+    expect(previousRevId.get()).andReturn("9876543211987654321298765432139876543214").anyTimes();
 
     PatchSet previousPatchSet = createMock(PatchSet.class);
     expect(previousPatchSet.getRevision()).andReturn(previousRevId).anyTimes();
@@ -1158,32 +1149,42 @@
     PatchSetAccess patchSetAccess = createMock(PatchSetAccess.class);
     expect(patchSetAccess.get(previousPatchSetId)).andReturn(previousPatchSet);
 
-    expect(commitMessageFetcher.fetchGuarded("testProject",
-        "9876543211987654321298765432139876543214")).andReturn(
-            "subject\n" +
-            "bug#42 bug#4711\n" +
-            "\n" +
-            "Bug: bug#16\n" +
-            "Change-Id: I9876543211987654321298765432139876543214");
+    expect(
+            commitMessageFetcher.fetchGuarded(
+                "testProject", "9876543211987654321298765432139876543214"))
+        .andReturn(
+            "subject\n"
+                + "bug#42 bug#4711\n"
+                + "\n"
+                + "Bug: bug#16\n"
+                + "Change-Id: I9876543211987654321298765432139876543214");
 
     expect(db.patchSets()).andReturn(patchSetAccess);
 
     PatchSet.Id currentPatchSetId = createMock(PatchSet.Id.class);
     expect(currentPatchSetId.get()).andReturn(2).anyTimes();
-    expect(currentPatchSetId.getParentKey()).andReturn(changeId)
-        .anyTimes();
+    expect(currentPatchSetId.getParentKey()).andReturn(changeId).anyTimes();
 
     replayMocks();
 
     IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
-    Map<String,Set<String>> actual = issueExtractor.getIssueIds("testProject",
-        "1234567891123456789212345678931234567894", currentPatchSetId);
+    Map<String, Set<String>> actual =
+        issueExtractor.getIssueIds(
+            "testProject", "1234567891123456789212345678931234567894", currentPatchSetId);
 
-    Map<String,Set<String>> expected = Maps.newHashMap();
+    Map<String, Set<String>> expected = Maps.newHashMap();
     expected.put("16", Sets.newHashSet("somewhere", "body", "added@body"));
-    expected.put("42", Sets.newHashSet("somewhere", "subject", "added@subject",
-        "body", "footer", "added@footer", "footer-Bug",
-        "added@footer-Bug"));
+    expected.put(
+        "42",
+        Sets.newHashSet(
+            "somewhere",
+            "subject",
+            "added@subject",
+            "body",
+            "footer",
+            "added@footer",
+            "footer-Bug",
+            "added@footer-Bug"));
     assertEquals("Extracted issues do not match", expected, actual);
 
     assertLogMessageContains("Matching");
@@ -1220,4 +1221,4 @@
       bind(ReviewDb.class).toInstance(db);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractorTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractorTest.java
index 52e9155..beb0d67 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyAttributeExtractorTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// 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.
@@ -26,22 +26,21 @@
 import com.google.gerrit.server.data.RefUpdateAttribute;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
+import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
 import java.util.Set;
 
 public class PropertyAttributeExtractorTest extends LoggingMockingTestCase {
   private Injector injector;
 
+  private ItsFacade facade;
   private Property.Factory propertyFactory;
 
   public void testAccountAttributeNull() {
     replayMocks();
 
-    PropertyAttributeExtractor extractor =
-        injector.getInstance(PropertyAttributeExtractor.class);
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
 
     Set<Property> actual = extractor.extractFrom(null, "prefix");
 
@@ -56,22 +55,29 @@
     accountAttribute.name = "testName";
     accountAttribute.username = "testUsername";
 
-    Property propertyEmail= createMock(Property.class);
-    expect(propertyFactory.create("prefix-email", "testEmail"))
-        .andReturn(propertyEmail);
+    // deprecated, to be removed soon. migrate to ones without dash.
+    Property propertyEmail2 = createMock(Property.class);
+    expect(propertyFactory.create("prefix-email", "testEmail")).andReturn(propertyEmail2);
+
+    Property propertyName2 = createMock(Property.class);
+    expect(propertyFactory.create("prefix-name", "testName")).andReturn(propertyName2);
+
+    Property propertyUsername2 = createMock(Property.class);
+    expect(propertyFactory.create("prefix-username", "testUsername")).andReturn(propertyUsername2);
+
+    // New style configs for vm and soy
+    Property propertyEmail = createMock(Property.class);
+    expect(propertyFactory.create("prefixEmail", "testEmail")).andReturn(propertyEmail);
 
     Property propertyName = createMock(Property.class);
-    expect(propertyFactory.create("prefix-name", "testName"))
-        .andReturn(propertyName);
+    expect(propertyFactory.create("prefixName", "testName")).andReturn(propertyName);
 
     Property propertyUsername = createMock(Property.class);
-    expect(propertyFactory.create("prefix-username", "testUsername"))
-        .andReturn(propertyUsername);
+    expect(propertyFactory.create("prefixUsername", "testUsername")).andReturn(propertyUsername);
 
     replayMocks();
 
-    PropertyAttributeExtractor extractor =
-        injector.getInstance(PropertyAttributeExtractor.class);
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
 
     Set<Property> actual = extractor.extractFrom(accountAttribute, "prefix");
 
@@ -79,6 +85,9 @@
     expected.add(propertyEmail);
     expected.add(propertyName);
     expected.add(propertyUsername);
+    expected.add(propertyEmail2);
+    expected.add(propertyName2);
+    expected.add(propertyUsername2);
     assertEquals("Properties do not match", expected, actual);
   }
 
@@ -94,64 +103,85 @@
     changeAttribute.topic = "testTopic";
     changeAttribute.subject = "testSubject";
     changeAttribute.id = "testId";
-    changeAttribute.number = "4711";
+    changeAttribute.number = 4711;
     changeAttribute.url = "http://www.example.org/test";
     changeAttribute.owner = owner;
     changeAttribute.commitMessage = "Commit Message";
 
     Property propertyProject = createMock(Property.class);
-    expect(propertyFactory.create("project", "testProject"))
-        .andReturn(propertyProject);
+    expect(propertyFactory.create("project", "testProject")).andReturn(propertyProject);
 
     Property propertyBranch = createMock(Property.class);
-    expect(propertyFactory.create("branch", "testBranch"))
-        .andReturn(propertyBranch);
+    expect(propertyFactory.create("branch", "testBranch")).andReturn(propertyBranch);
 
     Property propertyTopic = createMock(Property.class);
-    expect(propertyFactory.create("topic", "testTopic"))
-        .andReturn(propertyTopic);
+    expect(propertyFactory.create("topic", "testTopic")).andReturn(propertyTopic);
 
     Property propertySubject = createMock(Property.class);
-    expect(propertyFactory.create("subject", "testSubject"))
-        .andReturn(propertySubject);
+    expect(propertyFactory.create("subject", "testSubject")).andReturn(propertySubject);
+
+    Property propertyEscapedSubject = createMock(Property.class);
+    expect(propertyFactory.create("escapedSubject", "testSubject")).andReturn(propertyEscapedSubject);
+
+    Property propertyId2 = createMock(Property.class);
+    expect(propertyFactory.create("change-id", "testId")).andReturn(propertyId2);
 
     Property propertyId = createMock(Property.class);
-    expect(propertyFactory.create("change-id", "testId"))
-        .andReturn(propertyId);
+    expect(propertyFactory.create("changeId", "testId")).andReturn(propertyId);
+
+    Property propertyNumber2 = createMock(Property.class);
+    expect(propertyFactory.create("change-number", "4711")).andReturn(propertyNumber2);
 
     Property propertyNumber = createMock(Property.class);
-    expect(propertyFactory.create("change-number", "4711"))
-        .andReturn(propertyNumber);
+    expect(propertyFactory.create("changeNumber", "4711")).andReturn(propertyNumber);
+
+    Property propertyUrl2 = createMock(Property.class);
+    expect(propertyFactory.create("change-url", "http://www.example.org/test"))
+        .andReturn(propertyUrl2);
 
     Property propertyUrl = createMock(Property.class);
-    expect(propertyFactory.create("change-url", "http://www.example.org/test"))
+    expect(propertyFactory.create("changeUrl", "http://www.example.org/test"))
         .andReturn(propertyUrl);
 
     Property propertyStatus = createMock(Property.class);
-    expect(propertyFactory.create("status", null))
-        .andReturn(propertyStatus);
+    expect(propertyFactory.create("status", null)).andReturn(propertyStatus);
 
-    Property propertyEmail= createMock(Property.class);
-    expect(propertyFactory.create("owner-email", "testEmail"))
-        .andReturn(propertyEmail);
+    Property propertyEmail = createMock(Property.class);
+    expect(propertyFactory.create("ownerEmail", "testEmail")).andReturn(propertyEmail);
 
     Property propertyName = createMock(Property.class);
-    expect(propertyFactory.create("owner-name", "testName"))
-        .andReturn(propertyName);
+    expect(propertyFactory.create("ownerName", "testName")).andReturn(propertyName);
 
     Property propertyUsername = createMock(Property.class);
-    expect(propertyFactory.create("owner-username", "testUsername"))
-        .andReturn(propertyUsername);
+    expect(propertyFactory.create("ownerUsername", "testUsername")).andReturn(propertyUsername);
 
     Property propertyCommitMessage = createMock(Property.class);
-    expect(propertyFactory.create("commit-message", "Commit Message"))
+    expect(propertyFactory.create("commitMessage", "Commit Message"))
         .andReturn(propertyCommitMessage);
 
+    Property propertyEmail2 = createMock(Property.class);
+    expect(propertyFactory.create("owner-email", "testEmail")).andReturn(propertyEmail2);
+
+    Property propertyName2 = createMock(Property.class);
+    expect(propertyFactory.create("owner-name", "testName")).andReturn(propertyName2);
+
+    Property propertyUsername2 = createMock(Property.class);
+    expect(propertyFactory.create("owner-username", "testUsername")).andReturn(propertyUsername2);
+
+    Property propertyCommitMessage2 = createMock(Property.class);
+    expect(propertyFactory.create("commit-message", "Commit Message"))
+        .andReturn(propertyCommitMessage2);
+
+    Property propertyFormatChangeUrl = createMock(Property.class);
+    expect(propertyFactory.create("formatChangeUrl", "http://www.example.org/test"))
+        .andReturn(propertyFormatChangeUrl);
+
+    expect(facade.createLinkForWebui("http://www.example.org/test", "http://www.example.org/test"))
+        .andReturn("http://www.example.org/test");
 
     replayMocks();
 
-    PropertyAttributeExtractor extractor =
-        injector.getInstance(PropertyAttributeExtractor.class);
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
 
     Set<Property> actual = extractor.extractFrom(changeAttribute);
 
@@ -160,14 +190,23 @@
     expected.add(propertyBranch);
     expected.add(propertyTopic);
     expected.add(propertySubject);
+    expected.add(propertyEscapedSubject);
     expected.add(propertyId);
+    expected.add(propertyId2);
     expected.add(propertyNumber);
+    expected.add(propertyNumber2);
     expected.add(propertyUrl);
+    expected.add(propertyUrl2);
     expected.add(propertyStatus);
     expected.add(propertyEmail);
     expected.add(propertyName);
     expected.add(propertyUsername);
     expected.add(propertyCommitMessage);
+    expected.add(propertyEmail2);
+    expected.add(propertyName2);
+    expected.add(propertyUsername2);
+    expected.add(propertyCommitMessage2);
+    expected.add(propertyFormatChangeUrl);
     assertEquals("Properties do not match", expected, actual);
   }
 
@@ -183,65 +222,86 @@
     changeAttribute.topic = "testTopic";
     changeAttribute.subject = "testSubject";
     changeAttribute.id = "testId";
-    changeAttribute.number = "4711";
+    changeAttribute.number = 4711;
     changeAttribute.url = "http://www.example.org/test";
     changeAttribute.status = Status.ABANDONED;
     changeAttribute.owner = owner;
     changeAttribute.commitMessage = "Commit Message";
 
     Property propertyProject = createMock(Property.class);
-    expect(propertyFactory.create("project", "testProject"))
-        .andReturn(propertyProject);
+    expect(propertyFactory.create("project", "testProject")).andReturn(propertyProject);
 
     Property propertyBranch = createMock(Property.class);
-    expect(propertyFactory.create("branch", "testBranch"))
-        .andReturn(propertyBranch);
+    expect(propertyFactory.create("branch", "testBranch")).andReturn(propertyBranch);
 
     Property propertyTopic = createMock(Property.class);
-    expect(propertyFactory.create("topic", "testTopic"))
-        .andReturn(propertyTopic);
+    expect(propertyFactory.create("topic", "testTopic")).andReturn(propertyTopic);
 
     Property propertySubject = createMock(Property.class);
-    expect(propertyFactory.create("subject", "testSubject"))
-        .andReturn(propertySubject);
+    expect(propertyFactory.create("subject", "testSubject")).andReturn(propertySubject);
+
+    Property propertyEscapedSubject = createMock(Property.class);
+    expect(propertyFactory.create("escapedSubject", "testSubject")).andReturn(propertyEscapedSubject);
 
     Property propertyId = createMock(Property.class);
-    expect(propertyFactory.create("change-id", "testId"))
-        .andReturn(propertyId);
+    expect(propertyFactory.create("changeId", "testId")).andReturn(propertyId);
 
     Property propertyNumber = createMock(Property.class);
-    expect(propertyFactory.create("change-number", "4711"))
-        .andReturn(propertyNumber);
+    expect(propertyFactory.create("changeNumber", "4711")).andReturn(propertyNumber);
 
     Property propertyUrl = createMock(Property.class);
-    expect(propertyFactory.create("change-url", "http://www.example.org/test"))
+    expect(propertyFactory.create("changeUrl", "http://www.example.org/test"))
         .andReturn(propertyUrl);
 
-    Property propertyStatus = createMock(Property.class);
-    expect(propertyFactory.create("status", "ABANDONED"))
-        .andReturn(propertyStatus);
+    Property propertyId2 = createMock(Property.class);
+    expect(propertyFactory.create("change-id", "testId")).andReturn(propertyId2);
 
-    Property propertyEmail= createMock(Property.class);
-    expect(propertyFactory.create("owner-email", "testEmail"))
-        .andReturn(propertyEmail);
+    Property propertyNumber2 = createMock(Property.class);
+    expect(propertyFactory.create("change-number", "4711")).andReturn(propertyNumber2);
+
+    Property propertyUrl2 = createMock(Property.class);
+    expect(propertyFactory.create("change-url", "http://www.example.org/test"))
+        .andReturn(propertyUrl2);
+
+    Property propertyStatus = createMock(Property.class);
+    expect(propertyFactory.create("status", "ABANDONED")).andReturn(propertyStatus);
+
+    Property propertyEmail = createMock(Property.class);
+    expect(propertyFactory.create("ownerEmail", "testEmail")).andReturn(propertyEmail);
 
     Property propertyName = createMock(Property.class);
-    expect(propertyFactory.create("owner-name", "testName"))
-        .andReturn(propertyName);
+    expect(propertyFactory.create("ownerName", "testName")).andReturn(propertyName);
 
     Property propertyUsername = createMock(Property.class);
-    expect(propertyFactory.create("owner-username", "testUsername"))
-        .andReturn(propertyUsername);
+    expect(propertyFactory.create("ownerUsername", "testUsername")).andReturn(propertyUsername);
 
     Property propertyCommitMessage = createMock(Property.class);
-    expect(propertyFactory.create("commit-message", "Commit Message"))
+    expect(propertyFactory.create("commitMessage", "Commit Message"))
         .andReturn(propertyCommitMessage);
 
+    Property propertyEmail2 = createMock(Property.class);
+    expect(propertyFactory.create("owner-email", "testEmail")).andReturn(propertyEmail2);
+
+    Property propertyName2 = createMock(Property.class);
+    expect(propertyFactory.create("owner-name", "testName")).andReturn(propertyName2);
+
+    Property propertyUsername2 = createMock(Property.class);
+    expect(propertyFactory.create("owner-username", "testUsername")).andReturn(propertyUsername2);
+
+    Property propertyCommitMessage2 = createMock(Property.class);
+    expect(propertyFactory.create("commit-message", "Commit Message"))
+        .andReturn(propertyCommitMessage2);
+
+    Property propertyFormatChangeUrl = createMock(Property.class);
+    expect(propertyFactory.create("formatChangeUrl", "http://www.example.org/test"))
+        .andReturn(propertyFormatChangeUrl);
+
+    expect(facade.createLinkForWebui("http://www.example.org/test", "http://www.example.org/test"))
+        .andReturn("http://www.example.org/test");
 
     replayMocks();
 
-    PropertyAttributeExtractor extractor =
-        injector.getInstance(PropertyAttributeExtractor.class);
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
 
     Set<Property> actual = extractor.extractFrom(changeAttribute);
 
@@ -250,14 +310,23 @@
     expected.add(propertyBranch);
     expected.add(propertyTopic);
     expected.add(propertySubject);
+    expected.add(propertyEscapedSubject);
     expected.add(propertyId);
     expected.add(propertyNumber);
     expected.add(propertyUrl);
+    expected.add(propertyId2);
+    expected.add(propertyNumber2);
+    expected.add(propertyUrl2);
     expected.add(propertyStatus);
     expected.add(propertyEmail);
     expected.add(propertyName);
     expected.add(propertyUsername);
     expected.add(propertyCommitMessage);
+    expected.add(propertyEmail2);
+    expected.add(propertyName2);
+    expected.add(propertyUsername2);
+    expected.add(propertyCommitMessage2);
+    expected.add(propertyFormatChangeUrl);
     assertEquals("Properties do not match", expected, actual);
   }
 
@@ -274,7 +343,7 @@
 
     PatchSetAttribute patchSetAttribute = new PatchSetAttribute();
     patchSetAttribute.revision = "1234567891123456789212345678931234567894";
-    patchSetAttribute.number = "42";
+    patchSetAttribute.number = 42;
     patchSetAttribute.ref = "testRef";
     patchSetAttribute.createdOn = 1234567890L;
     patchSetAttribute.parents = Lists.newArrayList("parent1", "parent2");
@@ -285,84 +354,110 @@
     patchSetAttribute.author = author;
 
     Property propertyRevision = createMock(Property.class);
-    expect(propertyFactory.create("revision",
-        "1234567891123456789212345678931234567894"))
+    expect(propertyFactory.create("revision", "1234567891123456789212345678931234567894"))
         .andReturn(propertyRevision);
 
     Property propertyNumber = createMock(Property.class);
-    expect(propertyFactory.create("patch-set-number", "42"))
-        .andReturn(propertyNumber);
+    expect(propertyFactory.create("patchSetNumber", "42")).andReturn(propertyNumber);
+
+    Property propertyNumber2 = createMock(Property.class);
+    expect(propertyFactory.create("patch-set-number", "42")).andReturn(propertyNumber2);
 
     Property propertyRef = createMock(Property.class);
-    expect(propertyFactory.create("ref", "testRef"))
-        .andReturn(propertyRef);
+    expect(propertyFactory.create("ref", "testRef")).andReturn(propertyRef);
 
     Property propertyCreatedOn = createMock(Property.class);
-    expect(propertyFactory.create("created-on", "1234567890"))
-        .andReturn(propertyCreatedOn);
+    expect(propertyFactory.create("createdOn", "1234567890")).andReturn(propertyCreatedOn);
+
+    Property propertyCreatedOn2 = createMock(Property.class);
+    expect(propertyFactory.create("created-on", "1234567890")).andReturn(propertyCreatedOn2);
 
     Property propertyParents = createMock(Property.class);
-    expect(propertyFactory.create("parents", "[parent1, parent2]"))
-        .andReturn(propertyParents);
+    expect(propertyFactory.create("parents", "[parent1, parent2]")).andReturn(propertyParents);
 
     Property propertyDeletions = createMock(Property.class);
-    expect(propertyFactory.create("deletions", "7"))
-        .andReturn(propertyDeletions);
+    expect(propertyFactory.create("deletions", "7")).andReturn(propertyDeletions);
 
     Property propertyInsertions = createMock(Property.class);
-    expect(propertyFactory.create("insertions", "12"))
-        .andReturn(propertyInsertions);
+    expect(propertyFactory.create("insertions", "12")).andReturn(propertyInsertions);
 
-    Property propertyIsDraft= createMock(Property.class);
-    expect(propertyFactory.create("is-draft", "true"))
-        .andReturn(propertyIsDraft);
+    Property propertyIsDraft = createMock(Property.class);
+    expect(propertyFactory.create("is-draft", "true")).andReturn(propertyIsDraft);
 
-    Property propertyEmail1 = createMock(Property.class);
+    Property propertyIsDraft2 = createMock(Property.class);
+    expect(propertyFactory.create("isDraft", "true")).andReturn(propertyIsDraft2);
+
+    Property propertyUploaderEmail = createMock(Property.class);
+    expect(propertyFactory.create("uploaderEmail", "testEmail1")).andReturn(propertyUploaderEmail);
+
+    Property propertyUploaderName = createMock(Property.class);
+    expect(propertyFactory.create("uploaderName", "testName1")).andReturn(propertyUploaderName);
+
+    Property propertyUploaderUsername = createMock(Property.class);
+    expect(propertyFactory.create("uploaderUsername", "testUsername1"))
+        .andReturn(propertyUploaderUsername);
+
+    Property propertyUploaderEmail2 = createMock(Property.class);
     expect(propertyFactory.create("uploader-email", "testEmail1"))
-        .andReturn(propertyEmail1);
+        .andReturn(propertyUploaderEmail2);
 
-    Property propertyName1 = createMock(Property.class);
-    expect(propertyFactory.create("uploader-name", "testName1"))
-        .andReturn(propertyName1);
+    Property propertyUploaderName2 = createMock(Property.class);
+    expect(propertyFactory.create("uploader-name", "testName1")).andReturn(propertyUploaderName2);
 
-    Property propertyUsername1 = createMock(Property.class);
+    Property propertyUploaderUsername2 = createMock(Property.class);
     expect(propertyFactory.create("uploader-username", "testUsername1"))
-        .andReturn(propertyUsername1);
+        .andReturn(propertyUploaderUsername2);
 
-    Property propertyEmail2 = createMock(Property.class);
-    expect(propertyFactory.create("author-email", "testEmail2"))
-        .andReturn(propertyEmail2);
+    Property propertyAuthorEmail = createMock(Property.class);
+    expect(propertyFactory.create("authorEmail", "testEmail2")).andReturn(propertyAuthorEmail);
 
-    Property propertyName2 = createMock(Property.class);
-    expect(propertyFactory.create("author-name", "testName2"))
-        .andReturn(propertyName2);
+    Property propertyAuthorName = createMock(Property.class);
+    expect(propertyFactory.create("authorName", "testName2")).andReturn(propertyAuthorName);
 
-    Property propertyUsername2 = createMock(Property.class);
+    Property propertyAuthorUsername = createMock(Property.class);
+    expect(propertyFactory.create("authorUsername", "testUsername2"))
+        .andReturn(propertyAuthorUsername);
+
+    Property propertyAuthorEmail2 = createMock(Property.class);
+    expect(propertyFactory.create("author-email", "testEmail2")).andReturn(propertyAuthorEmail2);
+
+    Property propertyAuthorName2 = createMock(Property.class);
+    expect(propertyFactory.create("author-name", "testName2")).andReturn(propertyAuthorName2);
+
+    Property propertyAuthorUsername2 = createMock(Property.class);
     expect(propertyFactory.create("author-username", "testUsername2"))
-        .andReturn(propertyUsername2);
+        .andReturn(propertyAuthorUsername2);
 
     replayMocks();
 
-    PropertyAttributeExtractor extractor =
-        injector.getInstance(PropertyAttributeExtractor.class);
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
 
     Set<Property> actual = extractor.extractFrom(patchSetAttribute);
 
     Set<Property> expected = Sets.newHashSet();
     expected.add(propertyRevision);
     expected.add(propertyNumber);
+    expected.add(propertyNumber2);
     expected.add(propertyRef);
     expected.add(propertyCreatedOn);
+    expected.add(propertyCreatedOn2);
     expected.add(propertyParents);
     expected.add(propertyDeletions);
     expected.add(propertyInsertions);
     expected.add(propertyIsDraft);
-    expected.add(propertyEmail1);
-    expected.add(propertyName1);
-    expected.add(propertyUsername1);
-    expected.add(propertyEmail2);
-    expected.add(propertyName2);
-    expected.add(propertyUsername2);
+    expected.add(propertyIsDraft2);
+    expected.add(propertyUploaderEmail);
+    expected.add(propertyUploaderName);
+    expected.add(propertyUploaderUsername);
+    expected.add(propertyUploaderEmail2);
+    expected.add(propertyUploaderName2);
+    expected.add(propertyUploaderUsername2);
+    expected.add(propertyAuthorEmail);
+    expected.add(propertyAuthorName);
+    expected.add(propertyAuthorUsername);
+    expected.add(propertyAuthorEmail2);
+    expected.add(propertyAuthorName2);
+    expected.add(propertyAuthorUsername2);
     assertEquals("Properties do not match", expected, actual);
   }
 
@@ -374,33 +469,33 @@
     refUpdateAttribute.refName = "testRef";
 
     Property propertyRevision = createMock(Property.class);
-    expect(propertyFactory.create("revision",
-        "1234567891123456789212345678931234567894"))
+    expect(propertyFactory.create("revision", "1234567891123456789212345678931234567894"))
         .andReturn(propertyRevision);
 
     Property propertyRevisionOld = createMock(Property.class);
-    expect(propertyFactory.create("revision-old",
-        "9876543211987654321298765432139876543214"))
+    expect(propertyFactory.create("revisionOld", "9876543211987654321298765432139876543214"))
         .andReturn(propertyRevisionOld);
 
+    Property propertyRevisionOld2 = createMock(Property.class);
+    expect(propertyFactory.create("revision-old", "9876543211987654321298765432139876543214"))
+        .andReturn(propertyRevisionOld2);
+
     Property propertyProject = createMock(Property.class);
-    expect(propertyFactory.create("project", "testProject"))
-        .andReturn(propertyProject);
+    expect(propertyFactory.create("project", "testProject")).andReturn(propertyProject);
 
     Property propertyRef = createMock(Property.class);
-    expect(propertyFactory.create("ref", "testRef"))
-        .andReturn(propertyRef);
+    expect(propertyFactory.create("ref", "testRef")).andReturn(propertyRef);
 
     replayMocks();
 
-    PropertyAttributeExtractor extractor =
-        injector.getInstance(PropertyAttributeExtractor.class);
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
 
     Set<Property> actual = extractor.extractFrom(refUpdateAttribute);
 
     Set<Property> expected = Sets.newHashSet();
     expected.add(propertyRevision);
     expected.add(propertyRevisionOld);
+    expected.add(propertyRevisionOld2);
     expected.add(propertyProject);
     expected.add(propertyRef);
     assertEquals("Properties do not match", expected, actual);
@@ -412,18 +507,43 @@
     approvalAttribute.value = "TestValue";
 
     Property propertyApproval = createMock(Property.class);
-    expect(propertyFactory.create("approval-TestType", "TestValue"))
-        .andReturn(propertyApproval);
+    expect(propertyFactory.create("approvalTestType", "TestValue")).andReturn(propertyApproval);
+
+    Property propertyApproval2 = createMock(Property.class);
+    expect(propertyFactory.create("approval-TestType", "TestValue")).andReturn(propertyApproval2);
 
     replayMocks();
 
-    PropertyAttributeExtractor extractor =
-        injector.getInstance(PropertyAttributeExtractor.class);
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
 
     Set<Property> actual = extractor.extractFrom(approvalAttribute);
 
     Set<Property> expected = Sets.newHashSet();
     expected.add(propertyApproval);
+    expected.add(propertyApproval2);
+    assertEquals("Properties do not match", expected, actual);
+  }
+
+  public void testApprovalAttributeWithDash() {
+    ApprovalAttribute approvalAttribute = new ApprovalAttribute();
+    approvalAttribute.type = "Test-Type";
+    approvalAttribute.value = "TestValue";
+
+    Property propertyApproval = createMock(Property.class);
+    expect(propertyFactory.create("approvalTestType", "TestValue")).andReturn(propertyApproval);
+
+    Property propertyApproval2 = createMock(Property.class);
+    expect(propertyFactory.create("approval-Test-Type", "TestValue")).andReturn(propertyApproval2);
+
+    replayMocks();
+
+    PropertyAttributeExtractor extractor = injector.getInstance(PropertyAttributeExtractor.class);
+
+    Set<Property> actual = extractor.extractFrom(approvalAttribute);
+
+    Set<Property> expected = Sets.newHashSet();
+    expected.add(propertyApproval);
+    expected.add(propertyApproval2);
     assertEquals("Properties do not match", expected, actual);
   }
 
@@ -436,8 +556,10 @@
   private class TestModule extends FactoryModule {
     @Override
     protected void configure() {
+      facade = createMock(ItsFacade.class);
+      bind(ItsFacade.class).toInstance(facade);
       propertyFactory = createMock(Property.Factory.class);
       bind(Property.Factory.class).toInstance(propertyFactory);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractorTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractorTest.java
index e62cd1d..009a8d5 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/util/PropertyExtractorTest.java
@@ -37,10 +37,8 @@
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
 import java.util.HashMap;
 import java.util.Set;
 
@@ -52,26 +50,26 @@
   private PropertyAttributeExtractor propertyAttributeExtractor;
 
   public void testDummyChangeEvent() {
-    PropertyExtractor propertyExtractor = injector.getInstance(
-        PropertyExtractor.class);
+    PropertyExtractor propertyExtractor = injector.getInstance(PropertyExtractor.class);
 
     Property property1 = createMock(Property.class);
-    expect(propertyFactory.create("event", "com.googlesource.gerrit.plugins." +
-        "its.base.util.PropertyExtractorTest$DummyEvent"))
+    expect(
+            propertyFactory.create(
+                "event",
+                "com.googlesource.gerrit.plugins."
+                    + "its.base.util.PropertyExtractorTest$DummyEvent"))
         .andReturn(property1);
 
     replayMocks();
 
-    Set<Set<Property>> actual = propertyExtractor.extractFrom(
-        new DummyEvent());
+    Set<Set<Property>> actual = propertyExtractor.extractFrom(new DummyEvent());
 
     Set<Set<Property>> expected = Sets.newHashSet();
     assertEquals("Properties do not match", expected, actual);
   }
 
   public void testChangeAbandonedEvent() {
-    ChangeAbandonedEvent event =
-        new ChangeAbandonedEvent(testChange("testProject", "testBranch"));
+    ChangeAbandonedEvent event = new ChangeAbandonedEvent(testChange("testProject", "testBranch"));
 
     ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
     event.change = Suppliers.ofInstance(changeAttribute);
@@ -80,10 +78,10 @@
         .andReturn(Sets.newHashSet(propertyChange));
 
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
-    event.abandoner= Suppliers.ofInstance(accountAttribute);
+    event.abandoner = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "abandoner")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "abandoner"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
     PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
     event.patchSet = Suppliers.ofInstance(patchSetAttribute);
@@ -93,13 +91,12 @@
 
     event.reason = "testReason";
     Property propertyReason = createMock(Property.class);
-    expect(propertyFactory.create("reason", "testReason"))
-        .andReturn(propertyReason);
+    expect(propertyFactory.create("reason", "testReason")).andReturn(propertyReason);
 
     changeAttribute.project = "testProject";
-    changeAttribute.number = "176";
+    changeAttribute.number = 176;
     patchSetAttribute.revision = "testRevision";
-    patchSetAttribute.number = "3";
+    patchSetAttribute.number = 3;
 
     Set<Property> common = Sets.newHashSet();
     common.add(propertyChange);
@@ -107,13 +104,11 @@
     common.add(propertyPatchSet);
     common.add(propertyReason);
 
-    eventHelper(event, "ChangeAbandonedEvent", "change-abandoned", common,
-        true);
+    eventHelper(event, "ChangeAbandonedEvent", "change-abandoned", common, true);
   }
 
   public void testChangeMergedEvent() {
-    ChangeMergedEvent event =
-        new ChangeMergedEvent(testChange("testProject", "testBranch"));
+    ChangeMergedEvent event = new ChangeMergedEvent(testChange("testProject", "testBranch"));
 
     ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
     event.change = Suppliers.ofInstance(changeAttribute);
@@ -124,8 +119,8 @@
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
     event.submitter = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "submitter")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "submitter"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
     PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
     event.patchSet = Suppliers.ofInstance(patchSetAttribute);
@@ -134,9 +129,9 @@
         .andReturn(Sets.newHashSet(propertyPatchSet));
 
     changeAttribute.project = "testProject";
-    changeAttribute.number = "176";
+    changeAttribute.number = 176;
     patchSetAttribute.revision = "testRevision";
-    patchSetAttribute.number = "3";
+    patchSetAttribute.number = 3;
 
     Set<Property> common = Sets.newHashSet();
     common.add(propertyChange);
@@ -147,8 +142,7 @@
   }
 
   public void testChangeRestoredEvent() {
-    ChangeRestoredEvent event =
-        new ChangeRestoredEvent(testChange("testProject", "testBranch"));
+    ChangeRestoredEvent event = new ChangeRestoredEvent(testChange("testProject", "testBranch"));
 
     ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
     event.change = Suppliers.ofInstance(changeAttribute);
@@ -159,8 +153,8 @@
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
     event.restorer = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "restorer")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "restorer"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
     PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
     event.patchSet = Suppliers.ofInstance(patchSetAttribute);
@@ -170,13 +164,12 @@
 
     event.reason = "testReason";
     Property propertyReason = createMock(Property.class);
-    expect(propertyFactory.create("reason", "testReason"))
-        .andReturn(propertyReason);
+    expect(propertyFactory.create("reason", "testReason")).andReturn(propertyReason);
 
     changeAttribute.project = "testProject";
-    changeAttribute.number = "176";
+    changeAttribute.number = 176;
     patchSetAttribute.revision = "testRevision";
-    patchSetAttribute.number = "3";
+    patchSetAttribute.number = 3;
 
     Set<Property> common = Sets.newHashSet();
     common.add(propertyChange);
@@ -188,8 +181,7 @@
   }
 
   public void testCommentAddedEventWOApprovals() {
-    CommentAddedEvent event =
-        new CommentAddedEvent(testChange("testProject", "testBranch"));
+    CommentAddedEvent event = new CommentAddedEvent(testChange("testProject", "testBranch"));
 
     ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
     event.change = Suppliers.ofInstance(changeAttribute);
@@ -200,8 +192,8 @@
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
     event.author = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "commenter")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "commenter"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
     PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
     event.patchSet = Suppliers.ofInstance(patchSetAttribute);
@@ -211,13 +203,12 @@
 
     event.comment = "testComment";
     Property propertyComment = createMock(Property.class);
-    expect(propertyFactory.create("comment", "testComment"))
-        .andReturn(propertyComment);
+    expect(propertyFactory.create("comment", "testComment")).andReturn(propertyComment);
 
     changeAttribute.project = "testProject";
-    changeAttribute.number = "176";
+    changeAttribute.number = 176;
     patchSetAttribute.revision = "testRevision";
-    patchSetAttribute.number = "3";
+    patchSetAttribute.number = 3;
 
     Set<Property> common = Sets.newHashSet();
     common.add(propertyChange);
@@ -229,8 +220,7 @@
   }
 
   public void testCommentAddedEventWApprovals() {
-    CommentAddedEvent event =
-        new CommentAddedEvent(testChange("testProject", "testBranch"));
+    CommentAddedEvent event = new CommentAddedEvent(testChange("testProject", "testBranch"));
 
     ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
     event.change = Suppliers.ofInstance(changeAttribute);
@@ -241,8 +231,8 @@
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
     event.author = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "commenter")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "commenter"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
     PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
     event.patchSet = Suppliers.ofInstance(patchSetAttribute);
@@ -258,19 +248,17 @@
     Property propertyApproval2 = createMock(Property.class);
     expect(propertyAttributeExtractor.extractFrom(approvalAttribute2))
         .andReturn(Sets.newHashSet(propertyApproval2));
-    ApprovalAttribute approvalAttributes[] = { approvalAttribute1,
-        approvalAttribute2 };
+    ApprovalAttribute[] approvalAttributes = {approvalAttribute1, approvalAttribute2};
     event.approvals = Suppliers.ofInstance(approvalAttributes);
 
     event.comment = "testComment";
     Property propertyComment = createMock(Property.class);
-    expect(propertyFactory.create("comment", "testComment"))
-        .andReturn(propertyComment);
+    expect(propertyFactory.create("comment", "testComment")).andReturn(propertyComment);
 
     changeAttribute.project = "testProject";
-    changeAttribute.number = "176";
+    changeAttribute.number = 176;
     patchSetAttribute.revision = "testRevision";
-    patchSetAttribute.number = "3";
+    patchSetAttribute.number = 3;
 
     Set<Property> common = Sets.newHashSet();
     common.add(propertyChange);
@@ -284,8 +272,7 @@
   }
 
   public void testDraftPublishedEvent() {
-    DraftPublishedEvent event =
-        new DraftPublishedEvent(testChange("testProject", "testBranch"));
+    DraftPublishedEvent event = new DraftPublishedEvent(testChange("testProject", "testBranch"));
 
     ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
     event.change = Suppliers.ofInstance(changeAttribute);
@@ -296,8 +283,8 @@
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
     event.uploader = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "uploader")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "uploader"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
     PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
     event.patchSet = Suppliers.ofInstance(patchSetAttribute);
@@ -306,22 +293,20 @@
         .andReturn(Sets.newHashSet(propertyPatchSet));
 
     changeAttribute.project = "testProject";
-    changeAttribute.number = "176";
+    changeAttribute.number = 176;
     patchSetAttribute.revision = "testRevision";
-    patchSetAttribute.number = "3";
+    patchSetAttribute.number = 3;
 
     Set<Property> common = Sets.newHashSet();
     common.add(propertyChange);
     common.add(propertySubmitter);
     common.add(propertyPatchSet);
 
-    eventHelper(event, "DraftPublishedEvent", "draft-published", common,
-        true);
+    eventHelper(event, "DraftPublishedEvent", "draft-published", common, true);
   }
 
   public void testPatchSetCreatedEvent() {
-    PatchSetCreatedEvent event =
-        new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
+    PatchSetCreatedEvent event = new PatchSetCreatedEvent(testChange("testProject", "testBranch"));
 
     ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
     event.change = Suppliers.ofInstance(changeAttribute);
@@ -332,8 +317,8 @@
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
     event.uploader = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "uploader")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "uploader"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
     PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
     event.patchSet = Suppliers.ofInstance(patchSetAttribute);
@@ -342,17 +327,16 @@
         .andReturn(Sets.newHashSet(propertyPatchSet));
 
     changeAttribute.project = "testProject";
-    changeAttribute.number = "176";
+    changeAttribute.number = 176;
     patchSetAttribute.revision = "testRevision";
-    patchSetAttribute.number = "3";
+    patchSetAttribute.number = 3;
 
     Set<Property> common = Sets.newHashSet();
     common.add(propertyChange);
     common.add(propertySubmitter);
     common.add(propertyPatchSet);
 
-    eventHelper(event, "PatchSetCreatedEvent", "patchset-created", common,
-        true);
+    eventHelper(event, "PatchSetCreatedEvent", "patchset-created", common, true);
   }
 
   public void testRefUpdatedEvent() {
@@ -361,11 +345,10 @@
     AccountAttribute accountAttribute = createMock(AccountAttribute.class);
     event.submitter = Suppliers.ofInstance(accountAttribute);
     Property propertySubmitter = createMock(Property.class);
-    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
-        "submitter")).andReturn(Sets.newHashSet(propertySubmitter));
+    expect(propertyAttributeExtractor.extractFrom(accountAttribute, "submitter"))
+        .andReturn(Sets.newHashSet(propertySubmitter));
 
-    RefUpdateAttribute refUpdateAttribute =
-        createMock(RefUpdateAttribute.class);
+    RefUpdateAttribute refUpdateAttribute = createMock(RefUpdateAttribute.class);
     event.refUpdate = Suppliers.ofInstance(refUpdateAttribute);
     Property propertyRefUpdated = createMock(Property.class);
     expect(propertyAttributeExtractor.extractFrom(refUpdateAttribute))
@@ -381,53 +364,46 @@
     eventHelper(event, "RefUpdatedEvent", "ref-updated", common, false);
   }
 
-  private void eventHelper(Event event, String className, String type,
-      Set<Property> common, boolean withRevision) {
-    PropertyExtractor propertyExtractor = injector.getInstance(
-        PropertyExtractor.class);
+  private void eventHelper(
+      Event event, String className, String type, Set<Property> common, boolean withRevision) {
+    PropertyExtractor propertyExtractor = injector.getInstance(PropertyExtractor.class);
 
     Property propertyItsName = createMock(Property.class);
-    expect(propertyFactory.create("its-name", "ItsTestName"))
-        .andReturn(propertyItsName).anyTimes();
+    expect(propertyFactory.create("its-name", "ItsTestName")).andReturn(propertyItsName).anyTimes();
 
     Property propertyEvent = createMock(Property.class);
-    expect(propertyFactory.create("event", "com.google.gerrit.server.events." +
-        className)).andReturn(propertyEvent);
+    expect(propertyFactory.create("event", "com.google.gerrit.server.events." + className))
+        .andReturn(propertyEvent);
 
     Property propertyEventType = createMock(Property.class);
-    expect(propertyFactory.create("event-type", type))
-        .andReturn(propertyEventType);
+    expect(propertyFactory.create("event-type", type)).andReturn(propertyEventType);
 
     Property propertyAssociationFooter = createMock(Property.class);
-    expect(propertyFactory.create("association", "footer"))
-        .andReturn(propertyAssociationFooter);
+    expect(propertyFactory.create("association", "footer")).andReturn(propertyAssociationFooter);
 
     Property propertyAssociationAnywhere = createMock(Property.class);
     expect(propertyFactory.create("association", "anywhere"))
-        .andReturn(propertyAssociationAnywhere).times(2);
+        .andReturn(propertyAssociationAnywhere)
+        .times(2);
 
     Property propertyAssociationBody = createMock(Property.class);
-    expect(propertyFactory.create("association", "body"))
-        .andReturn(propertyAssociationBody);
+    expect(propertyFactory.create("association", "body")).andReturn(propertyAssociationBody);
 
     Property propertyIssue42 = createMock(Property.class);
-    expect(propertyFactory.create("issue", "42"))
-        .andReturn(propertyIssue42);
+    expect(propertyFactory.create("issue", "42")).andReturn(propertyIssue42);
 
     Property propertyIssue4711 = createMock(Property.class);
-    expect(propertyFactory.create("issue", "4711"))
-        .andReturn(propertyIssue4711);
+    expect(propertyFactory.create("issue", "4711")).andReturn(propertyIssue4711);
 
-    HashMap<String,Set<String>> issueMap = Maps.newHashMap();
+    HashMap<String, Set<String>> issueMap = Maps.newHashMap();
     issueMap.put("4711", Sets.newHashSet("body", "anywhere"));
     issueMap.put("42", Sets.newHashSet("footer", "anywhere"));
     if (withRevision) {
       PatchSet.Id patchSetId = new PatchSet.Id(new Change.Id(176), 3);
-      expect(issueExtractor.getIssueIds("testProject", "testRevision",
-          patchSetId)).andReturn(issueMap);
+      expect(issueExtractor.getIssueIds("testProject", "testRevision", patchSetId))
+          .andReturn(issueMap);
     } else {
-      expect(issueExtractor.getIssueIds("testProject", "testRevision"))
-      .andReturn(issueMap);
+      expect(issueExtractor.getIssueIds("testProject", "testRevision")).andReturn(issueMap);
     }
 
     replayMocks();
@@ -466,15 +442,13 @@
   private class TestModule extends FactoryModule {
     @Override
     protected void configure() {
-      bind(String.class).annotatedWith(PluginName.class)
-          .toInstance("ItsTestName");
+      bind(String.class).annotatedWith(PluginName.class).toInstance("ItsTestName");
 
       issueExtractor = createMock(IssueExtractor.class);
       bind(IssueExtractor.class).toInstance(issueExtractor);
 
       propertyAttributeExtractor = createMock(PropertyAttributeExtractor.class);
-      bind(PropertyAttributeExtractor.class).toInstance(
-          propertyAttributeExtractor);
+      bind(PropertyAttributeExtractor.class).toInstance(propertyAttributeExtractor);
 
       propertyFactory = createMock(Property.Factory.class);
       bind(Property.Factory.class).toInstance(propertyFactory);
@@ -487,4 +461,4 @@
       super(null);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateCommentTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateCommentTest.java
index 5a45dd4..5573878 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateCommentTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/validation/ItsValidateCommentTest.java
@@ -18,27 +18,25 @@
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.events.CommitReceivedEvent;
 import com.google.gerrit.server.git.validators.CommitValidationException;
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsConfig;
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.util.IssueExtractor;
-
+import java.io.IOException;
+import java.util.List;
+import java.util.regex.Pattern;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.transport.ReceiveCommand;
 import org.junit.runner.RunWith;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import java.io.IOException;
-import java.util.List;
-import java.util.regex.Pattern;
-
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({RevCommit.class})
 public class ItsValidateCommentTest extends LoggingMockingTestCase {
@@ -54,11 +52,11 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.OPTIONAL).atLeastOnce();
+        .andReturn(ItsAssociationPolicy.OPTIONAL)
+        .atLeastOnce();
 
     replayMocks();
 
@@ -72,41 +70,39 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
+        .atLeastOnce();
     expect(commit.getFullMessage()).andReturn("TestMessage").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("TestMessage")).andReturn(
-        new String[] {}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("TestMessage")).andReturn(new String[] {}).atLeastOnce();
 
     replayMocks();
 
     ret = ivc.onCommitReceived(event);
 
-    assertEquals("Size of returned CommitValidationMessages does not match",
-        1, ret.size());
-    assertTrue("First CommitValidationMessages does not contain 'Missing " +
-        "issue'",ret.get(0).getMessage().contains("Missing issue"));
+    assertEquals("Size of returned CommitValidationMessages does not match", 1, ret.size());
+    assertTrue(
+        "First CommitValidationMessages does not contain 'Missing " + "issue'",
+        ret.get(0).getMessage().contains("Missing issue"));
   }
 
   public void testMandatoryNonMatching() {
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.MANDATORY).atLeastOnce();
+        .andReturn(ItsAssociationPolicy.MANDATORY)
+        .atLeastOnce();
     expect(commit.getFullMessage()).andReturn("TestMessage").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("TestMessage")).andReturn(
-        new String[] {}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("TestMessage")).andReturn(new String[] {}).atLeastOnce();
 
     replayMocks();
 
@@ -114,27 +110,25 @@
       ivc.onCommitReceived(event);
       fail("onCommitReceived did not throw any exception");
     } catch (CommitValidationException e) {
-      assertTrue("Message of thrown CommitValidationException does not "
-          + "contain 'Missing issue'",
+      assertTrue(
+          "Message of thrown CommitValidationException does not " + "contain 'Missing issue'",
           e.getMessage().contains("Missing issue"));
     }
   }
 
-  public void testSuggestedMatchingSingleExisting()
-      throws CommitValidationException, IOException {
+  public void testSuggestedMatchingSingleExisting() throws CommitValidationException, IOException {
     List<CommitValidationMessage> ret;
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
+        .atLeastOnce();
     expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
-        new String[] {"4711"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(new String[] {"4711"}).atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
 
     replayMocks();
@@ -144,22 +138,20 @@
     assertEmptyList(ret);
   }
 
-  public void testMandatoryMatchingSingleExisting()
-      throws CommitValidationException, IOException {
+  public void testMandatoryMatchingSingleExisting() throws CommitValidationException, IOException {
     List<CommitValidationMessage> ret;
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-      .andReturn(ItsAssociationPolicy.MANDATORY).atLeastOnce();
+        .andReturn(ItsAssociationPolicy.MANDATORY)
+        .atLeastOnce();
     expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
-        new String[] {"4711"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(new String[] {"4711"}).atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
 
     replayMocks();
@@ -175,45 +167,43 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
+        .atLeastOnce();
     expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
-        new String[] {"4711"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(new String[] {"4711"}).atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
 
     replayMocks();
 
     ret = ivc.onCommitReceived(event);
 
-    assertEquals("Size of returned CommitValidationMessages does not match",
-        1, ret.size());
-    assertTrue("First CommitValidationMessages does not contain " +
-        "'Non-existing'",ret.get(0).getMessage().contains("Non-existing"));
-    assertTrue("First CommitValidationMessages does not contain '4711'",
+    assertEquals("Size of returned CommitValidationMessages does not match", 1, ret.size());
+    assertTrue(
+        "First CommitValidationMessages does not contain " + "'Non-existing'",
+        ret.get(0).getMessage().contains("Non-existing"));
+    assertTrue(
+        "First CommitValidationMessages does not contain '4711'",
         ret.get(0).getMessage().contains("4711"));
   }
 
-  public void testMandatoryMatchingSingleNonExisting()
-      throws IOException {
+  public void testMandatoryMatchingSingleNonExisting() throws IOException {
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.MANDATORY).atLeastOnce();
+        .andReturn(ItsAssociationPolicy.MANDATORY)
+        .atLeastOnce();
     expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
-        new String[] {"4711"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(new String[] {"4711"}).atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
 
     replayMocks();
@@ -222,28 +212,28 @@
       ivc.onCommitReceived(event);
       fail("onCommitReceived did not throw any exception");
     } catch (CommitValidationException e) {
-      assertTrue("Message of thrown CommitValidationException does not "
-          + "contain 'Non-existing'", e.getMessage().contains("Non-existing"));
+      assertTrue(
+          "Message of thrown CommitValidationException does not " + "contain 'Non-existing'",
+          e.getMessage().contains("Non-existing"));
     }
   }
 
-  public void testSuggestedMatchingMultiple()
-      throws CommitValidationException, IOException {
+  public void testSuggestedMatchingMultiple() throws CommitValidationException, IOException {
     List<CommitValidationMessage> ret;
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.SUGGESTED).atLeastOnce();
-    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
         .atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
-        new String[] {"4711", "42"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
+        .andReturn(new String[] {"4711", "42"})
+        .atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
     expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
 
@@ -254,23 +244,22 @@
     assertEmptyList(ret);
   }
 
-  public void testMandatoryMatchingMultiple()
-      throws CommitValidationException, IOException {
+  public void testMandatoryMatchingMultiple() throws CommitValidationException, IOException {
     List<CommitValidationMessage> ret;
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.MANDATORY).atLeastOnce();
-    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .andReturn(ItsAssociationPolicy.MANDATORY)
         .atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
-        new String[] {"4711", "42"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
+        .andReturn(new String[] {"4711", "42"})
+        .atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
     expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
 
@@ -287,17 +276,17 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.SUGGESTED).atLeastOnce();
-    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
         .atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
-        new String[] {"4711", "42"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
+        .andReturn(new String[] {"4711", "42"})
+        .atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
     expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
 
@@ -305,32 +294,33 @@
 
     ret = ivc.onCommitReceived(event);
 
-    assertEquals("Size of returned CommitValidationMessages does not match",
-        1, ret.size());
-    assertTrue("First CommitValidationMessages does not contain " +
-        "'Non-existing'",ret.get(0).getMessage().contains("Non-existing"));
-    assertTrue("First CommitValidationMessages does not contain '4711'",
+    assertEquals("Size of returned CommitValidationMessages does not match", 1, ret.size());
+    assertTrue(
+        "First CommitValidationMessages does not contain " + "'Non-existing'",
+        ret.get(0).getMessage().contains("Non-existing"));
+    assertTrue(
+        "First CommitValidationMessages does not contain '4711'",
         ret.get(0).getMessage().contains("4711"));
-    assertFalse("First CommitValidationMessages contains '42', although " +
-        "that bug exists", ret.get(0).getMessage().contains("42"));
+    assertFalse(
+        "First CommitValidationMessages contains '42', although " + "that bug exists",
+        ret.get(0).getMessage().contains("42"));
   }
 
-  public void testMandatoryMatchingMultipleOneNonExsting()
-      throws IOException {
+  public void testMandatoryMatchingMultipleOneNonExsting() throws IOException {
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.MANDATORY).atLeastOnce();
-    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .andReturn(ItsAssociationPolicy.MANDATORY)
         .atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
-        new String[] {"4711", "42"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
+        .andReturn(new String[] {"4711", "42"})
+        .atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
     expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
 
@@ -340,8 +330,9 @@
       ivc.onCommitReceived(event);
       fail("onCommitReceived did not throw any exception");
     } catch (CommitValidationException e) {
-      assertTrue("Message of thrown CommitValidationException does not "
-          + "contain 'Non-existing'", e.getMessage().contains("Non-existing"));
+      assertTrue(
+          "Message of thrown CommitValidationException does not " + "contain 'Non-existing'",
+          e.getMessage().contains("Non-existing"));
     }
   }
 
@@ -351,17 +342,17 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.SUGGESTED).atLeastOnce();
-    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
         .atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
-        new String[] {"4711", "42"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
+        .andReturn(new String[] {"4711", "42"})
+        .atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
     expect(itsFacade.exists("42")).andReturn(false).atLeastOnce();
 
@@ -369,32 +360,33 @@
 
     ret = ivc.onCommitReceived(event);
 
-    assertEquals("Size of returned CommitValidationMessages does not match",
-        1, ret.size());
-    assertTrue("First CommitValidationMessages does not contain " +
-        "'Non-existing'",ret.get(0).getMessage().contains("Non-existing"));
-    assertTrue("First CommitValidationMessages does not contain '4711'",
+    assertEquals("Size of returned CommitValidationMessages does not match", 1, ret.size());
+    assertTrue(
+        "First CommitValidationMessages does not contain " + "'Non-existing'",
+        ret.get(0).getMessage().contains("Non-existing"));
+    assertTrue(
+        "First CommitValidationMessages does not contain '4711'",
         ret.get(0).getMessage().contains("4711"));
-    assertTrue("First CommitValidationMessages does not contain '42'",
+    assertTrue(
+        "First CommitValidationMessages does not contain '42'",
         ret.get(0).getMessage().contains("42"));
   }
 
-  public void testMandatoryMatchingMultipleSomeNonExsting()
-      throws IOException {
+  public void testMandatoryMatchingMultipleSomeNonExsting() throws IOException {
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.MANDATORY).atLeastOnce();
-    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .andReturn(ItsAssociationPolicy.MANDATORY)
         .atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
-    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
-        new String[] {"4711", "42"}).atLeastOnce();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
+        .andReturn(new String[] {"4711", "42"})
+        .atLeastOnce();
     expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
     expect(itsFacade.exists("42")).andReturn(false).atLeastOnce();
 
@@ -404,8 +396,9 @@
       ivc.onCommitReceived(event);
       fail("onCommitReceived did not throw any exception");
     } catch (CommitValidationException e) {
-      assertTrue("Message of thrown CommitValidationException does not "
-          + "contain 'Non-existing'", e.getMessage().contains("Non-existing"));
+      assertTrue(
+          "Message of thrown CommitValidationException does not " + "contain 'Non-existing'",
+          e.getMessage().contains("Non-existing"));
     }
   }
 
@@ -415,38 +408,42 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
-        commit, null);
+    CommitReceivedEvent event = newCommitReceivedEvent(command, project, null, commit, null);
 
     expect(itsConfig.getItsAssociationPolicy())
-        .andReturn(ItsAssociationPolicy.SUGGESTED).atLeastOnce();
-    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .andReturn(ItsAssociationPolicy.SUGGESTED)
         .atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42").atLeastOnce();
     expect(commit.getId()).andReturn(commit).anyTimes();
     expect(commit.getName()).andReturn("TestCommit").anyTimes();
     expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
-        .andReturn(new String[] {"4711", "42"}).atLeastOnce();
-    expect(itsFacade.exists("4711")).andThrow(new IOException("InjectedEx1"))
+        .andReturn(new String[] {"4711", "42"})
         .atLeastOnce();
+    expect(itsFacade.exists("4711")).andThrow(new IOException("InjectedEx1")).atLeastOnce();
     expect(itsFacade.exists("42")).andReturn(false).atLeastOnce();
 
     replayMocks();
 
     ret = ivc.onCommitReceived(event);
 
-    assertEquals("Size of returned CommitValidationMessages does not match",
-        2, ret.size());
-    assertTrue("First CommitValidationMessages does not contain " +
-        "'Failed'",ret.get(0).getMessage().contains("Failed"));
-    assertTrue("First CommitValidationMessages does not contain '4711'",
+    assertEquals("Size of returned CommitValidationMessages does not match", 2, ret.size());
+    assertTrue(
+        "First CommitValidationMessages does not contain " + "'Failed'",
+        ret.get(0).getMessage().contains("Failed"));
+    assertTrue(
+        "First CommitValidationMessages does not contain '4711'",
         ret.get(0).getMessage().contains("4711"));
-    assertFalse("First CommitValidationMessages contains '42', although " +
-        "that bug exists", ret.get(0).getMessage().contains("42"));
-    assertTrue("Second CommitValidationMessages does not contain " +
-        "'Non-existing'",ret.get(1).getMessage().contains("Non-existing"));
-    assertTrue("Second CommitValidationMessages does not contain '4711'",
+    assertFalse(
+        "First CommitValidationMessages contains '42', although " + "that bug exists",
+        ret.get(0).getMessage().contains("42"));
+    assertTrue(
+        "Second CommitValidationMessages does not contain " + "'Non-existing'",
+        ret.get(1).getMessage().contains("Non-existing"));
+    assertTrue(
+        "Second CommitValidationMessages does not contain '4711'",
         ret.get(1).getMessage().contains("4711"));
-    assertTrue("Second CommitValidationMessages does not contain '42'",
+    assertTrue(
+        "Second CommitValidationMessages does not contain '42'",
         ret.get(1).getMessage().contains("42"));
 
     assertLogMessageContains("4711");
@@ -465,11 +462,9 @@
   }
 
   private void setupCommonMocks() {
-    expect(itsConfig.getIssuePattern())
-        .andReturn(Pattern.compile("bug#(\\d+)")).anyTimes();
+    expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)")).anyTimes();
     Project.NameKey projectNK = new Project.NameKey("myProject");
-    expect(itsConfig.isEnabled(projectNK, null)).andReturn(true)
-        .anyTimes();
+    expect(itsConfig.isEnabled(projectNK, null)).andReturn(true).anyTimes();
   }
 
   @Override
@@ -481,11 +476,27 @@
     setupCommonMocks();
   }
 
+  private CommitReceivedEvent newCommitReceivedEvent(
+      ReceiveCommand command,
+      Project project,
+      String refName,
+      RevCommit commit,
+      IdentifiedUser user) {
+    CommitReceivedEvent event = createMock(CommitReceivedEvent.class);
+    event.command = command;
+    event.project = project;
+    event.refName = refName;
+    event.commit = commit;
+    event.user = user;
+    expect(event.getProjectNameKey()).andReturn(project.getNameKey()).anyTimes();
+    expect(event.getRefName()).andReturn(null).anyTimes();
+    return event;
+  }
+
   private class TestModule extends FactoryModule {
     @Override
     protected void configure() {
-      bind(String.class).annotatedWith(PluginName.class)
-          .toInstance("ItsTestName");
+      bind(String.class).annotatedWith(PluginName.class).toInstance("ItsTestName");
 
       issueExtractor = createMock(IssueExtractor.class);
       bind(IssueExtractor.class).toInstance(issueExtractor);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionControllerTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionControllerTest.java
index e62184a..d2926f9 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionControllerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionControllerTest.java
@@ -23,11 +23,9 @@
 import com.google.gerrit.server.events.Event;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsConfig;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.util.PropertyExtractor;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
@@ -46,8 +44,7 @@
     ChangeEvent event = createMock(ChangeEvent.class);
 
     Set<Set<Property>> propertySets = Collections.emptySet();
-    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets)
-        .anyTimes();
+    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets).anyTimes();
 
     replayMocks();
 
@@ -63,8 +60,7 @@
     Set<Property> propertySet = Collections.emptySet();
     propertySets.add(propertySet);
 
-    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets)
-        .anyTimes();
+    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets).anyTimes();
 
     Collection<ActionRequest> actions = Collections.emptySet();
     expect(ruleBase.actionRequestsFor(propertySet)).andReturn(actions).once();
@@ -83,8 +79,7 @@
     Set<Property> propertySet = Collections.emptySet();
     propertySets.add(propertySet);
 
-    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets)
-        .anyTimes();
+    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets).anyTimes();
 
     Collection<ActionRequest> actions = Lists.newArrayListWithCapacity(1);
     ActionRequest action1 = createMock(ActionRequest.class);
@@ -111,15 +106,12 @@
     Set<Set<Property>> propertySets = Sets.newHashSet();
     propertySets.add(propertySet);
 
-    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets)
-        .anyTimes();
+    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets).anyTimes();
 
-    Collection<ActionRequest> actionRequests =
-        Lists.newArrayListWithCapacity(1);
+    Collection<ActionRequest> actionRequests = Lists.newArrayListWithCapacity(1);
     ActionRequest actionRequest1 = createMock(ActionRequest.class);
     actionRequests.add(actionRequest1);
-    expect(ruleBase.actionRequestsFor(propertySet)).andReturn(actionRequests)
-        .once();
+    expect(ruleBase.actionRequestsFor(propertySet)).andReturn(actionRequests).once();
 
     actionExecutor.execute("testIssue", actionRequests, propertySet);
 
@@ -152,25 +144,20 @@
     propertySets.add(propertySet1);
     propertySets.add(propertySet2);
 
-    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets)
-        .anyTimes();
+    expect(propertyExtractor.extractFrom(event)).andReturn(propertySets).anyTimes();
 
-    Collection<ActionRequest> actionRequests1 =
-        Lists.newArrayListWithCapacity(1);
+    Collection<ActionRequest> actionRequests1 = Lists.newArrayListWithCapacity(1);
     ActionRequest actionRequest1 = createMock(ActionRequest.class);
     actionRequests1.add(actionRequest1);
 
-    Collection<ActionRequest> actionRequests2 =
-        Lists.newArrayListWithCapacity(2);
+    Collection<ActionRequest> actionRequests2 = Lists.newArrayListWithCapacity(2);
     ActionRequest actionRequest2 = createMock(ActionRequest.class);
     actionRequests2.add(actionRequest2);
     ActionRequest actionRequest3 = createMock(ActionRequest.class);
     actionRequests2.add(actionRequest3);
 
-    expect(ruleBase.actionRequestsFor(propertySet1)).andReturn(actionRequests1)
-        .once();
-    expect(ruleBase.actionRequestsFor(propertySet2)).andReturn(actionRequests2)
-        .once();
+    expect(ruleBase.actionRequestsFor(propertySet1)).andReturn(actionRequests1).once();
+    expect(ruleBase.actionRequestsFor(propertySet2)).andReturn(actionRequests2).once();
 
     actionExecutor.execute("testIssue", actionRequests1, propertySet1);
     actionExecutor.execute("testIssue", actionRequests2, propertySet2);
@@ -180,13 +167,13 @@
 
     actionController.onEvent(event);
   }
+
   private ActionController createActionController() {
     return injector.getInstance(ActionController.class);
   }
 
   private void setupCommonMocks() {
-    expect(itsConfig.isEnabled(anyObject(Event.class))).andReturn(true)
-        .anyTimes();
+    expect(itsConfig.isEnabled(anyObject(Event.class))).andReturn(true).anyTimes();
   }
 
   @Override
@@ -213,4 +200,4 @@
       bind(ItsConfig.class).toInstance(itsConfig);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutorTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutorTest.java
index 2610b22..f2b6a55 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionExecutorTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// 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.
@@ -20,14 +20,13 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddComment;
+import com.googlesource.gerrit.plugins.its.base.workflow.action.AddSoyComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddStandardComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddVelocityComment;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.LogEvent;
-
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Set;
@@ -39,6 +38,7 @@
   private AddComment.Factory addCommentFactory;
   private AddStandardComment.Factory addStandardCommentFactory;
   private AddVelocityComment.Factory addVelocityCommentFactory;
+  private AddSoyComment.Factory addSoyCommentFactory;
   private LogEvent.Factory logEventFactory;
 
   public void testExecuteItem() throws IOException {
@@ -91,8 +91,7 @@
     replayMocks();
 
     ActionExecutor actionExecutor = createActionExecutor();
-    actionExecutor.execute("4711", Sets.newHashSet(
-        actionRequest1, actionRequest2), properties);
+    actionExecutor.execute("4711", Sets.newHashSet(actionRequest1, actionRequest2), properties);
   }
 
   public void testExecuteIterableExceptions() throws IOException {
@@ -119,8 +118,8 @@
     replayMocks();
 
     ActionExecutor actionExecutor = createActionExecutor();
-    actionExecutor.execute("4711", Sets.newHashSet(
-        actionRequest1, actionRequest2, actionRequest3), properties);
+    actionExecutor.execute(
+        "4711", Sets.newHashSet(actionRequest1, actionRequest2, actionRequest3), properties);
 
     assertLogThrowableMessageContains("injected exception 1");
     assertLogThrowableMessageContains("injected exception 3");
@@ -143,14 +142,30 @@
     actionExecutor.execute("4711", actionRequest, properties);
   }
 
+  public void testAddSoyCommentDelegation() throws IOException {
+    ActionRequest actionRequest = createMock(ActionRequest.class);
+    expect(actionRequest.getName()).andReturn("add-soy-comment");
+
+    Set<Property> properties = Collections.emptySet();
+
+    AddSoyComment addSoyComment = createMock(AddSoyComment.class);
+    expect(addSoyCommentFactory.create()).andReturn(addSoyComment);
+
+    addSoyComment.execute("4711", actionRequest, properties);
+
+    replayMocks();
+
+    ActionExecutor actionExecutor = createActionExecutor();
+    actionExecutor.execute("4711", actionRequest, properties);
+  }
+
   public void testAddStandardCommentDelegation() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getName()).andReturn("add-standard-comment");
 
     Set<Property> properties = Collections.emptySet();
 
-    AddStandardComment addStandardComment =
-        createMock(AddStandardComment.class);
+    AddStandardComment addStandardComment = createMock(AddStandardComment.class);
     expect(addStandardCommentFactory.create()).andReturn(addStandardComment);
 
     addStandardComment.execute("4711", actionRequest, properties);
@@ -167,8 +182,7 @@
 
     Set<Property> properties = Collections.emptySet();
 
-    AddVelocityComment addVelocityComment =
-        createMock(AddVelocityComment.class);
+    AddVelocityComment addVelocityComment = createMock(AddVelocityComment.class);
     expect(addVelocityCommentFactory.create()).andReturn(addVelocityComment);
 
     addVelocityComment.execute("4711", actionRequest, properties);
@@ -215,16 +229,17 @@
       addCommentFactory = createMock(AddComment.Factory.class);
       bind(AddComment.Factory.class).toInstance(addCommentFactory);
 
+      addSoyCommentFactory = createMock(AddSoyComment.Factory.class);
+      bind(AddSoyComment.Factory.class).toInstance(addSoyCommentFactory);
+
       addStandardCommentFactory = createMock(AddStandardComment.Factory.class);
-      bind(AddStandardComment.Factory.class).toInstance(
-          addStandardCommentFactory);
+      bind(AddStandardComment.Factory.class).toInstance(addStandardCommentFactory);
 
       addVelocityCommentFactory = createMock(AddVelocityComment.Factory.class);
-      bind(AddVelocityComment.Factory.class).toInstance(
-          addVelocityCommentFactory);
+      bind(AddVelocityComment.Factory.class).toInstance(addVelocityCommentFactory);
 
       logEventFactory = createMock(LogEvent.Factory.class);
       bind(LogEvent.Factory.class).toInstance(logEventFactory);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequestTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequestTest.java
index d2461dc..e6de999 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequestTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ActionRequestTest.java
@@ -16,9 +16,7 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
-
 import java.util.Arrays;
 
 public class ActionRequestTest extends LoggingMockingTestCase {
@@ -28,146 +26,127 @@
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action");
-    assertEquals("Unparsed string does not match", "action",
-        actionRequest.getUnparsed());
+    assertEquals("Unparsed string does not match", "action", actionRequest.getUnparsed());
   }
 
   public void testUnparsedNull() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest(null);
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getUnparsed());
+    assertEquals("Unparsed string does not match", "", actionRequest.getUnparsed());
   }
 
   public void testUnparsedSingleParameter() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param");
-    assertEquals("Unparsed string does not match", "action param",
-        actionRequest.getUnparsed());
+    assertEquals("Unparsed string does not match", "action param", actionRequest.getUnparsed());
   }
 
   public void testUnparsedMultipleParameters() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param1 param2");
-    assertEquals("Unparsed string does not match", "action param1 param2",
-        actionRequest.getUnparsed());
+    assertEquals(
+        "Unparsed string does not match", "action param1 param2", actionRequest.getUnparsed());
   }
 
   public void testNameParameterless() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action");
-    assertEquals("Unparsed string does not match", "action",
-        actionRequest.getName());
+    assertEquals("Unparsed string does not match", "action", actionRequest.getName());
   }
 
   public void testNameSingleParameter() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param");
-    assertEquals("Unparsed string does not match", "action",
-        actionRequest.getName());
+    assertEquals("Unparsed string does not match", "action", actionRequest.getName());
   }
 
   public void testNameMultipleParameters() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param1 param2");
-    assertEquals("Unparsed string does not match", "action",
-        actionRequest.getName());
+    assertEquals("Unparsed string does not match", "action", actionRequest.getName());
   }
 
   public void testNameNull() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest(null);
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getName());
+    assertEquals("Unparsed string does not match", "", actionRequest.getName());
   }
 
   public void testParameter1Parameterless() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action");
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getParameter(1));
+    assertEquals("Unparsed string does not match", "", actionRequest.getParameter(1));
   }
 
   public void testParameter1Null() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest(null);
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getParameter(1));
+    assertEquals("Unparsed string does not match", "", actionRequest.getParameter(1));
   }
 
   public void testParameter1SingleParameter() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param");
-    assertEquals("Unparsed string does not match", "param",
-        actionRequest.getParameter(1));
+    assertEquals("Unparsed string does not match", "param", actionRequest.getParameter(1));
   }
 
   public void testParemeter1MultipleParameters() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param1 param2");
-    assertEquals("Unparsed string does not match", "param1",
-        actionRequest.getParameter(1));
+    assertEquals("Unparsed string does not match", "param1", actionRequest.getParameter(1));
   }
 
   public void testParameter3Parameterless() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action");
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getParameter(3));
+    assertEquals("Unparsed string does not match", "", actionRequest.getParameter(3));
   }
 
   public void testParameter3Null() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest(null);
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getParameter(3));
+    assertEquals("Unparsed string does not match", "", actionRequest.getParameter(3));
   }
 
   public void testParameter3SingleParameter() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param");
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getParameter(3));
+    assertEquals("Unparsed string does not match", "", actionRequest.getParameter(3));
   }
 
   public void testParemeter3With2Parameters() {
     replayMocks();
 
     ActionRequest actionRequest = createActionRequest("action param1 param2");
-    assertEquals("Unparsed string does not match", "",
-        actionRequest.getParameter(3));
+    assertEquals("Unparsed string does not match", "", actionRequest.getParameter(3));
   }
 
   public void testParemeter3With3Parameters() {
     replayMocks();
 
-    ActionRequest actionRequest = createActionRequest("action param1 param2 " +
-        "param3");
-    assertEquals("Unparsed string does not match", "param3",
-        actionRequest.getParameter(3));
+    ActionRequest actionRequest = createActionRequest("action param1 param2 " + "param3");
+    assertEquals("Unparsed string does not match", "param3", actionRequest.getParameter(3));
   }
 
   public void testParemeter3With4Parameters() {
     replayMocks();
 
-    ActionRequest actionRequest = createActionRequest("action param1 param2 " +
-        "param3 param4");
-    assertEquals("Unparsed string does not match", "param3",
-        actionRequest.getParameter(3));
+    ActionRequest actionRequest = createActionRequest("action param1 param2 " + "param3 param4");
+    assertEquals("Unparsed string does not match", "param3", actionRequest.getParameter(3));
   }
 
   public void testParametersParameterless() {
@@ -176,7 +155,9 @@
     ActionRequest actionRequest = createActionRequest("action");
 
     String[] expected = new String[0];
-    assertEquals("Parameters do not match", Arrays.asList(expected),
+    assertEquals(
+        "Parameters do not match",
+        Arrays.asList(expected),
         Arrays.asList(actionRequest.getParameters()));
   }
 
@@ -186,7 +167,9 @@
     ActionRequest actionRequest = createActionRequest(null);
 
     String[] expected = new String[0];
-    assertEquals("Parameters do not match", Arrays.asList(expected),
+    assertEquals(
+        "Parameters do not match",
+        Arrays.asList(expected),
         Arrays.asList(actionRequest.getParameters()));
   }
 
@@ -195,25 +178,27 @@
 
     ActionRequest actionRequest = createActionRequest("action param");
 
-    String[] expected = new String[] { "param" };
-    assertEquals("Parameters do not match", Arrays.asList(expected),
+    String[] expected = new String[] {"param"};
+    assertEquals(
+        "Parameters do not match",
+        Arrays.asList(expected),
         Arrays.asList(actionRequest.getParameters()));
   }
 
   public void testParameters3Parameter() {
     replayMocks();
 
-    ActionRequest actionRequest = createActionRequest("action param1 param2 " +
-        "param3");
+    ActionRequest actionRequest = createActionRequest("action param1 param2 " + "param3");
 
-    String[] expected = new String[] { "param1", "param2", "param3" };
-    assertEquals("Parameters do not match", Arrays.asList(expected),
+    String[] expected = new String[] {"param1", "param2", "param3"};
+    assertEquals(
+        "Parameters do not match",
+        Arrays.asList(expected),
         Arrays.asList(actionRequest.getParameters()));
   }
 
   private ActionRequest createActionRequest(String specification) {
-    ActionRequest.Factory factory = injector.getInstance(
-        ActionRequest.Factory.class);
+    ActionRequest.Factory factory = injector.getInstance(ActionRequest.Factory.class);
     return factory.create(specification);
   }
 
@@ -229,4 +214,4 @@
       factory(ActionRequest.Factory.class);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ConditionTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ConditionTest.java
index 5f58dcc..c1a6a8d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ConditionTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/ConditionTest.java
@@ -19,13 +19,11 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
-
 import java.util.Collection;
 import java.util.Collections;
 
-public class ConditionTest  extends LoggingMockingTestCase {
+public class ConditionTest extends LoggingMockingTestCase {
   private Injector injector;
 
   public void testGetKeyNull() {
@@ -351,4 +349,4 @@
       factory(Condition.Factory.class);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/PropertyTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/PropertyTest.java
index 2d34838..06ac41a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/PropertyTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/PropertyTest.java
@@ -16,10 +16,9 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 
-public class PropertyTest  extends LoggingMockingTestCase {
+public class PropertyTest extends LoggingMockingTestCase {
   private Injector injector;
 
   public void testGetKeyNull() {
@@ -42,11 +41,6 @@
     assertEquals("Value does not match", "testValue", property.getValue());
   }
 
-  public void testEqualsSelf() {
-    Property property = createProperty("testKey", "testValue");
-    assertTrue("Property not equal to itself", property.equals(property));
-  }
-
   public void testEqualsSimilar() {
     Property propertyA = createProperty("testKey", "testValue");
     Property propertyB = createProperty("testKey", "testValue");
@@ -66,36 +60,31 @@
   public void testEqualsNulledKey() {
     Property propertyA = new Property(null, "testValue");
     Property propertyB = createProperty("testKey", "testValue");
-    assertFalse("Single nulled key does match",
-        propertyA.equals(propertyB));
+    assertFalse("Single nulled key does match", propertyA.equals(propertyB));
   }
 
   public void testEqualsNulledKey2() {
     Property propertyA = createProperty("testKey", "testValue");
     Property propertyB = new Property(null, "testValue");
-    assertFalse("Single nulled key does match",
-        propertyA.equals(propertyB));
+    assertFalse("Single nulled key does match", propertyA.equals(propertyB));
   }
 
   public void testEqualsNulledValue() {
     Property propertyA = createProperty("testKey", "testValue");
     Property propertyB = createProperty("testKey", null);
-    assertFalse("Single nulled value does match",
-        propertyA.equals(propertyB));
+    assertFalse("Single nulled value does match", propertyA.equals(propertyB));
   }
 
   public void testEqualsNulledValue2() {
     Property propertyA = createProperty("testKey", null);
     Property propertyB = createProperty("testKey", "testValue");
-    assertFalse("Single nulled value does match",
-        propertyA.equals(propertyB));
+    assertFalse("Single nulled value does match", propertyA.equals(propertyB));
   }
 
   public void testHashCodeEquals() {
     Property propertyA = createProperty("testKey", "testValue");
     Property propertyB = createProperty("testKey", "testValue");
-    assertEquals("Hash codes do not match", propertyA.hashCode(),
-        propertyB.hashCode());
+    assertEquals("Hash codes do not match", propertyA.hashCode(), propertyB.hashCode());
   }
 
   public void testHashCodeNullKey() {
@@ -126,4 +115,4 @@
       factory(Property.Factory.class);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBaseTest.java
index 596afc7..80e12fb 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBaseTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleBaseTest.java
@@ -21,11 +21,7 @@
 import com.google.gerrit.server.config.SitePath;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
-
-import org.eclipse.jgit.util.FileUtils;
-
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
@@ -37,6 +33,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
+import org.eclipse.jgit.util.FileUtils;
 
 public class RuleBaseTest extends LoggingMockingTestCase {
   private Injector injector;
@@ -49,9 +46,9 @@
   private boolean cleanupSitePath;
 
   private enum RuleBaseKind {
-      GLOBAL,
-      ITS,
-      FAULTY
+    GLOBAL,
+    ITS,
+    FAULTY
   }
 
   public void testWarnNonExistingRuleBase() {
@@ -71,9 +68,7 @@
   }
 
   public void testSimpleRuleBase() throws IOException {
-    injectRuleBase("[rule \"rule1\"]\n" +
-        "\tconditionA = value1\n" +
-        "\taction = action1");
+    injectRuleBase("[rule \"rule1\"]\n" + "\tconditionA = value1\n" + "\taction = action1");
 
     Rule rule1 = createMock(Rule.class);
     expect(ruleFactory.create("rule1")).andReturn(rule1);
@@ -92,36 +87,34 @@
   }
 
   public void testBasicRuleBase() throws IOException {
-    injectRuleBase("[rule \"rule1\"]\n" +
-        "\tconditionA = value1,value2\n" +
-        "\tconditionA = value3,value of 4\n" +
-        "\tconditionB = value5\n" +
-        "\taction = action1\n" +
-        "\taction = action2 param\n" +
-        "\n" +
-        "[ruleXZ \"nonrule\"]\n" +
-        "\tconditionA = value1\n" +
-        "\taction = action2\n" +
-        "[rule \"rule2\"]\n" +
-        "\tconditionC = value6\n" +
-        "\taction = action3");
+    injectRuleBase(
+        "[rule \"rule1\"]\n"
+            + "\tconditionA = value1,value2\n"
+            + "\tconditionA = value3,value of 4\n"
+            + "\tconditionB = value5\n"
+            + "\taction = action1\n"
+            + "\taction = action2 param\n"
+            + "\n"
+            + "[ruleXZ \"nonrule\"]\n"
+            + "\tconditionA = value1\n"
+            + "\taction = action2\n"
+            + "[rule \"rule2\"]\n"
+            + "\tconditionC = value6\n"
+            + "\taction = action3");
 
     Rule rule1 = createMock(Rule.class);
     expect(ruleFactory.create("rule1")).andReturn(rule1);
 
     Condition condition1 = createMock(Condition.class);
-    expect(conditionFactory.create("conditionA", "value1,value2")).
-        andReturn(condition1);
+    expect(conditionFactory.create("conditionA", "value1,value2")).andReturn(condition1);
     rule1.addCondition(condition1);
 
     Condition condition2 = createMock(Condition.class);
-    expect(conditionFactory.create("conditionA", "value3,value of 4")).
-        andReturn(condition2);
+    expect(conditionFactory.create("conditionA", "value3,value of 4")).andReturn(condition2);
     rule1.addCondition(condition2);
 
     Condition condition3 = createMock(Condition.class);
-    expect(conditionFactory.create("conditionB", "value5")).
-        andReturn(condition3);
+    expect(conditionFactory.create("conditionB", "value5")).andReturn(condition3);
     rule1.addCondition(condition3);
 
     ActionRequest actionRequest1 = createMock(ActionRequest.class);
@@ -136,8 +129,7 @@
     expect(ruleFactory.create("rule2")).andReturn(rule2);
 
     Condition condition4 = createMock(Condition.class);
-    expect(conditionFactory.create("conditionC", "value6")).
-        andReturn(condition4);
+    expect(conditionFactory.create("conditionC", "value6")).andReturn(condition4);
     rule2.addCondition(condition4);
 
     ActionRequest actionRequest3 = createMock(ActionRequest.class);
@@ -150,8 +142,7 @@
   }
 
   public void testActionRequestsForSimple() throws IOException {
-    injectRuleBase("[rule \"rule1\"]\n" +
-        "\taction = action1");
+    injectRuleBase("[rule \"rule1\"]\n" + "\taction = action1");
 
     Rule rule1 = createMock(Rule.class);
     expect(ruleFactory.create("rule1")).andReturn(rule1);
@@ -178,12 +169,13 @@
   }
 
   public void testActionRequestsForExtended() throws IOException {
-    injectRuleBase("[rule \"rule1\"]\n" +
-        "\taction = action1\n" +
-        "\taction = action2\n" +
-        "\n" +
-        "[rule \"rule2\"]\n" +
-        "\taction = action3");
+    injectRuleBase(
+        "[rule \"rule1\"]\n"
+            + "\taction = action1\n"
+            + "\taction = action2\n"
+            + "\n"
+            + "[rule \"rule2\"]\n"
+            + "\taction = action3");
 
     Rule rule1 = createMock(Rule.class);
     expect(ruleFactory.create("rule1")).andReturn(rule1);
@@ -241,9 +233,9 @@
   }
 
   public void testSimpleFaultyNameRuleBase() throws IOException {
-    injectRuleBase("[rule \"rule1\"]\n" +
-        "\tconditionA = value1\n" +
-        "\taction = action1", RuleBaseKind.FAULTY);
+    injectRuleBase(
+        "[rule \"rule1\"]\n" + "\tconditionA = value1\n" + "\taction = action1",
+        RuleBaseKind.FAULTY);
 
     Rule rule1 = createMock(Rule.class);
     expect(ruleFactory.create("rule1")).andReturn(rule1);
@@ -265,9 +257,8 @@
   }
 
   public void testSimpleItsRuleBase() throws IOException {
-    injectRuleBase("[rule \"rule1\"]\n" +
-        "\tconditionA = value1\n" +
-        "\taction = action1", RuleBaseKind.ITS);
+    injectRuleBase(
+        "[rule \"rule1\"]\n" + "\tconditionA = value1\n" + "\taction = action1", RuleBaseKind.ITS);
 
     Rule rule1 = createMock(Rule.class);
     expect(ruleFactory.create("rule1")).andReturn(rule1);
@@ -286,14 +277,11 @@
   }
 
   public void testAllRuleBaseFilesAreLoaded() throws IOException {
-    injectRuleBase("[rule \"rule1\"]\n" +
-        "\taction = action1", RuleBaseKind.FAULTY);
+    injectRuleBase("[rule \"rule1\"]\n" + "\taction = action1", RuleBaseKind.FAULTY);
 
-    injectRuleBase("[rule \"rule2\"]\n" +
-        "\taction = action2", RuleBaseKind.GLOBAL);
+    injectRuleBase("[rule \"rule2\"]\n" + "\taction = action2", RuleBaseKind.GLOBAL);
 
-    injectRuleBase("[rule \"rule3\"]\n" +
-        "\taction = action3", RuleBaseKind.ITS);
+    injectRuleBase("[rule \"rule3\"]\n" + "\taction = action3", RuleBaseKind.ITS);
 
     Collection<Property> properties = Collections.emptySet();
 
@@ -369,14 +357,16 @@
       default:
         fail("Unknown ruleBaseKind");
     }
-    File ruleBaseFile = new File(sitePath.toFile(),
-        "etc" + File.separatorChar + "its" + File.separator +
-        baseName + ".config");
+    File ruleBaseFile =
+        new File(
+            sitePath.toFile(),
+            "etc" + File.separatorChar + "its" + File.separator + baseName + ".config");
 
     File ruleBaseParentFile = ruleBaseFile.getParentFile();
     if (!ruleBaseParentFile.exists()) {
-      assertTrue("Failed to create parent (" + ruleBaseParentFile + ") for " +
-          "rule base", ruleBaseParentFile.mkdirs());
+      assertTrue(
+          "Failed to create parent (" + ruleBaseParentFile + ") for " + "rule base",
+          ruleBaseParentFile.mkdirs());
     }
     try (FileWriter unbufferedWriter = new FileWriter(ruleBaseFile);
         BufferedWriter writer = new BufferedWriter(unbufferedWriter)) {
@@ -409,12 +399,10 @@
     @Override
     protected void configure() {
 
-      bind(String.class).annotatedWith(PluginName.class)
-          .toInstance("ItsTestName");
+      bind(String.class).annotatedWith(PluginName.class).toInstance("ItsTestName");
 
       sitePath = randomTargetPath();
-      assertFalse("sitePath already (" + sitePath + ") already exists",
-          Files.exists(sitePath));
+      assertFalse("sitePath already (" + sitePath + ") already exists", Files.exists(sitePath));
       cleanupSitePath = true;
 
       bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
@@ -429,4 +417,4 @@
       bind(ActionRequest.Factory.class).toInstance(actionRequestFactory);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleTest.java
index 4b31618..6d4d234 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/RuleTest.java
@@ -19,9 +19,7 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -133,4 +131,4 @@
       factory(Rule.Factory.class);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddCommentTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddCommentTest.java
index a86798e..691fb6a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddCommentTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddCommentTest.java
@@ -18,11 +18,9 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
-import com.googlesource.gerrit.plugins.its.base.workflow.Property;
 
 import java.io.IOException;
 import java.util.HashSet;
@@ -34,26 +32,24 @@
 
   public void testEmpty() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {});
+    expect(actionRequest.getParameters()).andReturn(new String[] {});
 
     replayMocks();
 
     AddComment addComment = createAddComment();
-    addComment.execute("4711", actionRequest, new HashSet<Property>());
+    addComment.execute("4711", actionRequest, new HashSet<>());
   }
 
   public void testPlain() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"Some", "test", "comment"});
+    expect(actionRequest.getParameters()).andReturn(new String[] {"Some", "test", "comment"});
 
     its.addComment("4711", "Some test comment");
 
     replayMocks();
 
     AddComment addComment = createAddComment();
-    addComment.execute("4711", actionRequest, new HashSet<Property>());
+    addComment.execute("4711", actionRequest, new HashSet<>());
   }
 
   private AddComment createAddComment() {
@@ -73,4 +69,4 @@
       bind(ItsFacade.class).toInstance(its);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardCommentTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardCommentTest.java
index af013b8..cfcda01 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardCommentTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddStandardCommentTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// 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.
@@ -19,12 +19,10 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
 import java.io.IOException;
 import java.util.Set;
 
@@ -66,30 +64,29 @@
     properties.add(propertySubject);
 
     Property propertyChangeNumber = createMock(Property.class);
-    expect(propertyChangeNumber.getKey()).andReturn("change-number")
-        .anyTimes();
+    expect(propertyChangeNumber.getKey()).andReturn("changeNumber").anyTimes();
     expect(propertyChangeNumber.getValue()).andReturn("4711").anyTimes();
     properties.add(propertyChangeNumber);
 
     Property propertySubmitterName = createMock(Property.class);
-    expect(propertySubmitterName.getKey()).andReturn("submitter-name")
-        .anyTimes();
+    expect(propertySubmitterName.getKey()).andReturn("submitterName").anyTimes();
     expect(propertySubmitterName.getValue()).andReturn("John Doe").anyTimes();
     properties.add(propertySubmitterName);
 
-    Property propertyChangeUrl= createMock(Property.class);
-    expect(propertyChangeUrl.getKey()).andReturn("change-url").anyTimes();
-    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change")
-        .anyTimes();
+    Property propertyChangeUrl = createMock(Property.class);
+    expect(propertyChangeUrl.getKey()).andReturn("changeUrl").anyTimes();
+    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change").anyTimes();
     properties.add(propertyChangeUrl);
 
-    expect(its.createLinkForWebui("http://example.org/change",
-        "http://example.org/change")).andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
+    expect(its.createLinkForWebui("http://example.org/change", "http://example.org/change"))
+        .andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
 
-    its.addComment("176", "Change 4711 merged by John Doe:\n" +
-        "Test-Change-Subject\n" +
-        "\n" +
-        "HtTp://ExAmPlE.OrG/ChAnGe");
+    its.addComment(
+        "176",
+        "Change 4711 merged by John Doe:\n"
+            + "Test-Change-Subject\n"
+            + "\n"
+            + "HtTp://ExAmPlE.OrG/ChAnGe");
     replayMocks();
 
     Action action = injector.getInstance(AddStandardComment.class);
@@ -134,33 +131,32 @@
     properties.add(propertySubject);
 
     Property propertyChangeNumber = createMock(Property.class);
-    expect(propertyChangeNumber.getKey()).andReturn("change-number")
-        .anyTimes();
+    expect(propertyChangeNumber.getKey()).andReturn("changeNumber").anyTimes();
     expect(propertyChangeNumber.getValue()).andReturn("4711").anyTimes();
     properties.add(propertyChangeNumber);
 
     Property propertySubmitterName = createMock(Property.class);
-    expect(propertySubmitterName.getKey()).andReturn("abandoner-name")
-        .anyTimes();
+    expect(propertySubmitterName.getKey()).andReturn("abandonerName").anyTimes();
     expect(propertySubmitterName.getValue()).andReturn("John Doe").anyTimes();
     properties.add(propertySubmitterName);
 
-    Property propertyChangeUrl= createMock(Property.class);
-    expect(propertyChangeUrl.getKey()).andReturn("change-url").anyTimes();
-    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change")
-        .anyTimes();
+    Property propertyChangeUrl = createMock(Property.class);
+    expect(propertyChangeUrl.getKey()).andReturn("changeUrl").anyTimes();
+    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change").anyTimes();
     properties.add(propertyChangeUrl);
 
-    expect(its.createLinkForWebui("http://example.org/change",
-        "http://example.org/change")).andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
+    expect(its.createLinkForWebui("http://example.org/change", "http://example.org/change"))
+        .andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
 
-    its.addComment("176", "Change 4711 abandoned by John Doe:\n" +
-        "Test-Change-Subject\n" +
-        "\n" +
-        "Reason:\n" +
-        "Test-Reason\n" +
-        "\n" +
-        "HtTp://ExAmPlE.OrG/ChAnGe");
+    its.addComment(
+        "176",
+        "Change 4711 abandoned by John Doe:\n"
+            + "Test-Change-Subject\n"
+            + "\n"
+            + "Reason:\n"
+            + "Test-Reason\n"
+            + "\n"
+            + "HtTp://ExAmPlE.OrG/ChAnGe");
     replayMocks();
 
     Action action = injector.getInstance(AddStandardComment.class);
@@ -205,33 +201,32 @@
     properties.add(propertySubject);
 
     Property propertyChangeNumber = createMock(Property.class);
-    expect(propertyChangeNumber.getKey()).andReturn("change-number")
-        .anyTimes();
+    expect(propertyChangeNumber.getKey()).andReturn("changeNumber").anyTimes();
     expect(propertyChangeNumber.getValue()).andReturn("4711").anyTimes();
     properties.add(propertyChangeNumber);
 
     Property propertySubmitterName = createMock(Property.class);
-    expect(propertySubmitterName.getKey()).andReturn("restorer-name")
-        .anyTimes();
+    expect(propertySubmitterName.getKey()).andReturn("restorerName").anyTimes();
     expect(propertySubmitterName.getValue()).andReturn("John Doe").anyTimes();
     properties.add(propertySubmitterName);
 
-    Property propertyChangeUrl= createMock(Property.class);
-    expect(propertyChangeUrl.getKey()).andReturn("change-url").anyTimes();
-    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change")
-        .anyTimes();
+    Property propertyChangeUrl = createMock(Property.class);
+    expect(propertyChangeUrl.getKey()).andReturn("changeUrl").anyTimes();
+    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change").anyTimes();
     properties.add(propertyChangeUrl);
 
-    expect(its.createLinkForWebui("http://example.org/change",
-        "http://example.org/change")).andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
+    expect(its.createLinkForWebui("http://example.org/change", "http://example.org/change"))
+        .andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
 
-    its.addComment("176", "Change 4711 restored by John Doe:\n" +
-        "Test-Change-Subject\n" +
-        "\n" +
-        "Reason:\n" +
-        "Test-Reason\n" +
-        "\n" +
-        "HtTp://ExAmPlE.OrG/ChAnGe");
+    its.addComment(
+        "176",
+        "Change 4711 restored by John Doe:\n"
+            + "Test-Change-Subject\n"
+            + "\n"
+            + "Reason:\n"
+            + "Test-Reason\n"
+            + "\n"
+            + "HtTp://ExAmPlE.OrG/ChAnGe");
     replayMocks();
 
     Action action = injector.getInstance(AddStandardComment.class);
@@ -271,31 +266,30 @@
     properties.add(propertySubject);
 
     Property propertyChangeNumber = createMock(Property.class);
-    expect(propertyChangeNumber.getKey()).andReturn("change-number")
-        .anyTimes();
+    expect(propertyChangeNumber.getKey()).andReturn("changeNumber").anyTimes();
     expect(propertyChangeNumber.getValue()).andReturn("4711").anyTimes();
     properties.add(propertyChangeNumber);
 
     Property propertySubmitterName = createMock(Property.class);
-    expect(propertySubmitterName.getKey()).andReturn("uploader-name")
-        .anyTimes();
+    expect(propertySubmitterName.getKey()).andReturn("uploaderName").anyTimes();
     expect(propertySubmitterName.getValue()).andReturn("John Doe").anyTimes();
     properties.add(propertySubmitterName);
 
-    Property propertyChangeUrl= createMock(Property.class);
-    expect(propertyChangeUrl.getKey()).andReturn("change-url").anyTimes();
-    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change")
-        .anyTimes();
+    Property propertyChangeUrl = createMock(Property.class);
+    expect(propertyChangeUrl.getKey()).andReturn("changeUrl").anyTimes();
+    expect(propertyChangeUrl.getValue()).andReturn("http://example.org/change").anyTimes();
     properties.add(propertyChangeUrl);
 
-    expect(its.createLinkForWebui("http://example.org/change",
-        "http://example.org/change")).andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
+    expect(its.createLinkForWebui("http://example.org/change", "http://example.org/change"))
+        .andReturn("HtTp://ExAmPlE.OrG/ChAnGe");
 
-    its.addComment("176", "Change 4711 had a related patch set uploaded by " +
-        "John Doe:\n" +
-        "Test-Change-Subject\n" +
-        "\n" +
-        "HtTp://ExAmPlE.OrG/ChAnGe");
+    its.addComment(
+        "176",
+        "Change 4711 had a related patch set uploaded by "
+            + "John Doe:\n"
+            + "Test-Change-Subject\n"
+            + "\n"
+            + "HtTp://ExAmPlE.OrG/ChAnGe");
     replayMocks();
 
     Action action = injector.getInstance(AddStandardComment.class);
@@ -316,4 +310,4 @@
       bind(ItsFacade.class).toInstance(its);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityCommentTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityCommentTest.java
index 5a33db6..61042a4 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityCommentTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/AddVelocityCommentTest.java
@@ -23,20 +23,11 @@
 import com.google.gerrit.server.config.SitePath;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
 import com.googlesource.gerrit.plugins.its.base.workflow.action.AddVelocityComment.VelocityAdapterItsFacade;
-
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.runtime.RuntimeInstance;
-import org.easymock.Capture;
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.eclipse.jgit.util.FileUtils;
-
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
@@ -48,6 +39,12 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.UUID;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.runtime.RuntimeInstance;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.eclipse.jgit.util.FileUtils;
 
 public class AddVelocityCommentTest extends LoggingMockingTestCase {
   private Injector injector;
@@ -64,7 +61,7 @@
     replayMocks();
 
     AddVelocityComment addVelocityComment = createAddVelocityComment();
-    addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
+    addVelocityComment.execute("4711", actionRequest, new HashSet<>());
 
     assertLogMessageContains("No template name");
   }
@@ -72,12 +69,15 @@
   public void testInlinePlain() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("inline");
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"inline", "Simple-text"});
+    expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Simple-text"});
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Simple-text");
-    expect(velocityRuntime.evaluate((VelocityContext)anyObject(),
-        (Writer)anyObject(), (String)anyObject(), eq("Simple-text")))
+    expect(
+            velocityRuntime.evaluate(
+                (VelocityContext) anyObject(),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("Simple-text")))
         .andAnswer(answer);
 
     its.addComment("4711", "Simple-text");
@@ -85,20 +85,23 @@
     replayMocks();
 
     AddVelocityComment addVelocityComment = createAddVelocityComment();
-    addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
+    addVelocityComment.execute("4711", actionRequest, new HashSet<>());
   }
 
   public void testInlineWithMultipleParameters() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("inline");
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"inline", "Param2", "Param3"});
+    expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Param2", "Param3"});
 
     Set<Property> properties = Sets.newHashSet();
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Param2 Param3");
-    expect(velocityRuntime.evaluate((VelocityContext)anyObject(),
-        (Writer)anyObject(), (String)anyObject(), eq("Param2 Param3")))
+    expect(
+            velocityRuntime.evaluate(
+                (VelocityContext) anyObject(),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("Param2 Param3")))
         .andAnswer(answer);
 
     its.addComment("4711", "Param2 Param3");
@@ -112,8 +115,7 @@
   public void testInlineWithSingleProperty() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("inline");
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"inline", "${subject}"});
+    expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "${subject}"});
 
     Set<Property> properties = Sets.newHashSet();
 
@@ -124,8 +126,12 @@
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Rosebud");
     Capture<VelocityContext> contextCapture = createCapture();
-    expect(velocityRuntime.evaluate(capture(contextCapture),
-        (Writer)anyObject(), (String)anyObject(), eq("${subject}")))
+    expect(
+            velocityRuntime.evaluate(
+                capture(contextCapture),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("${subject}")))
         .andAnswer(answer);
 
     its.addComment("4711", "Rosebud");
@@ -136,15 +142,13 @@
     addVelocityComment.execute("4711", actionRequest, properties);
 
     VelocityContext context = contextCapture.getValue();
-    assertEquals("Subject property of context did not match", "Rosebud",
-        context.get("subject"));
+    assertEquals("Subject property of context did not match", "Rosebud", context.get("subject"));
   }
 
   public void testInlineWithUnusedProperty() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("inline");
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"inline", "Test"});
+    expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Test"});
 
     Set<Property> properties = Sets.newHashSet();
 
@@ -154,8 +158,12 @@
     properties.add(propertySubject);
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Test");
-    expect(velocityRuntime.evaluate((VelocityContext)anyObject(),
-        (Writer)anyObject(), (String)anyObject(), eq("Test")))
+    expect(
+            velocityRuntime.evaluate(
+                (VelocityContext) anyObject(),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("Test")))
         .andAnswer(answer);
 
     its.addComment("4711", "Test");
@@ -169,8 +177,8 @@
   public void testInlineWithMultipleProperties() throws IOException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("inline");
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"inline", "${subject}", "${reason}", "${subject}"});
+    expect(actionRequest.getParameters())
+        .andReturn(new String[] {"inline", "${subject}", "${reason}", "${subject}"});
 
     Set<Property> properties = Sets.newHashSet();
 
@@ -186,9 +194,13 @@
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Rosebud Life Rosebud");
     Capture<VelocityContext> contextCapture = createCapture();
-    expect(velocityRuntime.evaluate(capture(contextCapture),
-        (Writer)anyObject(), (String)anyObject(),
-        eq("${subject} ${reason} ${subject}"))).andAnswer(answer);
+    expect(
+            velocityRuntime.evaluate(
+                capture(contextCapture),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("${subject} ${reason} ${subject}")))
+        .andAnswer(answer);
 
     its.addComment("4711", "Rosebud Life Rosebud");
 
@@ -198,58 +210,61 @@
     addVelocityComment.execute("4711", actionRequest, properties);
 
     VelocityContext context = contextCapture.getValue();
-    assertEquals("Subject property of context did not match", "Rosebud",
-        context.get("subject"));
-    assertEquals("Reason property of context did not match", "Life",
-        context.get("reason"));
+    assertEquals("Subject property of context did not match", "Rosebud", context.get("subject"));
+    assertEquals("Reason property of context did not match", "Life", context.get("reason"));
   }
 
-  public void testItsWrapperFormatLink1Parameter() throws IOException,
-      SecurityException, IllegalArgumentException {
+  public void testItsWrapperFormatLink1Parameter()
+      throws IOException, SecurityException, IllegalArgumentException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("inline");
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"inline", "Simple-Text"});
+    expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Simple-Text"});
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Simple-Text");
     Capture<VelocityContext> contextCapture = createCapture();
-    expect(velocityRuntime.evaluate(capture(contextCapture),
-        (Writer)anyObject(), (String)anyObject(), eq("Simple-Text")))
+    expect(
+            velocityRuntime.evaluate(
+                capture(contextCapture),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("Simple-Text")))
         .andAnswer(answer);
 
     its.addComment("4711", "Simple-Text");
 
-    expect(its.createLinkForWebui("http://www.example.org/",
-        "http://www.example.org/")) .andReturn("Formatted Link");
+    expect(its.createLinkForWebui("http://www.example.org/", "http://www.example.org/"))
+        .andReturn("Formatted Link");
 
     replayMocks();
 
     AddVelocityComment addVelocityComment = createAddVelocityComment();
-    addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
+    addVelocityComment.execute("4711", actionRequest, new HashSet<>());
 
     VelocityContext context = contextCapture.getValue();
     Object itsAdapterObj = context.get("its");
     assertNotNull("its property is null", itsAdapterObj);
-    assertTrue("Its is not a VelocityAdapterItsFacade instance",
+    assertTrue(
+        "Its is not a VelocityAdapterItsFacade instance",
         itsAdapterObj instanceof VelocityAdapterItsFacade);
-    VelocityAdapterItsFacade itsAdapter =
-        (VelocityAdapterItsFacade) itsAdapterObj;
+    VelocityAdapterItsFacade itsAdapter = (VelocityAdapterItsFacade) itsAdapterObj;
     String formattedLink = itsAdapter.formatLink("http://www.example.org/");
-    assertEquals("Result of formatLink does not match", "Formatted Link",
-        formattedLink);
+    assertEquals("Result of formatLink does not match", "Formatted Link", formattedLink);
   }
 
-  public void testItsWrapperFormatLink2Parameters() throws IOException,
-      SecurityException, IllegalArgumentException {
+  public void testItsWrapperFormatLink2Parameters()
+      throws IOException, SecurityException, IllegalArgumentException {
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("inline");
-    expect(actionRequest.getParameters()).andReturn(
-        new String[] {"inline", "Simple-Text"});
+    expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Simple-Text"});
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Simple-Text");
     Capture<VelocityContext> contextCapture = createCapture();
-    expect(velocityRuntime.evaluate(capture(contextCapture),
-        (Writer)anyObject(), (String)anyObject(), eq("Simple-Text")))
+    expect(
+            velocityRuntime.evaluate(
+                capture(contextCapture),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("Simple-Text")))
         .andAnswer(answer);
 
     its.addComment("4711", "Simple-Text");
@@ -260,19 +275,17 @@
     replayMocks();
 
     AddVelocityComment addVelocityComment = createAddVelocityComment();
-    addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
+    addVelocityComment.execute("4711", actionRequest, new HashSet<>());
 
     VelocityContext context = contextCapture.getValue();
     Object itsAdapterObj = context.get("its");
     assertNotNull("its property is null", itsAdapterObj);
-    assertTrue("Its is not a VelocityAdapterItsFacade instance",
+    assertTrue(
+        "Its is not a VelocityAdapterItsFacade instance",
         itsAdapterObj instanceof VelocityAdapterItsFacade);
-    VelocityAdapterItsFacade itsAdapter =
-        (VelocityAdapterItsFacade) itsAdapterObj;
-    String formattedLink = itsAdapter.formatLink("http://www.example.org/",
-        "Caption");
-    assertEquals("Result of formatLink does not match", "Formatted Link",
-        formattedLink);
+    VelocityAdapterItsFacade itsAdapter = (VelocityAdapterItsFacade) itsAdapterObj;
+    String formattedLink = itsAdapter.formatLink("http://www.example.org/", "Caption");
+    assertEquals("Result of formatLink does not match", "Formatted Link", formattedLink);
   }
 
   public void testWarnTemplateNotFound() throws IOException {
@@ -282,7 +295,7 @@
     replayMocks();
 
     AddVelocityComment addVelocityComment = createAddVelocityComment();
-    addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
+    addVelocityComment.execute("4711", actionRequest, new HashSet<>());
 
     assertLogMessageContains("non-existing-template");
   }
@@ -294,16 +307,20 @@
     injectTestTemplate("Simple Test Template");
 
     IAnswer<Boolean> answer = new VelocityWriterFiller("Simple Test Template");
-    expect(velocityRuntime.evaluate((VelocityContext)anyObject(),
-        (Writer)anyObject(), (String)anyObject(),
-        eq("Simple Test Template"))).andAnswer(answer);
+    expect(
+            velocityRuntime.evaluate(
+                (VelocityContext) anyObject(),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq("Simple Test Template")))
+        .andAnswer(answer);
 
     its.addComment("4711", "Simple Test Template");
 
     replayMocks();
 
     AddVelocityComment addVelocityComment = createAddVelocityComment();
-    addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
+    addVelocityComment.execute("4711", actionRequest, new HashSet<>());
   }
 
   public void testTemplateMultipleParametersAndProperties() throws IOException {
@@ -322,20 +339,25 @@
     expect(propertyReason.getValue()).andReturn("Life").anyTimes();
     properties.add(propertyReason);
 
-    injectTestTemplate("Test Template with subject: ${subject}.\n" +
-        "${reason} is the reason for ${subject}.");
+    injectTestTemplate(
+        "Test Template with subject: ${subject}.\n" + "${reason} is the reason for ${subject}.");
 
-    IAnswer<Boolean> answer = new VelocityWriterFiller(
-        "Test Template with subject: Rosebud.\n" +
-        "Life is the reason for Rosebud.");
+    IAnswer<Boolean> answer =
+        new VelocityWriterFiller(
+            "Test Template with subject: Rosebud.\n" + "Life is the reason for Rosebud.");
     Capture<VelocityContext> contextCapture = createCapture();
-    expect(velocityRuntime.evaluate(capture(contextCapture),
-        (Writer)anyObject(), (String)anyObject(),
-        eq("Test Template with subject: ${subject}.\n" +
-            "${reason} is the reason for ${subject}."))).andAnswer(answer);
+    expect(
+            velocityRuntime.evaluate(
+                capture(contextCapture),
+                (Writer) anyObject(),
+                (String) anyObject(),
+                eq(
+                    "Test Template with subject: ${subject}.\n"
+                        + "${reason} is the reason for ${subject}.")))
+        .andAnswer(answer);
 
-    its.addComment("4711", "Test Template with subject: Rosebud.\n" +
-        "Life is the reason for Rosebud.");
+    its.addComment(
+        "4711", "Test Template with subject: Rosebud.\n" + "Life is the reason for Rosebud.");
 
     replayMocks();
 
@@ -343,10 +365,8 @@
     addVelocityComment.execute("4711", actionRequest, properties);
 
     VelocityContext context = contextCapture.getValue();
-    assertEquals("Subject property of context did not match", "Rosebud",
-        context.get("subject"));
-    assertEquals("Reason property of context did not match", "Life",
-        context.get("reason"));
+    assertEquals("Subject property of context did not match", "Rosebud", context.get("subject"));
+    assertEquals("Reason property of context did not match", "Life", context.get("reason"));
   }
 
   private AddVelocityComment createAddVelocityComment() {
@@ -354,10 +374,12 @@
   }
 
   private void injectTestTemplate(String template) throws IOException {
-    File templateParentFile = new File(sitePath.toFile(), "etc" +
-        File.separatorChar + "its" + File.separator + "templates");
-    assertTrue("Failed to create parent (" + templateParentFile + ") for " +
-        "rule base", templateParentFile.mkdirs());
+    File templateParentFile =
+        new File(
+            sitePath.toFile(), "etc" + File.separatorChar + "its" + File.separator + "templates");
+    assertTrue(
+        "Failed to create parent (" + templateParentFile + ") for " + "rule base",
+        templateParentFile.mkdirs());
     File templateFile = new File(templateParentFile, "test-template.vm");
 
     try (FileWriter unbufferedWriter = new FileWriter(templateFile);
@@ -391,8 +413,7 @@
     @Override
     protected void configure() {
       sitePath = randomTargetPath();
-      assertFalse("sitePath already (" + sitePath + ") already exists",
-          Files.exists(sitePath));
+      assertFalse("sitePath already (" + sitePath + ") already exists", Files.exists(sitePath));
       cleanupSitePath = true;
 
       bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
@@ -426,4 +447,4 @@
       return returnValue;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEventTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEventTest.java
index 3d147a9..99fa2c3 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEventTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/base/workflow/action/LogEventTest.java
@@ -19,16 +19,13 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
 import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.its.base.workflow.Property;
-
-import org.apache.log4j.Level;
-
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.Set;
+import org.apache.log4j.Level;
 
 public class LogEventTest extends LoggingMockingTestCase {
   private Injector injector;
@@ -40,7 +37,7 @@
     replayMocks();
 
     LogEvent logEvent = createLogEvent();
-    logEvent.execute("4711", actionRequest, new HashSet<Property>());
+    logEvent.execute("4711", actionRequest, new HashSet<>());
   }
 
   public void testLevelDefault() throws IOException {
@@ -117,7 +114,6 @@
     ActionRequest actionRequest = createMock(ActionRequest.class);
     expect(actionRequest.getParameter(1)).andReturn("info");
 
-
     Set<Property> properties = Sets.newHashSet();
     properties.add(new PropertyMock("KeyA", "ValueA", "PropertyA"));
     properties.add(new PropertyMock("KeyB", "ValueB", "PropertyB"));
@@ -144,8 +140,7 @@
 
   private class TestModule extends FactoryModule {
     @Override
-    protected void configure() {
-    }
+    protected void configure() {}
   }
 
   private class PropertyMock extends Property {
@@ -161,4 +156,4 @@
       return toString;
     }
   }
-}
\ No newline at end of file
+}
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..8b13789
--- /dev/null
+++ b/tools/bzl/BUILD
@@ -0,0 +1 @@
+
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/maven_jar.bzl b/tools/bzl/maven_jar.bzl
new file mode 100644
index 0000000..2eabedb
--- /dev/null
+++ b/tools/bzl/maven_jar.bzl
@@ -0,0 +1 @@
+load("@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", "maven_jar")
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..1cb33d5
--- /dev/null
+++ b/tools/eclipse/BUILD
@@ -0,0 +1,9 @@
+load("//tools/bzl:classpath.bzl", "classpath_collector")
+
+classpath_collector(
+    name = "main_classpath_collect",
+    testonly = 1,
+    deps = [
+        "//:its-base__plugin_test_deps",
+    ],
+)
diff --git a/tools/eclipse/project.sh b/tools/eclipse/project.sh
new file mode 100755
index 0000000..ba64b70
--- /dev/null
+++ b/tools/eclipse/project.sh
@@ -0,0 +1,15 @@
+#!/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 its-base -r .
diff --git a/tools/workspace-status.sh b/tools/workspace-status.sh
new file mode 100755
index 0000000..57797fb
--- /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_ITS-BASE_LABEL" $(rev .)