class ResourcePermissionService {

    public void grantAuthorizedEnvironmentsAndEnvTypesPerApplication(AbstractSecurityEnabledResource resource, String[] applicationsToAdd, String[] environmentsToAdd,
                                                                     String[] environmentTypesToAdd) {
        List<String> envIds = Lists.newArrayList();
        IResourceSaver noSave = null;

        if (ArrayUtils.isNotEmpty(applicationsToAdd)) {
            grantPermission(resource, noSave, Subject.APPLICATION, applicationsToAdd);
            // when an app is added, all eventual existing env authorizations are removed
            for (String applicationToAddId : applicationsToAdd) {
                ApplicationEnvironment[] aes = applicationEnvironmentService.getByApplicationId(applicationToAddId);
                for (ApplicationEnvironment ae : aes) {
                    envIds.add(ae.getId());
                }
            }
            if (!envIds.isEmpty()) {
                revokePermission(resource, noSave, Subject.ENVIRONMENT, envIds.toArray(new String[envIds.size()]));
            }
            // remove all all eventual existing env type authorizations
            Set<String> envTypes = Sets.newHashSet();
            for (String applicationToAddId : applicationsToAdd) {
                for (EnvironmentType envType : EnvironmentType.values()) {
                    envTypes.add(applicationToAddId + ":" + envType.toString());
                }
            }
            if (!envTypes.isEmpty()) {
                revokePermission(resource, noSave, Subject.ENVIRONMENT_TYPE, envTypes.toArray(new String[envTypes.size()]));
            }
        }
        if (ArrayUtils.isNotEmpty(environmentsToAdd)) {
            List<String> envToAddSet = Arrays.stream(environmentsToAdd).filter(env -> !envIds.contains(env)).collect(Collectors.toList());
            grantPermission(resource, noSave, Subject.ENVIRONMENT, envToAddSet.toArray(new String[envToAddSet.size()]));
        }
        if (ArrayUtils.isNotEmpty(environmentTypesToAdd)) {
            grantPermission(resource, noSave, Subject.ENVIRONMENT_TYPE, environmentTypesToAdd);
        }
        alienDAO.save(resource);
    }

}