docs: private IPortletDefinition savePortletDefinition(
              IPortletDefinition definition,
              List<PortletCategory> categories,
              Map<ExternalPermissionDefinition, Set<IGroupMember>> permissionMap) {
          boolean newChannel = (definition.getPortletDefinitionId() == null);
  
          // save the channel
          definition = portletDefinitionDao.savePortletDefinition(definition);
          definition = portletDefinitionDao.getPortletDefinitionByFname(definition.getFName());
  
          final String defId = definition.getPortletDefinitionId().getStringId();
          final IEntity portletDefEntity = GroupService.getEntity(defId, IPortletDefinition.class);
  
          // Sync on groups during update. This really should be a portal wide thread-safety check or
          // The groups service needs to deal with concurrent modification better.
          synchronized (this.groupUpdateLock) {
              // Delete existing category memberships for this channel
              if (!newChannel) {
                  for (IEntityGroup group : portletDefEntity.getAncestorGroups()) {
                      group.removeChild(portletDefEntity);
                      group.update();
                  }
              }
  
              // For each category ID, add channel to category
              for (PortletCategory category : categories) {
                  final IEntityGroup categoryGroup = GroupService.findGroup(category.getId());
                  categoryGroup.addChild(portletDefEntity);
                  categoryGroup.updateMembers();
              }
  
              // Set groups
              final AuthorizationServiceFacade authService = AuthorizationServiceFacade.instance();
              final String target =
                      PermissionHelper.permissionTargetIdForPortletDefinition(definition);
  
              // Loop over the affected permission managers...
              Map<String, Collection<ExternalPermissionDefinition>> permissionsBySystem =
                      getPermissionsBySystem(permissionMap.keySet());
              for (String system : permissionsBySystem.keySet()) {
                  Collection<ExternalPermissionDefinition> systemPerms =
                          permissionsBySystem.get(system);
  
                  // get the permission manager for this system...
                  final IUpdatingPermissionManager upm =
                          authService.newUpdatingPermissionManager(system);
                  final List<IPermission> permissions = new ArrayList<>();
  
                  // add activity grants for each permission..
                  for (ExternalPermissionDefinition permissionDef : systemPerms) {
  
                      Set<IGroupMember> members = permissionMap.get(permissionDef);
                      for (final IGroupMember member : members) {
  
                          final IAuthorizationPrincipal authPrincipal =
                                  authService.newPrincipal(member);
                          final IPermission permEntity = upm.newPermission(authPrincipal);
                          permEntity.setType(IPermission.PERMISSION_TYPE_GRANT);
                          permEntity.setActivity(permissionDef.getActivity());
                          permEntity.setTarget(target);
                          permissions.add(permEntity);
                      }
                  }
  
                  // If modifying the channel, remove the existing permissions before adding the new
                  // ones
                  if (!newChannel) {
                      for (ExternalPermissionDefinition permissionName : permissionMap.keySet()) {
                          IPermission[] oldPermissions =
                                  upm.getPermissions(permissionName.getActivity(), target);
                          upm.removePermissions(oldPermissions);
                      }
                  }
                  upm.addPermissions(permissions.toArray(new IPermission[permissions.size()]));
              }
          }
  
          if (logger.isDebugEnabled()) {
              logger.debug(
                      "Portlet "
                              + defId
                              + " has been "
                              + (newChannel ? "published" : "modified")
                              + ".");
          }
  
          return definition;
      }