Merge branch 'stable-3.7' into stable-3.8

* stable-3.7:
  Add missing binding of ProjectDeletedListener
  Fix the Docker-based setup for the HA test environment
  Verify high-availability formatting using GJF 1.7

Change-Id: If886c427df62ad6373a2749a89e622a5acd646cc
diff --git a/.gitignore b/.gitignore
index 64f8b81..f4aac45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,8 @@
 /src/test/docker/gitvolume
 /src/test/docker/pgdata
 /src/test/docker/shareddir
+
+# IntelliJ files
+.idea
+*.iml
+
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandler.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandler.java
index 857d2db..3dee851 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandler.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandler.java
@@ -16,10 +16,13 @@
 
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.entities.Project;
+import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryCache;
 
 /**
  * Update project list cache. This class is meant to be used on the receiving side of the {@link
@@ -31,10 +34,12 @@
   private static final FluentLogger log = FluentLogger.forEnclosingClass();
 
   private final ProjectCache projectCache;
+  private final GitRepositoryManager repoMgr;
 
   @Inject
-  ForwardedProjectListUpdateHandler(ProjectCache projectCache) {
+  ForwardedProjectListUpdateHandler(ProjectCache projectCache, GitRepositoryManager repoMgr) {
     this.projectCache = projectCache;
+    this.repoMgr = repoMgr;
   }
 
   /**
@@ -50,6 +55,7 @@
       Context.setForwardedEvent(true);
       if (remove) {
         projectCache.remove(projectKey);
+        removeFromRepositoryCache(projectKey);
         log.atFine().log("Removed %s from project list", projectName);
       } else {
         projectCache.onCreateProject(projectKey);
@@ -59,4 +65,14 @@
       Context.unsetForwardedEvent();
     }
   }
+
+  private void removeFromRepositoryCache(Project.NameKey projectKey) {
+    try (Repository repo = repoMgr.openRepository(projectKey)) {
+      if (repo != null) {
+        RepositoryCache.unregister(repo);
+      }
+    } catch (IOException e) {
+      // The repository does not exist: nothing to do
+    }
+  }
 }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandlerTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandlerTest.java
index 2067265..b4b6e26 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandlerTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedProjectListUpdateHandlerTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.verify;
 
 import com.google.gerrit.entities.Project;
+import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.project.ProjectCache;
 import org.junit.Before;
 import org.junit.Test;
@@ -35,11 +36,12 @@
   private static final String SOME_MESSAGE = "someMessage";
   private static final Project.NameKey PROJECT_KEY = Project.nameKey(PROJECT_NAME);
   @Mock private ProjectCache projectCacheMock;
+  @Mock private GitRepositoryManager repoMgrMock;
   private ForwardedProjectListUpdateHandler handler;
 
   @Before
   public void setUp() throws Exception {
-    handler = new ForwardedProjectListUpdateHandler(projectCacheMock);
+    handler = new ForwardedProjectListUpdateHandler(projectCacheMock, repoMgrMock);
   }
 
   @Test