Merge branch 'stable-2.15' into stable-2.16

* stable-2.15:
  Upgrade bazlets to latest stable-2.15 to build with 2.15.19 API
  Upgrade bazlets to latest stable-2.14 to build with 2.14.21 API

Change-Id: I8350fc1b587740f9b096b3409c381cbc7927f05a
diff --git a/.bazelversion b/.bazelversion
index 9084fa2..fd2a018 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-1.1.0
+3.1.0
diff --git a/WORKSPACE b/WORKSPACE
index ac12434..1244157 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "9af263722b7eafe99af079d6ef7cf1de23e6f8d7",
+    commit = "fff6f20bb2eceaf872a8acf8ad51471c25a82d38",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java
index 4df4f25..099a85f 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java
@@ -24,10 +24,10 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.account.GroupCache;
-import com.google.gerrit.server.git.MetaDataUpdate;
-import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
 import com.google.gerrit.server.group.InternalGroup;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectConfig;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.project.RefPattern;
 import com.google.inject.Inject;
diff --git a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java
index 347244b..f764b9e 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java
@@ -19,33 +19,28 @@
 import com.google.gerrit.common.data.GroupReference;
 import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
 import com.google.gerrit.extensions.annotations.PluginName;
-import com.google.gerrit.extensions.api.groups.GroupInput;
+import com.google.gerrit.extensions.api.groups.Groups;
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.account.GroupMembership;
 import com.google.gerrit.server.config.AllProjectsNameProvider;
 import com.google.gerrit.server.config.PluginConfigFactory;
-import com.google.gerrit.server.group.CreateGroup;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.project.CreateProjectArgs;
 import com.google.gerrit.server.project.NoSuchProjectException;
-import com.google.gerrit.server.project.ProjectControl;
 import com.google.gerrit.server.validators.ProjectCreationValidationListener;
 import com.google.gerrit.server.validators.ValidationException;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
-import java.io.IOException;
-import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -89,33 +84,30 @@
 
   static final String DISABLE_GRANTING_PROJECT_OWNERSHIP = "disableGrantingProjectOwnership";
 
-  private final CreateGroup.Factory createGroupFactory;
+  private final Groups groups;
   private final String documentationUrl;
   private final AllProjectsNameProvider allProjectsName;
   private final Provider<CurrentUser> self;
   private final PermissionBackend permissionBackend;
   private final PluginConfigFactory cfg;
   private final String pluginName;
-  private final ProjectControl.GenericFactory projectControlFactory;
 
   @Inject
   public ProjectCreationValidator(
-      CreateGroup.Factory createGroupFactory,
+      Groups groups,
       @PluginCanonicalWebUrl String url,
       AllProjectsNameProvider allProjectsName,
       Provider<CurrentUser> self,
       PermissionBackend permissionBackend,
       PluginConfigFactory cfg,
-      @PluginName String pluginName,
-      ProjectControl.GenericFactory projectControlFactory) {
-    this.createGroupFactory = createGroupFactory;
+      @PluginName String pluginName) {
+    this.groups = groups;
     this.documentationUrl = url + "Documentation/index.html";
     this.allProjectsName = allProjectsName;
     this.self = self;
     this.permissionBackend = permissionBackend;
     this.cfg = cfg;
     this.pluginName = pluginName;
-    this.projectControlFactory = projectControlFactory;
   }
 
   @Override
@@ -127,21 +119,10 @@
           String.format(PROJECT_CANNOT_CONTAINS_SPACES_MSG, documentationUrl));
     }
 
-    ProjectControl parentCtrl;
-    try {
-      parentCtrl = projectControlFactory.controlFor(args.newParent, self.get());
-    } catch (NoSuchProjectException | IOException e) {
-      log.error(
-          "Failed to create project {}; Cannot retrieve info about parent project {}: {}",
-          name,
-          args.newParent.get(),
-          e.getMessage(),
-          e);
-      throw new ValidationException(AN_ERROR_OCCURRED_MSG);
-    }
+    Project.NameKey newParent = args.newParent;
 
     try {
-      permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
+      permissionBackend.user(self.get()).check(GlobalPermission.ADMINISTRATE_SERVER);
 
       // Admins can bypass any rules to support creating projects that doesn't
       // comply with the new naming rules. New projects structures have to
@@ -153,31 +134,39 @@
       // continuing
     }
 
-    if (allProjectsName.get().equals(parentCtrl.getProject().getNameKey())) {
+    if (allProjectsName.get().equals(newParent)) {
       validateRootProject(name, args.permissionsOnly);
     } else {
-      validateProject(name, parentCtrl);
+      validateProject(name, newParent);
     }
 
     // If we reached that point, it means we allow project creation. Make the
     // user an owner if not already by inheritance.
-    if (!parentCtrl.isOwner() && !configDisableGrantingOwnership(parentCtrl)) {
+    if (!isOwner(newParent) && !configDisableGrantingOwnership(newParent)) {
       args.ownerIds.add(createGroup(name + "-admins"));
     }
   }
 
-  private boolean configDisableGrantingOwnership(ProjectControl parentCtrl)
+  private boolean isOwner(Project.NameKey project) {
+    try {
+      permissionBackend.user(self.get()).project(project).check(ProjectPermission.WRITE_CONFIG);
+    } catch (AuthException | PermissionBackendException noWriter) {
+      try {
+        permissionBackend.user(self.get()).check(GlobalPermission.ADMINISTRATE_SERVER);
+      } catch (AuthException | PermissionBackendException noAdmin) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private boolean configDisableGrantingOwnership(Project.NameKey parentCtrl)
       throws ValidationException {
     try {
-      return cfg.getFromProjectConfigWithInheritance(
-              parentCtrl.getProject().getNameKey(), pluginName)
+      return cfg.getFromProjectConfigWithInheritance(parentCtrl, pluginName)
           .getBoolean(DISABLE_GRANTING_PROJECT_OWNERSHIP, false);
     } catch (NoSuchProjectException e) {
-      log.error(
-          "Failed to check project config for {}: {}",
-          parentCtrl.getProject().getName(),
-          e.getMessage(),
-          e);
+      log.error("Failed to check project config for {}: {}", parentCtrl.get(), e.getMessage(), e);
       throw new ValidationException(AN_ERROR_OCCURRED_MSG);
     }
   }
@@ -186,8 +175,7 @@
     try {
       GroupInfo groupInfo = null;
       try {
-        groupInfo =
-            createGroupFactory.create(name).apply(TopLevelResource.INSTANCE, new GroupInput());
+        groupInfo = groups.create(name).get();
       } catch (ResourceConflictException e) {
         // name already exists, make sure it is unique by adding a abbreviated
         // sha1
@@ -200,13 +188,10 @@
             name,
             e.getMessage(),
             nameWithSha1);
-        groupInfo =
-            createGroupFactory
-                .create(nameWithSha1)
-                .apply(TopLevelResource.INSTANCE, new GroupInput());
+        groupInfo = groups.create(nameWithSha1).get();
       }
       return AccountGroup.UUID.parse(groupInfo.id);
-    } catch (RestApiException | OrmException | IOException | ConfigInvalidException e) {
+    } catch (RestApiException e) {
       log.error("Failed to create project {}: {}", name, e.getMessage(), e);
       throw new ValidationException(AN_ERROR_OCCURRED_MSG);
     }
@@ -231,33 +216,32 @@
     log.debug("allowing creation of root project {}", name);
   }
 
-  private void validateProject(String name, ProjectControl parentCtrl) throws ValidationException {
+  private void validateProject(String name, Project.NameKey parentCtrl) throws ValidationException {
     log.debug("validating name prefix of {}", name);
-    Project parent = parentCtrl.getProject();
-    String prefix = parent.getName() + "/";
+    String prefix = parentCtrl.get() + "/";
     if (!name.startsWith(prefix)) {
       log.debug("rejecting creation of {}: name is not starting with {}", name, prefix);
       throw new ValidationException(
           String.format(PROJECT_MUST_START_WITH_PARENT_NAME_MSG, prefix + name, documentationUrl));
     }
-    if (!parentCtrl.isOwner() && !isInDelegatingGroup(parentCtrl)) {
-      log.debug("rejecting creation of {}: user is not owner of {}", name, parent.getName());
+    if (!isOwner(parentCtrl) && !isInDelegatingGroup(parentCtrl)) {
+      log.debug("rejecting creation of {}: user is not owner of {}", name, parentCtrl.get());
       throw new ValidationException(
-          String.format(MUST_BE_OWNER_TO_CREATE_PROJECT_MSG, parent.getName(), documentationUrl));
+          String.format(MUST_BE_OWNER_TO_CREATE_PROJECT_MSG, parentCtrl.get(), documentationUrl));
     }
     log.debug("allowing creation of project {}", name);
   }
 
-  private boolean isInDelegatingGroup(ProjectControl parentCtrl) {
+  private boolean isInDelegatingGroup(Project.NameKey parentCtrl) {
     try {
       GroupReference delegateProjectCreationTo =
-          cfg.getFromProjectConfigWithInheritance(parentCtrl.getProject().getNameKey(), pluginName)
+          cfg.getFromProjectConfigWithInheritance(parentCtrl, pluginName)
               .getGroupReference(DELEGATE_PROJECT_CREATION_TO);
       if (delegateProjectCreationTo == null) {
         return false;
       }
       log.debug("delegateProjectCreationTo: {}", delegateProjectCreationTo);
-      GroupMembership effectiveGroups = parentCtrl.getUser().getEffectiveGroups();
+      GroupMembership effectiveGroups = self.get().getEffectiveGroups();
       return effectiveGroups.contains(delegateProjectCreationTo.getUUID());
     } catch (NoSuchProjectException e) {
       log.error("isInDelegatingGroup with error ({}): {}", e.getClass().getName(), e.getMessage());
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index a41015d..bd3e446 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -56,21 +56,19 @@
   bazel build plugins/@PLUGIN@
 ```
 
-Note that due to a [known issue in Bazel][bazelissue], if the plugin
-has previously been built in standalone mode, it is necessary to clean
-the workspace before building in-tree:
-
-```
-  cd plugins/@PLUGIN@
-  bazel clean --expunge
-```
-
 The output is created in
 
 ```
   bazel-bin/plugins/@PLUGIN@/@PLUGIN@.jar
 ```
 
+To execute the tests run either one of:
+
+```
+  bazel test --test_tag_filters=@PLUGIN@ //...
+  bazel test plugins/@PLUGIN@:@PLUGIN@_tests
+```
+
 This project can be imported into the Eclipse IDE:
 Add the plugin name to the `CUSTOM_PLUGINS` in `tools/bzl/plugins.bzl`, and
 execute:
@@ -79,14 +77,6 @@
   ./tools/eclipse/project.py
 ```
 
-To execute the tests run:
-
-```
-  bazel test --test_tag_filters=@PLUGIN@ //...
-```
-
-
 [Back to @PLUGIN@ documentation index][index]
 
 [index]: index.html
-[bazelissue]: https://github.com/bazelbuild/bazel/issues/2797
diff --git a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java
index a0f9140..33a986d 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java
@@ -26,7 +26,7 @@
 import com.google.gerrit.extensions.restapi.Url;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.project.ProjectConfig;
 import com.google.gerrit.server.project.ProjectState;
 import java.nio.file.Files;
 import org.junit.Before;
@@ -39,7 +39,7 @@
 
   @Override
   @Before
-  public void setUp() throws Exception {
+  public void setUpTestPlugin() throws Exception {
     String defaultAccessRights =
         "[access \"refs/*\"]\n"
             + "  read = group ${owner}\n"
@@ -57,7 +57,7 @@
             + "[access \"refs/invalidregex/${username(((((\"]\n";
     Files.write(
         tempDataDir.newFile(ProjectConfig.PROJECT_CONFIG).toPath(), defaultAccessRights.getBytes());
-    super.setUp();
+    super.setUpTestPlugin();
     // These access rights are mandatory configuration for this plugin as
     // documented in config.md
     allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.CREATE_GROUP);
diff --git a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java
index 8f53648..6f74514 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java
@@ -30,7 +30,7 @@
 import com.google.gerrit.extensions.restapi.Url;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.project.ProjectConfig;
 import com.google.gerrit.server.project.ProjectState;
 import org.junit.Before;
 import org.junit.Test;
@@ -44,8 +44,8 @@
 
   @Override
   @Before
-  public void setUp() throws Exception {
-    super.setUp();
+  public void setUpTestPlugin() throws Exception {
+    super.setUpTestPlugin();
     // These access rights are mandatory configuration for this plugin as
     // documented in config.md
     allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.CREATE_GROUP);
@@ -214,13 +214,15 @@
     dGroup.addMembers(user.username);
     // the group is in the project.config
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
-    String gId = gApi.groups().id(delegatingGroup).get().id;
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setGroupReference(
-            ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-            new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-    saveProjectConfig(parentNameKey, cfg);
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
+      String gId = gApi.groups().id(delegatingGroup).get().id;
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setGroupReference(
+              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfgUpdate.save();
+    }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
   }
 
@@ -235,13 +237,15 @@
     GroupApi dGroup = gApi.groups().create(delegatingGroup);
     dGroup.addMembers(user.username);
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
-    String gId = gApi.groups().id(delegatingGroup).get().id;
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setGroupReference(
-            ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-            new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-    saveProjectConfig(parentNameKey, cfg);
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
+      String gId = gApi.groups().id(delegatingGroup).get().id;
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setGroupReference(
+              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfgUpdate.save();
+    }
 
     // normal case, when <project-name>-admins group does not exist
     in = new ProjectInput();
@@ -288,15 +292,17 @@
     GroupApi dGroup = gApi.groups().create(delegatingGroup);
     dGroup.addMembers(user.username);
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
-    String gId = gApi.groups().id(delegatingGroup).get().id;
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setGroupReference(
-            ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-            new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setBoolean(ProjectCreationValidator.DISABLE_GRANTING_PROJECT_OWNERSHIP, true);
-    saveProjectConfig(parentNameKey, cfg);
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
+      String gId = gApi.groups().id(delegatingGroup).get().id;
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setGroupReference(
+              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setBoolean(ProjectCreationValidator.DISABLE_GRANTING_PROJECT_OWNERSHIP, true);
+      cfgUpdate.save();
+    }
 
     in = new ProjectInput();
     in.parent = parent;
@@ -329,10 +335,12 @@
     dGroup.addMembers(user.username);
     // the group is in the project.config
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setString(ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO, delegatingGroup);
-    saveProjectConfig(parentNameKey, cfg);
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setString(ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO, delegatingGroup);
+      cfgUpdate.save();
+    }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
   }
 
@@ -364,13 +372,15 @@
     dGroup.addGroups(nestedGroup);
     // the group is in the project.config
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
-    String gId = gApi.groups().id(delegatingGroup).get().id;
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setGroupReference(
-            ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-            new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-    saveProjectConfig(parentNameKey, cfg);
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
+      String gId = gApi.groups().id(delegatingGroup).get().id;
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setGroupReference(
+              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfgUpdate.save();
+    }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
   }
 
@@ -397,13 +407,15 @@
     // The user is not added to the delegated group
     // the group is in the project.config
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
-    String gId = gApi.groups().id(delegatingGroup).get().id;
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setGroupReference(
-            ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-            new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-    saveProjectConfig(parentNameKey, cfg);
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
+      String gId = gApi.groups().id(delegatingGroup).get().id;
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setGroupReference(
+              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfgUpdate.save();
+    }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
   }
 
@@ -428,13 +440,15 @@
     String delegatingGroup = name("groupB");
     // the group is in the project.config
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
-    String gId = "fake-gId";
-    cfg.getPluginConfig(PLUGIN_NAME)
-        .setGroupReference(
-            ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-            new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-    saveProjectConfig(parentNameKey, cfg);
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
+      String gId = "fake-gId";
+      cfg.getPluginConfig(PLUGIN_NAME)
+          .setGroupReference(
+              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfgUpdate.save();
+    }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
   }
 
@@ -461,14 +475,16 @@
     dGroup.addMembers(user.username);
     // the group is in the project.config
     Project.NameKey parentNameKey = new Project.NameKey(parent);
-    ProjectConfig cfg = projectCache.checkedGet(parentNameKey).getConfig();
+    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
+      ProjectConfig cfg = cfgUpdate.getConfig();
 
-    String gId = gApi.groups().id(delegatingGroup).get().id;
-    cfg.getPluginConfig("project-group-structure")
-        .setGroupReference(
-            ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-            new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-    saveProjectConfig(parentNameKey, cfg);
+      String gId = gApi.groups().id(delegatingGroup).get().id;
+      cfg.getPluginConfig("project-group-structure")
+          .setGroupReference(
+              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfgUpdate.save();
+    }
 
     String newDelegatingGroup = name("groupC");
     gApi.groups().id(delegatingGroup).name(newDelegatingGroup);