diff --git a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/EventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/EventHandler.java
new file mode 100644
index 0000000..5925ec0
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/EventHandler.java
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 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.repositoryuse;
+
+import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
+
+import com.google.inject.Inject;
+
+public class EventHandler implements GitReferenceUpdatedListener {
+  RefUpdateHandlerFactory refUpdateHandlerFactory;
+
+  @Inject
+  public EventHandler(RefUpdateHandlerFactory refUpdateHandlerFactory) {
+    this.refUpdateHandlerFactory = refUpdateHandlerFactory;
+  }
+
+  @Override
+  public void onGitReferenceUpdated(Event event) {
+    RefUpdate update = new RefUpdate(event);
+    refUpdateHandlerFactory.create(update).run();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/Module.java b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/Module.java
index 4c7b822..1a97a63 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/Module.java
@@ -20,16 +20,20 @@
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.internal.UniqueAnnotations;
 
 public class Module extends AbstractModule {
   @Override
   protected void configure() {
     DynamicSet.bind(binder(), GitReferenceUpdatedListener.class)
-        .to(RefUpdateHandler.class);
+        .to(EventHandler.class);
     requestStaticInjection(Config.class);
     requestStaticInjection(Ref.Table.class);
     requestStaticInjection(Usage.Table.class);
+    install(new FactoryModuleBuilder()
+        .implement(RefUpdateHandler.class, RefUpdateHandlerImpl.class)
+        .build(RefUpdateHandlerFactory.class));
     bind(LifecycleListener.class).annotatedWith(UniqueAnnotations.create())
         .to(SQLDriver.class);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdate.java b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdate.java
new file mode 100644
index 0000000..a9a3923
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdate.java
@@ -0,0 +1,73 @@
+// Copyright (C) 2015 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.repositoryuse;
+
+import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
+
+import org.eclipse.jgit.lib.ObjectId;
+
+public class RefUpdate {
+  private String projectName;
+  private String refName;
+  private String oldObjectId;
+  private String newObjectId;
+  private boolean isCreate;
+  private boolean isDelete;
+
+  public RefUpdate(String projectName, String refName, String oldObjectId,
+      String newObjectId) {
+    this.projectName = projectName;
+    this.refName = refName;
+    this.oldObjectId = oldObjectId;
+    this.newObjectId = newObjectId;
+    this.isCreate = oldObjectId.equals(ObjectId.zeroId().name());
+    this.isDelete = newObjectId.equals(ObjectId.zeroId().name());
+  }
+
+  public RefUpdate(GitReferenceUpdatedListener.Event event) {
+    this.projectName = event.getProjectName();
+    this.refName = event.getRefName();
+    this.oldObjectId = event.getOldObjectId();
+    this.newObjectId = event.getNewObjectId();
+    // TODO: could use event.isCreate() / isDelete() hree, but keep
+    // some compatibility with Gerrit 2.11
+    this.isCreate = oldObjectId.equals(ObjectId.zeroId().name());
+    this.isDelete = newObjectId.equals(ObjectId.zeroId().name());
+  }
+
+  public String getProjectName() {
+    return projectName;
+  }
+
+  public String getRefName() {
+    return refName;
+  }
+
+  public String getOldObjectId() {
+    return oldObjectId;
+  }
+
+  public String getNewObjectId() {
+    return newObjectId;
+  }
+
+  public boolean isCreate() {
+    return isCreate;
+  }
+
+  public boolean isDelete() {
+    return isDelete;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandler.java b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandler.java
index f3685b2..e56417d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandler.java
@@ -14,279 +14,6 @@
 
 package com.googlesource.gerrit.plugins.repositoryuse;
 
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.config.CanonicalWebUrl;
-import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.inject.Inject;
-
-import org.eclipse.jgit.diff.DiffEntry;
-import org.eclipse.jgit.diff.DiffFormatter;
-import org.eclipse.jgit.diff.RawTextComparator;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.ObjectLoader;
-import org.eclipse.jgit.lib.ObjectReader;
-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.submodule.SubmoduleWalk;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.util.io.DisabledOutputStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class RefUpdateHandler implements GitReferenceUpdatedListener {
-
-  private static final Logger log =
-      LoggerFactory.getLogger(RefUpdateHandler.class);
-  private final GitRepositoryManager repoManager;
-  private final String serverName;
-
-  @Inject
-  RefUpdateHandler(GitRepositoryManager repoManager,
-      @CanonicalWebUrl String canonicalWebUrl) {
-    this.repoManager = repoManager;
-    if (canonicalWebUrl != null) {
-      try {
-        URL url = new URL(canonicalWebUrl);
-        canonicalWebUrl = url.getHost();
-      } catch (MalformedURLException e) {
-        log.warn("Could not parse canonicalWebUrl", e);
-      }
-    }
-    this.serverName = canonicalWebUrl;
-  }
-
-  @Override
-  public void onGitReferenceUpdated(Event event) {
-    if (event.isDelete() && event.getRefName().startsWith(Constants.R_HEADS)
-        || event.getRefName().startsWith(Constants.R_TAGS)) {
-      // Ref was deleted... clean up any references
-      Ref ref = Ref.fetchByRef(event.getProjectName(), event.getRefName());
-      if (ref != null) {
-        ref.delete();
-      }
-      if (event.getRefName().startsWith(Constants.R_HEADS)) {
-        // Also clean up uses from this ref
-        Usage.deleteByBranch(getCanonicalProject(event.getProjectName()),
-            event.getRefName());
-      }
-    } else if (event.getRefName().startsWith(Constants.R_TAGS)) {
-      Ref updatedRef = new Ref(event.getProjectName(), event.getRefName(),
-          event.getNewObjectId());
-      updatedRef.save();
-    } else if (event.getRefName().startsWith(Constants.R_HEADS)) {
-      Ref updatedRef = new Ref(event.getProjectName(), event.getRefName(),
-          event.getNewObjectId());
-      updatedRef.save();
-      Project.NameKey nameKey = new Project.NameKey(event.getProjectName());
-      try {
-        if (Config.refreshAllSubmodules() || event.isCreate()
-            || isSubmoduleUpdate(event, nameKey)) {
-          Map<String, String> submodules = getSubmodules(event, nameKey);
-          updateProjects(event.getProjectName(), event.getRefName(),
-              submodules);
-        }
-        if (Config.parseManifests()) {
-          parseManifests(event, nameKey);
-        }
-      } catch (IOException e) {
-        log.error(e.getMessage(), e);
-      }
-    }
-  }
-
-  private void parseManifests(Event event, Project.NameKey project)
-      throws RepositoryNotFoundException, IOException {
-    if (event.isDelete()) {
-      return;
-    }
-    try (Repository repo = repoManager.openRepository(project)) {
-      try (RevWalk walk = new RevWalk(repo); TreeWalk tw = new TreeWalk(repo)) {
-        RevCommit commit =
-            walk.parseCommit(repo.resolve(event.getNewObjectId()));
-
-        tw.setRecursive(false);
-        tw.addTree(commit.getTree());
-        ObjectReader or = tw.getObjectReader();
-        while (tw.next()) {
-          String path = tw.getPathString();
-          if (path.endsWith(".xml")) {
-            ManifestParser mp = new ManifestParser();
-            ObjectLoader ol = or.open(tw.getObjectId(0));
-            if (!ol.isLarge()) {
-              Map<String, String> tmp = mp.parseManifest(ol.getBytes());
-              HashMap<String, String> projects = new HashMap<>();
-              for (String key : tmp.keySet()) {
-                projects
-                    .put(
-                        normalizePath(String.format("%s:%s",
-                            event.getProjectName(), path), key, true),
-                    tmp.get(key));
-              }
-              updateProjects(
-                  String.format("%s:%s", event.getProjectName(), path),
-                  event.getRefName(), projects);
-            } else {
-              log.warn(String.format("%s is too large, skipping manifest parse",
-                  tw.getPathString()));
-            }
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Has a submodule been updated?
-   *
-   * @param event the Event
-   * @return True if a submodule update occurred, otherwise False.
-   */
-  private boolean isSubmoduleUpdate(Event event, Project.NameKey project)
-      throws RepositoryNotFoundException, IOException {
-    if (event.isDelete()) {
-      return false;
-    }
-    try (Repository repo = repoManager.openRepository(project)) {
-      try (RevWalk walk = new RevWalk(repo);
-          DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE)) {
-        RevTree aTree = null;
-        if (!event.isCreate()) {
-          // If this is a new ref, we can't get the original commit.
-          // We can still use the DiffFormatter to give us what changed
-          // by passing null, however.
-          RevCommit aCommit =
-              walk.parseCommit(repo.resolve(event.getOldObjectId()));
-          aTree = aCommit.getTree();
-        }
-        RevCommit bCommit =
-            walk.parseCommit(repo.resolve(event.getNewObjectId()));
-        RevTree bTree = bCommit.getTree();
-
-        df.setRepository(repo);
-        df.setDiffComparator(RawTextComparator.DEFAULT);
-        df.setDetectRenames(true);
-        List<DiffEntry> diffEntries = df.scan(aTree, bTree);
-        for (DiffEntry de : diffEntries) {
-          FileMode oldMode = de.getOldMode();
-          FileMode newMode = de.getNewMode();
-          if ((oldMode != null && oldMode == FileMode.GITLINK)
-              || (newMode != null && newMode == FileMode.GITLINK)) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  private Map<String, String> getSubmodules(Event event,
-      Project.NameKey project) throws RepositoryNotFoundException, IOException {
-    HashMap<String, String> submodules = new HashMap<>();
-    try (Repository repo = repoManager.openRepository(project)) {
-      try (RevWalk walk = new RevWalk(repo);
-          SubmoduleWalk sw = new SubmoduleWalk(repo)) {
-        RevCommit commit =
-            walk.parseCommit(repo.resolve(event.getNewObjectId()));
-        sw.setTree(commit.getTree());
-        sw.setRootTree(commit.getTree());
-        while (sw.next()) {
-          submodules.put(
-              normalizePath(event.getProjectName(), sw.getModulesUrl(), false),
-              sw.getObjectId().name());
-        }
-      } catch (ConfigInvalidException e) {
-        log.warn("Invalid .gitmodules configuration while parsing "
-            + event.getProjectName());
-      }
-    }
-    return submodules;
-  }
-
-  private void updateProjects(String project, String branch,
-      Map<String, String> projects) {
-    String canonicalProject = getCanonicalProject(project);
-    List<Usage> uses = Usage.fetchByProject(canonicalProject, branch);
-    for (Usage use : uses) {
-      if (!projects.containsKey(use.getDestination())) {
-        // No longer exists; delete.
-        use.delete();
-      } else {
-        // Update SHA1 here.
-        use.setRef(projects.get(use.getDestination()));
-        use.save();
-        projects.remove(use.getDestination());
-      }
-    }
-    // At this point, submodules only contains new elements.
-    // Create them.
-    for (String key : projects.keySet()) {
-      Usage use = new Usage(canonicalProject, branch, key, projects.get(key));
-      use.save();
-    }
-  }
-
-  private String getCanonicalProject(String project) {
-    String canonicalProject =
-        String.format("https://%s/%s", serverName, project);
-    try {
-      URL url = new URL(canonicalProject);
-      canonicalProject = url.getHost() + url.getPath();
-    } catch (MalformedURLException e) {
-      log.warn("Could not parse project as URL: " + canonicalProject);
-    }
-    return canonicalProject;
-  }
-
-  private String normalizePath(String project, String destination,
-      boolean isManifest) {
-    String originalProject =
-        isManifest ? project.substring(0, project.lastIndexOf(":")) : project;
-
-    // Handle relative and absolute paths on the same server
-    if (destination.startsWith("/")) {
-      if (serverName != null) {
-        destination = serverName + destination;
-      } else {
-        log.warn("Could not parse absolute path; canonicalWebUrl not set");
-      }
-    } else if (destination.startsWith(".")) {
-      if (serverName != null) {
-        Path path = Paths.get(String.format("/%s/%s", project, destination));
-        destination = serverName + path.normalize().toString();
-      } else {
-        log.warn("Could not parse relative path; canonicalWebUrl not set");
-      }
-    } else if (!destination.matches("^[^:]+://.*")) {
-      if (serverName != null) {
-        destination = serverName + "/" + originalProject + "/" + destination;
-      } else {
-        log.warn("Could not parse relative path; canonicalWebURl not set");
-      }
-    }
-
-    try {
-      // Replace the protocol with a known scheme, to avoid angering URL
-      destination = destination.replaceFirst("^[^:]+://", "");
-      URL url = new URL("https://" + destination);
-      destination = url.getHost() + url.getPath();
-    } catch (MalformedURLException e) {
-      log.warn("Could not parse destination as URL: " + destination);
-    }
-    return destination;
-  }
+public interface RefUpdateHandler {
+  void run();
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandlerFactory.java b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandlerFactory.java
new file mode 100644
index 0000000..8c8cedb
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandlerFactory.java
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 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.repositoryuse;
+
+public interface RefUpdateHandlerFactory {
+  RefUpdateHandler create(RefUpdate update);
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandlerImpl.java b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandlerImpl.java
new file mode 100644
index 0000000..638c267
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/repositoryuse/RefUpdateHandlerImpl.java
@@ -0,0 +1,295 @@
+// Copyright (C) 2015 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.repositoryuse;
+
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.config.CanonicalWebUrl;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawTextComparator;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectReader;
+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.submodule.SubmoduleWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.io.DisabledOutputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class RefUpdateHandlerImpl implements RefUpdateHandler {
+  private static final Logger log =
+      LoggerFactory.getLogger(RefUpdateHandlerImpl.class);
+
+  private RefUpdate event;
+  private final GitRepositoryManager repoManager;
+  private final String serverName;
+
+  @Inject
+  public RefUpdateHandlerImpl(@Assisted RefUpdate event,
+      GitRepositoryManager repoManager,
+      @CanonicalWebUrl String canonicalWebUrl) {
+    this.event = event;
+    this.repoManager = repoManager;
+    if (canonicalWebUrl != null) {
+      try {
+        URL url = new URL(canonicalWebUrl);
+        canonicalWebUrl = url.getHost();
+      } catch (MalformedURLException e) {
+        log.warn("Could not parse canonicalWebUrl", e);
+      }
+    }
+    this.serverName = canonicalWebUrl;
+  }
+
+  @Override
+  public void run() {
+    if (event.isDelete() && event.getRefName().startsWith(Constants.R_HEADS)
+        || event.getRefName().startsWith(Constants.R_TAGS)) {
+      // Ref was deleted... clean up any references
+      Ref ref = Ref.fetchByRef(event.getProjectName(), event.getRefName());
+      if (ref != null) {
+        ref.delete();
+      }
+      if (event.getRefName().startsWith(Constants.R_HEADS)) {
+        // Also clean up uses from this ref
+        Usage.deleteByBranch(getCanonicalProject(event.getProjectName()),
+            event.getRefName());
+      }
+    } else if (event.getRefName().startsWith(Constants.R_TAGS)) {
+      Ref updatedRef = new Ref(event.getProjectName(), event.getRefName(),
+          event.getNewObjectId());
+      updatedRef.save();
+    } else if (event.getRefName().startsWith(Constants.R_HEADS)) {
+      Ref updatedRef = new Ref(event.getProjectName(), event.getRefName(),
+          event.getNewObjectId());
+      updatedRef.save();
+      Project.NameKey nameKey = new Project.NameKey(event.getProjectName());
+      try {
+        if (Config.refreshAllSubmodules() || event.isCreate()
+            || isSubmoduleUpdate(event, nameKey)) {
+          Map<String, String> submodules = getSubmodules(event, nameKey);
+          updateProjects(event.getProjectName(), event.getRefName(),
+              submodules);
+        }
+        if (Config.parseManifests()) {
+          parseManifests(event, nameKey);
+        }
+      } catch (IOException e) {
+        log.error(e.getMessage(), e);
+      }
+    }
+  }
+
+  private void parseManifests(RefUpdate event, Project.NameKey project)
+      throws RepositoryNotFoundException, IOException {
+    if (event.isDelete()) {
+      return;
+    }
+    try (Repository repo = repoManager.openRepository(project)) {
+      try (RevWalk walk = new RevWalk(repo); TreeWalk tw = new TreeWalk(repo)) {
+        RevCommit commit =
+            walk.parseCommit(repo.resolve(event.getNewObjectId()));
+
+        tw.setRecursive(false);
+        tw.addTree(commit.getTree());
+        ObjectReader or = tw.getObjectReader();
+        while (tw.next()) {
+          String path = tw.getPathString();
+          if (path.endsWith(".xml")) {
+            ManifestParser mp = new ManifestParser();
+            ObjectLoader ol = or.open(tw.getObjectId(0));
+            if (!ol.isLarge()) {
+              Map<String, String> tmp = mp.parseManifest(ol.getBytes());
+              HashMap<String, String> projects = new HashMap<>();
+              for (String key : tmp.keySet()) {
+                projects
+                    .put(
+                        normalizePath(String.format("%s:%s",
+                            event.getProjectName(), path), key, true),
+                    tmp.get(key));
+              }
+              updateProjects(
+                  String.format("%s:%s", event.getProjectName(), path),
+                  event.getRefName(), projects);
+            } else {
+              log.warn(String.format("%s is too large, skipping manifest parse",
+                  tw.getPathString()));
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Has a submodule been updated?
+   *
+   * @param event the Event
+   * @return True if a submodule update occurred, otherwise False.
+   */
+  private boolean isSubmoduleUpdate(RefUpdate event, Project.NameKey project)
+      throws RepositoryNotFoundException, IOException {
+    if (event.isDelete()) {
+      return false;
+    }
+    try (Repository repo = repoManager.openRepository(project)) {
+      try (RevWalk walk = new RevWalk(repo);
+          DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE)) {
+        RevTree aTree = null;
+        if (!event.isCreate()) {
+          // If this is a new ref, we can't get the original commit.
+          // We can still use the DiffFormatter to give us what changed
+          // by passing null, however.
+          RevCommit aCommit =
+              walk.parseCommit(repo.resolve(event.getOldObjectId()));
+          aTree = aCommit.getTree();
+        }
+        RevCommit bCommit =
+            walk.parseCommit(repo.resolve(event.getNewObjectId()));
+        RevTree bTree = bCommit.getTree();
+
+        df.setRepository(repo);
+        df.setDiffComparator(RawTextComparator.DEFAULT);
+        df.setDetectRenames(true);
+        List<DiffEntry> diffEntries = df.scan(aTree, bTree);
+        for (DiffEntry de : diffEntries) {
+          FileMode oldMode = de.getOldMode();
+          FileMode newMode = de.getNewMode();
+          if ((oldMode != null && oldMode == FileMode.GITLINK)
+              || (newMode != null && newMode == FileMode.GITLINK)) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  private Map<String, String> getSubmodules(RefUpdate event,
+      Project.NameKey project) throws RepositoryNotFoundException, IOException {
+    HashMap<String, String> submodules = new HashMap<>();
+    try (Repository repo = repoManager.openRepository(project)) {
+      try (RevWalk walk = new RevWalk(repo);
+          SubmoduleWalk sw = new SubmoduleWalk(repo)) {
+        RevCommit commit =
+            walk.parseCommit(repo.resolve(event.getNewObjectId()));
+        sw.setTree(commit.getTree());
+        sw.setRootTree(commit.getTree());
+        while (sw.next()) {
+          submodules.put(
+              normalizePath(event.getProjectName(), sw.getModulesUrl(), false),
+              sw.getObjectId().name());
+        }
+      } catch (ConfigInvalidException e) {
+        log.warn("Invalid .gitmodules configuration while parsing "
+            + event.getProjectName());
+      }
+    }
+    return submodules;
+  }
+
+  private void updateProjects(String project, String branch,
+      Map<String, String> projects) {
+    String canonicalProject = getCanonicalProject(project);
+    List<Usage> uses = Usage.fetchByProject(canonicalProject, branch);
+    for (Usage use : uses) {
+      if (!projects.containsKey(use.getDestination())) {
+        // No longer exists; delete.
+        use.delete();
+      } else {
+        // Update SHA1 here.
+        use.setRef(projects.get(use.getDestination()));
+        use.save();
+        projects.remove(use.getDestination());
+      }
+    }
+    // At this point, submodules only contains new elements.
+    // Create them.
+    for (String key : projects.keySet()) {
+      Usage use = new Usage(canonicalProject, branch, key, projects.get(key));
+      use.save();
+    }
+  }
+
+  private String getCanonicalProject(String project) {
+    String canonicalProject =
+        String.format("https://%s/%s", serverName, project);
+    try {
+      URL url = new URL(canonicalProject);
+      canonicalProject = url.getHost() + url.getPath();
+    } catch (MalformedURLException e) {
+      log.warn("Could not parse project as URL: " + canonicalProject);
+    }
+    return canonicalProject;
+  }
+
+  private String normalizePath(String project, String destination,
+      boolean isManifest) {
+    String originalProject =
+        isManifest ? project.substring(0, project.lastIndexOf(":")) : project;
+
+    // Handle relative and absolute paths on the same server
+    if (destination.startsWith("/")) {
+      if (serverName != null) {
+        destination = serverName + destination;
+      } else {
+        log.warn("Could not parse absolute path; canonicalWebUrl not set");
+      }
+    } else if (destination.startsWith(".")) {
+      if (serverName != null) {
+        Path path = Paths.get(String.format("/%s/%s", project, destination));
+        destination = serverName + path.normalize().toString();
+      } else {
+        log.warn("Could not parse relative path; canonicalWebUrl not set");
+      }
+    } else if (!destination.matches("^[^:]+://.*")) {
+      if (serverName != null) {
+        destination = serverName + "/" + originalProject + "/" + destination;
+      } else {
+        log.warn("Could not parse relative path; canonicalWebURl not set");
+      }
+    }
+
+    try {
+      // Replace the protocol with a known scheme, to avoid angering URL
+      destination = destination.replaceFirst("^[^:]+://", "");
+      URL url = new URL("https://" + destination);
+      destination = url.getHost() + url.getPath();
+    } catch (MalformedURLException e) {
+      log.warn("Could not parse destination as URL: " + destination);
+    }
+    return destination;
+  }
+}
