Merge branch 'stable-2.14'

* stable-2.14:
  Use latest bazlets

Change-Id: I1eac94a9beec187167e3901e79c1cba5c4fa9841
diff --git a/BUILD b/BUILD
index 6ee6491..322ca3d 100644
--- a/BUILD
+++ b/BUILD
@@ -6,14 +6,10 @@
     srcs = glob(["src/main/java/**/*.java"]),
     manifest_entries = [
         "Gerrit-PluginName: uploadvalidator",
-        "Gerrit-ApiVersion: 2.14",
+        "Gerrit-ApiVersion: 2.15-SNAPSHOT",
         "Gerrit-Module: com.googlesource.gerrit.plugins.uploadvalidator.Module",
     ],
     resources = glob(["src/main/resources/**/*"]),
-    deps = [
-        "@commons_io//jar",
-        "@tika_core//jar",
-    ],
 )
 
 TEST_SRCS = "src/test/java/**/*Test.java"
diff --git a/WORKSPACE b/WORKSPACE
index 1e1182d..f96b9ff 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,27 +3,27 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "e57da7c1ddde1389c15c86154a2ac4019099b050",
+    commit = "42bffc66c0e92753133e4cea2debe65abc359c4d",
     # local_path = "/home/<user>/projects/bazlets",
 )
 
 #Snapshot Plugin API
-#load(
-#    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
-#    "gerrit_api_maven_local",
-#)
-
-# Load snapshot Plugin API
-#gerrit_api_maven_local()
-
-# Release Plugin API
 load(
-    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
-    "gerrit_api",
+    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
+    "gerrit_api_maven_local",
 )
 
+# Load snapshot Plugin API
+gerrit_api_maven_local()
+
+# Release Plugin API
+#load(
+#    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
+#    "gerrit_api",
+#)
+
 # Load release Plugin API
-gerrit_api()
+#gerrit_api()
 
 load("//:external_plugin_deps.bzl", "external_plugin_deps")
 
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 388ff06..759653a 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -2,12 +2,6 @@
 
 def external_plugin_deps():
   maven_jar(
-      name = 'tika_core',
-      artifact = 'org.apache.tika:tika-core:1.12',
-      sha1 = '5ab95580d22fe1dee79cffbcd98bb509a32da09b',
-  )
-
-  maven_jar(
     name = "commons_io",
     artifact = "commons-io:commons-io:1.4",
     sha1 = "a8762d07e76cfde2395257a5da47ba7c1dbd3dce",
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidator.java
index bd5420e..4a0751f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidator.java
@@ -39,13 +39,16 @@
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
+import org.eclipse.jgit.diff.RawText;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 import java.text.MessageFormat;
@@ -68,14 +71,18 @@
     return new AbstractModule() {
       @Override
       protected void configure() {
-        DynamicSet.bind(binder(), CommitValidationListener.class)
-            .to(BlockedKeywordValidator.class);
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(BlockedKeywordValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_CHECK_BLOCKED_KEYWORD_PATTERN))
-            .toInstance(new ProjectConfigEntry("Blocked Keyword Pattern", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "Pushes of commits that contain files or commit messages with "
-                + "blocked keywords will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Blocked Keyword Pattern",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "Pushes of commits that contain files or commit messages with "
+                        + "blocked keywords will be rejected."));
       }
     };
   }
@@ -88,7 +95,8 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  BlockedKeywordValidator(@PluginName String pluginName,
+  BlockedKeywordValidator(
+      @PluginName String pluginName,
       ContentTypeUtil contentTypeUtil,
       @Named(CACHE_NAME) LoadingCache<String, Pattern> patternCache,
       PluginConfigFactory cfgFactory,
@@ -107,24 +115,29 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
-      PluginConfig cfg = cfgFactory
-          .getFromProjectConfigWithInheritance(
+      PluginConfig cfg =
+          cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_CHECK_BLOCKED_KEYWORD)) {
         ImmutableMap<String, Pattern> blockedKeywordPatterns =
-            patternCache.getAll(Arrays
-                .asList(cfg.getStringList(KEY_CHECK_BLOCKED_KEYWORD_PATTERN)));
-        try (Repository repo =
-            repoManager.openRepository(receiveEvent.project.getNameKey())) {
+            patternCache.getAll(
+                Arrays.asList(cfg.getStringList(KEY_CHECK_BLOCKED_KEYWORD_PATTERN)));
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit,
-                  blockedKeywordPatterns.values(), cfg);
+              performValidation(
+                  repo,
+                  receiveEvent.commit,
+                  receiveEvent.revWalk,
+                  blockedKeywordPatterns.values(),
+                  cfg);
           if (!messages.isEmpty()) {
             throw new CommitValidationException(
                 "includes files containing blocked keywords", messages);
@@ -132,24 +145,28 @@
         }
       }
     } catch (NoSuchProjectException | IOException | ExecutionException e) {
-      throw new CommitValidationException("failed to check on blocked keywords",
-          e);
+      throw new CommitValidationException("failed to check on blocked keywords", e);
     }
     return Collections.emptyList();
   }
 
   @VisibleForTesting
-  List<CommitValidationMessage> performValidation(Repository repo, RevCommit c,
-      ImmutableCollection<Pattern> blockedKeywordPartterns, PluginConfig cfg)
-          throws IOException, ExecutionException {
+  List<CommitValidationMessage> performValidation(
+      Repository repo,
+      RevCommit c,
+      RevWalk revWalk,
+      ImmutableCollection<Pattern> blockedKeywordPartterns,
+      PluginConfig cfg)
+      throws IOException, ExecutionException {
     List<CommitValidationMessage> messages = new LinkedList<>();
-    checkCommitMessageForBlockedKeywords(blockedKeywordPartterns, messages,
-        c.getFullMessage());
-    Map<String, ObjectId> content = CommitUtils.getChangedContent(repo, c);
+    checkCommitMessageForBlockedKeywords(blockedKeywordPartterns, messages, c.getFullMessage());
+    Map<String, ObjectId> content = CommitUtils.getChangedContent(repo, c, revWalk);
     for (String path : content.keySet()) {
-      ObjectLoader ol = repo.open(content.get(path));
-      if (contentTypeUtil.isBinary(ol, path, cfg)) {
-        continue;
+      ObjectLoader ol = revWalk.getObjectReader().open(content.get(path));
+      try (InputStream in = ol.openStream()) {
+        if (RawText.isBinary(in) || contentTypeUtil.isBlacklistedBinaryContentType(ol, path, cfg)) {
+          continue;
+        }
       }
       checkFileForBlockedKeywords(blockedKeywordPartterns, messages, path, ol);
     }
@@ -158,33 +175,36 @@
 
   private static void checkCommitMessageForBlockedKeywords(
       ImmutableCollection<Pattern> blockedKeywordPatterns,
-      List<CommitValidationMessage> messages, String commitMessage) {
+      List<CommitValidationMessage> messages,
+      String commitMessage) {
     int line = 0;
     for (String l : commitMessage.split("[\r\n]+")) {
       line++;
-      checkLineForBlockedKeywords(blockedKeywordPatterns, messages,
-          Patch.COMMIT_MSG, line, l);
+      checkLineForBlockedKeywords(blockedKeywordPatterns, messages, Patch.COMMIT_MSG, line, l);
     }
   }
 
   private static void checkFileForBlockedKeywords(
       ImmutableCollection<Pattern> blockedKeywordPartterns,
-      List<CommitValidationMessage> messages, String path, ObjectLoader ol)
-          throws IOException {
-    try (BufferedReader br = new BufferedReader(
-        new InputStreamReader(ol.openStream(), StandardCharsets.UTF_8))) {
+      List<CommitValidationMessage> messages,
+      String path,
+      ObjectLoader ol)
+      throws IOException {
+    try (BufferedReader br =
+        new BufferedReader(new InputStreamReader(ol.openStream(), StandardCharsets.UTF_8))) {
       int line = 0;
       for (String l = br.readLine(); l != null; l = br.readLine()) {
         line++;
-        checkLineForBlockedKeywords(blockedKeywordPartterns, messages, path,
-            line, l);
+        checkLineForBlockedKeywords(blockedKeywordPartterns, messages, path, line, l);
       }
     }
   }
 
   private static void checkLineForBlockedKeywords(
       ImmutableCollection<Pattern> blockedKeywordPartterns,
-      List<CommitValidationMessage> messages, String path, int lineNumber,
+      List<CommitValidationMessage> messages,
+      String path,
+      int lineNumber,
       String line) {
     List<String> found = new ArrayList<>();
     for (Pattern p : blockedKeywordPartterns) {
@@ -194,9 +214,12 @@
       }
     }
     if (!found.isEmpty()) {
-      messages.add(new CommitValidationMessage(MessageFormat.format(
-          "blocked keyword(s) found in: {0} (Line: {1}) (found: {2})",
-          path, lineNumber, Joiner.on(", ").join(found)), true));
+      messages.add(
+          new CommitValidationMessage(
+              MessageFormat.format(
+                  "blocked keyword(s) found in: {0} (Line: {1}) (found: {2})",
+                  path, lineNumber, Joiner.on(", ").join(found)),
+              true));
     }
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/CommitUtils.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/CommitUtils.java
index 8b622ab..8df6412 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/CommitUtils.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/CommitUtils.java
@@ -27,51 +27,57 @@
 import java.util.Map;
 import java.util.Set;
 
+/** Utility class for checking whether commits are different. */
 public class CommitUtils {
 
   /**
-   * This method spots all files which differ between the passed commit and its
-   * parents. The paths of the spotted files will be returned as a Set.
+   * This method spots all files which differ between the passed commit and its parents. The paths
+   * of the spotted files will be returned as a Set.
    *
    * @param repo The repository
    * @param c The commit
-   * @return A Set containing the paths of all files which differ between the
-   *     passed commit and its parents.
+   * @return A Set containing the paths of all files which differ between the passed commit and its
+   *     parents.
    * @throws IOException
    */
-  public static Set<String> getChangedPaths(Repository repo, RevCommit c)
+  public static Set<String> getChangedPaths(Repository repo, RevCommit c, RevWalk revWalk)
       throws IOException {
-    Map<String, ObjectId> content = getChangedContent(repo, c);
+    Map<String, ObjectId> content = getChangedContent(repo, c, revWalk);
     return content.keySet();
   }
 
   /**
-   * This method spots all files which differ between the passed commit and its
-   * parents. The spotted files will be returned as a Map. The structure of the
-   * returned map looks like this:
+   * This method spots all files which differ between the passed commit and its parents. The spotted
+   * files will be returned as a Map. The structure of the returned map looks like this:
+   *
    * <p>
+   *
    * <ul>
-   * <li> Key: Path to the changed file.</li>
-   * <li> Value: ObjectId of the changed file.</li>
-   * <ul>
+   *   <li>Key: Path to the changed file.
+   *   <li>Value: ObjectId of the changed file.
+   *       <ul>
+   *
    * @param repo The repository
    * @param c The commit
-   * @return A Map containing all files which differ between the passed commit
-   *     and its parents.
+   * @return A Map containing all files which differ between the passed commit and its parents.
    * @throws IOException
    */
-  public static Map<String, ObjectId> getChangedContent(Repository repo,
-      RevCommit c) throws IOException {
+  public static Map<String, ObjectId> getChangedContent(
+      Repository repo, RevCommit c, RevWalk revWalk) throws IOException {
     final Map<String, ObjectId> content = new HashMap<>();
 
-    visitChangedEntries(repo, c, new TreeWalkVisitor() {
-      @Override
-      public void onVisit(TreeWalk tw) {
-        if (isFile(tw)) {
-          content.put(tw.getPathString(), tw.getObjectId(0));
-        }
-      }
-    });
+    visitChangedEntries(
+        repo,
+        c,
+        revWalk,
+        new TreeWalkVisitor() {
+          @Override
+          public void onVisit(TreeWalk tw) {
+            if (isFile(tw)) {
+              content.put(tw.getPathString(), tw.getObjectId(0));
+            }
+          }
+        });
     return content;
   }
 
@@ -81,38 +87,27 @@
   }
 
   /**
-   * This method spots all TreeWalk entries which differ between the passed
-   * commit and its parents. If a TreeWalk entry is found this method calls the
-   * onVisit() method of the class TreeWalkVisitor.
+   * This method spots all TreeWalk entries which differ between the passed commit and its parents.
+   * If a TreeWalk entry is found this method calls the onVisit() method of the class
+   * TreeWalkVisitor.
    *
    * @param repo The repository
    * @param c The commit
    * @param visitor A TreeWalkVisitor with the desired action
    * @throws IOException
    */
-  public static void visitChangedEntries(Repository repo, RevCommit c,
-      TreeWalkVisitor visitor) throws IOException {
-    try (TreeWalk tw = new TreeWalk(repo)) {
+  public static void visitChangedEntries(
+      Repository repo, RevCommit c, RevWalk revWalk, TreeWalkVisitor visitor) throws IOException {
+    try (TreeWalk tw = new TreeWalk(revWalk.getObjectReader())) {
       tw.setRecursive(true);
       tw.setFilter(TreeFilter.ANY_DIFF);
       tw.addTree(c.getTree());
       if (c.getParentCount() > 0) {
-        @SuppressWarnings("resource")
-        RevWalk rw = null;
-        try {
-          for (RevCommit p : c.getParents()) {
-            if (p.getTree() == null) {
-              if (rw == null) {
-                rw = new RevWalk(repo);
-              }
-              rw.parseHeaders(p);
-            }
-            tw.addTree(p.getTree());
+        for (RevCommit p : c.getParents()) {
+          if (p.getTree() == null) {
+            revWalk.parseHeaders(p);
           }
-        } finally {
-          if (rw != null) {
-            rw.close();
-          }
+          tw.addTree(p.getTree());
         }
         while (tw.next()) {
           if (isDifferentToAllParents(c, tw)) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtil.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtil.java
index 493a108..133a42d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtil.java
@@ -22,14 +22,11 @@
 import com.google.gerrit.extensions.api.projects.ProjectConfigEntryType;
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.ProjectConfigEntry;
+import com.google.gerrit.server.mime.FileTypeRegistry;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
-import org.apache.tika.Tika;
-import org.apache.tika.config.TikaConfig;
-import org.apache.tika.io.TikaInputStream;
-import org.apache.tika.metadata.Metadata;
 import org.eclipse.jgit.lib.ObjectLoader;
 
 import java.io.IOException;
@@ -48,13 +45,18 @@
         bind(ContentTypeUtil.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_BINARY_TYPES))
-            .toInstance(new ProjectConfigEntry("Binary Types", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "At the moment, there is no ideal solution to detect binary "
-                    + "files. But some checks shouldn't run on binary files "
-                    + "(e. g. InvalidLineEndingCheck). Because of that you can "
-                    + "enter content types to avoid that these checks run on "
-                    + "files with one of the entered content types."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Binary Types",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "At the moment, there is no ideal solution to detect binary "
+                        + "files. But some checks shouldn't run on binary files "
+                        + "(e. g. InvalidLineEndingCheck). Because of that you can "
+                        + "enter content types to avoid that these checks run on "
+                        + "files with one of the entered content types."));
       }
     };
   }
@@ -65,37 +67,32 @@
   }
 
   private final LoadingCache<String, Pattern> patternCache;
-  private final Tika tika = new Tika(TikaConfig.getDefaultConfig());
+  private final FileTypeRegistry mimeUtil;
 
   @Inject
   ContentTypeUtil(
-      @Named(CACHE_NAME) LoadingCache<String, Pattern> patternCache) {
+      @Named(CACHE_NAME) LoadingCache<String, Pattern> patternCache, FileTypeRegistry mimeUtil) {
     this.patternCache = patternCache;
+    this.mimeUtil = mimeUtil;
   }
 
-  public boolean isBinary(ObjectLoader ol, String pathname, PluginConfig cfg)
+  public boolean isBlacklistedBinaryContentType(ObjectLoader ol, String pathname, PluginConfig cfg)
       throws IOException, ExecutionException {
+    return matchesAny(getContentType(ol, pathname), getBinaryTypes(cfg));
+  }
+
+  public String getContentType(ObjectLoader ol, String pathname) throws IOException {
     try (InputStream is = ol.openStream()) {
-      return matchesAny(getContentType(is, pathname), getBinaryTypes(cfg));
+      return mimeUtil.getMimeType(pathname, is).toString();
     }
   }
 
-  public String getContentType(InputStream is, String pathname)
-      throws IOException {
-    Metadata metadata = new Metadata();
-    metadata.set(Metadata.RESOURCE_NAME_KEY, pathname);
-    return tika.detect(TikaInputStream.get(is), metadata);
-  }
-
   @VisibleForTesting
-  boolean matchesAny(String s, String[] patterns)
-      throws ExecutionException {
+  boolean matchesAny(String s, String[] patterns) throws ExecutionException {
     for (String p : patterns) {
-      if (p.startsWith("^")
-          && patternCache.get(p).matcher(s).matches()) {
+      if (p.startsWith("^") && patternCache.get(p).matcher(s).matches()) {
         return true;
-      } else if (p.endsWith("*")
-          && s.startsWith(p.substring(0, p.length() - 1))) {
+      } else if (p.endsWith("*") && s.startsWith(p.substring(0, p.length() - 1))) {
         return true;
       } else {
         if (p.equals(s)) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidator.java
index ed236e1..3303fa9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidator.java
@@ -33,9 +33,9 @@
 
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
-import org.eclipse.jgit.lib.ObjectStream;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -51,28 +51,36 @@
 
       @Override
       protected void configure() {
-        DynamicSet.bind(binder(), CommitValidationListener.class)
-            .to(ContentTypeValidator.class);
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(ContentTypeValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_BLOCKED_CONTENT_TYPE))
-            .toInstance(new ProjectConfigEntry("Blocked Content Type", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "Pushes of commits that contain files with blocked content "
-                    + "types will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Blocked Content Type",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "Pushes of commits that contain files with blocked content "
+                        + "types will be rejected."));
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_BLOCKED_CONTENT_TYPE_WHITELIST))
-            .toInstance(new ProjectConfigEntry("Blocked Content Type Whitelist",
-                "false", ProjectConfigEntryType.BOOLEAN, null, false,
-                "If this option is checked, the entered content types are "
-                    + "interpreted as a whitelist. Otherwise commits that "
-                    + "contain one of these content types will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Blocked Content Type Whitelist",
+                    "false",
+                    ProjectConfigEntryType.BOOLEAN,
+                    null,
+                    false,
+                    "If this option is checked, the entered content types are "
+                        + "interpreted as a whitelist. Otherwise commits that "
+                        + "contain one of these content types will be rejected."));
       }
     };
   }
 
   public static final String KEY_BLOCKED_CONTENT_TYPE = "blockedContentType";
-  public static final String KEY_BLOCKED_CONTENT_TYPE_WHITELIST =
-      "blockedContentTypeWhitelist";
+  public static final String KEY_BLOCKED_CONTENT_TYPE_WHITELIST = "blockedContentTypeWhitelist";
 
   @VisibleForTesting
   static boolean isWhitelist(PluginConfig cfg) {
@@ -95,7 +103,8 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  ContentTypeValidator(@PluginName String pluginName,
+  ContentTypeValidator(
+      @PluginName String pluginName,
       ContentTypeUtil contentTypeUtil,
       PluginConfigFactory cfgFactory,
       GitRepositoryManager repoManager,
@@ -108,24 +117,28 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
-      PluginConfig cfg = cfgFactory
-          .getFromProjectConfigWithInheritance(
+      PluginConfig cfg =
+          cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_BLOCKED_CONTENT_TYPE)) {
-        try (Repository repo =
-            repoManager.openRepository(receiveEvent.project.getNameKey())) {
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit, getBlockedTypes(cfg),
+              performValidation(
+                  repo,
+                  receiveEvent.commit,
+                  receiveEvent.revWalk,
+                  getBlockedTypes(cfg),
                   isWhitelist(cfg));
           if (!messages.isEmpty()) {
-            throw new CommitValidationException("contains blocked content type",
-                messages);
+            throw new CommitValidationException("contains blocked content type", messages);
           }
         }
       }
@@ -136,23 +149,19 @@
   }
 
   @VisibleForTesting
-  List<CommitValidationMessage> performValidation(Repository repo,
-      RevCommit c, String[] blockedTypes, boolean whitelist)
+  List<CommitValidationMessage> performValidation(
+      Repository repo, RevCommit c, RevWalk revWalk, String[] blockedTypes, boolean whitelist)
       throws IOException, ExecutionException {
     List<CommitValidationMessage> messages = new LinkedList<>();
-    Map<String, ObjectId> content = CommitUtils.getChangedContent(repo, c);
+    Map<String, ObjectId> content = CommitUtils.getChangedContent(repo, c, revWalk);
     for (String path : content.keySet()) {
-      ObjectLoader ol = repo.open(content.get(path));
-      try (ObjectStream os = ol.openStream()) {
-        String contentType = contentTypeUtil.getContentType(os, path);
-        if ((contentTypeUtil.matchesAny(contentType, blockedTypes)
-            && !whitelist)
-            || (!contentTypeUtil.matchesAny(contentType, blockedTypes)
-                && whitelist)) {
-          messages.add(new CommitValidationMessage(
-              "found blocked content type (" + contentType + ") in file: "
-                  + path, true));
-        }
+      ObjectLoader ol = revWalk.getObjectReader().open(content.get(path));
+      String contentType = contentTypeUtil.getContentType(ol, path);
+      if ((contentTypeUtil.matchesAny(contentType, blockedTypes) && !whitelist)
+          || (!contentTypeUtil.matchesAny(contentType, blockedTypes) && whitelist)) {
+        messages.add(
+            new CommitValidationMessage(
+                "found blocked content type (" + contentType + ") in file: " + path, true));
       }
     }
     return messages;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidator.java
index 72ae551..450c05f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidator.java
@@ -38,6 +38,7 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -56,7 +57,8 @@
   public static AbstractModule module() {
     return new AbstractModule() {
       private List<String> getAvailableLocales() {
-        return Lists.transform(Arrays.asList(Locale.getAvailableLocales()),
+        return Lists.transform(
+            Arrays.asList(Locale.getAvailableLocales()),
             new Function<Locale, String>() {
               @Override
               public String apply(Locale input) {
@@ -71,25 +73,34 @@
             .to(DuplicatePathnameValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_REJECT_DUPLICATE_PATHNAMES))
-            .toInstance(new ProjectConfigEntry("Reject Duplicate Pathnames",
-                null, ProjectConfigEntryType.BOOLEAN, null, false,
-                "Pushes of commits that contain duplicate pathnames, or that "
-                    + "contain duplicates of existing pathnames will be "
-                    + "rejected. Pathnames y and z are considered to be "
-                    + "duplicates if they are equal, case-insensitive."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Reject Duplicate Pathnames",
+                    null,
+                    ProjectConfigEntryType.BOOLEAN,
+                    null,
+                    false,
+                    "Pushes of commits that contain duplicate pathnames, or that "
+                        + "contain duplicates of existing pathnames will be "
+                        + "rejected. Pathnames y and z are considered to be "
+                        + "duplicates if they are equal, case-insensitive."));
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_REJECT_DUPLICATE_PATHNAMES_LOCALE))
-            .toInstance(new ProjectConfigEntry("Reject Duplicate Pathnames Locale",
-                "en", ProjectConfigEntryType.STRING, getAvailableLocales(), false,
-                "To avoid problems caused by comparing pathnames with different "
-                    + "locales it is possible to use a specific locale. The "
-                    + "default is English (en)."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Reject Duplicate Pathnames Locale",
+                    "en",
+                    ProjectConfigEntryType.STRING,
+                    getAvailableLocales(),
+                    false,
+                    "To avoid problems caused by comparing pathnames with different "
+                        + "locales it is possible to use a specific locale. The "
+                        + "default is English (en)."));
       }
     };
   }
 
-  public static final String KEY_REJECT_DUPLICATE_PATHNAMES =
-      "rejectDuplicatePathnames";
+  public static final String KEY_REJECT_DUPLICATE_PATHNAMES = "rejectDuplicatePathnames";
   public static final String KEY_REJECT_DUPLICATE_PATHNAMES_LOCALE =
       "rejectDuplicatePathnamesLocale";
 
@@ -100,8 +111,7 @@
 
   @VisibleForTesting
   static Locale getLocale(PluginConfig cfg) {
-    return Locale.forLanguageTag(
-        cfg.getString(KEY_REJECT_DUPLICATE_PATHNAMES_LOCALE, "en"));
+    return Locale.forLanguageTag(cfg.getString(KEY_REJECT_DUPLICATE_PATHNAMES_LOCALE, "en"));
   }
 
   @VisibleForTesting
@@ -134,8 +144,7 @@
 
   @VisibleForTesting
   static CommitValidationMessage conflict(String f1, String f2) {
-    return new CommitValidationMessage(f1 + ": pathname conflicts with " + f2,
-        true);
+    return new CommitValidationMessage(f1 + ": pathname conflicts with " + f2, true);
   }
 
   private static boolean isDeleted(TreeWalk tw) {
@@ -155,8 +164,10 @@
   }
 
   @Inject
-  DuplicatePathnameValidator(@PluginName String pluginName,
-      PluginConfigFactory cfgFactory, GitRepositoryManager repoManager,
+  DuplicatePathnameValidator(
+      @PluginName String pluginName,
+      PluginConfigFactory cfgFactory,
+      GitRepositoryManager repoManager,
       ValidatorConfig validatorConfig) {
     this.pluginName = pluginName;
     this.cfgFactory = cfgFactory;
@@ -165,40 +176,39 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
-      PluginConfig cfg = cfgFactory
-          .getFromProjectConfigWithInheritance(
+      PluginConfig cfg =
+          cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_REJECT_DUPLICATE_PATHNAMES)) {
         locale = getLocale(cfg);
-        try (Repository repo =
-            repoManager.openRepository(receiveEvent.project.getNameKey())) {
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit);
+              performValidation(repo, receiveEvent.commit, receiveEvent.revWalk);
           if (!messages.isEmpty()) {
-            throw new CommitValidationException("contains duplicate pathnames",
-                messages);
+            throw new CommitValidationException("contains duplicate pathnames", messages);
           }
         }
       }
     } catch (NoSuchProjectException | IOException e) {
-      throw new CommitValidationException(
-          "failed to check for duplicate pathnames", e);
+      throw new CommitValidationException("failed to check for duplicate pathnames", e);
     }
     return Collections.emptyList();
   }
 
   @VisibleForTesting
-  List<CommitValidationMessage> performValidation(Repository repo, RevCommit c)
+  List<CommitValidationMessage> performValidation(Repository repo, RevCommit c, RevWalk revWalk)
       throws IOException {
     List<CommitValidationMessage> messages = new LinkedList<>();
 
-    Set<String> pathnames = CommitUtils.getChangedPaths(repo, c);
+    Set<String> pathnames = CommitUtils.getChangedPaths(repo, c, revWalk);
     checkForDuplicatesInSet(pathnames, messages);
     if (!messages.isEmpty() || c.getParentCount() == 0) {
       return messages;
@@ -213,9 +223,8 @@
   }
 
   @VisibleForTesting
-  void checkForDuplicatesAgainstTheWholeTree(TreeWalk tw,
-      Set<String> changed, List<CommitValidationMessage> messages)
-          throws IOException {
+  void checkForDuplicatesAgainstTheWholeTree(
+      TreeWalk tw, Set<String> changed, List<CommitValidationMessage> messages) throws IOException {
     Map<String, String> all = allPaths(changed);
 
     while (tw.next()) {
@@ -239,8 +248,7 @@
     }
   }
 
-  private void checkForDuplicatesInSet(Set<String> files,
-      List<CommitValidationMessage> messages) {
+  private void checkForDuplicatesInSet(Set<String> files, List<CommitValidationMessage> messages) {
     Set<String> filesAndFolders = Sets.newHashSet(files);
     filesAndFolders.addAll(allParentFolders(files));
     Map<String, String> seen = new HashMap<>();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidator.java
index 79cac3f..e3c4393 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidator.java
@@ -32,6 +32,7 @@
 
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -47,14 +48,18 @@
 
       @Override
       public void configure() {
-        DynamicSet.bind(binder(), CommitValidationListener.class)
-            .to(FileExtensionValidator.class);
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(FileExtensionValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_BLOCKED_FILE_EXTENSION))
-            .toInstance(new ProjectConfigEntry("Blocked File Extensions", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "Forbidden file extensions. Pushes of commits that "
-                    + "contain files with these extensions will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Blocked File Extensions",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "Forbidden file extensions. Pushes of commits that "
+                        + "contain files with these extensions will be rejected."));
       }
     };
   }
@@ -103,7 +108,7 @@
         try (Repository repo =
             repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages = performValidation(repo,
-              receiveEvent.commit, getBlockedExtensions(cfg));
+              receiveEvent.commit, receiveEvent.revWalk, getBlockedExtensions(cfg));
           if (!messages.isEmpty()) {
             throw new CommitValidationException(
                 "contains files with blocked file extensions", messages);
@@ -117,9 +122,9 @@
   }
 
   static List<CommitValidationMessage> performValidation(Repository repo,
-      RevCommit c, List<String> blockedFileExtensions) throws IOException {
+      RevCommit c, RevWalk revWalk, List<String> blockedFileExtensions) throws IOException {
     List<CommitValidationMessage> messages = new LinkedList<>();
-    for (String file : CommitUtils.getChangedPaths(repo, c)) {
+    for (String file : CommitUtils.getChangedPaths(repo, c, revWalk)) {
       for (String blockedExtension : blockedFileExtensions) {
         if (file.toLowerCase().endsWith(blockedExtension.toLowerCase())) {
           messages.add(new CommitValidationMessage("blocked file: " + file, true));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FooterValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FooterValidator.java
index f4c5810..ac6b81a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FooterValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/FooterValidator.java
@@ -46,14 +46,18 @@
 
       @Override
       protected void configure() {
-        DynamicSet.bind(binder(), CommitValidationListener.class)
-            .to(FooterValidator.class);
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(FooterValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_REQUIRED_FOOTER))
-            .toInstance(new ProjectConfigEntry("Required Footers", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "Required footers. Pushes of commits that miss any"
-                    + " of the footers will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Required Footers",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "Required footers. Pushes of commits that miss any"
+                        + " of the footers will be rejected."));
       }
     };
   }
@@ -65,7 +69,9 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  FooterValidator(@PluginName String pluginName, PluginConfigFactory cfgFactory,
+  FooterValidator(
+      @PluginName String pluginName,
+      PluginConfigFactory cfgFactory,
       ValidatorConfig validatorConfig) {
     this.pluginName = pluginName;
     this.cfgFactory = cfgFactory;
@@ -73,31 +79,35 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
       PluginConfig cfg =
           cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
-      String[] requiredFooters =
-          cfg.getStringList(KEY_REQUIRED_FOOTER);
+      String[] requiredFooters = cfg.getStringList(KEY_REQUIRED_FOOTER);
       if (requiredFooters.length > 0
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_REQUIRED_FOOTER)) {
         List<CommitValidationMessage> messages = new LinkedList<>();
-        Set<String> footers = FluentIterable.from(receiveEvent.commit.getFooterLines())
-            .transform(new Function<FooterLine, String>() {
-                @Override
-                public String apply(FooterLine f) {
-                    return f.getKey().toLowerCase(Locale.US);
-                }
-            })
-            .toSet();
+        Set<String> footers =
+            FluentIterable.from(receiveEvent.commit.getFooterLines())
+                .transform(
+                    new Function<FooterLine, String>() {
+                      @Override
+                      public String apply(FooterLine f) {
+                        return f.getKey().toLowerCase(Locale.US);
+                      }
+                    })
+                .toSet();
         for (int i = 0; i < requiredFooters.length; i++) {
           if (!footers.contains(requiredFooters[i].toLowerCase(Locale.US))) {
-            messages.add(new CommitValidationMessage(
-                "missing required footer: " + requiredFooters[i], true));
+            messages.add(
+                new CommitValidationMessage(
+                    "missing required footer: " + requiredFooters[i], true));
           }
         }
         if (!messages.isEmpty()) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidator.java
index e2fd516..d1925c2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidator.java
@@ -32,6 +32,7 @@
 
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -51,17 +52,21 @@
             .to(InvalidFilenameValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_INVALID_FILENAME_PATTERN))
-            .toInstance(new ProjectConfigEntry("Invalid Filename Pattern", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "Invalid filenames. Pushes of commits that contain filenames "
-                    + "which match one of these patterns will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Invalid Filename Pattern",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "Invalid filenames. Pushes of commits that contain filenames "
+                        + "which match one of these patterns will be rejected."));
       }
     };
   }
 
   public static final String KEY_INVALID_FILENAME = "invalidFilename";
-  public static final String KEY_INVALID_FILENAME_PATTERN =
-      KEY_INVALID_FILENAME + "Pattern";
+  public static final String KEY_INVALID_FILENAME_PATTERN = KEY_INVALID_FILENAME + "Pattern";
 
   private final String pluginName;
   private final PluginConfigFactory cfgFactory;
@@ -69,8 +74,10 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  InvalidFilenameValidator(@PluginName String pluginName,
-      PluginConfigFactory cfgFactory, GitRepositoryManager repoManager,
+  InvalidFilenameValidator(
+      @PluginName String pluginName,
+      PluginConfigFactory cfgFactory,
+      GitRepositoryManager repoManager,
       ValidatorConfig validatorConfig) {
     this.pluginName = pluginName;
     this.cfgFactory = cfgFactory;
@@ -83,20 +90,24 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
       PluginConfig cfg =
           cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_INVALID_FILENAME)) {
-        try (Repository repo = repoManager.openRepository(
-            receiveEvent.project.getNameKey())) {
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit,
+              performValidation(
+                  repo,
+                  receiveEvent.commit,
+                  receiveEvent.revWalk,
                   cfg.getStringList(KEY_INVALID_FILENAME_PATTERN));
           if (!messages.isEmpty()) {
             throw new CommitValidationException(
@@ -105,24 +116,23 @@
         }
       }
     } catch (NoSuchProjectException | IOException e) {
-      throw new CommitValidationException(
-          "failed to check on invalid file names", e);
+      throw new CommitValidationException("failed to check on invalid file names", e);
     }
     return Collections.emptyList();
   }
 
-  static List<CommitValidationMessage> performValidation(Repository repo,
-      RevCommit c, String[] patterns) throws IOException {
+  static List<CommitValidationMessage> performValidation(
+      Repository repo, RevCommit c, RevWalk revWalk, String[] patterns) throws IOException {
     List<Pattern> invalidFilenamePatterns = new ArrayList<>();
     for (String s : patterns) {
       invalidFilenamePatterns.add(Pattern.compile(s));
     }
     List<CommitValidationMessage> messages = new LinkedList<>();
-    for (String file : CommitUtils.getChangedPaths(repo, c)) {
+    for (String file : CommitUtils.getChangedPaths(repo, c, revWalk)) {
       for (Pattern p : invalidFilenamePatterns) {
         if (p.matcher(file).find()) {
-          messages.add(new CommitValidationMessage(
-              "invalid characters found in filename: " + file, true));
+          messages.add(
+              new CommitValidationMessage("invalid characters found in filename: " + file, true));
           break;
         }
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidator.java
index 559b745..f0b8931 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidator.java
@@ -31,12 +31,15 @@
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 
+import org.eclipse.jgit.diff.RawText;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 import java.util.Collections;
@@ -55,19 +58,22 @@
         DynamicSet.bind(binder(), CommitValidationListener.class)
             .to(InvalidLineEndingValidator.class);
         bind(ProjectConfigEntry.class)
-            .annotatedWith(
-                Exports.named(KEY_CHECK_REJECT_WINDOWS_LINE_ENDINGS))
-            .toInstance(new ProjectConfigEntry("Reject Windows Line Endings",
-                "false", ProjectConfigEntryType.BOOLEAN, null, false,
-                "Windows line endings. Pushes of commits that include files "
-                    + "containing carriage return (CR) characters will be "
-                    + "rejected."));
+            .annotatedWith(Exports.named(KEY_CHECK_REJECT_WINDOWS_LINE_ENDINGS))
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Reject Windows Line Endings",
+                    "false",
+                    ProjectConfigEntryType.BOOLEAN,
+                    null,
+                    false,
+                    "Windows line endings. Pushes of commits that include files "
+                        + "containing carriage return (CR) characters will be "
+                        + "rejected."));
       }
     };
   }
 
-  public static final String KEY_CHECK_REJECT_WINDOWS_LINE_ENDINGS =
-      "rejectWindowsLineEndings";
+  public static final String KEY_CHECK_REJECT_WINDOWS_LINE_ENDINGS = "rejectWindowsLineEndings";
 
   private final String pluginName;
   private final PluginConfigFactory cfgFactory;
@@ -76,7 +82,8 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  InvalidLineEndingValidator(@PluginName String pluginName,
+  InvalidLineEndingValidator(
+      @PluginName String pluginName,
       ContentTypeUtil contentTypeUtil,
       PluginConfigFactory cfgFactory,
       GitRepositoryManager repoManager,
@@ -93,20 +100,21 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
       PluginConfig cfg =
           cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_CHECK_REJECT_WINDOWS_LINE_ENDINGS)) {
-        try (Repository repo =
-            repoManager.openRepository(receiveEvent.project.getNameKey())) {
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit, cfg);
+              performValidation(repo, receiveEvent.commit, receiveEvent.revWalk, cfg);
           if (!messages.isEmpty()) {
             throw new CommitValidationException(
                 "contains files with a Windows line ending", messages);
@@ -114,35 +122,36 @@
         }
       }
     } catch (NoSuchProjectException | IOException | ExecutionException e) {
-      throw new CommitValidationException(
-          "failed to check on Windows line endings", e);
+      throw new CommitValidationException("failed to check on Windows line endings", e);
     }
     return Collections.emptyList();
   }
 
   @VisibleForTesting
-  List<CommitValidationMessage> performValidation(Repository repo, RevCommit c,
-      PluginConfig cfg) throws IOException, ExecutionException {
+  List<CommitValidationMessage> performValidation(
+      Repository repo, RevCommit c, RevWalk revWalk, PluginConfig cfg)
+      throws IOException, ExecutionException {
     List<CommitValidationMessage> messages = new LinkedList<>();
-    Map<String, ObjectId> content = CommitUtils.getChangedContent(repo, c);
+    Map<String, ObjectId> content = CommitUtils.getChangedContent(repo, c, revWalk);
     for (String path : content.keySet()) {
-      ObjectLoader ol = repo.open(content.get(path));
-      if (contentTypeUtil.isBinary(ol, path, cfg)) {
-        continue;
+      ObjectLoader ol = revWalk.getObjectReader().open(content.get(path));
+      try (InputStream in = ol.openStream()) {
+        if (RawText.isBinary(in) || contentTypeUtil.isBlacklistedBinaryContentType(ol, path, cfg)) {
+          continue;
+        }
       }
-      try (InputStreamReader isr =
-          new InputStreamReader(ol.openStream(), StandardCharsets.UTF_8)) {
+      try (InputStreamReader isr = new InputStreamReader(ol.openStream(), StandardCharsets.UTF_8)) {
         if (doesInputStreanContainCR(isr)) {
-          messages.add(new CommitValidationMessage(
-              "found carriage return (CR) character in file: " + path, true));
+          messages.add(
+              new CommitValidationMessage(
+                  "found carriage return (CR) character in file: " + path, true));
         }
       }
     }
     return messages;
   }
 
-  private static boolean doesInputStreanContainCR(InputStreamReader isr)
-      throws IOException {
+  private static boolean doesInputStreanContainCR(InputStreamReader isr) throws IOException {
     char[] buffer = new char[1024];
     int n;
     while ((n = isr.read(buffer, 0, buffer.length)) > 0) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidator.java
index 53dc2e3..188ce09 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidator.java
@@ -31,6 +31,7 @@
 
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -44,14 +45,17 @@
 
       @Override
       protected void configure() {
-        DynamicSet.bind(binder(), CommitValidationListener.class)
-            .to(MaxPathLengthValidator.class);
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(MaxPathLengthValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_MAX_PATH_LENGTH))
-            .toInstance(new ProjectConfigEntry("Max Path Length", 0, false,
-                "Maximum path length. Pushes of commits that "
-                    + "contain files with longer paths will be rejected. "
-                    + "'0' means no limit."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Max Path Length",
+                    0,
+                    false,
+                    "Maximum path length. Pushes of commits that "
+                        + "contain files with longer paths will be rejected. "
+                        + "'0' means no limit."));
       }
     };
   }
@@ -64,8 +68,10 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  MaxPathLengthValidator(@PluginName String pluginName,
-      PluginConfigFactory cfgFactory, GitRepositoryManager repoManager,
+  MaxPathLengthValidator(
+      @PluginName String pluginName,
+      PluginConfigFactory cfgFactory,
+      GitRepositoryManager repoManager,
       ValidatorConfig validatorConfig) {
     this.pluginName = pluginName;
     this.cfgFactory = cfgFactory;
@@ -78,39 +84,39 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
       PluginConfig cfg =
           cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_MAX_PATH_LENGTH)) {
         int maxPathLength = cfg.getInt(KEY_MAX_PATH_LENGTH, 0);
-        try (Repository repo =
-            repoManager.openRepository(receiveEvent.project.getNameKey())) {
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit, maxPathLength);
+              performValidation(repo, receiveEvent.commit, receiveEvent.revWalk, maxPathLength);
           if (!messages.isEmpty()) {
             throw new CommitValidationException(
-                "contains files with too long paths (max path length: "
-                    + maxPathLength + ")", messages);
+                "contains files with too long paths (max path length: " + maxPathLength + ")",
+                messages);
           }
         }
       }
     } catch (NoSuchProjectException | IOException e) {
-      throw new CommitValidationException(
-          "failed to check for max file path length", e);
+      throw new CommitValidationException("failed to check for max file path length", e);
     }
     return Collections.emptyList();
   }
 
-  static List<CommitValidationMessage> performValidation(Repository repo,
-      RevCommit c, int maxPathLength) throws IOException {
+  static List<CommitValidationMessage> performValidation(
+      Repository repo, RevCommit c, RevWalk revWalk, int maxPathLength) throws IOException {
     List<CommitValidationMessage> messages = new LinkedList<>();
-    for (String file : CommitUtils.getChangedPaths(repo, c)) {
+    for (String file : CommitUtils.getChangedPaths(repo, c, revWalk)) {
       if (file.length() > maxPathLength) {
         messages.add(new CommitValidationMessage("path too long: " + file, true));
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/Module.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/Module.java
index b605165..5b6677a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/Module.java
@@ -36,7 +36,6 @@
     install(DuplicatePathnameValidator.module());
     install(ValidatorConfig.module());
 
-    bind(ConfigFactory.class).to(PluginConfigWithInheritanceFactory.class).in(
-        Scopes.SINGLETON);
+    bind(ConfigFactory.class).to(PluginConfigWithInheritanceFactory.class).in(Scopes.SINGLETON);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/PluginConfigWithInheritanceFactory.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/PluginConfigWithInheritanceFactory.java
index 1e90f2c..1e748b4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/PluginConfigWithInheritanceFactory.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/PluginConfigWithInheritanceFactory.java
@@ -25,13 +25,13 @@
 import org.slf4j.LoggerFactory;
 
 public class PluginConfigWithInheritanceFactory implements ConfigFactory {
-  private static final Logger log = LoggerFactory.getLogger(PluginConfigWithInheritanceFactory.class);
+  private static final Logger log =
+      LoggerFactory.getLogger(PluginConfigWithInheritanceFactory.class);
   private final PluginConfigFactory pluginConfigFactory;
   private final String pluginName;
 
   @Inject
-  public PluginConfigWithInheritanceFactory(PluginConfigFactory pcf,
-      @PluginName String pn) {
+  public PluginConfigWithInheritanceFactory(PluginConfigFactory pcf, @PluginName String pn) {
     this.pluginConfigFactory = pcf;
     this.pluginName = pn;
   }
@@ -39,8 +39,7 @@
   @Override
   public PluginConfig get(Project.NameKey projectName) {
     try {
-      return pluginConfigFactory.getFromProjectConfigWithInheritance(projectName,
-          pluginName);
+      return pluginConfigFactory.getFromProjectConfigWithInheritance(projectName, pluginName);
     } catch (NoSuchProjectException e) {
       log.warn(projectName.get() + " not found");
       return null;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidator.java
index 5dd9ee5..82b9ad0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidator.java
@@ -33,6 +33,7 @@
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.treewalk.TreeWalk;
 
 import java.io.IOException;
@@ -47,13 +48,17 @@
 
       @Override
       protected void configure() {
-        DynamicSet.bind(binder(), CommitValidationListener.class)
-            .to(SubmoduleValidator.class);
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(SubmoduleValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_CHECK_SUBMODULE))
-            .toInstance(new ProjectConfigEntry("Reject Submodules", "false",
-                ProjectConfigEntryType.BOOLEAN, null, false, "Pushes of "
-                    + "commits that include submodules will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Reject Submodules",
+                    "false",
+                    ProjectConfigEntryType.BOOLEAN,
+                    null,
+                    false,
+                    "Pushes of " + "commits that include submodules will be rejected."));
       }
     };
   }
@@ -66,8 +71,10 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  SubmoduleValidator(@PluginName String pluginName,
-      PluginConfigFactory cfgFactory, GitRepositoryManager repoManager,
+  SubmoduleValidator(
+      @PluginName String pluginName,
+      PluginConfigFactory cfgFactory,
+      GitRepositoryManager repoManager,
       ValidatorConfig validatorConfig) {
     this.pluginName = pluginName;
     this.cfgFactory = cfgFactory;
@@ -80,20 +87,21 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
-      PluginConfig cfg = cfgFactory
-          .getFromProjectConfigWithInheritance(
+      PluginConfig cfg =
+          cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_CHECK_SUBMODULE)) {
-        try (Repository repo =
-            repoManager.openRepository(receiveEvent.project.getNameKey())) {
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit);
+              performValidation(repo, receiveEvent.commit, receiveEvent.revWalk);
           if (!messages.isEmpty()) {
             throw new CommitValidationException("contains submodules", messages);
           }
@@ -105,28 +113,31 @@
     return Collections.emptyList();
   }
 
-  private static void addValidationMessage(
-      List<CommitValidationMessage> messages, TreeWalk tw) {
-    messages.add(new CommitValidationMessage(
-        "submodules are not allowed: " + tw.getPathString(), true));
+  private static void addValidationMessage(List<CommitValidationMessage> messages, TreeWalk tw) {
+    messages.add(
+        new CommitValidationMessage("submodules are not allowed: " + tw.getPathString(), true));
   }
 
   private static boolean isSubmodule(TreeWalk tw) {
     return (tw.getRawMode(0) & FileMode.TYPE_MASK) == FileMode.TYPE_GITLINK;
   }
 
-  static List<CommitValidationMessage> performValidation(Repository repo,
-      RevCommit c) throws IOException {
+  static List<CommitValidationMessage> performValidation(
+      Repository repo, RevCommit c, RevWalk revWalk) throws IOException {
     final List<CommitValidationMessage> messages = new LinkedList<>();
 
-    CommitUtils.visitChangedEntries(repo, c, new TreeWalkVisitor() {
-      @Override
-      public void onVisit(TreeWalk tw) {
-        if (isSubmodule(tw)) {
-          addValidationMessage(messages, tw);
-        }
-      }
-    });
+    CommitUtils.visitChangedEntries(
+        repo,
+        c,
+        revWalk,
+        new TreeWalkVisitor() {
+          @Override
+          public void onVisit(TreeWalk tw) {
+            if (isSubmodule(tw)) {
+              addValidationMessage(messages, tw);
+            }
+          }
+        });
     return messages;
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidator.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidator.java
index 572600c..b7ec041 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidator.java
@@ -33,6 +33,7 @@
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.treewalk.TreeWalk;
 
 import java.io.IOException;
@@ -47,14 +48,18 @@
 
       @Override
       protected void configure() {
-        DynamicSet.bind(binder(), CommitValidationListener.class)
-            .to(SymlinkValidator.class);
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(SymlinkValidator.class);
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_CHECK_SYMLINK))
-            .toInstance(new ProjectConfigEntry("Reject Symbolic Links", "false",
-                ProjectConfigEntryType.BOOLEAN, null, false,
-                "Symbolic Links. Pushes of commits that include symbolic "
-                    + "links will be rejected."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Reject Symbolic Links",
+                    "false",
+                    ProjectConfigEntryType.BOOLEAN,
+                    null,
+                    false,
+                    "Symbolic Links. Pushes of commits that include symbolic "
+                        + "links will be rejected."));
       }
     };
   }
@@ -67,8 +72,10 @@
   private final ValidatorConfig validatorConfig;
 
   @Inject
-  SymlinkValidator(@PluginName String pluginName,
-      PluginConfigFactory cfgFactory, GitRepositoryManager repoManager,
+  SymlinkValidator(
+      @PluginName String pluginName,
+      PluginConfigFactory cfgFactory,
+      GitRepositoryManager repoManager,
       ValidatorConfig validatorConfig) {
     this.pluginName = pluginName;
     this.cfgFactory = cfgFactory;
@@ -81,56 +88,57 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(
-      CommitReceivedEvent receiveEvent) throws CommitValidationException {
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
     try {
       PluginConfig cfg =
           cfgFactory.getFromProjectConfigWithInheritance(
               receiveEvent.project.getNameKey(), pluginName);
       if (isActive(cfg)
-          && validatorConfig.isEnabledForRef(receiveEvent.user,
-              receiveEvent.getProjectNameKey(), receiveEvent.getRefName(),
+          && validatorConfig.isEnabledForRef(
+              receiveEvent.user,
+              receiveEvent.getProjectNameKey(),
+              receiveEvent.getRefName(),
               KEY_CHECK_SYMLINK)) {
-        try (Repository repo =
-            repoManager.openRepository(receiveEvent.project.getNameKey())) {
+        try (Repository repo = repoManager.openRepository(receiveEvent.project.getNameKey())) {
           List<CommitValidationMessage> messages =
-              performValidation(repo, receiveEvent.commit);
+              performValidation(repo, receiveEvent.commit, receiveEvent.revWalk);
           if (!messages.isEmpty()) {
-            throw new CommitValidationException("contains symbolic links",
-                messages);
+            throw new CommitValidationException("contains symbolic links", messages);
           }
         }
       }
     } catch (NoSuchProjectException | IOException e) {
-      throw new CommitValidationException(
-          "failed to check on symbolic links", e);
+      throw new CommitValidationException("failed to check on symbolic links", e);
     }
     return Collections.emptyList();
   }
 
-  private static void addValidationMessage(
-      List<CommitValidationMessage> messages, TreeWalk tw) {
-    messages.add(new CommitValidationMessage(
-        "Symbolic links are not allowed: "
-        + tw.getPathString(), true));
+  private static void addValidationMessage(List<CommitValidationMessage> messages, TreeWalk tw) {
+    messages.add(
+        new CommitValidationMessage("Symbolic links are not allowed: " + tw.getPathString(), true));
   }
 
   private static boolean isSymLink(TreeWalk tw) {
     return (tw.getRawMode(0) & FileMode.TYPE_MASK) == FileMode.TYPE_SYMLINK;
   }
 
-  static List<CommitValidationMessage> performValidation(Repository repo,
-      RevCommit c) throws IOException {
+  static List<CommitValidationMessage> performValidation(
+      Repository repo, RevCommit c, RevWalk revWalk) throws IOException {
     final List<CommitValidationMessage> messages = new LinkedList<>();
 
-    CommitUtils.visitChangedEntries(repo, c, new TreeWalkVisitor() {
-      @Override
-      public void onVisit(TreeWalk tw) {
-        if (isSymLink(tw)) {
-          addValidationMessage(messages, tw);
-        }
-      }
-    });
+    CommitUtils.visitChangedEntries(
+        repo,
+        c,
+        revWalk,
+        new TreeWalkVisitor() {
+          @Override
+          public void onVisit(TreeWalk tw) {
+            if (isSymLink(tw)) {
+              addValidationMessage(messages, tw);
+            }
+          }
+        });
     return messages;
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/TreeWalkVisitor.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/TreeWalkVisitor.java
index 3386fda..9a6de33 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/TreeWalkVisitor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/TreeWalkVisitor.java
@@ -19,5 +19,4 @@
 public interface TreeWalkVisitor {
 
   void onVisit(TreeWalk tw);
-
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ValidatorConfig.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ValidatorConfig.java
index 30227fc..ef0030f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ValidatorConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/ValidatorConfig.java
@@ -20,27 +20,28 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.ProjectConfigEntry;
+import com.google.gerrit.server.group.InternalGroup;
 import com.google.gerrit.server.project.RefPatternMatcher;
+import com.google.gerrit.server.query.group.InternalGroupQuery;
+import com.google.gwtorm.server.OrmException;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
-
+import com.google.inject.Provider;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Arrays;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-
 public class ValidatorConfig {
-  private static final Logger log = LoggerFactory
-      .getLogger(ValidatorConfig.class);
+  private static final Logger log = LoggerFactory.getLogger(ValidatorConfig.class);
   private static final String KEY_PROJECT = "project";
   private static final String KEY_REF = "ref";
   private final ConfigFactory configFactory;
-  private final GroupCache groupCache;
+  private final GroupByNameFinder groupByNameFinder;
 
   public static AbstractModule module() {
     return new AbstractModule() {
@@ -48,27 +49,37 @@
       protected void configure() {
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_PROJECT))
-            .toInstance(new ProjectConfigEntry("Projects", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "Only projects that match this regex will be validated."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Projects",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "Only projects that match this regex will be validated."));
         bind(ProjectConfigEntry.class)
             .annotatedWith(Exports.named(KEY_REF))
-            .toInstance(new ProjectConfigEntry("Refs", null,
-                ProjectConfigEntryType.ARRAY, null, false,
-                "Only refs that match this regex will be validated."));
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Refs",
+                    null,
+                    ProjectConfigEntryType.ARRAY,
+                    null,
+                    false,
+                    "Only refs that match this regex will be validated."));
+        bind(GroupByNameFinder.class).to(GroupByNameFromIndexFinder.class);
       }
     };
   }
 
   @Inject
-  public ValidatorConfig(ConfigFactory configFactory,
-      GroupCache groupCache) {
+  public ValidatorConfig(ConfigFactory configFactory, GroupByNameFinder groupByNameFinder) {
     this.configFactory = configFactory;
-    this.groupCache = groupCache;
+    this.groupByNameFinder = groupByNameFinder;
   }
 
-  public boolean isEnabledForRef(IdentifiedUser user,
-      Project.NameKey projectName, String refName, String validatorOp) {
+  public boolean isEnabledForRef(
+      IdentifiedUser user, Project.NameKey projectName, String refName, String validatorOp) {
     PluginConfig conf = configFactory.get(projectName);
 
     return conf != null
@@ -87,14 +98,16 @@
         && hasValidConfigRef(config, "skipRef", projectName);
   }
 
-  private boolean hasValidConfigRef(PluginConfig config, String refKey,
-      Project.NameKey projectName) {
+  private boolean hasValidConfigRef(
+      PluginConfig config, String refKey, Project.NameKey projectName) {
     boolean valid = true;
     for (String refPattern : config.getStringList(refKey)) {
       if (!RefConfigSection.isValid(refPattern)) {
         log.error(
             "Invalid {} name/pattern/regex '{}' in {} project's plugin config",
-            refKey, refPattern, projectName.get());
+            refKey,
+            refPattern,
+            projectName.get());
         valid = false;
       }
     }
@@ -125,12 +138,11 @@
     return matchCriteria(config, "skipRef", ref, true, true);
   }
 
-  private boolean matchCriteria(PluginConfig config, String criteria,
-      String value, boolean allowRegex, boolean refMatcher) {
+  private boolean matchCriteria(
+      PluginConfig config, String criteria, String value, boolean allowRegex, boolean refMatcher) {
     boolean match = true;
     for (String s : config.getStringList(criteria)) {
-      if ((allowRegex && match(value, s, refMatcher)) ||
-          (!allowRegex && s.equals(value))) {
+      if ((allowRegex && match(value, s, refMatcher)) || (!allowRegex && s.equals(value))) {
         return true;
       }
       match = false;
@@ -138,13 +150,11 @@
     return match;
   }
 
-  private static boolean match(String value, String pattern,
-      boolean refMatcher) {
+  private static boolean match(String value, String pattern, boolean refMatcher) {
     if (refMatcher) {
       return RefPatternMatcher.getMatcher(pattern).match(value, null);
-    } else {
-      return Pattern.matches(pattern, value);
     }
+    return Pattern.matches(pattern, value);
   }
 
   private boolean canSkipGroup(PluginConfig conf, IdentifiedUser user) {
@@ -154,16 +164,36 @@
 
     Stream<AccountGroup.UUID> skipGroups =
         Arrays.stream(conf.getStringList("skipGroup")).map(this::groupUUID);
-    return user.asIdentifiedUser().getEffectiveGroups()
-        .containsAnyOf(skipGroups::iterator);
+    return user.asIdentifiedUser().getEffectiveGroups().containsAnyOf(skipGroups::iterator);
   }
 
   private AccountGroup.UUID groupUUID(String groupNameOrUUID) {
-    AccountGroup group =
-        groupCache.get(new AccountGroup.NameKey(groupNameOrUUID));
-    if (group == null) {
-      return new AccountGroup.UUID(groupNameOrUUID);
+    Optional<InternalGroup> group =
+        groupByNameFinder.get(new AccountGroup.NameKey(groupNameOrUUID));
+    return group.map(InternalGroup::getGroupUUID).orElse(new AccountGroup.UUID(groupNameOrUUID));
+  }
+
+  interface GroupByNameFinder {
+    Optional<InternalGroup> get(AccountGroup.NameKey groupName);
+  }
+
+  static class GroupByNameFromIndexFinder implements GroupByNameFinder {
+
+    private final Provider<InternalGroupQuery> groupQueryProvider;
+
+    @Inject
+    GroupByNameFromIndexFinder(Provider<InternalGroupQuery> groupQueryProvider) {
+      this.groupQueryProvider = groupQueryProvider;
     }
-    return group.getGroupUUID();
+
+    @Override
+    public Optional<InternalGroup> get(AccountGroup.NameKey groupName) {
+      try {
+        return groupQueryProvider.get().byName(groupName);
+      } catch (OrmException e) {
+        log.warn(String.format("Cannot lookup group %s by name", groupName.get()), e);
+      }
+      return Optional.empty();
+    }
   }
 }
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index 9c20e5c..20b8cd1 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -60,15 +60,6 @@
   ln -s ../../@PLUGIN@ .
 ```
 
-Put the external dependency Bazel build file into the Gerrit /plugins
-directory, replacing the existing empty one.
-
-```
-  cd gerrit/plugins
-  rm external_plugin_deps.bzl
-  ln -s @PLUGIN@/external_plugin_deps.bzl .
-```
-
 From Gerrit source tree issue the command:
 
 ```
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 04c04a1..18b79ee 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -76,7 +76,10 @@
 	Using this option it is possible to configure which content types are
 	considered binary types.
 
-	To detect content types [Apache Tika library][2] is used.
+	If there is a NUL byte in the first 8k then the file will be considered
+	binary regardless of this setting.
+
+	To detect content types, the [MimeUtil2 library][2] is used.
 
 	Content type can be specified as a string, wildcard or a regular expression,
 	for example:
@@ -121,8 +124,8 @@
 	This check does not run on [binary files][4]
 
 [1]: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
-[2]: https://tika.apache.org/
-[3]: https://tika.apache.org/1.12/formats.html#Full_list_of_Supported_Formats
+[2]: https://mvnrepository.com/artifact/eu.medsea.mimeutil/mime-util
+[3]: https://gerrit.googlesource.com/gerrit/+/refs/heads/master/gerrit-server/src/main/resources/com/google/gerrit/server/mime/mime-types.properties
 [4]: #binary_type
 
 plugin.@PLUGIN@.blockedContentType
@@ -131,7 +134,7 @@
 	This check looks for blocked content types. If the check finds a
 	blocked content type the push will be rejected.
 
-	To detect content types [Apache Tika library][2] is used.
+	To detect content types the [MimeUtil2 library][2] is used.
 
 	Content type can be specified as a string, wildcard or a regular expression,
 	for example:
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidatorTest.java
index c2a92e5..a5b0c32 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/BlockedKeywordValidatorTest.java
@@ -25,6 +25,7 @@
 
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 import java.io.File;
@@ -38,55 +39,63 @@
 
 public class BlockedKeywordValidatorTest extends ValidatorTestCase {
   private static ImmutableMap<String, Pattern> getPatterns() {
-    return ImmutableMap.<String, Pattern> builder()
+    return ImmutableMap.<String, Pattern>builder()
         .put("myp4ssw0rd", Pattern.compile("myp4ssw0rd"))
         .put("foobar", Pattern.compile("foobar"))
-        .put("\\$(Id|Header):[^$]*\\$",
-            Pattern.compile("\\$(Id|Header):[^$]*\\$"))
+        .put("\\$(Id|Header):[^$]*\\$", Pattern.compile("\\$(Id|Header):[^$]*\\$"))
         .build();
   }
 
-  private RevCommit makeCommit() throws IOException, GitAPIException {
+  private RevCommit makeCommit(RevWalk rw) throws IOException, GitAPIException {
     Map<File, byte[]> files = new HashMap<>();
     // invalid files
     String content = "http://foo.bar.tld/?pw=myp4ssw0rdTefoobarstline2\n";
-    files.put(new File(repo.getDirectory().getParent(), "foo.txt"),
+    files.put(
+        new File(repo.getDirectory().getParent(), "foo.txt"),
         content.getBytes(StandardCharsets.UTF_8));
 
-    content = "$Id$\n"
-        + "$Header$\n"
-        + "$Author$\n"
-        + "processXFile($File::Find::name, $Config{$type});\n"
-        + "$Id: foo bar$\n";
-    files.put(new File(repo.getDirectory().getParent(), "bar.txt"),
+    content =
+        "$Id$\n"
+            + "$Header$\n"
+            + "$Author$\n"
+            + "processXFile($File::Find::name, $Config{$type});\n"
+            + "$Id: foo bar$\n";
+    files.put(
+        new File(repo.getDirectory().getParent(), "bar.txt"),
         content.getBytes(StandardCharsets.UTF_8));
 
     // valid file
-    content = "Testline1\n"
-        + "Testline2\n"
-        + "Testline3\n"
-        + "Testline4";
-    files.put(new File(repo.getDirectory().getParent(), "foobar.txt"),
+    content = "Testline1\n" + "Testline2\n" + "Testline3\n" + "Testline4";
+    files.put(
+        new File(repo.getDirectory().getParent(), "foobar.txt"),
         content.getBytes(StandardCharsets.UTF_8));
-    return TestUtils.makeCommit(repo, "Commit foobar with test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit foobar with test files.", files);
   }
 
   @Test
   public void testKeywords() throws Exception {
-    RevCommit c = makeCommit();
-    BlockedKeywordValidator validator = new BlockedKeywordValidator(null,
-        new ContentTypeUtil(PATTERN_CACHE), PATTERN_CACHE, null, null, null);
-    List<CommitValidationMessage> m = validator.performValidation(
-        repo, c, getPatterns().values(), EMPTY_PLUGIN_CONFIG);
-    Set<String> expected = ImmutableSet.of(
-        "ERROR: blocked keyword(s) found in: foo.txt (Line: 1)"
-            + " (found: myp4ssw0rd, foobar)",
-        "ERROR: blocked keyword(s) found in: bar.txt (Line: 5)"
-            + " (found: $Id: foo bar$)",
-        "ERROR: blocked keyword(s) found in: " + Patch.COMMIT_MSG
-            + " (Line: 1) (found: foobar)");
-    assertThat(TestUtils.transformMessages(m))
-        .containsExactlyElementsIn(expected);
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw);
+      BlockedKeywordValidator validator =
+          new BlockedKeywordValidator(
+              null,
+              new ContentTypeUtil(PATTERN_CACHE, new FakeMimeUtilFileTypeRegistry()),
+              PATTERN_CACHE,
+              null,
+              null,
+              null);
+      List<CommitValidationMessage> m =
+          validator.performValidation(repo, c, rw, getPatterns().values(), EMPTY_PLUGIN_CONFIG);
+      Set<String> expected =
+          ImmutableSet.of(
+              "ERROR: blocked keyword(s) found in: foo.txt (Line: 1)"
+                  + " (found: myp4ssw0rd, foobar)",
+              "ERROR: blocked keyword(s) found in: bar.txt (Line: 5)" + " (found: $Id: foo bar$)",
+              "ERROR: blocked keyword(s) found in: "
+                  + Patch.COMMIT_MSG
+                  + " (Line: 1) (found: foobar)");
+      assertThat(TestUtils.transformMessages(m)).containsExactlyElementsIn(expected);
+    }
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtilTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtilTest.java
index 47c6106..31025b6 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtilTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeUtilTest.java
@@ -18,6 +18,9 @@
 import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.EMPTY_PLUGIN_CONFIG;
 import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.PATTERN_CACHE;
 
+import com.google.gerrit.server.mime.MimeUtilFileTypeRegistry;
+import com.google.inject.Inject;
+
 import org.junit.Before;
 import org.junit.Test;
 
@@ -25,16 +28,16 @@
 
 public class ContentTypeUtilTest {
   private ContentTypeUtil ctu;
+  @Inject private MimeUtilFileTypeRegistry mimeUtil;
 
   @Before
   public void setUp() {
-    ctu = new ContentTypeUtil(PATTERN_CACHE);
+    ctu = new ContentTypeUtil(PATTERN_CACHE, mimeUtil);
   }
 
   @Test
   public void testMatchesAny() throws ExecutionException {
-    String[] patterns =
-        new String[] {"text/*", "^application/(pdf|xml)", "application/zip"};
+    String[] patterns = new String[] {"text/*", "^application/(pdf|xml)", "application/zip"};
 
     matchesAny("text/xml", patterns);
     matchesAny("text/html", patterns);
@@ -47,13 +50,11 @@
     noMatch("application/msword", patterns);
   }
 
-  private void matchesAny(String p, String[] patterns)
-      throws ExecutionException {
+  private void matchesAny(String p, String[] patterns) throws ExecutionException {
     assertThat(ctu.matchesAny(p, patterns)).isTrue();
   }
 
-  private void noMatch(String p, String[] patterns)
-      throws ExecutionException {
+  private void noMatch(String p, String[] patterns) throws ExecutionException {
     assertThat(ctu.matchesAny(p, patterns)).isFalse();
   }
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidatorTest.java
index edad751..092c251 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ContentTypeValidatorTest.java
@@ -22,6 +22,7 @@
 
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -34,53 +35,66 @@
 
 public class ContentTypeValidatorTest extends ValidatorTestCase {
 
-  private static final byte[] TEST_PDF = ("%PDF-1.4\n"
-        + "1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>\n"
-        + "endobj 2 0 obj << /Type /Outlines /Count 0 >>\n"
-        + "endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1\n"
-        + ">> endobj 4 0 obj << /Type /Page /Parent 3 0 R\n"
-        + "/MediaBox [0 0 612 144] /Contents 5 0 R /Resources << /ProcSet 6 0 R\n"
-        + "/Font << /F1 7 0 R >> >> >> endobj 5 0 obj\n"
-        + "<< /Length 73 >> stream BT\n" + "/F1 24 Tf\n" + "100 100 Td\n"
-        + "(Small pdf) Tj\n"
-        + "ET endstream endobj 6 0 obj [/PDF /Text] endobj 7 0 obj\n"
-        + "<< /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica\n"
-        + "/Encoding /MacRomanEncoding >> endobj xref 0 8\n"
-        + "0000000000 65535 f 0000000009 00000 n 0000000074 00000 n\n"
-        + "0000000120 00000 n 0000000179 00000 n 0000000364 00000 n\n"
-        + "0000000466 00000 n 0000000496 00000 n\n"
-        + "trailer << /Size 8 /Root 1 0 R >> startxref 625\n" + "%%EOF")
-        .getBytes(StandardCharsets.UTF_8);
+  private static final byte[] TEST_PDF =
+      ("%PDF-1.4\n"
+              + "1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>\n"
+              + "endobj 2 0 obj << /Type /Outlines /Count 0 >>\n"
+              + "endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1\n"
+              + ">> endobj 4 0 obj << /Type /Page /Parent 3 0 R\n"
+              + "/MediaBox [0 0 612 144] /Contents 5 0 R /Resources << /ProcSet 6 0 R\n"
+              + "/Font << /F1 7 0 R >> >> >> endobj 5 0 obj\n"
+              + "<< /Length 73 >> stream BT\n"
+              + "/F1 24 Tf\n"
+              + "100 100 Td\n"
+              + "(Small pdf) Tj\n"
+              + "ET endstream endobj 6 0 obj [/PDF /Text] endobj 7 0 obj\n"
+              + "<< /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica\n"
+              + "/Encoding /MacRomanEncoding >> endobj xref 0 8\n"
+              + "0000000000 65535 f 0000000009 00000 n 0000000074 00000 n\n"
+              + "0000000120 00000 n 0000000179 00000 n 0000000364 00000 n\n"
+              + "0000000466 00000 n 0000000496 00000 n\n"
+              + "trailer << /Size 8 /Root 1 0 R >> startxref 625\n"
+              + "%%EOF")
+          .getBytes(StandardCharsets.UTF_8);
 
   private ContentTypeValidator validator;
 
   @Before
   public void setUp() {
-    validator = new ContentTypeValidator(
-        null, new ContentTypeUtil(PATTERN_CACHE), null, null, null);
+    validator =
+        new ContentTypeValidator(
+            null,
+            new ContentTypeUtil(PATTERN_CACHE, new FakeMimeUtilFileTypeRegistry()),
+            null,
+            null,
+            null);
   }
 
   @Test
   public void testBlocked() throws Exception {
-    String[] patterns =
-        new String[] {"application/pdf", "application/xml", "text/html"};
+    String[] patterns = new String[] {"application/pdf", "application/xml", "text/html"};
 
-    List<CommitValidationMessage> m = validator.performValidation(
-        repo, makeCommit(), patterns, false);
-    assertThat(TestUtils.transformMessages(m)).containsExactly(
-        "ERROR: found blocked content type (application/pdf) in file: foo.pdf",
-        "ERROR: found blocked content type (application/xml) in file: foo.xml",
-        "ERROR: found blocked content type (text/html) in file: foo.html");
+    try (RevWalk rw = new RevWalk(repo)) {
+      List<CommitValidationMessage> m =
+          validator.performValidation(repo, makeCommit(rw), rw, patterns, false);
+      assertThat(TestUtils.transformMessages(m))
+          .containsExactly(
+              "ERROR: found blocked content type (application/pdf) in file: foo.pdf",
+              "ERROR: found blocked content type (application/xml) in file: foo.xml",
+              "ERROR: found blocked content type (text/html) in file: foo.html");
+    }
   }
 
   @Test
   public void testWhitelist() throws Exception {
     String[] patterns = new String[] {"application/pdf", "application/xml"};
 
-    List<CommitValidationMessage> m = validator.performValidation(
-        repo, makeCommit(), patterns, true);
-    assertThat(TestUtils.transformMessages(m)).containsExactly(
-        "ERROR: found blocked content type (text/html) in file: foo.html");
+    try (RevWalk rw = new RevWalk(repo)) {
+      List<CommitValidationMessage> m =
+          validator.performValidation(repo, makeCommit(rw), rw, patterns, true);
+      assertThat(TestUtils.transformMessages(m))
+          .containsExactly("ERROR: found blocked content type (text/html) in file: foo.html");
+    }
   }
 
   @Test
@@ -89,18 +103,17 @@
     assertThat(ContentTypeValidator.isWhitelist(EMPTY_PLUGIN_CONFIG)).isFalse();
   }
 
-  private RevCommit makeCommit() throws IOException, GitAPIException {
+  private RevCommit makeCommit(RevWalk rw) throws IOException, GitAPIException {
     Map<File, byte[]> files = new HashMap<>();
 
     String content = "<?xml version=\"1.0\"?><a><b>c</b></a>";
-    files.put(TestUtils.createEmptyFile("foo.xml", repo),
-        content.getBytes(StandardCharsets.UTF_8));
+    files.put(TestUtils.createEmptyFile("foo.xml", repo), content.getBytes(StandardCharsets.UTF_8));
 
     content = "<html><body><h1>Hello World!</h1></body></html>";
-    files.put(TestUtils.createEmptyFile("foo.html", repo),
-        content.getBytes(StandardCharsets.UTF_8));
+    files.put(
+        TestUtils.createEmptyFile("foo.html", repo), content.getBytes(StandardCharsets.UTF_8));
 
     files.put(TestUtils.createEmptyFile("foo.pdf", repo), TEST_PDF);
-    return TestUtils.makeCommit(repo, "Commit with test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with test files.", files);
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidatorTest.java
index 2461bf6..8954d35 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/DuplicatePathnameValidatorTest.java
@@ -33,6 +33,7 @@
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.junit.Before;
 import org.junit.Test;
@@ -44,10 +45,7 @@
 
 public class DuplicatePathnameValidatorTest extends ValidatorTestCase {
   private static final ImmutableList<String> INITIAL_PATHNAMES =
-      ImmutableList.of(
-          "a" , "ab",
-          "f1/a", "f1/ab",
-          "f2/a", "f2/ab", "f2/sF1/a", "f2/sF1/ab");
+      ImmutableList.of("a", "ab", "f1/a", "f1/ab", "f2/a", "f2/ab", "f2/sF1/a", "f2/sF1/ab");
 
   private final List<String> vistedPaths = Lists.newArrayList();
   private final List<CommitValidationMessage> messages = Lists.newArrayList();
@@ -56,11 +54,17 @@
   private Set<String> changedPaths;
   private DuplicatePathnameValidator validator;
 
-  private void runCheck(List<String> existingTreePaths, Set<String> testPaths,
-      List<CommitValidationMessage> messages, List<String> visitedPaths)
-          throws Exception {
-    RevCommit c = makeCommit(
-        createEmptyDirCacheEntries(existingTreePaths, testRepo), testRepo);
+  private void runCheck(
+      List<String> existingTreePaths,
+      Set<String> testPaths,
+      List<CommitValidationMessage> messages,
+      List<String> visitedPaths)
+      throws Exception {
+    RevCommit c =
+        makeCommit(
+            testRepo.getRevWalk(),
+            createEmptyDirCacheEntries(existingTreePaths, testRepo),
+            testRepo);
     try (TreeWalk tw = new TreeWalk(repo)) {
       tw.setRecursive(false);
       tw.addTree(c.getTree());
@@ -84,16 +88,14 @@
     runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
     assertThat(transformMessages(messages))
         .containsExactly(transformMessage(conflict("f1/A", "f1/a")));
-    assertThat(vistedPaths).containsExactly(
-        "a", "ab", "f1", "f1/a", "f1/ab", "f2");
+    assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f1/a", "f1/ab", "f2");
   }
 
   @Test
   public void testFindConflictingSubtree() throws Exception {
     changedPaths = Sets.newHashSet("F1/a");
     runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
-    assertThat(transformMessages(messages))
-        .containsExactly(transformMessage(conflict("F1", "f1")));
+    assertThat(transformMessages(messages)).containsExactly(transformMessage(conflict("F1", "f1")));
     assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f2");
   }
 
@@ -101,23 +103,23 @@
   public void testFindConflictingSubtree2() throws Exception {
     changedPaths = Sets.newHashSet("f2/sf1", "F1/a");
     runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
-    assertThat(transformMessages(messages)).containsExactly(
-        transformMessage(conflict("F1", "f1")),
-        transformMessage(conflict("f2/sf1", "f2/sF1")));
-    assertThat(vistedPaths).containsExactly(
-        "a", "ab", "f1", "f2", "f2/a", "f2/ab", "f2/sF1");
+    assertThat(transformMessages(messages))
+        .containsExactly(
+            transformMessage(conflict("F1", "f1")), transformMessage(conflict("f2/sf1", "f2/sF1")));
+    assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f2", "f2/a", "f2/ab", "f2/sF1");
   }
 
   @Test
   public void testFindDuplicates() throws Exception {
     changedPaths = Sets.newHashSet("AB", "f1/A", "f2/Ab");
     runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
-    assertThat(transformMessages(messages)).containsExactly(
-        transformMessage(conflict("AB", "ab")),
-        transformMessage(conflict("f1/A", "f1/a")),
-        transformMessage(conflict("f2/Ab", "f2/ab")));
-    assertThat(vistedPaths).containsExactly(
-        "a", "ab", "f1", "f1/a", "f1/ab", "f2", "f2/a", "f2/ab", "f2/sF1");
+    assertThat(transformMessages(messages))
+        .containsExactly(
+            transformMessage(conflict("AB", "ab")),
+            transformMessage(conflict("f1/A", "f1/a")),
+            transformMessage(conflict("f2/Ab", "f2/ab")));
+    assertThat(vistedPaths)
+        .containsExactly("a", "ab", "f1", "f1/a", "f1/ab", "f2", "f2/a", "f2/ab", "f2/sF1");
   }
 
   @Test
@@ -125,8 +127,7 @@
     changedPaths = Sets.newHashSet("a", "ab", "f1/ab");
     runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
     assertThat(messages).isEmpty();
-    assertThat(vistedPaths).containsExactly(
-        "a", "ab", "f1", "f1/a", "f1/ab", "f2");
+    assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f1/a", "f1/ab", "f2");
   }
 
   @Test
@@ -136,62 +137,62 @@
     filenames.add("A");
     filenames.add("F1/ab");
     filenames.add("f2/sF1/aB");
-    RevCommit c =
-        makeCommit(createEmptyDirCacheEntries(filenames, testRepo), testRepo);
-    List<CommitValidationMessage> m = validator.performValidation(repo, c);
-    assertThat(m).hasSize(4);
-    // During checking inside of the commit it's unknown which file is checked
-    // first, because of that, both capabilities must be checked.
-    assertThat(transformMessages(m)).containsAnyOf(
-        transformMessage(conflict("A", "a")),
-        transformMessage(conflict("a", "A")));
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, createEmptyDirCacheEntries(filenames, testRepo), testRepo);
+      List<CommitValidationMessage> m = validator.performValidation(repo, c, rw);
+      assertThat(m).hasSize(4);
+      // During checking inside of the commit it's unknown which file is checked
+      // first, because of that, both capabilities must be checked.
+      assertThat(transformMessages(m))
+          .containsAnyOf(
+              transformMessage(conflict("A", "a")), transformMessage(conflict("a", "A")));
 
-    assertThat(transformMessages(m)).containsAnyOf(
-        transformMessage(conflict("F1", "f1")),
-        transformMessage(conflict("f1", "F1")));
+      assertThat(transformMessages(m))
+          .containsAnyOf(
+              transformMessage(conflict("F1", "f1")), transformMessage(conflict("f1", "F1")));
 
-    assertThat(transformMessages(m)).containsAnyOf(
-        transformMessage(conflict("F1/ab", "f1/ab")),
-        transformMessage(conflict("f1/ab", "F1/ab")));
+      assertThat(transformMessages(m))
+          .containsAnyOf(
+              transformMessage(conflict("F1/ab", "f1/ab")),
+              transformMessage(conflict("f1/ab", "F1/ab")));
 
-    assertThat(transformMessages(m)).containsAnyOf(
-        transformMessage(
-            conflict("f2/sF1/aB", "f2/sF1/ab")),
-        transformMessage(
-            conflict("f2/sF1/ab", "f2/sF1/aB")));
+      assertThat(transformMessages(m))
+          .containsAnyOf(
+              transformMessage(conflict("f2/sF1/aB", "f2/sF1/ab")),
+              transformMessage(conflict("f2/sF1/ab", "f2/sF1/aB")));
+    }
   }
 
   @Test
   public void testCheckRenaming() throws Exception {
-    RevCommit c = makeCommit(
-        createEmptyDirCacheEntries(INITIAL_PATHNAMES, testRepo), testRepo);
-    DirCacheEntry[] entries = new DirCacheEntry[INITIAL_PATHNAMES.size()];
-    for (int x = 0; x < INITIAL_PATHNAMES.size(); x++) {
-      // Rename files
-      entries[x] = createDirCacheEntry(INITIAL_PATHNAMES.get(x).toUpperCase(),
-          EMPTY_CONTENT, testRepo);
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c =
+          makeCommit(rw, createEmptyDirCacheEntries(INITIAL_PATHNAMES, testRepo), testRepo);
+      DirCacheEntry[] entries = new DirCacheEntry[INITIAL_PATHNAMES.size()];
+      for (int x = 0; x < INITIAL_PATHNAMES.size(); x++) {
+        // Rename files
+        entries[x] =
+            createDirCacheEntry(INITIAL_PATHNAMES.get(x).toUpperCase(), EMPTY_CONTENT, testRepo);
+      }
+      RevCommit c1 = makeCommit(rw, entries, testRepo, c);
+      List<CommitValidationMessage> m = validator.performValidation(repo, c1, rw);
+      assertThat(m).isEmpty();
     }
-    RevCommit c1 = makeCommit(entries, testRepo, c);
-    List<CommitValidationMessage> m = validator.performValidation(repo, c1);
-    assertThat(m).isEmpty();
   }
 
   @Test
   public void validatorInactiveWhenConfigEmpty() {
-    assertThat(DuplicatePathnameValidator.isActive(EMPTY_PLUGIN_CONFIG))
-        .isFalse();
+    assertThat(DuplicatePathnameValidator.isActive(EMPTY_PLUGIN_CONFIG)).isFalse();
   }
 
   @Test
   public void defaultLocale() {
-    assertThat(DuplicatePathnameValidator.getLocale(EMPTY_PLUGIN_CONFIG))
-        .isEqualTo(Locale.ENGLISH);
+    assertThat(DuplicatePathnameValidator.getLocale(EMPTY_PLUGIN_CONFIG)).isEqualTo(Locale.ENGLISH);
   }
 
   @Test
   public void testGetParentFolder() {
     assertThat(validator.allParentFolders(INITIAL_PATHNAMES))
-        .containsExactlyElementsIn(
-            ImmutableList.of("f1", "f2", "f2/sF1"));
+        .containsExactlyElementsIn(ImmutableList.of("f1", "f2", "f2/sF1"));
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/EmailAwareValidatorConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/EmailAwareValidatorConfigTest.java
index 46bf3c7..b385259 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/EmailAwareValidatorConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/EmailAwareValidatorConfigTest.java
@@ -18,7 +18,6 @@
 
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
-
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.junit.Test;
 
@@ -29,52 +28,59 @@
   @Test
   public void isEnabledForAllEmailsByDefault() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "blockedFileExtension = jar");
+        getConfig("[plugin \"uploadvalidator\"]\n" + "blockedFileExtension = jar");
 
-    assertThat(
-        config.isEnabledForRef(anyUser, projectName, "anyRef",
-            "blockedFileExtension")).isTrue();
+    assertThat(config.isEnabledForRef(anyUser, projectName, "anyRef", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
   public void isEnabledForSingleEmail() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   email = " + FakeUserProvider.FAKE_EMAIL + "\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   email = "
+                + FakeUserProvider.FAKE_EMAIL
+                + "\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
   public void isDisabledForInvalidEmail() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   email = anInvalidEmail@example.com\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   email = anInvalidEmail@example.com\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isFalse();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isFalse();
   }
 
   @Test
   public void isEnabledForRegexEmail() throws Exception {
     IdentifiedUser exampleOrgUser = new FakeUserProvider().get("a@example.org");
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   email = .*@example.org$\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   email = .*@example.org$\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isFalse();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isFalse();
     assertThat(
-        config.isEnabledForRef(exampleOrgUser, projectName,
-            "refs/heads/anyref", "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(
+                exampleOrgUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
@@ -82,27 +88,27 @@
     IdentifiedUser exampleOrgUser = new FakeUserProvider().get("a@example.org");
     IdentifiedUser xUser = new FakeUserProvider().get("x@example.com");
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   email = .*@example.org$\n"
-            + "   email = x@example.com\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   email = .*@example.org$\n"
+                + "   email = x@example.com\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(exampleOrgUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(
+                exampleOrgUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isTrue();
     assertThat(
-        config.isEnabledForRef(xUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(xUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isTrue();
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isFalse();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isFalse();
   }
 
-  private ValidatorConfig getConfig(String defaultConfig)
-      throws ConfigInvalidException {
-    ValidatorConfig config =
-        new ValidatorConfig(new FakeConfigFactory(projectName, defaultConfig),
-            new FakeGroupCacheUUIDByName());
-    return config;
+  private ValidatorConfig getConfig(String defaultConfig) throws ConfigInvalidException {
+    return new ValidatorConfig(
+        new FakeConfigFactory(projectName, defaultConfig), new FakeGroupByNameFinder());
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupByNameFinder.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupByNameFinder.java
new file mode 100644
index 0000000..69f1b74
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupByNameFinder.java
@@ -0,0 +1,40 @@
+// 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.uploadvalidator;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.server.group.InternalGroup;
+import java.util.Objects;
+import java.util.Optional;
+
+public class FakeGroupByNameFinder implements ValidatorConfig.GroupByNameFinder {
+
+  private final Optional<InternalGroup> onlyGroup;
+
+  public FakeGroupByNameFinder() {
+    onlyGroup = Optional.empty();
+  }
+
+  public FakeGroupByNameFinder(AccountGroup accountGroup) {
+    onlyGroup =
+        Optional.of(InternalGroup.create(accountGroup, ImmutableSet.of(), ImmutableSet.of()));
+  }
+
+  @Override
+  public Optional<InternalGroup> get(AccountGroup.NameKey groupName) {
+    return onlyGroup.filter(group -> Objects.equals(group.getNameKey(), groupName));
+  }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupCacheUUIDByName.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupCacheUUIDByName.java
deleted file mode 100644
index 8cefe93..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupCacheUUIDByName.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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.uploadvalidator;
-
-import com.google.common.collect.ImmutableList;
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.AccountGroup.Id;
-import com.google.gerrit.reviewdb.client.AccountGroup.NameKey;
-import com.google.gerrit.reviewdb.client.AccountGroup.UUID;
-import com.google.gerrit.server.account.GroupCache;
-
-import java.io.IOException;
-
-public class FakeGroupCacheUUIDByName implements GroupCache {
-  private AccountGroup accountGroup;
-
-  public FakeGroupCacheUUIDByName(AccountGroup accountGroup) {
-    this.accountGroup = accountGroup;
-  }
-
-  public FakeGroupCacheUUIDByName() {
-    // TODO Auto-generated constructor stub
-  }
-
-  @Override
-  public AccountGroup get(Id groupId) {
-    return null;
-  }
-
-  @Override
-  public AccountGroup get(NameKey name) {
-    return accountGroup != null && accountGroup.getNameKey().equals(name)
-        ? accountGroup : null;
-  }
-
-  @Override
-  public AccountGroup get(UUID uuid) {
-    return null;
-  }
-
-  @Override
-  public ImmutableList<AccountGroup> all() {
-    return null;
-  }
-
-  @Override
-  public void onCreateGroup(NameKey newGroupName) throws IOException {
-  }
-
-  @Override
-  public void evict(AccountGroup group) throws IOException {
-  }
-
-  @Override
-  public void evictAfterRename(NameKey oldName, NameKey newName)
-      throws IOException {
-  }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupMembership.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupMembership.java
index 102c6a4..43f8bb5 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupMembership.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeGroupMembership.java
@@ -43,12 +43,12 @@
   @Override
   public Set<UUID> intersection(Iterable<UUID> groupIds) {
     return StreamSupport.stream(groupIds.spliterator(), false)
-        .filter(this::contains).collect(Collectors.toSet());
+        .filter(this::contains)
+        .collect(Collectors.toSet());
   }
 
   @Override
   public Set<UUID> getKnownGroups() {
     return new HashSet<>();
   }
-
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeMimeUtilFileTypeRegistry.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeMimeUtilFileTypeRegistry.java
new file mode 100644
index 0000000..f2e275b
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeMimeUtilFileTypeRegistry.java
@@ -0,0 +1,59 @@
+// 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.uploadvalidator;
+
+import com.google.gerrit.server.mime.FileTypeRegistry;
+import com.google.inject.Singleton;
+
+import java.io.InputStream;
+
+import eu.medsea.mimeutil.MimeType;
+
+@Singleton
+class FakeMimeUtilFileTypeRegistry implements FileTypeRegistry {
+
+  @Override
+  public MimeType getMimeType(String path, byte[] content) {
+    if (path.endsWith(".pdf")) {
+      return new MimeType("application/pdf");
+    }
+    if (path.endsWith(".xml")) {
+      return new MimeType("application/xml");
+    }
+    if (path.endsWith(".html")) {
+      return new MimeType("text/html");
+    }
+    return new MimeType("application/octet-stream");
+  }
+
+  @Override
+  public MimeType getMimeType(String path, InputStream is) {
+    if (path.endsWith(".pdf")) {
+      return new MimeType("application/pdf");
+    }
+    if (path.endsWith(".xml")) {
+      return new MimeType("application/xml");
+    }
+    if (path.endsWith(".html")) {
+      return new MimeType("text/html");
+    }
+    return new MimeType("application/octet-stream");
+  }
+
+  @Override
+  public boolean isSafeInline(MimeType type) {
+    return false;
+  }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeUserProvider.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeUserProvider.java
index 8b36ee7..bf488e1 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeUserProvider.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FakeUserProvider.java
@@ -48,8 +48,7 @@
     expect(user.isIdentifiedUser()).andReturn(true);
     expect(user.asIdentifiedUser()).andReturn(user);
     expect(user.getAccount()).andStubReturn(account);
-    expect(user.getEffectiveGroups()).andReturn(
-        new FakeGroupMembership(groupUUID));
+    expect(user.getEffectiveGroups()).andReturn(new FakeGroupMembership(groupUUID));
     replay(user);
     return user;
   }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidatorTest.java
index 0b8af8a..84dbbca 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/FileExtensionValidatorTest.java
@@ -23,6 +23,7 @@
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.NoFilepatternException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 import java.io.File;
@@ -38,7 +39,7 @@
   private static final List<String> BLOCKED_EXTENSIONS_UC =
       Lists.newArrayList("JPEG", "PDF", "ZIP", "EXE", "TAR.GZ");
 
-  private RevCommit makeCommit(List<String> blockedExtensions)
+  private RevCommit makeCommit(RevWalk rw, List<String> blockedExtensions)
       throws NoFilepatternException, IOException, GitAPIException {
     Set<File> files = new HashSet<>();
     for (String extension : blockedExtensions) {
@@ -49,33 +50,35 @@
     files.add(new File(repo.getDirectory().getParent(), "foo.core.tmp"));
     files.add(new File(repo.getDirectory().getParent(), "foo.c"));
     files.add(new File(repo.getDirectory().getParent(), "foo.txt"));
-    return TestUtils.makeCommit(repo, "Commit with empty test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with empty test files.", files);
   }
 
   @Test
   public void testBlockedExtensions() throws Exception {
-    RevCommit c = makeCommit(BLOCKED_EXTENSIONS_LC);
-    List<CommitValidationMessage> m = FileExtensionValidator
-        .performValidation(repo, c, BLOCKED_EXTENSIONS_LC);
-    List<String> expected = new ArrayList<>();
-    for (String extension : BLOCKED_EXTENSIONS_LC) {
-      expected.add("ERROR: blocked file: foo." + extension);
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, BLOCKED_EXTENSIONS_LC);
+      List<CommitValidationMessage> m =
+          FileExtensionValidator.performValidation(repo, c, rw, BLOCKED_EXTENSIONS_LC);
+      List<String> expected = new ArrayList<>();
+      for (String extension : BLOCKED_EXTENSIONS_LC) {
+        expected.add("ERROR: blocked file: foo." + extension);
+      }
+      assertThat(TestUtils.transformMessages(m)).containsExactlyElementsIn(expected);
     }
-    assertThat(TestUtils.transformMessages(m))
-        .containsExactlyElementsIn(expected);
   }
 
   @Test
   public void testBlockedExtensionsCaseInsensitive() throws Exception {
-    RevCommit c = makeCommit(BLOCKED_EXTENSIONS_UC);
-    List<CommitValidationMessage> m = FileExtensionValidator
-        .performValidation(repo, c, BLOCKED_EXTENSIONS_LC);
-    List<String> expected = new ArrayList<>();
-    for (String extension : BLOCKED_EXTENSIONS_UC) {
-      expected.add("ERROR: blocked file: foo." + extension);
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, BLOCKED_EXTENSIONS_UC);
+      List<CommitValidationMessage> m =
+          FileExtensionValidator.performValidation(repo, c, rw, BLOCKED_EXTENSIONS_LC);
+      List<String> expected = new ArrayList<>();
+      for (String extension : BLOCKED_EXTENSIONS_UC) {
+        expected.add("ERROR: blocked file: foo." + extension);
+      }
+      assertThat(TestUtils.transformMessages(m)).containsExactlyElementsIn(expected);
     }
-    assertThat(TestUtils.transformMessages(m))
-        .containsExactlyElementsIn(expected);
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidatorTest.java
index a620824..dfb81bc 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidFilenameValidatorTest.java
@@ -21,6 +21,7 @@
 
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 import java.io.File;
@@ -42,28 +43,29 @@
     return filenames;
   }
 
-  private RevCommit makeCommit() throws IOException, GitAPIException {
+  private RevCommit makeCommit(RevWalk rw) throws IOException, GitAPIException {
     Set<File> files = new HashSet<>();
     for (String filenames : getInvalidFilenames()) {
       files.add(new File(repo.getDirectory().getParent(), filenames));
     }
     // valid filename
     files.add(new File(repo.getDirectory().getParent(), "test"));
-    return TestUtils.makeCommit(repo, "Commit with empty test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with empty test files.", files);
   }
 
   @Test
   public void test() throws Exception {
     String[] invalidFilenamePattern = {"\\[|\\]|\\*|#", "[%:@]"};
-    RevCommit c = makeCommit();
-    List<CommitValidationMessage> m = InvalidFilenameValidator
-        .performValidation(repo, c, invalidFilenamePattern);
-    Set<String> expected = new HashSet<>();
-    for (String filenames : getInvalidFilenames()) {
-      expected.add("ERROR: invalid characters found in filename: " + filenames);
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw);
+      List<CommitValidationMessage> m =
+          InvalidFilenameValidator.performValidation(repo, c, rw, invalidFilenamePattern);
+      Set<String> expected = new HashSet<>();
+      for (String filenames : getInvalidFilenames()) {
+        expected.add("ERROR: invalid characters found in filename: " + filenames);
+      }
+      assertThat(TestUtils.transformMessages(m)).containsExactlyElementsIn(expected);
     }
-    assertThat(TestUtils.transformMessages(m))
-        .containsExactlyElementsIn(expected);
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidatorTest.java
index 9c3505e..31c144d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/InvalidLineEndingValidatorTest.java
@@ -19,9 +19,12 @@
 import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.PATTERN_CACHE;
 
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
+import com.google.gerrit.server.mime.MimeUtilFileTypeRegistry;
+import com.google.inject.Inject;
 
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 import java.io.File;
@@ -32,35 +35,38 @@
 import java.util.Map;
 
 public class InvalidLineEndingValidatorTest extends ValidatorTestCase {
-  private RevCommit makeCommit() throws IOException, GitAPIException {
+  private RevCommit makeCommit(RevWalk rw) throws IOException, GitAPIException {
     Map<File, byte[]> files = new HashMap<>();
     // invalid line endings
-    String content = "Testline1\r\n"
-        + "Testline2\n"
-        + "Testline3\r\n"
-        + "Testline4";
-    files.put(new File(repo.getDirectory().getParent(), "foo.txt"),
+    String content = "Testline1\r\n" + "Testline2\n" + "Testline3\r\n" + "Testline4";
+    files.put(
+        new File(repo.getDirectory().getParent(), "foo.txt"),
         content.getBytes(StandardCharsets.UTF_8));
 
     // valid line endings
-    content = "Testline1\n"
-        + "Testline2\n"
-        + "Testline3\n"
-        + "Testline4";
-    files.put(new File(repo.getDirectory().getParent(), "bar.txt"),
+    content = "Testline1\n" + "Testline2\n" + "Testline3\n" + "Testline4";
+    files.put(
+        new File(repo.getDirectory().getParent(), "bar.txt"),
         content.getBytes(StandardCharsets.UTF_8));
-    return TestUtils.makeCommit(repo, "Commit with test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with test files.", files);
   }
 
   @Test
   public void testCarriageReturn() throws Exception {
-    RevCommit c = makeCommit();
-    InvalidLineEndingValidator validator = new InvalidLineEndingValidator(null,
-        new ContentTypeUtil(PATTERN_CACHE), null, null, null);
-    List<CommitValidationMessage> m = validator.performValidation(repo, c,
-        EMPTY_PLUGIN_CONFIG);
-    assertThat(TestUtils.transformMessages(m)).containsExactly(
-        "ERROR: found carriage return (CR) character in file: foo.txt");
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw);
+      InvalidLineEndingValidator validator =
+          new InvalidLineEndingValidator(
+              null,
+              new ContentTypeUtil(PATTERN_CACHE, new FakeMimeUtilFileTypeRegistry()),
+              null,
+              null,
+              null);
+      List<CommitValidationMessage> m =
+          validator.performValidation(repo, c, rw, EMPTY_PLUGIN_CONFIG);
+      assertThat(TestUtils.transformMessages(m))
+          .containsExactly("ERROR: found carriage return (CR) character in file: foo.txt");
+    }
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidatorTest.java
index 4ce9dba..951659a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/MaxPathLengthValidatorTest.java
@@ -23,6 +23,7 @@
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 import java.io.File;
@@ -39,36 +40,39 @@
     return (TOO_LONG.length() + GOOD.length()) / 2;
   }
 
-  private RevCommit makeCommit() throws IOException, GitAPIException {
+  private RevCommit makeCommit(RevWalk rw) throws IOException, GitAPIException {
     Set<File> files = new HashSet<>();
     files.add(TestUtils.createEmptyFile(TOO_LONG, repo));
     files.add(TestUtils.createEmptyFile(GOOD, repo));
-    return TestUtils.makeCommit(repo, "Commit with empty test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with empty test files.", files);
   }
 
   @Test
   public void testAddTooLongPath() throws Exception {
-    RevCommit c = makeCommit();
-    List<CommitValidationMessage> m =
-        MaxPathLengthValidator.performValidation(repo, c, getMaxPathLength());
-    Set<String> expected =
-        ImmutableSet.of("ERROR: path too long: " + TOO_LONG);
-    assertThat(TestUtils.transformMessages(m))
-        .containsExactlyElementsIn(expected);
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw);
+      List<CommitValidationMessage> m =
+          MaxPathLengthValidator.performValidation(repo, c, rw, getMaxPathLength());
+      Set<String> expected = ImmutableSet.of("ERROR: path too long: " + TOO_LONG);
+      assertThat(TestUtils.transformMessages(m)).containsExactlyElementsIn(expected);
+    }
   }
 
   @Test
   public void testDeleteTooLongPath() throws Exception {
-    RevCommit c = makeCommit();
-    try(Git git = new Git(repo)) {
-      Set<File> files = new HashSet<>();
-      files.add(TestUtils.createEmptyFile(TOO_LONG, repo));
-      TestUtils.removeFiles(git, files);
-      c = git.commit().setMessage("Delete file which is too long").call();
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw);
+      try (Git git = new Git(repo)) {
+        Set<File> files = new HashSet<>();
+        files.add(TestUtils.createEmptyFile(TOO_LONG, repo));
+        TestUtils.removeFiles(git, files);
+        c = git.commit().setMessage("Delete file which is too long").call();
+        rw.parseCommit(c);
+      }
+      List<CommitValidationMessage> m =
+          MaxPathLengthValidator.performValidation(repo, c, rw, getMaxPathLength());
+      assertThat(m).isEmpty();
     }
-    List<CommitValidationMessage> m = MaxPathLengthValidator
-        .performValidation(repo, c, getMaxPathLength());
-    assertThat(m).isEmpty();
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ProjectAwareValidatorConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ProjectAwareValidatorConfigTest.java
index 1ddcdc3..e6e1be7 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ProjectAwareValidatorConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/ProjectAwareValidatorConfigTest.java
@@ -18,7 +18,6 @@
 
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
-
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.junit.Test;
 
@@ -29,58 +28,58 @@
   @Test
   public void isEnabledForAllProjectsByDefault() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "blockedFileExtension = jar", projectName);
+        getConfig("[plugin \"uploadvalidator\"]\n" + "blockedFileExtension = jar", projectName);
 
-    assertThat(
-        config.isEnabledForRef(anyUser, projectName, "anyRef",
-            "blockedFileExtension")).isTrue();
+    assertThat(config.isEnabledForRef(anyUser, projectName, "anyRef", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
   public void isEnabledForSingleProject() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   project = testProject\n"
-            + "   blockedFileExtension = jar", projectName);
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   project = testProject\n"
+                + "   blockedFileExtension = jar",
+            projectName);
 
-    assertThat(
-        config.isEnabledForRef(anyUser, projectName, "anyRef",
-            "blockedFileExtension")).isTrue();
+    assertThat(config.isEnabledForRef(anyUser, projectName, "anyRef", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
   public void isDisabledForInvalidProject() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   project = someOtherProject\n"
-            + "   blockedFileExtension = jar", projectName);
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   project = someOtherProject\n"
+                + "   blockedFileExtension = jar",
+            projectName);
 
-    assertThat(
-        config.isEnabledForRef(anyUser, projectName, "anyRef",
-            "blockedFileExtension")).isFalse();
+    assertThat(config.isEnabledForRef(anyUser, projectName, "anyRef", "blockedFileExtension"))
+        .isFalse();
   }
 
   @Test
   public void isEnabledForRegexProject() throws Exception {
-    String configString = "[plugin \"uploadvalidator\"]\n"
-        + "   project = test.*\n"
-        + "   blockedFileExtension = jar";
+    String configString =
+        "[plugin \"uploadvalidator\"]\n"
+            + "   project = test.*\n"
+            + "   blockedFileExtension = jar";
     Project.NameKey otherNameKey = new Project.NameKey("someOtherProject");
     ValidatorConfig config = getConfig(configString, projectName);
     ValidatorConfig config2 = getConfig(configString, otherNameKey);
 
-    assertThat(
-        config.isEnabledForRef(anyUser, projectName, "anyRef",
-            "blockedFileExtension")).isTrue();
-    assertThat(
-        config2.isEnabledForRef(anyUser, otherNameKey,
-            "anyRef", "blockedFileExtension")).isFalse();
+    assertThat(config.isEnabledForRef(anyUser, projectName, "anyRef", "blockedFileExtension"))
+        .isTrue();
+    assertThat(config2.isEnabledForRef(anyUser, otherNameKey, "anyRef", "blockedFileExtension"))
+        .isFalse();
   }
 
   @Test
   public void isEnabledForMultipleProjects() throws Exception {
-    String configString = "[plugin \"uploadvalidator\"]\n"
+    String configString =
+        "[plugin \"uploadvalidator\"]\n"
             + "   project = testProject\n"
             + "   project = another.*\n"
             + "   blockedFileExtension = jar";
@@ -90,23 +89,17 @@
     ValidatorConfig config2 = getConfig(configString, anotherNameKey);
     ValidatorConfig config3 = getConfig(configString, someOtherNameKey);
 
-    assertThat(
-        config.isEnabledForRef(anyUser, projectName, "anyRef",
-            "blockedFileExtension")).isTrue();
-    assertThat(
-        config2.isEnabledForRef(anyUser, anotherNameKey, "anyRef",
-            "blockedFileExtension")).isTrue();
-    assertThat(
-        config3.isEnabledForRef(anyUser, someOtherNameKey, "anyRef",
-            "blockedFileExtension")).isFalse();
+    assertThat(config.isEnabledForRef(anyUser, projectName, "anyRef", "blockedFileExtension"))
+        .isTrue();
+    assertThat(config2.isEnabledForRef(anyUser, anotherNameKey, "anyRef", "blockedFileExtension"))
+        .isTrue();
+    assertThat(config3.isEnabledForRef(anyUser, someOtherNameKey, "anyRef", "blockedFileExtension"))
+        .isFalse();
   }
 
-  private ValidatorConfig getConfig(
-      String defaultConfig, Project.NameKey projName)
+  private ValidatorConfig getConfig(String defaultConfig, Project.NameKey projName)
       throws ConfigInvalidException {
-    ValidatorConfig config =
-        new ValidatorConfig(new FakeConfigFactory(projName, defaultConfig),
-            new FakeGroupCacheUUIDByName());
-    return config;
+    return new ValidatorConfig(
+        new FakeConfigFactory(projName, defaultConfig), new FakeGroupByNameFinder());
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/RefAwareValidatorConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/RefAwareValidatorConfigTest.java
index 111b16b..acc2bdc 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/RefAwareValidatorConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/RefAwareValidatorConfigTest.java
@@ -18,89 +18,93 @@
 
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
-
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.junit.Test;
 
 public class RefAwareValidatorConfigTest {
-  private final Project.NameKey projectName =
-      new Project.NameKey("testProject");
+  private final Project.NameKey projectName = new Project.NameKey("testProject");
   private final IdentifiedUser anyUser = new FakeUserProvider().get();
 
   @Test
   public void isEnabledForAllRefsByDefault() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "blockedFileExtension = jar");
+        getConfig("[plugin \"uploadvalidator\"]\n" + "blockedFileExtension = jar");
 
-    assertThat(
-        config.isEnabledForRef(anyUser, projectName, "anyRef",
-            "blockedFileExtension")).isTrue();
+    assertThat(config.isEnabledForRef(anyUser, projectName, "anyRef", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
   public void isEnabledForSingleRef() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   ref = refs/heads/anyref\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   ref = refs/heads/anyref\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
   public void isDisabledForInvalidRef() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   ref = anInvalidRef\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   ref = anInvalidRef\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/anyref",
-            "blockedFileExtension")).isFalse();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anyref", "blockedFileExtension"))
+        .isFalse();
   }
 
   @Test
   public void isEnabledForRegexRef() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   ref = ^refs/heads/mybranch.*\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   ref = ^refs/heads/mybranch.*\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/anotherref",
-            "blockedFileExtension")).isFalse();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anotherref", "blockedFileExtension"))
+        .isFalse();
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/mybranch123",
-            "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/mybranch123", "blockedFileExtension"))
+        .isTrue();
   }
 
   @Test
   public void isEnabledForMultipleRefs() throws Exception {
     ValidatorConfig config =
-        getConfig("[plugin \"uploadvalidator\"]\n"
-            + "   ref = refs/heads/branch1\n"
-            + "   ref = refs/heads/branch2\n"
-            + "   blockedFileExtension = jar");
+        getConfig(
+            "[plugin \"uploadvalidator\"]\n"
+                + "   ref = refs/heads/branch1\n"
+                + "   ref = refs/heads/branch2\n"
+                + "   blockedFileExtension = jar");
 
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/branch1",
-            "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/branch1", "blockedFileExtension"))
+        .isTrue();
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/branch2",
-            "blockedFileExtension")).isTrue();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/branch2", "blockedFileExtension"))
+        .isTrue();
     assertThat(
-        config.isEnabledForRef(anyUser, projectName, "refs/heads/branch3",
-            "blockedFileExtension")).isFalse();
+            config.isEnabledForRef(
+                anyUser, projectName, "refs/heads/branch3", "blockedFileExtension"))
+        .isFalse();
   }
 
-  private ValidatorConfig getConfig(String defaultConfig)
-      throws ConfigInvalidException {
-    ValidatorConfig config =
-        new ValidatorConfig(new FakeConfigFactory(projectName, defaultConfig),
-            new FakeGroupCacheUUIDByName());
-    return config;
+  private ValidatorConfig getConfig(String defaultConfig) throws ConfigInvalidException {
+    return new ValidatorConfig(
+        new FakeConfigFactory(projectName, defaultConfig), new FakeGroupByNameFinder());
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SkipValidationTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SkipValidationTest.java
index bfbd069..4942391 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SkipValidationTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SkipValidationTest.java
@@ -15,27 +15,23 @@
 package com.googlesource.gerrit.plugins.uploadvalidator;
 
 import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.reviewdb.client.AccountGroup;
 
+import com.google.gerrit.common.TimeUtil;
+import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
-
 import org.junit.Test;
 
 public class SkipValidationTest {
-  private final Project.NameKey projectName =
-      new Project.NameKey("testProject");
+  private final Project.NameKey projectName = new Project.NameKey("testProject");
   private final IdentifiedUser anyUser = new FakeUserProvider().get();
 
   @Test
   public void dontSkipByDefault() throws Exception {
     ValidatorConfig validatorConfig =
-        new ValidatorConfig(new FakeConfigFactory(projectName, ""),
-            new FakeGroupCacheUUIDByName());
+        new ValidatorConfig(new FakeConfigFactory(projectName, ""), new FakeGroupByNameFinder());
 
-    assertThat(
-        validatorConfig
-            .isEnabledForRef(anyUser, projectName, "anyRef", "anyOp")).isTrue();
+    assertThat(validatorConfig.isEnabledForRef(anyUser, projectName, "anyRef", "anyOp")).isTrue();
   }
 
   @Test
@@ -47,32 +43,37 @@
             + "skipGroup=anotherGroup";
 
     ValidatorConfig validatorConfig =
-        new ValidatorConfig(new FakeConfigFactory(projectName, config),
-            new FakeGroupCacheUUIDByName());
+        new ValidatorConfig(
+            new FakeConfigFactory(projectName, config), new FakeGroupByNameFinder());
 
     assertThat(
-        validatorConfig.isEnabledForRef(new FakeUserProvider("testGroup",
-            "yetAnotherGroup").get(), projectName, "anyRef", "testOp"))
+            validatorConfig.isEnabledForRef(
+                new FakeUserProvider("testGroup", "yetAnotherGroup").get(),
+                projectName,
+                "anyRef",
+                "testOp"))
         .isFalse();
   }
 
   @Test
   public void skipWhenUserBelongsToGroupName() throws Exception {
     String config =
-        "[plugin \"uploadvalidator\"]\n"
-            + "skipValidation=testOp\n"
-            + "skipGroup=testGroupName\n";
+        "[plugin \"uploadvalidator\"]\n" + "skipValidation=testOp\n" + "skipGroup=testGroupName\n";
 
     ValidatorConfig validatorConfig =
-        new ValidatorConfig(new FakeConfigFactory(projectName, config),
-            new FakeGroupCacheUUIDByName(new AccountGroup(
-                new AccountGroup.NameKey("testGroupName"), new AccountGroup.Id(
-                    1), new AccountGroup.UUID("testGroupId"))));
+        new ValidatorConfig(
+            new FakeConfigFactory(projectName, config),
+            new FakeGroupByNameFinder(
+                new AccountGroup(
+                    new AccountGroup.NameKey("testGroupName"),
+                    new AccountGroup.Id(1),
+                    new AccountGroup.UUID("testGroupId"),
+                    TimeUtil.nowTs())));
 
     assertThat(
-        validatorConfig.isEnabledForRef(
-            new FakeUserProvider("testGroupId").get(), projectName, "anyRef",
-            "testOp")).isFalse();
+            validatorConfig.isEnabledForRef(
+                new FakeUserProvider("testGroupId").get(), projectName, "anyRef", "testOp"))
+        .isFalse();
   }
 
   @Test
@@ -84,13 +85,13 @@
             + "skipGroup=anotherGroup";
 
     ValidatorConfig validatorConfig =
-        new ValidatorConfig(new FakeConfigFactory(projectName, config),
-            new FakeGroupCacheUUIDByName());
+        new ValidatorConfig(
+            new FakeConfigFactory(projectName, config), new FakeGroupByNameFinder());
 
     assertThat(
-        validatorConfig.isEnabledForRef(
-            new FakeUserProvider("yetAnotherGroup").get(), projectName,
-            "anyRef", "testOp")).isTrue();
+            validatorConfig.isEnabledForRef(
+                new FakeUserProvider("yetAnotherGroup").get(), projectName, "anyRef", "testOp"))
+        .isTrue();
   }
 
   @Test
@@ -102,12 +103,11 @@
             + "skipGroup=anotherGroup";
 
     ValidatorConfig validatorConfig =
-        new ValidatorConfig(new FakeConfigFactory(projectName, config),
-            new FakeGroupCacheUUIDByName());
+        new ValidatorConfig(
+            new FakeConfigFactory(projectName, config), new FakeGroupByNameFinder());
 
-    assertThat(
-        validatorConfig.isEnabledForRef(anyUser, projectName, "anyRef",
-            "anotherOp")).isTrue();
+    assertThat(validatorConfig.isEnabledForRef(anyUser, projectName, "anyRef", "anotherOp"))
+        .isTrue();
   }
 
   @Test
@@ -119,13 +119,13 @@
             + "skipGroup=testGroup";
 
     ValidatorConfig validatorConfig =
-        new ValidatorConfig(new FakeConfigFactory(projectName, config),
-            new FakeGroupCacheUUIDByName());
+        new ValidatorConfig(
+            new FakeConfigFactory(projectName, config), new FakeGroupByNameFinder());
 
     assertThat(
-        validatorConfig.isEnabledForRef(
-            new FakeUserProvider("testGroup").get(), projectName,
-            "refs/heads/myref", "testOp")).isFalse();
+            validatorConfig.isEnabledForRef(
+                new FakeUserProvider("testGroup").get(), projectName, "refs/heads/myref", "testOp"))
+        .isFalse();
   }
 
   @Test
@@ -137,11 +137,12 @@
             + "skipGroup=testGroup";
 
     ValidatorConfig validatorConfig =
-        new ValidatorConfig(new FakeConfigFactory(projectName, config),
-            new FakeGroupCacheUUIDByName());
+        new ValidatorConfig(
+            new FakeConfigFactory(projectName, config), new FakeGroupByNameFinder());
 
     assertThat(
-        validatorConfig.isEnabledForRef(anyUser, projectName,
-            "refs/heads/anotherRef", "testOp")).isTrue();
+            validatorConfig.isEnabledForRef(
+                anyUser, projectName, "refs/heads/anotherRef", "testOp"))
+        .isTrue();
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidatorTest.java
index d24b3c2..04d4dda 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SubmoduleValidatorTest.java
@@ -23,6 +23,7 @@
 import org.eclipse.jgit.api.SubmoduleAddCommand;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 import java.io.File;
@@ -32,40 +33,40 @@
 import java.util.Map;
 
 public class SubmoduleValidatorTest extends ValidatorTestCase {
-  private RevCommit makeCommitWithSubmodule()
-      throws IOException, GitAPIException {
+  private RevCommit makeCommitWithSubmodule(RevWalk rw) throws IOException, GitAPIException {
     try (Git git = new Git(repo)) {
       SubmoduleAddCommand addCommand = git.submoduleAdd();
       addCommand.setURI(repo.getDirectory().getCanonicalPath());
       addCommand.setPath("modules/library");
       addCommand.call().close();
       git.add().addFilepattern(".").call();
-      return git.commit().setMessage("Commit with submodule.").call();
+      return rw.parseCommit(git.commit().setMessage("Commit with submodule.").call());
     }
   }
 
   @Test
   public void testWithSubmodule() throws Exception {
-    RevCommit c = makeCommitWithSubmodule();
-    List<CommitValidationMessage> m =
-        SubmoduleValidator.performValidation(repo, c);
-    assertThat(TestUtils.transformMessages(m))
-        .containsExactly("ERROR: submodules are not allowed: modules/library");
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommitWithSubmodule(rw);
+      List<CommitValidationMessage> m = SubmoduleValidator.performValidation(repo, c, rw);
+      assertThat(TestUtils.transformMessages(m))
+          .containsExactly("ERROR: submodules are not allowed: modules/library");
+    }
   }
 
-  private RevCommit makeCommitWithoutSubmodule()
-      throws IOException, GitAPIException {
+  private RevCommit makeCommitWithoutSubmodule(RevWalk rw) throws IOException, GitAPIException {
     Map<File, byte[]> files = new HashMap<>();
     files.put(new File(repo.getDirectory().getParent(), "foo.txt"), null);
-    return TestUtils.makeCommit(repo, "Commit with empty test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with empty test files.", files);
   }
 
   @Test
   public void testWithoutSubmodule() throws Exception {
-    RevCommit c = makeCommitWithoutSubmodule();
-    List<CommitValidationMessage> m =
-        SubmoduleValidator.performValidation(repo, c);
-    assertThat(m).isEmpty();
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommitWithoutSubmodule(rw);
+      List<CommitValidationMessage> m = SubmoduleValidator.performValidation(repo, c, rw);
+      assertThat(m).isEmpty();
+    }
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidatorTest.java
index a4c2127..3d1f3c0 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/SymlinkValidatorTest.java
@@ -22,6 +22,7 @@
 
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.junit.Test;
 
 import java.io.File;
@@ -34,8 +35,7 @@
 import java.util.Set;
 
 public class SymlinkValidatorTest extends ValidatorTestCase {
-  private RevCommit makeCommitWithSymlink()
-      throws IOException, GitAPIException {
+  private RevCommit makeCommitWithSymlink(RevWalk rw) throws IOException, GitAPIException {
     Map<File, byte[]> files = new HashMap<>();
     File link = new File(repo.getDirectory().getParent(), "foo.txt");
     Files.createSymbolicLink(link.toPath(), Paths.get("bar.txt"));
@@ -45,34 +45,37 @@
     Files.createSymbolicLink(link.toPath(), Paths.get("folder"));
     files.put(link, null);
 
-    return TestUtils.makeCommit(repo, "Commit with symlink.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with symlink.", files);
   }
 
   @Test
   public void testWithSymlink() throws Exception {
-    RevCommit c = makeCommitWithSymlink();
-    List<CommitValidationMessage> m =
-        SymlinkValidator.performValidation(repo, c);
-    Set<String> expected = ImmutableSet.of(
-        "ERROR: Symbolic links are not allowed: foo.txt",
-        "ERROR: Symbolic links are not allowed: symbolicFolder");
-    assertThat(TestUtils.transformMessages(m))
-        .containsExactlyElementsIn(expected);
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommitWithSymlink(rw);
+      List<CommitValidationMessage> m =
+          SymlinkValidator.performValidation(repo, rw.parseCommit(c), rw);
+      Set<String> expected =
+          ImmutableSet.of(
+              "ERROR: Symbolic links are not allowed: foo.txt",
+              "ERROR: Symbolic links are not allowed: symbolicFolder");
+      assertThat(TestUtils.transformMessages(m)).containsExactlyElementsIn(expected);
+    }
   }
 
-  private RevCommit makeCommitWithoutSymlink()
-      throws IOException, GitAPIException {
+  private RevCommit makeCommitWithoutSymlink(RevWalk rw) throws IOException, GitAPIException {
     Map<File, byte[]> files = new HashMap<>();
     files.put(new File(repo.getDirectory().getParent(), "foo.txt"), null);
-    return TestUtils.makeCommit(repo, "Commit with empty test files.", files);
+    return TestUtils.makeCommit(rw, repo, "Commit with empty test files.", files);
   }
 
   @Test
   public void testWithoutSymlink() throws Exception {
-    RevCommit c = makeCommitWithoutSymlink();
-    List<CommitValidationMessage> m =
-        SymlinkValidator.performValidation(repo, c);
-    assertThat(m).isEmpty();
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommitWithoutSymlink(rw);
+      List<CommitValidationMessage> m =
+          SymlinkValidator.performValidation(repo, rw.parseCommit(c), rw);
+      assertThat(m).isEmpty();
+    }
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/TestUtils.java b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/TestUtils.java
index ab17832..91d9052 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/TestUtils.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/uploadvalidator/TestUtils.java
@@ -33,6 +33,7 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
 
 import java.io.File;
@@ -44,8 +45,7 @@
 import java.util.regex.Pattern;
 
 public class TestUtils {
-  public static final PluginConfig EMPTY_PLUGIN_CONFIG =
-      new PluginConfig("", new Config());
+  public static final PluginConfig EMPTY_PLUGIN_CONFIG = new PluginConfig("", new Config());
 
   protected static final byte[] EMPTY_CONTENT = "".getBytes(Charsets.UTF_8);
 
@@ -59,32 +59,31 @@
       };
 
   public static final LoadingCache<String, Pattern> PATTERN_CACHE =
-    CacheBuilder.newBuilder().build(new PatternCacheModule.Loader());
+      CacheBuilder.newBuilder().build(new PatternCacheModule.Loader());
 
-  public static Repository createNewRepository(File repoFolder)
-      throws IOException {
-    Repository repository =
-        FileRepositoryBuilder.create(new File(repoFolder, ".git"));
+  public static Repository createNewRepository(File repoFolder) throws IOException {
+    Repository repository = FileRepositoryBuilder.create(new File(repoFolder, ".git"));
     repository.create();
     return repository;
   }
 
-  public static RevCommit makeCommit(Repository repo, String message,
-      Set<File> files) throws IOException, GitAPIException {
+  public static RevCommit makeCommit(RevWalk rw, Repository repo, String message, Set<File> files)
+      throws IOException, GitAPIException {
     Map<File, byte[]> tmp = new HashMap<>();
     for (File f : files) {
       tmp.put(f, null);
     }
-    return makeCommit(repo, message, tmp);
+    return makeCommit(rw, repo, message, tmp);
   }
 
-  public static RevCommit makeCommit(Repository repo, String message,
-      Map<File, byte[]> files) throws IOException, GitAPIException {
+  public static RevCommit makeCommit(
+      RevWalk rw, Repository repo, String message, Map<File, byte[]> files)
+      throws IOException, GitAPIException {
     try (Git git = new Git(repo)) {
       if (files != null) {
         addFiles(git, files);
       }
-      return git.commit().setMessage(message).call();
+      return rw.parseCommit(git.commit().setMessage(message).call());
     }
   }
 
@@ -94,8 +93,7 @@
         .substring(1);
   }
 
-  public static void removeFiles(Git git, Set<File> files)
-      throws GitAPIException {
+  public static void removeFiles(Git git, Set<File> files) throws GitAPIException {
     RmCommand rmc = git.rm();
     for (File f : files) {
       rmc.addFilepattern(generateFilePattern(f, git));
@@ -126,40 +124,35 @@
     return MESSAGE_TRANSFORMER.apply(messages);
   }
 
-  public static List<String> transformMessages(
-      List<CommitValidationMessage> messages) {
+  public static List<String> transformMessages(List<CommitValidationMessage> messages) {
     return Lists.transform(messages, MESSAGE_TRANSFORMER);
   }
 
   public static DirCacheEntry[] createEmptyDirCacheEntries(
-      List<String> filenames, TestRepository<Repository> repo)
-      throws Exception {
+      List<String> filenames, TestRepository<Repository> repo) throws Exception {
     DirCacheEntry[] entries = new DirCacheEntry[filenames.size()];
     for (int x = 0; x < filenames.size(); x++) {
       entries[x] = createDirCacheEntry(filenames.get(x), EMPTY_CONTENT, repo);
     }
     return entries;
-
   }
 
-  public static DirCacheEntry createDirCacheEntry(String pathname,
-      byte[] content, TestRepository<Repository> repo)
-      throws Exception {
+  public static DirCacheEntry createDirCacheEntry(
+      String pathname, byte[] content, TestRepository<Repository> repo) throws Exception {
     return repo.file(pathname, repo.blob(content));
   }
 
-  public static RevCommit makeCommit(DirCacheEntry[] entries,
-      TestRepository<Repository> repo) throws Exception {
-    return makeCommit(entries, repo, (RevCommit[]) null);
+  public static RevCommit makeCommit(
+      RevWalk rw, DirCacheEntry[] entries, TestRepository<Repository> repo) throws Exception {
+    return makeCommit(rw, entries, repo, (RevCommit[]) null);
   }
 
-  public static RevCommit makeCommit(DirCacheEntry[] entries,
-      TestRepository<Repository> repo, RevCommit... parents)
+  public static RevCommit makeCommit(
+      RevWalk rw, DirCacheEntry[] entries, TestRepository<Repository> repo, RevCommit... parents)
       throws Exception {
     final RevTree ta = repo.tree(entries);
-    RevCommit c =
-        (parents == null) ? repo.commit(ta) : repo.commit(ta, parents);
+    RevCommit c = (parents == null) ? repo.commit(ta) : repo.commit(ta, parents);
     repo.parseBody(c);
-    return c;
+    return rw.parseCommit(c);
   }
 }