diff --git a/BUILD b/BUILD
index eb304bb..72c2671 100644
--- a/BUILD
+++ b/BUILD
@@ -40,6 +40,7 @@
   # resources = glob(['src/test/resources/**/*']),
   tags = ['findowners'],
   deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
+    '@commons_io//jar',
     ':find-owners-lib',
     ':find-owners-prolog-rules',
   ],
diff --git a/src/main/java/com/googlesource/gerrit/plugins/findowners/Config.java b/src/main/java/com/googlesource/gerrit/plugins/findowners/Config.java
index d7008b3..1b5bcd9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/findowners/Config.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/findowners/Config.java
@@ -32,16 +32,15 @@
   static final String MAX_CACHE_AGE = "maxCacheAge"; // seconds to stay in cache
   static final String MAX_CACHE_SIZE = "maxCacheSize"; // number of OwnersDb in cache
   static final String MIN_OWNER_VOTE_LEVEL = "minOwnerVoteLevel"; // default +1
-  static final String OWNERS_FILE_NAME = "ownersFileName"; // default "OWNERS"
+  static final String OWNERS = "OWNERS"; // Default file name
+  static final String OWNERS_FILE_NAME = "ownersFileName"; // config key for file name
+  static final String REJECT_ERROR_IN_OWNERS = "rejectErrorInOwners"; // config key for validator
   static final String REPORT_SYNTAX_ERROR = "reportSyntaxError";
 
   // Name of plugin and namespace.
   static final String PLUGIN_NAME = "find-owners";
   static final String PROLOG_NAMESPACE = "find_owners";
 
-  // Default values.
-  private static final String DEFAULT_OWNERS_FILE_NAME = "OWNERS";
-
   // Global/plugin config parameters.
   private static PluginConfigFactory config = null;
   private static boolean addDebugMsg = false;
@@ -94,18 +93,18 @@
         String name =
             config
                 .getFromProjectConfigWithInheritance(project, PLUGIN_NAME)
-                .getString(OWNERS_FILE_NAME, DEFAULT_OWNERS_FILE_NAME);
+                .getString(OWNERS_FILE_NAME, OWNERS);
         if (name.trim().equals("")) {
           log.error(
               "Project " + project.get() + " has wrong " + OWNERS_FILE_NAME + ": \"" + name + "\"");
-          return DEFAULT_OWNERS_FILE_NAME;
+          return OWNERS;
         }
         return name;
       } catch (NoSuchProjectException e) {
         log.error("Cannot find project: " + project);
       }
     }
-    return DEFAULT_OWNERS_FILE_NAME;
+    return OWNERS;
   }
 
   @VisibleForTesting
diff --git a/src/main/java/com/googlesource/gerrit/plugins/findowners/Module.java b/src/main/java/com/googlesource/gerrit/plugins/findowners/Module.java
index 9fc2709..e57bd51 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/findowners/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/findowners/Module.java
@@ -47,6 +47,7 @@
 
   @Override
   protected void configure() {
+    install(OwnersValidator.module());
     install(
         new RestApiModule() {
           @Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/findowners/OwnersValidator.java b/src/main/java/com/googlesource/gerrit/plugins/findowners/OwnersValidator.java
new file mode 100644
index 0000000..ce3b36e
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/findowners/OwnersValidator.java
@@ -0,0 +1,359 @@
+// 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.findowners;
+
+import static com.googlesource.gerrit.plugins.findowners.Config.OWNERS;
+import static com.googlesource.gerrit.plugins.findowners.Config.OWNERS_FILE_NAME;
+import static com.googlesource.gerrit.plugins.findowners.Config.REJECT_ERROR_IN_OWNERS;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Multimap;
+import com.google.gerrit.extensions.annotations.Exports;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.api.projects.ProjectConfigEntryType;
+import com.google.gerrit.extensions.registration.DynamicSet;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.account.Emails;
+import com.google.gerrit.server.config.PluginConfig;
+import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.gerrit.server.config.ProjectConfigEntry;
+import com.google.gerrit.server.events.CommitReceivedEvent;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.validators.CommitValidationException;
+import com.google.gerrit.server.git.validators.CommitValidationListener;
+import com.google.gerrit.server.git.validators.CommitValidationMessage;
+import com.google.gerrit.server.project.NoSuchProjectException;
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.jgit.diff.RawText;
+import org.eclipse.jgit.lib.FileMode;
+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 org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+
+/** Check syntax of changed OWNERS files. */
+public class OwnersValidator implements CommitValidationListener {
+  private interface TreeWalkVisitor {
+    void onVisit(TreeWalk tw);
+  }
+
+  public static AbstractModule module() {
+    return new AbstractModule() {
+      @Override
+      protected void configure() {
+        DynamicSet.bind(binder(), CommitValidationListener.class).to(OwnersValidator.class);
+        bind(ProjectConfigEntry.class)
+            .annotatedWith(Exports.named(REJECT_ERROR_IN_OWNERS))
+            .toInstance(
+                new ProjectConfigEntry(
+                    "Reject OWNERS Files With Errors",
+                    null,
+                    ProjectConfigEntryType.BOOLEAN,
+                    null,
+                    false,
+                    "Pushes of commits with errors in OWNERS files will be rejected."));
+      }
+    };
+  }
+
+  private final String pluginName;
+  private final PluginConfigFactory cfgFactory;
+  private final GitRepositoryManager repoManager;
+  private final Emails emails;
+
+  @Inject
+  OwnersValidator(
+      @PluginName String pluginName,
+      PluginConfigFactory cfgFactory,
+      GitRepositoryManager repoManager,
+      Emails emails) {
+    this.pluginName = pluginName;
+    this.cfgFactory = cfgFactory;
+    this.repoManager = repoManager;
+    this.emails = emails;
+  }
+
+  public static String getOwnersFileName(PluginConfig cfg) {
+    return getOwnersFileName(cfg, OWNERS);
+  }
+
+  public static String getOwnersFileName(PluginConfig cfg, String defaultName) {
+    return cfg.getString(OWNERS_FILE_NAME, defaultName);
+  }
+
+  public String getOwnersFileName(Project.NameKey project) {
+    String name = getOwnersFileName(cfgFactory.getFromGerritConfig(pluginName, true));
+    try {
+      return getOwnersFileName(
+          cfgFactory.getFromProjectConfigWithInheritance(project, pluginName), name);
+    } catch (NoSuchProjectException e) {
+      return name;
+    }
+  }
+
+  @VisibleForTesting
+  static boolean isActive(PluginConfig cfg) {
+    return cfg.getBoolean(REJECT_ERROR_IN_OWNERS, false);
+  }
+
+  @Override
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+      throws CommitValidationException {
+    List<CommitValidationMessage> messages = new LinkedList<>();
+    try {
+      Project.NameKey project = receiveEvent.project.getNameKey();
+      PluginConfig cfg = cfgFactory.getFromProjectConfigWithInheritance(project, pluginName);
+      if (isActive(cfg)) {
+        try (Repository repo = repoManager.openRepository(project)) {
+          String name = getOwnersFileName(project);
+          messages =
+              performValidation(repo, receiveEvent.commit, receiveEvent.revWalk, name, false);
+        }
+      }
+    } catch (NoSuchProjectException | IOException | ExecutionException e) {
+      throw new CommitValidationException("failed to check owners files", e);
+    }
+    if (hasError(messages)) {
+      throw new CommitValidationException("found invalid owners file", messages);
+    }
+    return messages;
+  }
+
+  @VisibleForTesting
+  List<CommitValidationMessage> performValidation(
+      Repository repo, RevCommit c, RevWalk revWalk, String ownersFileName, boolean verbose)
+      throws IOException, ExecutionException {
+    // Collect all messages from all files.
+    List<CommitValidationMessage> messages = new LinkedList<>();
+    // Collect all email addresses from all files and check each address only once.
+    Map<String, Set<String>> email2lines = new HashMap<>();
+    Map<String, ObjectId> content = getChangedOwners(repo, c, revWalk, ownersFileName);
+    for (String path : content.keySet()) {
+      ObjectLoader ol = revWalk.getObjectReader().open(content.get(path));
+      try (InputStream in = ol.openStream()) {
+        if (RawText.isBinary(in)) {
+          add(messages, path + " is a binary file", true); // OWNERS files cannot be binary
+          continue;
+        }
+      }
+      checkFile(messages, email2lines, path, ol, verbose);
+    }
+    checkEmails(messages, emails, email2lines, verbose);
+    return messages;
+  }
+
+  private static void checkEmails(
+      List<CommitValidationMessage> messages,
+      Emails emails,
+      Map<String, Set<String>> email2lines,
+      boolean verbose) {
+    List<String> owners = new ArrayList<>(email2lines.keySet());
+    if (verbose) {
+      for (String owner : owners) {
+        add(messages, "owner: " + owner, false);
+      }
+    }
+    if (emails == null || owners.isEmpty()) {
+      return;
+    }
+    String[] ownerEmailsAsArray = new String[owners.size()];
+    owners.toArray(ownerEmailsAsArray);
+    try {
+      Multimap<String, Account.Id> email2ids = emails.getAccountsFor(ownerEmailsAsArray);
+      for (String owner : ownerEmailsAsArray) {
+        boolean wrongEmail = (email2ids == null);
+        if (!wrongEmail) {
+          try {
+            Collection<Account.Id> ids = email2ids.get(owner);
+            wrongEmail = (ids == null || ids.size() != 1);
+          } catch (Exception e) {
+            wrongEmail = true;
+          }
+        }
+        if (wrongEmail) {
+          String locations = String.join(" ", email2lines.get(owner));
+          add(messages, "unknown: " + owner + " at " + locations, true);
+        }
+      }
+    } catch (Exception e) {
+      add(messages, "checkEmails failed.", true);
+    }
+  }
+
+  private static void checkFile(
+      List<CommitValidationMessage> messages,
+      Map<String, Set<String>> email2lines,
+      String path,
+      ObjectLoader ol,
+      boolean verbose)
+      throws IOException {
+    if (verbose) {
+      add(messages, "validate: " + path, false);
+    }
+    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++;
+        checkLine(messages, email2lines, path, line, l, verbose);
+      }
+    }
+  }
+
+  // Line patterns accepted by Parser.java in the find-owners plugin.
+  static final Pattern patComment = Pattern.compile("^ *(#.*)?$");
+  static final Pattern patEmail = // email address or a "*"
+      Pattern.compile("^ *([^ <>@]+@[^ <>@#]+|\\*) *(#.*)?$");
+  static final Pattern patFile = Pattern.compile("^ *file:.*$");
+  static final Pattern patNoParent = Pattern.compile("^ *set +noparent *(#.*)?$");
+  static final Pattern patPerFileNoParent =
+      Pattern.compile("^ *per-file +([^= ]+) *= *set +noparent *(#.*)?$");
+  static final Pattern patPerFileEmail =
+      Pattern.compile("^ *per-file +([^= ]+) *= *([^ <>@]+@[^ <>@#]+|\\*) *(#.*)?$");
+
+  private static void collectEmail(
+      Map<String, Set<String>> map, String email, String file, int lineNumber) {
+    if (!email.equals("*")) {
+      if (map.get(email) == null) {
+        map.put(email, new HashSet<>());
+      }
+      map.get(email).add(file + ":" + lineNumber);
+    }
+  }
+
+  private static boolean hasError(List<CommitValidationMessage> messages) {
+    for (CommitValidationMessage m : messages) {
+      if (m.isError()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private static void add(List<CommitValidationMessage> messages, String msg, boolean error) {
+    messages.add(new CommitValidationMessage(msg, error));
+  }
+
+  private static void checkLine(
+      List<CommitValidationMessage> messages,
+      Map<String, Set<String>> email2lines,
+      String path,
+      int lineNumber,
+      String line,
+      boolean verbose) {
+    Matcher m;
+    if (patComment.matcher(line).find()
+        || patNoParent.matcher(line).find()
+        || patPerFileNoParent.matcher(line).find()) {
+      return;
+    } else if ((m = patEmail.matcher(line)).find()) {
+      collectEmail(email2lines, m.group(1), path, lineNumber);
+    } else if ((m = patPerFileEmail.matcher(line)).find()) {
+      collectEmail(email2lines, m.group(2).trim(), path, lineNumber);
+    } else {
+      String prefix = patFile.matcher(line).find() ? "ignored" : "syntax";
+      add(messages, prefix + ": " + path + ":" + lineNumber + ": " + line, true);
+    }
+  }
+
+  /**
+   * Find all changed OWNERS files which differ between the commit and its parents. Return a map
+   * from "Path to the changed file" to "ObjectId of the file".
+   */
+  private static Map<String, ObjectId> getChangedOwners(
+      Repository repo, RevCommit c, RevWalk revWalk, String ownersFileName) throws IOException {
+    final Map<String, ObjectId> content = new HashMap<>();
+    visitChangedEntries(
+        repo,
+        c,
+        revWalk,
+        new TreeWalkVisitor() {
+          @Override
+          public void onVisit(TreeWalk tw) {
+            if (isFile(tw) && ownersFileName.equals(tw.getNameString())) {
+              content.put(tw.getPathString(), tw.getObjectId(0));
+            }
+          }
+        });
+    return content;
+  }
+
+  private static boolean isFile(TreeWalk tw) {
+    return FileMode.EXECUTABLE_FILE.equals(tw.getRawMode(0))
+        || FileMode.REGULAR_FILE.equals(tw.getRawMode(0));
+  }
+
+  /**
+   * Find all TreeWalk entries which differ between the commit and its parents. If a TreeWalk entry
+   * is found this method calls the onVisit() method of the class TreeWalkVisitor.
+   */
+  private 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) {
+        for (RevCommit p : c.getParents()) {
+          if (p.getTree() == null) {
+            revWalk.parseHeaders(p);
+          }
+          tw.addTree(p.getTree());
+        }
+        while (tw.next()) {
+          if (isDifferentToAllParents(c, tw)) {
+            visitor.onVisit(tw);
+          }
+        }
+      } else {
+        while (tw.next()) {
+          visitor.onVisit(tw);
+        }
+      }
+    }
+  }
+
+  private static boolean isDifferentToAllParents(RevCommit c, TreeWalk tw) {
+    if (c.getParentCount() > 1) {
+      for (int p = 1; p <= c.getParentCount(); p++) {
+        if (tw.getObjectId(0).equals(tw.getObjectId(p))) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+}
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 9e81e69..fa046cc 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -70,6 +70,16 @@
 If a project has already used OWNERS files for other purpose,
 the "ownersFileName" parameter can be used to change the default.
 
+## Validate OWNERS files before upload
+
+To check syntax of OWNERS files before they are uploaded,
+set the following variable in project.config files.
+
+```bash
+[plugin "find-owners"]
+    rejectErrorInOwners = true
+```
+
 ## Example 0, call `submit_filter/2`
 
 The simplest configuration adds to `rules.pl` of the root
diff --git a/src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorTest.java
new file mode 100644
index 0000000..dfbc0fa
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorTest.java
@@ -0,0 +1,314 @@
+// 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.findowners;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.googlesource.gerrit.plugins.findowners.Config.OWNERS;
+import static com.googlesource.gerrit.plugins.findowners.Config.OWNERS_FILE_NAME;
+import static com.googlesource.gerrit.plugins.findowners.Config.REJECT_ERROR_IN_OWNERS;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Lists;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.server.account.Emails;
+import com.google.gerrit.server.config.PluginConfig;
+import com.google.gerrit.server.git.validators.CommitValidationMessage;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.io.FileUtils;
+import org.eclipse.jgit.api.AddCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/** Test OwnersValidator, which checks syntax of changed OWNERS files. */
+public class OwnersValidatorTest {
+
+  private class MockedEmails extends Emails {
+    Set<String> registered;
+
+    MockedEmails() {
+      super(null, null);
+      registered =
+          ImmutableSet.of(
+              "u1@g.com", "u2@g.com", "u2.m@g.com", "user1@google.com", "u1+review@g.com");
+    }
+
+    public ImmutableSetMultimap<String, Account.Id> getAccountsFor(String... emails) {
+      // Used by checkEmails; each email should have exactly one Account.Id
+      ImmutableSetMultimap.Builder<String, Account.Id> builder = ImmutableSetMultimap.builder();
+      int id = 1000000;
+      for (String s : registered) {
+        builder.put(s, new Account.Id(++id));
+      }
+      return builder.build();
+    }
+  }
+
+  private File repoFolder;
+  private Repository repo;
+
+  @Before
+  public void init() throws IOException {
+    repoFolder = File.createTempFile("Git", "");
+    repoFolder.delete();
+    repo = FileRepositoryBuilder.create(new File(repoFolder, ".git"));
+    repo.create();
+  }
+
+  @After
+  public void cleanup() throws IOException {
+    repo.close();
+    if (repoFolder.exists()) {
+      FileUtils.deleteDirectory(repoFolder);
+    }
+  }
+
+  private static final String OWNERS_ANDROID = "OWNERS.android"; // alternative OWNERS file name
+  private static final PluginConfig ANDROID_CONFIG = createAndroidConfig(); // use OWNERS_ANDROID
+  private static final PluginConfig EMPTY_CONFIG = new PluginConfig("", new Config());
+  private static final PluginConfig ENABLED_CONFIG = createEnabledConfig(); // use OWNERS
+  private static final PluginConfig DISABLED_CONFIG = createDisabledConfig();
+
+  @Test
+  public void chekIsActiveAndFileName() throws Exception {
+    // This check should be enabled in project.config, default is not active.
+    assertThat(OwnersValidator.isActive(EMPTY_CONFIG)).isFalse();
+    assertThat(OwnersValidator.isActive(ENABLED_CONFIG)).isTrue();
+    assertThat(OwnersValidator.isActive(ANDROID_CONFIG)).isTrue();
+    assertThat(OwnersValidator.isActive(DISABLED_CONFIG)).isFalse();
+    // Default file name is "OWNERS".
+    assertThat(OwnersValidator.getOwnersFileName(EMPTY_CONFIG)).isEqualTo(OWNERS);
+    assertThat(OwnersValidator.getOwnersFileName(ENABLED_CONFIG)).isEqualTo(OWNERS);
+    assertThat(OwnersValidator.getOwnersFileName(DISABLED_CONFIG)).isEqualTo(OWNERS);
+    assertThat(OwnersValidator.getOwnersFileName(ANDROID_CONFIG)).isEqualTo(OWNERS_ANDROID);
+  }
+
+  private static final Map<String, String> FILES_WITHOUT_OWNERS =
+      ImmutableMap.of("README", "any\n", "d1/test.c", "int x;\n");
+
+  @Test
+  public void testNoOwners() throws Exception {
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, "Commit no OWNERS.", FILES_WITHOUT_OWNERS);
+      assertThat(validate(rw, c, false, ENABLED_CONFIG)).isEmpty();
+      assertThat(validate(rw, c, true, ENABLED_CONFIG)).isEmpty();
+    }
+  }
+
+  private static final Map<String, String> FILES_WITH_NO_ERROR =
+      ImmutableMap.of(
+          OWNERS,
+          "\n\n#comments ...\n  ###  more comments\n"
+              + "   user1@google.com # comment\n"
+              + "u1+review@g.com###\n"
+              + " * # everyone can approve\n"
+              + "per-file *.py =  set  noparent###\n"
+              + "per-file   *.py=u2.m@g.com\n"
+              + "per-file *.txt = * # everyone can approve\n"
+              + "set  noparent  # comment\n");
+
+  private static final Set<String> EXPECTED_VERBOSE_OUTPUT =
+      ImmutableSet.of(
+          "MSG: validate: " + OWNERS,
+          "MSG: owner: user1@google.com",
+          "MSG: owner: u1+review@g.com",
+          "MSG: owner: u2.m@g.com");
+
+  @Test
+  public void testGoodInput() throws Exception {
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, "Commit good files", FILES_WITH_NO_ERROR);
+      assertThat(validate(rw, c, false, ENABLED_CONFIG)).isEmpty();
+      assertThat(validate(rw, c, true, ENABLED_CONFIG))
+          .containsExactlyElementsIn(EXPECTED_VERBOSE_OUTPUT);
+    }
+  }
+
+  private static final Map<String, String> FILES_WITH_WRONG_SYNTAX =
+      ImmutableMap.of(
+          "README",
+          "# some content\nu2@g.com\n",
+          OWNERS,
+          "\nwrong syntax\n#comment\nuser1@google.com\n",
+          "d2/" + OWNERS,
+          "u1@g.com\nu3@g.com\n*\n",
+          "d3/" + OWNERS,
+          "\nfile: common/Owners\n");
+
+  private static final Set<String> EXPECTED_WRONG_SYNTAX =
+      ImmutableSet.of(
+          "ERROR: syntax: " + OWNERS + ":2: wrong syntax",
+          "ERROR: unknown: u3@g.com at d2/" + OWNERS + ":2",
+          "ERROR: ignored: d3/" + OWNERS + ":2: file: common/Owners");
+
+  private static final Set<String> EXPECTED_VERBOSE_WRONG_SYNTAX =
+      ImmutableSet.of(
+          "MSG: validate: d3/" + OWNERS,
+          "MSG: validate: d2/" + OWNERS,
+          "MSG: validate: " + OWNERS,
+          "MSG: owner: user1@google.com",
+          "MSG: owner: u1@g.com",
+          "MSG: owner: u3@g.com",
+          "ERROR: syntax: " + OWNERS + ":2: wrong syntax",
+          "ERROR: unknown: u3@g.com at d2/" + OWNERS + ":2",
+          "ERROR: ignored: d3/" + OWNERS + ":2: file: common/Owners");
+
+  @Test
+  public void testWrongSyntax() throws Exception {
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, "Commit wrong syntax", FILES_WITH_WRONG_SYNTAX);
+      assertThat(validate(rw, c, false, ENABLED_CONFIG))
+          .containsExactlyElementsIn(EXPECTED_WRONG_SYNTAX);
+      assertThat(validate(rw, c, true, ENABLED_CONFIG))
+          .containsExactlyElementsIn(EXPECTED_VERBOSE_WRONG_SYNTAX);
+    }
+  }
+
+  private static final Map<String, String> FILES_WITH_WRONG_EMAILS =
+      ImmutableMap.of("d1/" + OWNERS, "u1@g.com\n", "d2/" + OWNERS_ANDROID, "u2@g.com\n");
+
+  private static final Set<String> EXPECTED_VERBOSE_DEFAULT =
+      ImmutableSet.of("MSG: validate: d1/" + OWNERS, "MSG: owner: u1@g.com");
+
+  private static final Set<String> EXPECTED_VERBOSE_ANDROID =
+      ImmutableSet.of("MSG: validate: d2/" + OWNERS_ANDROID, "MSG: owner: u2@g.com");
+
+  @Test
+  public void checkWrongEmails() throws Exception {
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, "Commit Default", FILES_WITH_WRONG_EMAILS);
+      assertThat(validate(rw, c, true, ENABLED_CONFIG))
+          .containsExactlyElementsIn(EXPECTED_VERBOSE_DEFAULT);
+    }
+  }
+
+  @Test
+  public void checkAndroidOwners() throws Exception {
+    try (RevWalk rw = new RevWalk(repo)) {
+      RevCommit c = makeCommit(rw, "Commit Android", FILES_WITH_WRONG_EMAILS);
+      assertThat(validate(rw, c, true, ANDROID_CONFIG))
+          .containsExactlyElementsIn(EXPECTED_VERBOSE_ANDROID);
+    }
+  }
+
+  private static PluginConfig createEnabledConfig() {
+    PluginConfig c = new PluginConfig("", new Config());
+    c.setBoolean(REJECT_ERROR_IN_OWNERS, true);
+    return c;
+  }
+
+  private static PluginConfig createDisabledConfig() {
+    PluginConfig c = new PluginConfig("", new Config());
+    c.setBoolean(REJECT_ERROR_IN_OWNERS, false);
+    return c;
+  }
+
+  private static PluginConfig createAndroidConfig() {
+    PluginConfig c = createEnabledConfig();
+    c.setString(OWNERS_FILE_NAME, OWNERS_ANDROID);
+    return c;
+  }
+
+  private RevCommit makeCommit(RevWalk rw, String message, Map<String, String> fileStrings)
+      throws IOException, GitAPIException {
+    Map<File, byte[]> fileBytes = new HashMap<>();
+    for (String path : fileStrings.keySet()) {
+      fileBytes.put(
+          new File(repo.getDirectory().getParent(), path),
+          fileStrings.get(path).getBytes(StandardCharsets.UTF_8));
+    }
+    return makeCommit(rw, repo, message, fileBytes);
+  }
+
+  private List<String> validate(RevWalk rw, RevCommit c, boolean verbose, PluginConfig cfg)
+      throws Exception {
+    MockedEmails myEmails = new MockedEmails();
+    OwnersValidator validator = new OwnersValidator(null, null, null, myEmails);
+    String ownersFileName = OwnersValidator.getOwnersFileName(cfg);
+    List<CommitValidationMessage> m =
+        validator.performValidation(repo, c, rw, ownersFileName, verbose);
+    return transformMessages(m);
+  }
+
+  private static String generateFilePattern(File f, Git git) {
+    return f.getAbsolutePath()
+        .replace(git.getRepository().getWorkTree().getAbsolutePath(), "")
+        .substring(1);
+  }
+
+  private static void addFiles(Git git, Map<File, byte[]> files)
+      throws IOException, GitAPIException {
+    AddCommand ac = git.add();
+    for (File f : files.keySet()) {
+      if (!f.exists()) {
+        FileUtils.touch(f);
+      }
+      if (files.get(f) != null) {
+        FileUtils.writeByteArrayToFile(f, files.get(f));
+      }
+      ac = ac.addFilepattern(generateFilePattern(f, git));
+    }
+    ac.call();
+  }
+
+  private 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 rw.parseCommit(git.commit().setMessage(message).call());
+    }
+  }
+
+  private static List<String> transformMessages(List<CommitValidationMessage> messages) {
+    return Lists.transform(
+        messages,
+        new Function<CommitValidationMessage, String>() {
+          @Override
+          public String apply(CommitValidationMessage input) {
+            String pre = (input.isError()) ? "ERROR: " : "MSG: ";
+            return pre + input.getMessage();
+          }
+        });
+  }
+
+  @Test
+  public void testTransformer() {
+    List<CommitValidationMessage> messages = new LinkedList<>();
+    messages.add(new CommitValidationMessage("a message", false));
+    messages.add(new CommitValidationMessage("an error", true));
+    Set<String> expected = ImmutableSet.of("ERROR: an error", "MSG: a message");
+    assertThat(transformMessages(messages)).containsExactlyElementsIn(expected);
+  }
+}
