/** Remove repository from management */
  protected void removeRepositoryForGroupId(String groupId, ManagedRepository repository)
      throws NoSuchPrivilegeException, NoSuchAuthorizationManagerException {
    final AuthorizationManager authorizationManager =
        this.securitySystem.getAuthorizationManager(SECURITY_CONTEXT);

    // Assumes priv name is unique
    final Map<String, Privilege> existingPrivs = new HashMap<String, Privilege>();
    for (final Privilege priv : authorizationManager.listPrivileges()) {
      existingPrivs.put(priv.getName(), priv);
    }

    this.removeRepositoryForGroupId(groupId, repository, authorizationManager, existingPrivs);
  }
  protected void removeRepositoryForGroupId(
      String groupId,
      ManagedRepository repository,
      AuthorizationManager authorizationManager,
      Map<String, Privilege> existingPrivs)
      throws NoSuchPrivilegeException {

    final Logger logger = getLogger();

    for (final String method : PRIVILEGE_METHODS) {
      final String name = createPrivilegeName(repository, groupId, method);
      final Privilege priv = existingPrivs.remove(name);
      if (priv != null) {
        authorizationManager.deletePrivilege(priv.getId());
        logger.info("Deleted privilege: " + priv.getName());
      }
    }
  }
  /** Logic shared when adding new managed GroupIds and Repositories. */
  protected void addRepositoryForGroupId(
      String groupId,
      ManagedRepository repository,
      Target managedTarget,
      AuthorizationManager authorizationManager,
      Set<String> deployerPrivs,
      Set<String> readOnlyPrivs,
      Map<String, Privilege> existingPrivs)
      throws InvalidConfigurationException {

    final Logger logger = this.getLogger();

    for (final String method : PRIVILEGE_METHODS) {
      final String name = createPrivilegeName(repository, groupId, method);

      // Check for existing priv before creating a new one
      Privilege priv = existingPrivs.get(name);
      if (priv == null) {
        priv = new Privilege();
        logger.info("Creating new privilege: " + name);
      } else {
        logger.info("Updating existing privilege: " + name);
      }

      priv.setName(name);
      priv.setDescription(priv.getName());
      priv.setType(TargetPrivilegeDescriptor.TYPE);

      priv.addProperty(ApplicationPrivilegeMethodPropertyDescriptor.ID, method);
      priv.addProperty(TargetPrivilegeRepositoryTargetPropertyDescriptor.ID, managedTarget.getId());
      priv.addProperty(TargetPrivilegeRepositoryPropertyDescriptor.ID, repository.getId());

      // Store, capturing updated reference
      priv = authorizationManager.addPrivilege(priv);

      // Build up the priv lists
      if (DEPLOYER_METHODS.contains(method)) {
        deployerPrivs.add(priv.getId());
      }
      if (READONLY_METHODS.contains(method)) {
        readOnlyPrivs.add(priv.getId());
      }
    }
  }
  /** Setup Privs and Roles for the newly managed repository */
  protected void addRepositoryForGroupId(String groupId, ManagedRepository repository)
      throws InvalidConfigurationException, NoSuchAuthorizationManagerException,
          NoSuchRoleException {
    final String targetId = GIDM_ID_PREFIX + groupId;
    final Target managedTarget = this.targetRegistry.getRepositoryTarget(targetId);
    if (managedTarget == null) {
      throw new IllegalStateException(
          "Failed to find repository target '" + targetId + "' for managed groupId: " + groupId);
    }

    final AuthorizationManager authorizationManager =
        this.securitySystem.getAuthorizationManager(SECURITY_CONTEXT);

    // Get or Create the deployer and readonly Roles, need these here to add the privs to them as
    // they are created in the next step
    final Role deployerRole = getOrCreateRole(authorizationManager, groupId, DEPLOYER_ROLE_SUFFIX);
    final Set<String> deployerPrivs = deployerRole.getPrivileges();

    final Role readOnlyRole = getOrCreateRole(authorizationManager, groupId, READONLY_ROLE_SUFFIX);
    final Set<String> readOnlyPrivs = readOnlyRole.getPrivileges();

    // Assumes priv name is unique
    final Map<String, Privilege> existingPrivs = new HashMap<String, Privilege>();
    for (final Privilege priv : authorizationManager.listPrivileges()) {
      existingPrivs.put(priv.getName(), priv);
    }

    addRepositoryForGroupId(
        groupId,
        repository,
        managedTarget,
        authorizationManager,
        deployerPrivs,
        readOnlyPrivs,
        existingPrivs);

    authorizationManager.updateRole(deployerRole);
    authorizationManager.updateRole(readOnlyRole);
  }
  @Override
  public void removeManagedGroupId(String groupId)
      throws NoSuchAuthorizationManagerException, NoSuchPrivilegeException, NoSuchRoleException,
          IOException {
    final Logger logger = getLogger();

    final AuthorizationManager authorizationManager =
        this.securitySystem.getAuthorizationManager(SECURITY_CONTEXT);

    // Assumes priv name is unique
    final Map<String, Privilege> existingPrivs = new HashMap<String, Privilege>();
    for (final Privilege priv : authorizationManager.listPrivileges()) {
      existingPrivs.put(priv.getName(), priv);
    }

    /*
     * Deletes privs
     */
    final ManagedRepositories managedRepositoriesObj = this.getManagedRepositories();
    for (final ManagedRepository repository : managedRepositoriesObj.getManagedRepositories()) {
      removeRepositoryForGroupId(groupId, repository, authorizationManager, existingPrivs);
    }

    // Delete roles
    final String deployerRoleId = this.createRoleId(groupId, DEPLOYER_ROLE_SUFFIX);
    authorizationManager.deleteRole(deployerRoleId);
    logger.info("Deleted role: " + deployerRoleId);

    final String readOnlyRoleId = this.createRoleId(groupId, READONLY_ROLE_SUFFIX);
    authorizationManager.deleteRole(readOnlyRoleId);
    logger.info("Deleted role: " + readOnlyRoleId);

    // delete the repository target
    final String targetId = GIDM_ID_PREFIX + groupId;
    this.targetRegistry.removeRepositoryTarget(targetId);
    logger.info("Deleted repository target: " + targetId);

    this.nexusConfiguration.saveConfiguration();
  }
  @Override
  public void addManagedGroupId(String groupId)
      throws ConfigurationException, IOException, NoSuchAuthorizationManagerException,
          NoSuchRoleException {
    final Logger logger = this.getLogger();

    // Validate the groupId and convert it to a repo target pattern
    final String targetPattern = groupIdToTargetPattern(groupId);

    // Get or Create the Target and persist the changes
    final String targetId = GIDM_ID_PREFIX + groupId;
    Target managedTarget = this.targetRegistry.getRepositoryTarget(targetId);
    if (managedTarget == null) {
      // Just using the name as the id ... hope thats ok!
      managedTarget =
          new Target(
              targetId,
              GIDM_NAME_PREFIX + groupId,
              M2_CONTENT_CLASS,
              Collections.singleton(targetPattern));
      logger.info("Created new repository target: " + managedTarget.getName());
    } else {
      final Set<String> patternTexts = managedTarget.getPatternTexts();
      patternTexts.clear();
      patternTexts.add(targetPattern);
      logger.info("Updated existing repository target: " + managedTarget.getName());
    }
    this.targetRegistry.addRepositoryTarget(managedTarget);

    final AuthorizationManager authorizationManager =
        this.securitySystem.getAuthorizationManager(SECURITY_CONTEXT);

    // Get or Create the deployer and readonly Roles, need these here to add the privs to them as
    // they are created in the next step
    final Role deployerRole = getOrCreateRole(authorizationManager, groupId, DEPLOYER_ROLE_SUFFIX);
    final Set<String> deployerPrivs = deployerRole.getPrivileges();
    deployerPrivs.clear();

    final Role readOnlyRole = getOrCreateRole(authorizationManager, groupId, READONLY_ROLE_SUFFIX);
    final Set<String> readOnlyPrivs = readOnlyRole.getPrivileges();
    readOnlyPrivs.clear();

    // Assumes priv name is unique
    final Map<String, Privilege> existingPrivs = new HashMap<String, Privilege>();
    for (final Privilege priv : authorizationManager.listPrivileges()) {
      existingPrivs.put(priv.getName(), priv);
    }

    /*
     * Adds create/read privs for each managed repository
     */
    final ManagedRepositories managedRepositoriesObj = this.getManagedRepositories();
    for (final ManagedRepository repository : managedRepositoriesObj.getManagedRepositories()) {
      addRepositoryForGroupId(
          groupId,
          repository,
          managedTarget,
          authorizationManager,
          deployerPrivs,
          readOnlyPrivs,
          existingPrivs);
    }

    // Add the roles
    authorizationManager.updateRole(deployerRole);
    authorizationManager.updateRole(readOnlyRole);

    this.nexusConfiguration.saveConfiguration();
  }