diff --git a/src/main/java/com/googlesource/gerrit/plugins/findowners/OwnersValidator.java b/src/main/java/com/googlesource/gerrit/plugins/findowners/OwnersValidator.java
index c36afcb..1b890a8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/findowners/OwnersValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/findowners/OwnersValidator.java
@@ -14,6 +14,7 @@
 
 package com.googlesource.gerrit.plugins.findowners;
 
+import static com.google.common.base.Strings.isNullOrEmpty;
 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;
@@ -31,6 +32,7 @@
 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;
@@ -38,6 +40,7 @@
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -49,6 +52,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 import org.eclipse.jgit.diff.RawText;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.ObjectId;
@@ -85,14 +89,17 @@
 
   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.repoManager = repoManager;
     this.cfgFactory = cfgFactory;
     this.emails = emails;
   }
@@ -121,169 +128,269 @@
   }
 
   @Override
-  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
+  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent event)
       throws CommitValidationException {
-    List<CommitValidationMessage> messages = new ArrayList<>();
+    Checker checker = new Checker(event, false);
     try {
-      Project.NameKey project = receiveEvent.project.getNameKey();
+      Project.NameKey project = event.project.getNameKey();
       PluginConfig cfg = cfgFactory.getFromProjectConfigWithInheritance(project, pluginName);
       if (isActive(cfg)) {
-        String name = getOwnersFileName(project);
-        messages = performValidation(receiveEvent.commit, receiveEvent.revWalk, name, false);
+        checker.check(getOwnersFileName(project));
       }
     } catch (NoSuchProjectException | IOException e) {
       throw new CommitValidationException("failed to check owners files", e);
     }
-    if (hasError(messages)) {
-      add(messages, "See OWNERS file syntax document at "
+    if (checker.hasError()) {
+      checker.addError("See OWNERS file syntax document at "
           + "https://gerrit.googlesource.com/plugins/find-owners/+/"
-          + "master/src/main/resources/Documentation/syntax.md", true);
-      throw new CommitValidationException("found invalid owners file", messages);
+          + "master/src/main/resources/Documentation/syntax.md");
+      throw new CommitValidationException("found invalid owners file", checker.messages);
     }
-    return messages;
+    return checker.messages;
   }
 
-  @VisibleForTesting
-  List<CommitValidationMessage> performValidation(
-      RevCommit c, RevWalk revWalk, String ownersFileName, boolean verbose) throws IOException {
-    // Collect all messages from all files.
-    List<CommitValidationMessage> messages = new ArrayList<>();
+  class Checker {
+    // An inner class to keep needed data specific to one commit event.
+    CommitReceivedEvent event;
+    boolean verbose;
+    List<CommitValidationMessage> messages;
+    Map<String, ObjectId> allFiles; // changedFilePath => ObjectId
+    Map<String, String> readFiles; // project:file => content
+    Set<String> checkedFiles; // project:file
     // 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(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;
-  }
+    Map<String, Set<String>> email2lines;
 
-  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);
+    Checker(CommitReceivedEvent event, boolean verbose) {
+      this.event = event;
+      this.verbose = verbose;
+      messages = new ArrayList<>();
+      readFiles = new HashMap<>();
+      checkedFiles = new HashSet<>();
+      email2lines = new HashMap<>();
+      try {
+        allFiles = getChangedFiles(event.commit, event.revWalk);
+      } catch (Exception e) {
+        allFiles = new HashMap<>();
+        addError("getChangedFiles failed.");
       }
     }
-    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.isEmpty());
-          } catch (Exception e) {
-            wrongEmail = true;
+
+    @VisibleForTesting
+    void check(String ownersFileName) throws IOException {
+      Map<String, ObjectId> ownerFiles =
+          allFiles.entrySet().stream()
+          .filter(e -> ownersFileName.equals(new File(e.getKey()).getName()))
+          .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
+      String projectName = event.project.getName();
+      for (String path : ownerFiles.keySet()) {
+        String key = projectName + ":" + path;
+        ObjectLoader ol = event.revWalk.getObjectReader().open(ownerFiles.get(path));
+        try (InputStream in = ol.openStream()) {
+          if (RawText.isBinary(in)) {
+            addError(path + " is a binary file"); // OWNERS files cannot be binary
+            continue;
           }
         }
-        if (wrongEmail) {
-          String locations = String.join(" ", email2lines.get(owner));
-          add(messages, "unknown: " + owner + " at " + locations, true);
+        checkedFiles.add(key);
+        checkFile(projectName, path, ol);
+      }
+      checkEmails(emails);
+    }
+
+    void checkEmails(Emails emails) {
+      List<String> owners = new ArrayList<>(email2lines.keySet());
+      if (owners.isEmpty()) {
+        return;
+      }
+      if (verbose) {
+        for (String owner : owners) {
+          addMsg("owner: " + owner);
         }
       }
-    } 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);
+      if (emails == null) {
+        addError("cannot check owner emails with null Emails cache.");
+      }
+      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.isEmpty());
+            } catch (Exception e) {
+              wrongEmail = true;
+            }
+          }
+          if (wrongEmail) {
+            String locations = String.join(" ", email2lines.get(owner));
+            addError("unknown: " + owner + " at " + locations);
+          }
+        }
+      } catch (Exception e) {
+        addError("checkEmails failed.");
       }
     }
-  }
 
-  private static void collectEmail(
-      Map<String, Set<String>> map, String email, String file, int lineNumber) {
-    if (!email.equals("*")) {
-      map.computeIfAbsent(email, (String k) -> new HashSet<>());
-      map.get(email).add(file + ":" + lineNumber);
+    void checkFile(String project, String path, String[] lines) {
+      addVerboseMsg("checking " + path);
+      int num = 0;
+      for (String line : lines) {
+        checkLine(project, path, ++num, line);
+      };
     }
-  }
 
-  private static boolean hasError(List<CommitValidationMessage> messages) {
-    for (CommitValidationMessage m : messages) {
-      if (m.isError()) {
-        return true;
+    void checkFile(String project, String path, String content) {
+      checkFile(project, path, content.split("\\R"));
+    }
+
+    void checkFile(String project, String path, ObjectLoader ol) {
+      try {
+        BufferedReader reader = new BufferedReader(
+            new InputStreamReader(ol.openStream(), StandardCharsets.UTF_8));
+        checkFile(project, path, reader.lines().toArray(String[]::new));
+      } catch (Exception e) {
+        addError("cannot open file: " + path);
       }
     }
-    return false;
-  }
 
-  private static void add(List<CommitValidationMessage> messages, String msg, boolean error) {
-    messages.add(new CommitValidationMessage(msg, error));
-  }
+    private void collectEmail(String email, String project, String file, int lineNumber) {
+      if (!email.equals("*")) {
+        email2lines.computeIfAbsent(email, (String k) -> new HashSet<>());
+        email2lines.get(email).add(qualifiedPath(project, file) + ":" + lineNumber);
+      }
+    }
 
-  private static void checkIncludeOrFile(
-      List<CommitValidationMessage> messages, String path, int num, String line) {
-    // TODO: Check if an included file exists and that it has valid syntax.
-    // An included file could be a new file added by a CL and not in the repository yet
-    add(messages, "unchecked: " + path + ":" + num + ": " + Parser.getIncludeOrFile(line), false);
-  }
-
-  private static void checkLine(
-      List<CommitValidationMessage> messages,
-      Map<String, Set<String>> email2lines,
-      String path,
-      int lineNumber,
-      String line) {
-    String email;
-    String[] emails;
-    if (Parser.isComment(line) || Parser.isNoParent(line)) {
-      // no email address to check
-    } else if ((email = Parser.parseEmail(line)) != null) {
-      collectEmail(email2lines, email, path, lineNumber);
-    } else if ((emails = Parser.parsePerFileOwners(line)) != null) {
-      for (String e : emails) {
-        if (e.startsWith("file:")) {
-          checkIncludeOrFile(messages, path, lineNumber, line);
-        } else if (!e.equals(Parser.TOK_SET_NOPARENT)) {
-          collectEmail(email2lines, e, path, lineNumber);
+    private boolean hasError() {
+      for (CommitValidationMessage m : messages) {
+        if (m.isError()) {
+          return true;
         }
       }
-    } else if (Parser.isInclude(line)) {
-      checkIncludeOrFile(messages, path, lineNumber, line);
-    } else {
-      add(messages, "syntax: " + path + ":" + lineNumber + ": " + line, true);
+      return false;
     }
-  }
+
+    void addError(String msg) {
+      messages.add(new CommitValidationMessage(msg, true));
+    }
+
+    String qualifiedPath(String project, String path) {
+      return event.project.getName().equals(project) ? path : (project + ":" + path);
+    }
+
+    void addSyntaxError(String path, int lineNumber, String line) {
+      addError("syntax: " + path + ":" + lineNumber + ": " + line);
+    }
+
+    void addMsg(String msg) {
+      messages.add(new CommitValidationMessage(msg, false));
+    }
+
+    void addVerboseMsg(String msg) {
+      if (verbose) {
+        addMsg(msg);
+      }
+    }
+
+    String normalizeChangedFilePath(String dir, String file) {
+      try {
+        if (file.startsWith("/")) {
+          file = new File(file).getCanonicalPath();
+        } else {
+          file = new File("/" + dir + "/" + file).getCanonicalPath();
+        }
+      } catch (IOException e) {
+        addError("cannot build file path " + dir + ":" + file);
+      }
+      return file.startsWith("/") ? file.substring(1) : file;
+    }
+
+    /**
+     * Check if an included file exists and with valid syntax.
+     * An included file could be (1) in the current CL, (2) in the same repository,
+     * (3) in a different repository, (4) in another CL.
+     * Case (4) is not checked yet.
+     */
+    void checkIncludeOrFile(String project, String path, int num, String line) {
+      // project is the including file's project, not necessarily the same as CL event's.
+      String directive = Parser.getIncludeOrFile(line);
+      String[] KPF = Parser.parseInclude(project, directive);
+      if (KPF == null || KPF[1] == null || KPF[2] == null) {
+        addSyntaxError(qualifiedPath(project, path), num, line);
+      }
+      String file = KPF[2];
+      String curDir = Util.getParentDir(path);
+      String repoFile = normalizeChangedFilePath(curDir, file);
+      // Check each file only once.
+      String key = KPF[1] + ":" + repoFile;
+      if (checkedFiles.contains(key)) {
+        addVerboseMsg("skip repeated include of " + key);
+        return;
+      }
+      checkedFiles.add(key);
+      if (KPF[1].equals(event.project.getName())) {
+        if (allFiles.get(repoFile) != null) {
+          // Case (1): included file is in current CL.
+          addVerboseMsg("check changed file " + key);
+          try {
+            ObjectLoader ol = event.revWalk.getObjectReader().open(allFiles.get(repoFile));
+            try (InputStream in = ol.openStream()) {
+              if (RawText.isBinary(in)) {
+                addError(path + " is a binary file"); // OWNERS files cannot be binary
+                return;
+              }
+            }
+            checkFile(KPF[1], repoFile, ol);
+          } catch (Exception e) {
+            addError("cannot open changed file: " + path);
+          }
+          return;
+        }
+      }
+      // Included file is in repository or other CL.
+      addVerboseMsg("check repo file " + key);
+      String content = OwnersDb.getRepoFile(readFiles, repoManager, KPF[1],
+          event.refName, repoFile, new ArrayList<>());
+      if (isNullOrEmpty(content)) {
+        addVerboseMsg("cannot find file: " + key);
+        // unchecked: including-file-path : line number : source line
+        addMsg("unchecked: " + qualifiedPath(project, path) + ":" + num + ": " + directive);
+      } else {
+        checkFile(KPF[1], repoFile, content);
+      }
+    }
+
+    void checkLine(String project, String path, int lineNumber, String line) {
+      String email;
+      String[] owners;
+      if (Parser.isComment(line) || Parser.isNoParent(line)) {
+        // no email address to check
+      } else if ((email = Parser.parseEmail(line)) != null) {
+        collectEmail(email, project, path, lineNumber);
+      } else if ((owners = Parser.parsePerFileOwners(line)) != null) {
+        for (String owner: owners) {
+          if (owner.startsWith("file:")) {
+            // Pass the whole line, not just owner, to report any syntax error.,
+            checkIncludeOrFile(project, path, lineNumber, line);
+          } else if (!owner.equals(Parser.TOK_SET_NOPARENT)) {
+            collectEmail(owner, project, path, lineNumber);
+          }
+        }
+      } else if (Parser.isInclude(line)) {
+        checkIncludeOrFile(project, path, lineNumber, line);
+      } else {
+        addSyntaxError(qualifiedPath(project, path), lineNumber, line);
+      }
+    }
+  } // end of inner class Checker
 
   /**
-   * 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".
+   * Return a map from "Path to changed file" to "ObjectId of the file".
    */
-  private static Map<String, ObjectId> getChangedOwners(
-      RevCommit c, RevWalk revWalk, String ownersFileName) throws IOException {
+  private static Map<String, ObjectId> getChangedFiles(
+      RevCommit c, RevWalk revWalk) throws IOException {
     final Map<String, ObjectId> content = new HashMap<>();
     visitChangedEntries(
         c,
@@ -291,7 +398,8 @@
         new TreeWalkVisitor() {
           @Override
           public void onVisit(TreeWalk tw) {
-            if (isFile(tw) && ownersFileName.equals(tw.getNameString())) {
+            // getPathString() returns path names without leading "/"
+            if (isFile(tw)) {
               content.put(tw.getPathString(), tw.getObjectId(0));
             }
           }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorIT.java
similarity index 65%
rename from src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorTest.java
rename to src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorIT.java
index c294f30..8587b35 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/findowners/OwnersValidatorIT.java
@@ -25,10 +25,18 @@
 import com.google.common.collect.ImmutableSetMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
+import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.TestPlugin;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.extensions.api.changes.SubmitInput;
 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.events.CommitReceivedEvent;
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
+import com.google.inject.Inject;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
@@ -51,15 +59,44 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
 
 /** Test OwnersValidator, which checks syntax of changed OWNERS files. */
-@RunWith(JUnit4.class)
-public class OwnersValidatorTest {
+@TestPlugin(name = "find-owners", sysModule = "com.googlesource.gerrit.plugins.findowners.Module")
+public class OwnersValidatorIT extends LightweightPluginDaemonTest {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
   @Rule public Watcher watcher = new Watcher(logger);
 
+  @Inject private ProjectOperations projectOperations;
+
+  protected Project.NameKey newProject(String name) {
+    return projectOperations.newProject().parent(new Project.NameKey("All-Projects")).
+        name(name).create();
+  }
+
+  private void switchProject(Project.NameKey p) throws Exception {
+    project = p;
+    testRepo = cloneProject(project);
+  }
+
+  private void addProjectFile(
+      String project, String file, String content) throws Exception {
+    switchProject(newProject(project));
+    PushOneCommit.Result c = createChange("c", file, content);
+    approve(c.getChangeId());
+    gApi.changes().id(c.getChangeId()).current().submit(new SubmitInput());
+  }
+
+  private static class MockedCommitReceivedEvent extends CommitReceivedEvent {
+    MockedCommitReceivedEvent(String project, RevWalk revWalk, RevCommit commit) {
+      this.project = new Project(new Project.NameKey(project));
+      this.revWalk = revWalk;
+      this.commit = commit;
+      this.refName = "master";
+    }
+  }
+
   private static class MockedEmails extends Emails {
     Set<String> registered;
 
@@ -126,25 +163,26 @@
 
   @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();
-    }
+    CommitReceivedEvent event = makeCommitEvent("myTest", "no OWNERS.", FILES_WITHOUT_OWNERS);
+    assertThat(validate(event, false, ENABLED_CONFIG)).isEmpty();
+    assertThat(validate(event, true, ENABLED_CONFIG)).isEmpty();
   }
 
   private static final String[] INCLUDE_STMTS = new String[]{
       "  include  p1/p2 : /d1/owners",
-      "include  p1/p2://d1/owners #comment",
+      "include  p2/p1://d1/owners #comment",
       "include ../d2/owners",
       " per-file *.java = file:  //d2/OWNERS.java #",
       "per-file *.cpp,*cc=file:p1/p2:/c++owners",
-      "  file:   p1/p2 : /d1/owners ",
-      "file:  p1/p2://d1/owners #comment",
-      "file: ../d2/owners",
-      "file: //OWNERS",
+      "  file:   p1/p2 : /d1/owners ",  // repeated
+      "file:  p3/p2://d1/owners #comment",
+      "file: ../d2/owners",  // repeated
+      "file: //OWNERS",  // recursive inclusion
       "file:///OWNERS.android"};
 
+  private static final ImmutableSet<String> SKIP_INCLUDE_STMTS =
+      ImmutableSet.of("  file:   p1/p2 : /d1/owners ", "file: ../d2/owners", "file: //OWNERS");
+
   private static String allIncludeStatements() {
     String statement = "";
     for (String s: INCLUDE_STMTS) {
@@ -156,8 +194,10 @@
   private static Set<String> allIncludeMsgs() {
     Set<String> msgs = new HashSet<>();
     for (int i = 0; i < INCLUDE_STMTS.length; i++) {
-      msgs.add("MSG: unchecked: OWNERS:" + (i + 1)
-          + ": " + Parser.getIncludeOrFile(INCLUDE_STMTS[i]));
+      if (!SKIP_INCLUDE_STMTS.contains(INCLUDE_STMTS[i])) {
+        msgs.add("MSG: unchecked: OWNERS:" + (i + 1)
+            + ": " + Parser.getIncludeOrFile(INCLUDE_STMTS[i]));
+      }
     }
     return msgs;
   };
@@ -178,11 +218,32 @@
 
   private static Set<String> allVerboseMsgs() {
     Set<String> msgs = allIncludeMsgs();
-    msgs.add("MSG: validate: " + OWNERS);
+    msgs.add("MSG: checking " + OWNERS);
     msgs.add("MSG: owner: u1+review@g.com");
     msgs.add("MSG: owner: u1@g.com");
     msgs.add("MSG: owner: u2.m@g.com");
     msgs.add("MSG: owner: user1@google.com");
+    String[] missing = new String[]{
+        "p1/p2:OWNERS.android",
+        "p1/p2:c++owners",
+        "p1/p2:d1/owners",
+        "p1/p2:d2/OWNERS.java",
+        "p1/p2:d2/owners",
+        "p2/p1:d1/owners",
+        "p3/p2:d1/owners",
+    };
+    for (String s : missing) {
+      msgs.add("MSG: cannot find file: " + s);
+      msgs.add("MSG: check repo file " + s);
+    }
+    String[] skips = new String[]{
+        "p1/p2:OWNERS",
+        "p1/p2:d1/owners",
+        "p1/p2:d2/owners",
+    };
+    for (String s : skips) {
+      msgs.add("MSG: skip repeated include of " + s);
+    }
     return msgs;
   };
 
@@ -193,13 +254,11 @@
 
   @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))
-          .containsExactlyElementsIn(EXPECTED_NON_VERBOSE_OUTPUT);
-      assertThat(validate(rw, c, true, ENABLED_CONFIG))
-          .containsExactlyElementsIn(EXPECTED_VERBOSE_OUTPUT);
-    }
+    CommitReceivedEvent event = makeCommitEvent("p1/p2", "good files", FILES_WITH_NO_ERROR);
+    assertThat(validate(event, false, ENABLED_CONFIG))
+        .containsExactlyElementsIn(EXPECTED_NON_VERBOSE_OUTPUT);
+    assertThat(validate(event, true, ENABLED_CONFIG))
+        .containsExactlyElementsIn(EXPECTED_VERBOSE_OUTPUT);
   }
 
   private static final ImmutableMap<String, String> FILES_WITH_WRONG_SYNTAX =
@@ -211,7 +270,6 @@
           "d2/" + OWNERS,
           "u1@g.com\n\nu3@g.com\n*\n");
 
-
   private static final ImmutableSet<String> EXPECTED_WRONG_SYNTAX =
       ImmutableSet.of(
           "ERROR: syntax: " + OWNERS + ":4: wrong syntax",
@@ -219,8 +277,8 @@
 
   private static final ImmutableSet<String> EXPECTED_VERBOSE_WRONG_SYNTAX =
       ImmutableSet.of(
-          "MSG: validate: d2/" + OWNERS,
-          "MSG: validate: " + OWNERS,
+          "MSG: checking d2/" + OWNERS,
+          "MSG: checking " + OWNERS,
           "MSG: owner: user1@google.com",
           "MSG: owner: u1@g.com",
           "MSG: owner: u3@g.com",
@@ -229,40 +287,51 @@
 
   @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);
-    }
+    CommitReceivedEvent event = makeCommitEvent("p1/p2", "wrong syntax", FILES_WITH_WRONG_SYNTAX);
+    assertThat(validate(event, false, ENABLED_CONFIG))
+        .containsExactlyElementsIn(EXPECTED_WRONG_SYNTAX);
+    assertThat(validate(event, true, ENABLED_CONFIG))
+        .containsExactlyElementsIn(EXPECTED_VERBOSE_WRONG_SYNTAX);
   }
 
   private static final ImmutableMap<String, String> FILES_WITH_WRONG_EMAILS =
       ImmutableMap.of("d1/" + OWNERS, "u1@g.com\n", "d2/" + OWNERS_ANDROID, "u2@g.com\n");
 
   private static final ImmutableSet<String> EXPECTED_VERBOSE_DEFAULT =
-      ImmutableSet.of("MSG: validate: d1/" + OWNERS, "MSG: owner: u1@g.com");
+      ImmutableSet.of("MSG: checking d1/" + OWNERS, "MSG: owner: u1@g.com");
 
   private static final ImmutableSet<String> EXPECTED_VERBOSE_ANDROID =
-      ImmutableSet.of("MSG: validate: d2/" + OWNERS_ANDROID, "MSG: owner: u2@g.com");
+      ImmutableSet.of("MSG: checking 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);
-    }
+    CommitReceivedEvent event = makeCommitEvent("test", "default", FILES_WITH_WRONG_EMAILS);
+    assertThat(validate(event, 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);
-    }
+    CommitReceivedEvent event = makeCommitEvent("test", "Android", FILES_WITH_WRONG_EMAILS);
+    assertThat(validate(event, true, ANDROID_CONFIG))
+        .containsExactlyElementsIn(EXPECTED_VERBOSE_ANDROID);
+  }
+
+  @Test
+  public void simpleIncludeTest() throws Exception {
+    addProjectFile("p1", "d2/owners", "wrong\nxyz\n");
+    addProjectFile("p2", "d2/owners", "x@g.com\nerr\ninclude ../d2/owners\n");
+    ImmutableMap<String, String> files =
+        ImmutableMap.of(
+            "d1/" + OWNERS, "include ../d2/owners\ninclude /d2/owners\n"
+            + "include p1:/d2/owners\ninclude p2:/d2/owners\n");
+    ImmutableSet<String> expected = ImmutableSet.of(
+       "ERROR: unknown: x@g.com at p2:d2/owners:1",
+       "ERROR: syntax: p2:d2/owners:2: err",
+       "ERROR: syntax: d2/owners:1: wrong",
+       "ERROR: syntax: d2/owners:2: xyz");
+    CommitReceivedEvent event = makeCommitEvent("p1", "T", files);
+    assertThat(validate(event, false, ENABLED_CONFIG)).containsExactlyElementsIn(expected);
   }
 
   private static PluginConfig createEnabledConfig() {
@@ -305,13 +374,19 @@
     }
   }
 
-  private List<String> validate(RevWalk rw, RevCommit c, boolean verbose, PluginConfig cfg)
+  private CommitReceivedEvent makeCommitEvent(
+      String project, String message, Map<String, String> fileStrings) throws Exception {
+    RevWalk rw = new RevWalk(repo);
+    return new MockedCommitReceivedEvent(project, rw, makeCommit(rw, message, fileStrings));
+  }
+
+  private List<String> validate(CommitReceivedEvent event, boolean verbose, PluginConfig cfg)
       throws Exception {
-    MockedEmails myEmails = new MockedEmails();
-    OwnersValidator validator = new OwnersValidator(null, null, myEmails);
-    String ownersFileName = OwnersValidator.getOwnersFileName(cfg);
-    List<CommitValidationMessage> m = validator.performValidation(c, rw, ownersFileName, verbose);
-    return transformMessages(m);
+    OwnersValidator validator =
+        new OwnersValidator("find-owners", pluginConfig, repoManager, new MockedEmails());
+    OwnersValidator.Checker checker = validator.new Checker(event, verbose);
+    checker.check(OwnersValidator.getOwnersFileName(cfg));
+    return transformMessages(checker.messages);
   }
 
   private static String generateFilePattern(File f, Git git) {
