You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/08/22 15:09:09 UTC

[05/16] syncope git commit: [SYNCOPE-938] Switching from commons-collections to Java 8 features

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index fa9fa5f..5bae851 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -24,24 +24,18 @@ import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 import javax.annotation.Resource;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.MembershipPatch;
 import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.RelationshipPatch;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
 import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.RelationshipTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
@@ -59,11 +53,11 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.core.spring.BeanUtils;
-import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.RelationshipType;
@@ -71,7 +65,6 @@ import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
@@ -189,14 +182,14 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         user.setSecurityAnswer(userTO.getSecurityAnswer());
 
         // roles
-        for (String roleKey : userTO.getRoles()) {
+        userTO.getRoles().forEach(roleKey -> {
             Role role = roleDAO.find(roleKey);
             if (role == null) {
                 LOG.warn("Ignoring unknown role with id {}", roleKey);
             } else {
                 user.add(role);
             }
-        }
+        });
 
         // realm
         Realm realm = realmDAO.findByFullPath(userTO.getRealm());
@@ -210,11 +203,11 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         AnyUtils anyUtils = anyUtilsFactory.getInstance(AnyTypeKind.USER);
         if (user.getRealm() != null) {
             // relationships
-            Collection<String> assignableAnyObjects = CollectionUtils.collect(
-                    searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT),
-                    EntityUtils.keyTransformer());
+            Collection<String> assignableAnyObjects =
+                    searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT).stream().
+                            map(a -> a.getKey()).collect(Collectors.toList());
 
-            for (RelationshipTO relationshipTO : userTO.getRelationships()) {
+            userTO.getRelationships().forEach(relationshipTO -> {
                 AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
                 if (otherEnd == null) {
                     LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
@@ -239,14 +232,14 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                     unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
                     scce.addException(unassignabled);
                 }
-            }
+            });
 
             // memberships
-            Collection<String> assignableGroups = CollectionUtils.collect(
-                    searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.GROUP),
-                    EntityUtils.keyTransformer());
+            Collection<String> assignableGroups =
+                    searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.GROUP).stream().
+                            map(g -> g.getKey()).collect(Collectors.toList());
 
-            for (MembershipTO membershipTO : userTO.getMemberships()) {
+            userTO.getMemberships().forEach(membershipTO -> {
                 Group group = membershipTO.getRightKey() == null
                         ? groupDAO.findByName(membershipTO.getGroupName())
                         : groupDAO.find(membershipTO.getRightKey());
@@ -270,7 +263,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                     unassignable.getElements().add("Cannot be assigned: " + group);
                     scce.addException(unassignable);
                 }
-            }
+            });
         }
 
         // attributes and resources
@@ -285,15 +278,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
     private boolean isPasswordMapped(final ExternalResource resource) {
         boolean result = false;
 
-        Provision provision = resource.getProvision(anyTypeDAO.findUser());
-        if (provision != null && provision.getMapping() != null) {
-            result = IterableUtils.matchesAny(provision.getMapping().getItems(), new Predicate<MappingItem>() {
-
-                @Override
-                public boolean evaluate(final MappingItem item) {
-                    return item.isPassword();
-                }
-            });
+        Optional<? extends Provision> provision = resource.getProvision(anyTypeDAO.findUser());
+        if (provision.isPresent() && provision.get().getMapping() != null) {
+            result = provision.get().getMapping().getItems().stream().anyMatch(item -> item.isPassword());
         }
 
         return result;
@@ -389,139 +376,136 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         Set<String> toBeProvisioned = new HashSet<>();
 
         // relationships
-        Collection<String> assignableAnyObjects = CollectionUtils.collect(
-                searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT),
-                EntityUtils.keyTransformer());
-
-        for (RelationshipPatch patch : userPatch.getRelationships()) {
-            if (patch.getRelationshipTO() != null) {
-                RelationshipType relationshipType = relationshipTypeDAO.find(patch.getRelationshipTO().getType());
-                if (relationshipType == null) {
-                    LOG.debug("Ignoring invalid relationship type {}", patch.getRelationshipTO().getType());
-                } else {
-                    URelationship relationship =
-                            user.getRelationship(relationshipType, patch.getRelationshipTO().getRightKey());
-                    if (relationship != null) {
-                        user.getRelationships().remove(relationship);
-                        relationship.setLeftEnd(null);
-
-                        toBeDeprovisioned.addAll(
-                                anyObjectDAO.findAllResourceKeys(relationship.getRightEnd().getKey()));
-                    }
+        Collection<String> assignableAnyObjects =
+                searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT).stream().
+                        map(a -> a.getKey()).collect(Collectors.toList());
+
+        userPatch.getRelationships().stream().
+                filter(patch -> patch.getRelationshipTO() != null).forEachOrdered((patch) -> {
+            RelationshipType relationshipType = relationshipTypeDAO.find(patch.getRelationshipTO().getType());
+            if (relationshipType == null) {
+                LOG.debug("Ignoring invalid relationship type {}", patch.getRelationshipTO().getType());
+            } else {
+                Optional<? extends URelationship> relationship =
+                        user.getRelationship(relationshipType, patch.getRelationshipTO().getRightKey());
+                if (relationship.isPresent()) {
+                    user.getRelationships().remove(relationship.get());
+                    relationship.get().setLeftEnd(null);
+
+                    toBeDeprovisioned.addAll(
+                            anyObjectDAO.findAllResourceKeys(relationship.get().getRightEnd().getKey()));
+                }
 
-                    if (patch.getOperation() == PatchOperation.ADD_REPLACE) {
-                        AnyObject otherEnd = anyObjectDAO.find(patch.getRelationshipTO().getRightKey());
-                        if (otherEnd == null) {
-                            LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getRightKey());
-                        } else if (assignableAnyObjects.contains(otherEnd.getKey())) {
-                            relationship = entityFactory.newEntity(URelationship.class);
-                            relationship.setType(relationshipType);
-                            relationship.setRightEnd(otherEnd);
-                            relationship.setLeftEnd(user);
+                if (patch.getOperation() == PatchOperation.ADD_REPLACE) {
+                    AnyObject otherEnd = anyObjectDAO.find(patch.getRelationshipTO().getRightKey());
+                    if (otherEnd == null) {
+                        LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getRightKey());
+                    } else if (assignableAnyObjects.contains(otherEnd.getKey())) {
+                        URelationship newRelationship = entityFactory.newEntity(URelationship.class);
+                        newRelationship.setType(relationshipType);
+                        newRelationship.setRightEnd(otherEnd);
+                        newRelationship.setLeftEnd(user);
 
-                            user.add(relationship);
+                        user.add(newRelationship);
 
-                            toBeProvisioned.addAll(anyObjectDAO.findAllResourceKeys(otherEnd.getKey()));
-                        } else {
-                            LOG.error("{} cannot be assigned to {}", otherEnd, user);
+                        toBeProvisioned.addAll(anyObjectDAO.findAllResourceKeys(otherEnd.getKey()));
+                    } else {
+                        LOG.error("{} cannot be assigned to {}", otherEnd, user);
 
-                            SyncopeClientException unassignable =
-                                    SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
-                            unassignable.getElements().add("Cannot be assigned: " + otherEnd);
-                            scce.addException(unassignable);
-                        }
+                        SyncopeClientException unassignable =
+                                SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+                        unassignable.getElements().add("Cannot be assigned: " + otherEnd);
+                        scce.addException(unassignable);
                     }
                 }
             }
-        }
+        });
 
         Collection<ExternalResource> resources = userDAO.findAllResources(user);
         SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
 
         // memberships
-        Collection<String> assignableGroups = CollectionUtils.collect(
-                searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.GROUP),
-                EntityUtils.keyTransformer());
-
-        for (MembershipPatch membPatch : userPatch.getMemberships()) {
-            if (membPatch.getGroup() != null) {
-                UMembership membership = user.getMembership(membPatch.getGroup());
-                if (membership != null) {
-                    user.getMemberships().remove(membership);
-                    membership.setLeftEnd(null);
-                    for (UPlainAttr attr : user.getPlainAttrs(membership)) {
-                        user.remove(attr);
-                        attr.setOwner(null);
-                        attr.setMembership(null);
-                    }
+        Collection<String> assignableGroups =
+                searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.GROUP).stream().
+                        map(g -> g.getKey()).collect(Collectors.toList());
+
+        userPatch.getMemberships().stream().
+                filter(membPatch -> membPatch.getGroup() != null).forEachOrdered((membPatch) -> {
+            Optional<? extends UMembership> membership = user.getMembership(membPatch.getGroup());
+            if (membership.isPresent()) {
+                user.getMemberships().remove(membership.get());
+                membership.get().setLeftEnd(null);
+                user.getPlainAttrs(membership.get()).forEach(attr -> {
+                    user.remove(attr);
+                    attr.setOwner(null);
+                    attr.setMembership(null);
+                });
+
+                toBeDeprovisioned.addAll(groupDAO.findAllResourceKeys(membership.get().getRightEnd().getKey()));
+            }
+            if (membPatch.getOperation() == PatchOperation.ADD_REPLACE) {
+                Group group = groupDAO.find(membPatch.getGroup());
+                if (group == null) {
+                    LOG.debug("Ignoring invalid group {}", membPatch.getGroup());
+                } else if (assignableGroups.contains(group.getKey())) {
+                    UMembership newMembership = entityFactory.newEntity(UMembership.class);
+                    newMembership.setRightEnd(group);
+                    newMembership.setLeftEnd(user);
 
-                    toBeDeprovisioned.addAll(groupDAO.findAllResourceKeys(membership.getRightEnd().getKey()));
-                }
+                    user.add(newMembership);
 
-                if (membPatch.getOperation() == PatchOperation.ADD_REPLACE) {
-                    Group group = groupDAO.find(membPatch.getGroup());
-                    if (group == null) {
-                        LOG.debug("Ignoring invalid group {}", membPatch.getGroup());
-                    } else if (assignableGroups.contains(group.getKey())) {
-                        membership = entityFactory.newEntity(UMembership.class);
-                        membership.setRightEnd(group);
-                        membership.setLeftEnd(user);
-
-                        user.add(membership);
-
-                        for (AttrTO attrTO : membPatch.getPlainAttrs()) {
-                            PlainSchema schema = getPlainSchema(attrTO.getSchema());
-                            if (schema == null) {
-                                LOG.debug("Invalid " + PlainSchema.class.getSimpleName()
-                                        + "{}, ignoring...", attrTO.getSchema());
-                            } else {
-                                UPlainAttr attr = user.getPlainAttr(schema.getKey(), membership);
-                                if (attr == null) {
-                                    LOG.debug("No plain attribute found for {} and membership of {}",
-                                            schema, membership.getRightEnd());
-
-                                    attr = anyUtils.newPlainAttr();
-                                    attr.setOwner(user);
-                                    attr.setMembership(membership);
-                                    attr.setSchema(schema);
-                                    user.add(attr);
-
-                                    AttrPatch patch = new AttrPatch.Builder().attrTO(attrTO).build();
-                                    processAttrPatch(
-                                            user, patch, schema, attr, anyUtils,
-                                            resources, propByRes, invalidValues);
-                                }
+                    membPatch.getPlainAttrs().forEach(attrTO -> {
+                        PlainSchema schema = getPlainSchema(attrTO.getSchema());
+                        if (schema == null) {
+                            LOG.debug("Invalid " + PlainSchema.class.getSimpleName()
+                                    + "{}, ignoring...", attrTO.getSchema());
+                        } else {
+                            UPlainAttr attr = user.getPlainAttr(schema.getKey(), newMembership).orElse(null);
+                            if (attr == null) {
+                                LOG.debug("No plain attribute found for {} and membership of {}",
+                                        schema, newMembership.getRightEnd());
+
+                                attr = anyUtils.newPlainAttr();
+                                attr.setOwner(user);
+                                attr.setMembership(newMembership);
+                                attr.setSchema(schema);
+                                user.add(attr);
+
+                                AttrPatch patch = new AttrPatch.Builder().attrTO(attrTO).build();
+                                processAttrPatch(
+                                        user, patch, schema, attr, anyUtils,
+                                        resources, propByRes, invalidValues);
                             }
                         }
-                        if (!invalidValues.isEmpty()) {
-                            scce.addException(invalidValues);
-                        }
+                    });
+                    if (!invalidValues.isEmpty()) {
+                        scce.addException(invalidValues);
+                    }
 
-                        toBeProvisioned.addAll(groupDAO.findAllResourceKeys(group.getKey()));
+                    toBeProvisioned.addAll(groupDAO.findAllResourceKeys(group.getKey()));
 
-                        // SYNCOPE-686: if password is invertible and we are adding resources with password mapping,
-                        // ensure that they are counted for password propagation
-                        if (toBeUpdated.canDecodePassword()) {
-                            if (userPatch.getPassword() == null) {
-                                userPatch.setPassword(new PasswordPatch());
-                            }
-                            for (ExternalResource resource : group.getResources()) {
-                                if (isPasswordMapped(resource)) {
-                                    userPatch.getPassword().getResources().add(resource.getKey());
-                                }
-                            }
+                    // SYNCOPE-686: if password is invertible and we are adding resources with password mapping,
+                    // ensure that they are counted for password propagation
+                    if (toBeUpdated.canDecodePassword()) {
+                        if (userPatch.getPassword() == null) {
+                            userPatch.setPassword(new PasswordPatch());
                         }
-                    } else {
-                        LOG.error("{} cannot be assigned to {}", group, user);
-
-                        SyncopeClientException unassignabled =
-                                SyncopeClientException.build(ClientExceptionType.InvalidMembership);
-                        unassignabled.getElements().add("Cannot be assigned: " + group);
-                        scce.addException(unassignabled);
+                        group.getResources().stream().
+                                filter(resource -> isPasswordMapped(resource)).
+                                forEachOrdered(resource -> {
+                                    userPatch.getPassword().getResources().add(resource.getKey());
+                                });
                     }
+                } else {
+                    LOG.error("{} cannot be assigned to {}", group, user);
+
+                    SyncopeClientException unassignabled =
+                            SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+                    unassignabled.getElements().add("Cannot be assigned: " + group);
+                    scce.addException(unassignabled);
                 }
             }
-        }
+        });
 
         propByRes.addAll(ResourceOperation.DELETE, toBeDeprovisioned);
         propByRes.addAll(ResourceOperation.UPDATE, toBeProvisioned);
@@ -535,14 +519,14 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
 
         // check if some connObjectKey was changed by the update above
         Map<String, String> newcCnnObjectKeys = getConnObjectKeys(user);
-        for (Map.Entry<String, String> entry : oldConnObjectKeys.entrySet()) {
-            if (newcCnnObjectKeys.containsKey(entry.getKey())
-                    && !entry.getValue().equals(newcCnnObjectKeys.get(entry.getKey()))) {
+        oldConnObjectKeys.entrySet().stream().
+                filter(entry -> newcCnnObjectKeys.containsKey(entry.getKey())
+                && !entry.getValue().equals(newcCnnObjectKeys.get(entry.getKey()))).
+                forEach(entry -> {
 
-                propByRes.addOldConnObjectKey(entry.getKey(), entry.getValue());
-                propByRes.add(ResourceOperation.UPDATE, entry.getKey());
-            }
-        }
+                    propByRes.addOldConnObjectKey(entry.getKey(), entry.getValue());
+                    propByRes.add(ResourceOperation.UPDATE, entry.getKey());
+                });
 
         userDAO.save(user);
 
@@ -581,46 +565,33 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             userTO.getDynRealms().addAll(userDAO.findDynRealms(user.getKey()));
 
             // roles
-            CollectionUtils.collect(user.getRoles(),
-                    EntityUtils.<Role>keyTransformer(), userTO.getRoles());
+            userTO.getRoles().addAll(user.getRoles().stream().map(r -> r.getKey()).collect(Collectors.toList()));
 
             // relationships
-            CollectionUtils.collect(user.getRelationships(), new Transformer<URelationship, RelationshipTO>() {
-
-                @Override
-                public RelationshipTO transform(final URelationship relationship) {
-                    return UserDataBinderImpl.this.getRelationshipTO(relationship);
-                }
-
-            }, userTO.getRelationships());
+            userTO.getRelationships().addAll(
+                    user.getRelationships().stream().map(relationship -> getRelationshipTO(relationship)).
+                            collect(Collectors.toList()));
 
             // memberships
-            CollectionUtils.collect(user.getMemberships(), new Transformer<UMembership, MembershipTO>() {
-
-                @Override
-                public MembershipTO transform(final UMembership membership) {
-                    return getMembershipTO(
-                            user.getPlainAttrs(membership),
-                            derAttrHandler.getValues(user, membership),
-                            virAttrHandler.getValues(user, membership),
-                            membership);
-                }
-            }, userTO.getMemberships());
+            userTO.getMemberships().addAll(
+                    user.getMemberships().stream().map(membership -> {
+                        return getMembershipTO(
+                                user.getPlainAttrs(membership),
+                                derAttrHandler.getValues(user, membership),
+                                virAttrHandler.getValues(user, membership),
+                                membership);
+                    }).collect(Collectors.toList()));
 
             // dynamic memberships
-            CollectionUtils.collect(userDAO.findDynRoles(user.getKey()),
-                    EntityUtils.<Role>keyTransformer(), userTO.getDynRoles());
-            CollectionUtils.collect(userDAO.findDynGroups(user.getKey()), new Transformer<Group, MembershipTO>() {
-
-                @Override
-                public MembershipTO transform(final Group group) {
-                    MembershipTO membershipTO = new MembershipTO.Builder().
-                            group(group.getKey(), group.getName()).
-                            build();
-                    return membershipTO;
-
-                }
-            }, userTO.getDynMemberships());
+            userTO.getDynRoles().addAll(
+                    userDAO.findDynRoles(user.getKey()).stream().map(Entity::getKey).collect(Collectors.toList()));
+
+            userTO.getDynMemberships().addAll(
+                    userDAO.findDynGroups(user.getKey()).stream().map(group -> {
+                        return new MembershipTO.Builder().
+                                group(group.getKey(), group.getName()).
+                                build();
+                    }).collect(Collectors.toList()));
         }
 
         return userTO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
index f68ec60..62587e1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
@@ -37,7 +37,6 @@ import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.apache.syncope.core.persistence.api.entity.Any;
@@ -168,27 +167,25 @@ public final class JexlUtils {
     public static void addPlainAttrsToContext(
             final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
 
-        for (PlainAttr<?> attr : attrs) {
-            if (attr.getSchema() != null) {
-                List<String> attrValues = attr.getValuesAsStrings();
-                String expressionValue = attrValues.isEmpty()
-                        ? StringUtils.EMPTY
-                        : attrValues.get(0);
+        attrs.stream().filter(attr -> attr.getSchema() != null).forEachOrdered((attr) -> {
+            List<String> attrValues = attr.getValuesAsStrings();
+            String expressionValue = attrValues.isEmpty()
+                    ? StringUtils.EMPTY
+                    : attrValues.get(0);
 
-                LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
+            LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
 
-                jexlContext.set(attr.getSchema().getKey(), expressionValue);
-            }
-        }
+            jexlContext.set(attr.getSchema().getKey(), expressionValue);
+        });
     }
 
     public static void addDerAttrsToContext(final Any<?> any, final JexlContext jexlContext) {
         Map<DerSchema, String> derAttrs =
                 ApplicationContextProvider.getBeanFactory().getBean(DerAttrHandler.class).getValues(any);
 
-        for (Map.Entry<DerSchema, String> entry : derAttrs.entrySet()) {
+        derAttrs.entrySet().forEach(entry -> {
             jexlContext.set(entry.getKey().getKey(), entry.getValue());
-        }
+        });
     }
 
     public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?> any) {
@@ -202,7 +199,7 @@ public final class JexlUtils {
     public static String evaluate(final String expression, final AnyTO anyTO, final JexlContext context) {
         addFieldsToContext(anyTO, context);
 
-        for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
+        anyTO.getPlainAttrs().forEach(plainAttr -> {
             List<String> values = plainAttr.getValues();
             String expressionValue = values.isEmpty()
                     ? StringUtils.EMPTY
@@ -211,8 +208,8 @@ public final class JexlUtils {
             LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
 
             context.set(plainAttr.getSchema(), expressionValue);
-        }
-        for (AttrTO derAttr : anyTO.getDerAttrs()) {
+        });
+        anyTO.getDerAttrs().forEach(derAttr -> {
             List<String> values = derAttr.getValues();
             String expressionValue = values.isEmpty()
                     ? StringUtils.EMPTY
@@ -221,8 +218,8 @@ public final class JexlUtils {
             LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
 
             context.set(derAttr.getSchema(), expressionValue);
-        }
-        for (AttrTO virAttr : anyTO.getVirAttrs()) {
+        });
+        anyTO.getVirAttrs().forEach(virAttr -> {
             List<String> values = virAttr.getValues();
             String expressionValue = values.isEmpty()
                     ? StringUtils.EMPTY
@@ -231,7 +228,7 @@ public final class JexlUtils {
             LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
 
             context.set(virAttr.getSchema(), expressionValue);
-        }
+        });
 
         // Evaluate expression using the context prepared before
         return evaluate(expression, context);

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SyncopeJexlFunctions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SyncopeJexlFunctions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SyncopeJexlFunctions.java
index a3b5c36..684c021 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SyncopeJexlFunctions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SyncopeJexlFunctions.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.provisioning.java.jexl;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
-import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.lang3.StringUtils;
 
 /**
@@ -61,7 +61,8 @@ public class SyncopeJexlFunctions {
         }
 
         List<String> headless = Arrays.asList(fullPathSplitted).subList(1, fullPathSplitted.length);
-        return prefix + attr + "=" + StringUtils.join(IterableUtils.reversedIterable(headless), "," + attr + "=");
+        Collections.reverse(headless);
+        return prefix + attr + "=" + StringUtils.join(headless, "," + attr + "=");
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/IdentityRecertification.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/IdentityRecertification.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/IdentityRecertification.java
index 8b3f4e5..f9d310f 100755
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/IdentityRecertification.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/IdentityRecertification.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.java.job;
 
+import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
@@ -47,15 +48,16 @@ public class IdentityRecertification extends AbstractSchedTaskJobDelegate {
     protected void init() {
         synchronized (this) {
             if (recertificationTime == -1) {
-                CPlainAttr recertificationTimeAttr = confDAO.find(RECERTIFICATION_TIME);
-                if (recertificationTimeAttr == null
-                        || recertificationTimeAttr.getValues().get(0).getLongValue() == null) {
+                Optional<? extends CPlainAttr> recertificationTimeAttr = confDAO.find(RECERTIFICATION_TIME);
+                if (!recertificationTimeAttr.isPresent()
+                        || recertificationTimeAttr.get().getValues().get(0).getLongValue() == null) {
 
                     recertificationTime = -1;
                     return;
                 }
 
-                recertificationTime = recertificationTimeAttr.getValues().get(0).getLongValue() * 1000 * 60 * 60 * 24;
+                recertificationTime = recertificationTimeAttr.get().getValues().
+                        get(0).getLongValue() * 1000 * 60 * 60 * 24;
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
index 1af62c5..f82c243 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
@@ -26,9 +26,8 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -53,7 +52,6 @@ import org.quartz.CronScheduleBuilder;
 import org.quartz.Job;
 import org.quartz.JobBuilder;
 import org.quartz.JobDataMap;
-import org.quartz.JobExecutionContext;
 import org.quartz.JobKey;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
@@ -100,14 +98,8 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
     }
 
     private boolean isRunningHere(final JobKey jobKey) throws SchedulerException {
-        return IterableUtils.matchesAny(scheduler.getScheduler().getCurrentlyExecutingJobs(),
-                new Predicate<JobExecutionContext>() {
-
-            @Override
-            public boolean evaluate(final JobExecutionContext jec) {
-                return jobKey.equals(jec.getJobDetail().getKey());
-            }
-        });
+        return scheduler.getScheduler().getCurrentlyExecutingJobs().stream().
+                anyMatch(jec -> jobKey.equals(jec.getJobDetail().getKey()));
     }
 
     private boolean isRunningElsewhere(final JobKey jobKey) throws SchedulerException {
@@ -299,54 +291,45 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
             }
         }
 
-        final Pair<String, Long> conf = AuthContextUtils.execWithAuthContext(
-                SyncopeConstants.MASTER_DOMAIN, new AuthContextUtils.Executable<Pair<String, Long>>() {
+        final Pair<String, Long> conf = AuthContextUtils.execWithAuthContext(SyncopeConstants.MASTER_DOMAIN, () -> {
+            String notificationJobCronExpression = StringUtils.EMPTY;
 
-            @Override
-            public Pair<String, Long> exec() {
-                String notificationJobCronExpression = StringUtils.EMPTY;
-
-                CPlainAttr notificationJobCronExp = confDAO.find("notificationjob.cronExpression");
-                if (notificationJobCronExp == null) {
-                    notificationJobCronExpression = NotificationJob.DEFAULT_CRON_EXP;
-                } else if (!notificationJobCronExp.getValuesAsStrings().isEmpty()) {
-                    notificationJobCronExpression = notificationJobCronExp.getValuesAsStrings().get(0);
-                }
+            Optional<? extends CPlainAttr> notificationJobCronExp = confDAO.find("notificationjob.cronExpression");
+            if (!notificationJobCronExp.isPresent()) {
+                notificationJobCronExpression = NotificationJob.DEFAULT_CRON_EXP;
+            } else if (!notificationJobCronExp.get().getValuesAsStrings().isEmpty()) {
+                notificationJobCronExpression = notificationJobCronExp.get().getValuesAsStrings().get(0);
+            }
 
-                long interruptMaxRetries = confDAO.find("tasks.interruptMaxRetries", 1L);
+            long interruptMaxRetries = confDAO.find("tasks.interruptMaxRetries", 1L);
 
-                return Pair.of(notificationJobCronExpression, interruptMaxRetries);
-            }
+            return Pair.of(notificationJobCronExpression, interruptMaxRetries);
         });
 
         for (String domain : domainsHolder.getDomains().keySet()) {
-            AuthContextUtils.execWithAuthContext(domain, new AuthContextUtils.Executable<Void>() {
-
-                @Override
-                public Void exec() {
-                    // 1. jobs for SchedTasks
-                    Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
-                    tasks.addAll(taskDAO.<PullTask>findAll(TaskType.PULL));
-                    tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
-                    for (SchedTask task : tasks) {
-                        try {
-                            register(task, task.getStartAt(), conf.getRight());
-                        } catch (Exception e) {
-                            LOG.error("While loading job instance for task " + task.getKey(), e);
-                        }
+            AuthContextUtils.execWithAuthContext(domain, () -> {
+                // 1. jobs for SchedTasks
+                Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
+                tasks.addAll(taskDAO.<PullTask>findAll(TaskType.PULL));
+                tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
+                tasks.forEach(task -> {
+                    try {
+                        register(task, task.getStartAt(), conf.getRight());
+                    } catch (Exception e) {
+                        LOG.error("While loading job instance for task " + task.getKey(), e);
                     }
-
-                    // 2. jobs for Reports
-                    for (Report report : reportDAO.findAll()) {
-                        try {
-                            register(report, null, conf.getRight());
-                        } catch (Exception e) {
-                            LOG.error("While loading job instance for report " + report.getName(), e);
-                        }
+                });
+
+                // 2. jobs for Reports
+                reportDAO.findAll().forEach(report -> {
+                    try {
+                        register(report, null, conf.getRight());
+                    } catch (Exception e) {
+                        LOG.error("While loading job instance for report " + report.getName(), e);
                     }
+                });
 
-                    return null;
-                }
+                return null;
             });
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java
index 0328e62..2e973b0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java
@@ -18,16 +18,15 @@
  */
 package org.apache.syncope.core.provisioning.java.job.report;
 
+import java.util.Base64;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -52,7 +51,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -60,7 +58,6 @@ import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
-import org.identityconnectors.common.Base64;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -266,9 +263,9 @@ public class ReconciliationReportlet extends AbstractReportlet {
             values = Collections.emptySet();
         } else if (attr.getValue().get(0) instanceof byte[]) {
             values = new HashSet<>(attr.getValue().size());
-            for (Object single : attr.getValue()) {
-                values.add(Base64.encode((byte[]) single));
-            }
+            attr.getValue().forEach(single -> {
+                values.add(Base64.getMimeEncoder().encode((byte[]) single));
+            });
         } else {
             values = new HashSet<>(attr.getValue());
         }
@@ -287,18 +284,18 @@ public class ReconciliationReportlet extends AbstractReportlet {
             misaligned.clear();
 
             AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-            for (final ExternalResource resource : anyUtils.getAllResources(any)) {
-                Provision provision = resource.getProvision(any.getType());
-                MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
-                final String connObjectKeyValue = connObjectKeyItem == null
-                        ? StringUtils.EMPTY
-                        : mappingManager.getConnObjectKeyValue(any, provision);
-                if (provision != null && connObjectKeyItem != null && StringUtils.isNotBlank(connObjectKeyValue)) {
+            anyUtils.getAllResources(any).forEach(resource -> {
+                Provision provision = resource.getProvision(any.getType()).orElse(null);
+                Optional<MappingItem> connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
+                final String connObjectKeyValue = connObjectKeyItem.isPresent()
+                        ? mappingManager.getConnObjectKeyValue(any, provision).get()
+                        : StringUtils.EMPTY;
+                if (provision != null && connObjectKeyItem.isPresent() && StringUtils.isNotBlank(connObjectKeyValue)) {
                     // 1. read from the underlying connector
                     Connector connector = connFactory.getConnector(resource);
                     ConnectorObject connectorObject = connector.getObject(
                             provision.getObjectClass(),
-                            AttributeBuilder.build(connObjectKeyItem.getExtAttrName(), connObjectKeyValue),
+                            AttributeBuilder.build(connObjectKeyItem.get().getExtAttrName(), connObjectKeyValue),
                             MappingUtils.buildOperationOptions(provision.getMapping().getItems().iterator()));
 
                     if (connectorObject == null) {
@@ -314,37 +311,33 @@ public class ReconciliationReportlet extends AbstractReportlet {
                         preparedAttrs.getRight().add(AttributeBuilder.build(
                                 Uid.NAME, preparedAttrs.getLeft()));
                         preparedAttrs.getRight().add(AttributeBuilder.build(
-                                connObjectKeyItem.getExtAttrName(), preparedAttrs.getLeft()));
+                                connObjectKeyItem.get().getExtAttrName(), preparedAttrs.getLeft()));
 
                         final Map<String, Set<Object>> syncopeAttrs = new HashMap<>();
-                        for (Attribute attr : preparedAttrs.getRight()) {
+                        preparedAttrs.getRight().forEach(attr -> {
                             syncopeAttrs.put(attr.getName(), getValues(attr));
-                        }
+                        });
 
                         final Map<String, Set<Object>> resourceAttrs = new HashMap<>();
-                        for (Attribute attr : connectorObject.getAttributes()) {
-                            if (!OperationalAttributes.PASSWORD_NAME.equals(attr.getName())
-                                    && !OperationalAttributes.ENABLE_NAME.equals(attr.getName())) {
-
-                                resourceAttrs.put(attr.getName(), getValues(attr));
-                            }
-                        }
-
-                        IterableUtils.forEach(CollectionUtils.subtract(syncopeAttrs.keySet(), resourceAttrs.keySet()),
-                                new Closure<String>() {
-
-                            @Override
-                            public void execute(final String name) {
-                                misaligned.add(new Misaligned(
-                                        resource.getKey(),
-                                        connObjectKeyValue,
-                                        name,
-                                        syncopeAttrs.get(name),
-                                        Collections.emptySet()));
-                            }
-                        });
+                        connectorObject.getAttributes().stream().
+                                filter(attr -> (!OperationalAttributes.PASSWORD_NAME.equals(attr.getName())
+                                && !OperationalAttributes.ENABLE_NAME.equals(attr.getName()))).
+                                forEachOrdered(attr -> {
+                                    resourceAttrs.put(attr.getName(), getValues(attr));
+                                });
+
+                        syncopeAttrs.keySet().stream().
+                                filter(syncopeAttr -> !resourceAttrs.containsKey(syncopeAttr)).
+                                forEach(name -> {
+                                    misaligned.add(new Misaligned(
+                                            resource.getKey(),
+                                            connObjectKeyValue,
+                                            name,
+                                            syncopeAttrs.get(name),
+                                            Collections.emptySet()));
+                                });
 
-                        for (Map.Entry<String, Set<Object>> entry : resourceAttrs.entrySet()) {
+                        resourceAttrs.entrySet().forEach(entry -> {
                             if (syncopeAttrs.containsKey(entry.getKey())) {
                                 if (!Objects.equals(syncopeAttrs.get(entry.getKey()), entry.getValue())) {
                                     misaligned.add(new Misaligned(
@@ -362,10 +355,10 @@ public class ReconciliationReportlet extends AbstractReportlet {
                                         Collections.emptySet(),
                                         entry.getValue()));
                             }
-                        }
+                        });
                     }
                 }
-            }
+            });
 
             if (!missing.isEmpty() || !misaligned.isEmpty()) {
                 doExtract(handler, any, missing, misaligned);

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/UserReportlet.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/UserReportlet.java
index 2e4314d..a485672 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/UserReportlet.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/UserReportlet.java
@@ -287,7 +287,7 @@ public class UserReportlet extends AbstractReportlet {
                     handler.startElement("", "", "membership", atts);
 
                     if (conf.getFeatures().contains(Feature.resources)) {
-                        UMembership actualMemb = user.getMembership(memb.getRightKey());
+                        UMembership actualMemb = user.getMembership(memb.getRightKey()).orElse(null);
                         if (actualMemb == null) {
                             LOG.warn("Unexpected: cannot find membership for group {} for user {}",
                                     memb.getRightKey(), user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 5438cee..f2eeaf4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
@@ -25,9 +25,8 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -63,7 +62,6 @@ import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyAbout;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -196,7 +194,7 @@ public class NotificationManagerImpl implements NotificationManager {
 
         Set<String> recipientEmails = new HashSet<>();
         List<UserTO> recipientTOs = new ArrayList<>(recipients.size());
-        for (User recipient : recipients) {
+        recipients.forEach(recipient -> {
             virAttrHander.getValues(recipient);
 
             String email = getRecipientEmail(notification.getRecipientAttrName(), recipient);
@@ -206,7 +204,7 @@ public class NotificationManagerImpl implements NotificationManager {
                 recipientEmails.add(email);
                 recipientTOs.add(userDataBinder.getUserTO(recipient, true));
             }
-        }
+        });
 
         if (notification.getStaticRecipients() != null) {
             recipientEmails.addAll(notification.getStaticRecipients());
@@ -266,15 +264,10 @@ public class NotificationManagerImpl implements NotificationManager {
 
         final String successEvent = AuditLoggerName.buildEvent(type, category, subcategory, event, Result.SUCCESS);
         final String failureEvent = AuditLoggerName.buildEvent(type, category, subcategory, event, Result.FAILURE);
-        return IterableUtils.matchesAny(notificationDAO.findAll(), new Predicate<Notification>() {
-
-            @Override
-            public boolean evaluate(final Notification notification) {
-                return notification.isActive()
-                        && (notification.getEvents().contains(successEvent)
-                        || notification.getEvents().contains(failureEvent));
-            }
-        });
+        return notificationDAO.findAll().stream().
+                anyMatch(notification -> notification.isActive()
+                && (notification.getEvents().contains(successEvent)
+                || notification.getEvents().contains(failureEvent)));
     }
 
     @Override
@@ -339,9 +332,9 @@ public class NotificationManagerImpl implements NotificationManager {
         List<NotificationTask> notifications = new ArrayList<>();
         for (Notification notification : notificationDAO.findAll()) {
             if (LOG.isDebugEnabled()) {
-                for (AnyAbout about : notification.getAbouts()) {
+                notification.getAbouts().forEach(about -> {
                     LOG.debug("Notification about {} defined: {}", about.getAnyType(), about.get());
-                }
+                });
             }
 
             if (notification.isActive()) {
@@ -349,8 +342,9 @@ public class NotificationManagerImpl implements NotificationManager {
                 if (!notification.getEvents().contains(currentEvent)) {
                     LOG.debug("No events found about {}", any);
                 } else if (anyType == null || any == null
-                        || notification.getAbout(anyType) == null
-                        || searchDAO.matches(any, SearchCondConverter.convert(notification.getAbout(anyType).get()))) {
+                        || !notification.getAbout(anyType).isPresent()
+                        || searchDAO.matches(
+                                any, SearchCondConverter.convert(notification.getAbout(anyType).get().get()))) {
 
                     LOG.debug("Creating notification task for event {} about {}", currentEvent, any);
 
@@ -395,17 +389,19 @@ public class NotificationManagerImpl implements NotificationManager {
             if (intAttrName.getMembershipOfGroup() != null) {
                 Group group = groupDAO.findByName(intAttrName.getMembershipOfGroup());
                 if (group != null) {
-                    membership = user.getMembership(group.getKey());
+                    membership = user.getMembership(group.getKey()).orElse(null);
                 }
             }
 
             switch (intAttrName.getSchemaType()) {
                 case PLAIN:
-                    UPlainAttr attr = membership == null
+                    Optional<? extends UPlainAttr> attr = membership == null
                             ? user.getPlainAttr(recipientAttrName)
                             : user.getPlainAttr(recipientAttrName, membership);
-                    if (attr != null) {
-                        email = attr.getValuesAsStrings().isEmpty() ? null : attr.getValuesAsStrings().get(0);
+                    if (attr.isPresent()) {
+                        email = attr.get().getValuesAsStrings().isEmpty()
+                                ? null
+                                : attr.get().getValuesAsStrings().get(0);
                     }
                     break;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 395a5a8..833edfc 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -27,7 +27,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import org.apache.commons.collections4.IteratorUtils;
+import org.apache.syncope.common.lib.collections.IteratorChain;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.types.AuditElements;
@@ -52,7 +52,6 @@ import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
@@ -160,7 +159,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         List<PropagationActions> result = new ArrayList<>();
 
         if (!resource.getPropagationActionsClassNames().isEmpty()) {
-            for (String className : resource.getPropagationActionsClassNames()) {
+            resource.getPropagationActionsClassNames().forEach(className -> {
                 try {
                     Class<?> actionsClass = Class.forName(className);
                     result.add((PropagationActions) ApplicationContextProvider.getBeanFactory().
@@ -168,7 +167,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                 } catch (ClassNotFoundException e) {
                     LOG.error("Invalid PropagationAction class name '{}' for resource {}", resource, className, e);
                 }
-            }
+            });
         }
 
         return result;
@@ -192,9 +191,9 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
      */
     private Map<String, Attribute> toMap(final Collection<? extends Attribute> attributes) {
         Map<String, Attribute> map = new HashMap<>();
-        for (Attribute attr : attributes) {
+        attributes.forEach(attr -> {
             map.put(attr.getName().toUpperCase(), attr);
-        }
+        });
         return map;
     }
 
@@ -254,9 +253,9 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
             // Only compare attribute from beforeObj that are also being updated
             Set<String> skipAttrNames = originalAttrMap.keySet();
             skipAttrNames.removeAll(updateAttrMap.keySet());
-            for (String attrName : new HashSet<>(skipAttrNames)) {
+            new HashSet<>(skipAttrNames).forEach(attrName -> {
                 originalAttrMap.remove(attrName);
-            }
+            });
 
             Set<Attribute> originalAttrs = new HashSet<>(originalAttrMap.values());
 
@@ -267,11 +266,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                 LOG.debug("Attributes that would be updated {}", attributes);
 
                 Set<Attribute> strictlyModified = new HashSet<>();
-                for (Attribute attr : attributes) {
-                    if (!originalAttrs.contains(attr)) {
-                        strictlyModified.add(attr);
-                    }
-                }
+                attributes.stream().filter(attr -> (!originalAttrs.contains(attr))).
+                        forEachOrdered(attr -> {
+                            strictlyModified.add(attr);
+                        });
 
                 // 3. provision entry
                 LOG.debug("Update {} on {}", strictlyModified, task.getResource().getKey());
@@ -377,7 +375,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         Connector connector = null;
         Result result;
         try {
-            provision = task.getResource().getProvision(new ObjectClass(task.getObjectClassName()));
+            provision = task.getResource().getProvision(new ObjectClass(task.getObjectClassName())).orElse(null);
             orgUnit = task.getResource().getOrgUnit();
             connector = connFactory.getConnector(task.getResource());
 
@@ -439,9 +437,9 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
 
             propagationAttempted[0] = true;
 
-            for (PropagationActions action : actions) {
+            actions.forEach(action -> {
                 action.onError(task, execution, e);
-            }
+            });
         } finally {
             // Try to read remote object AFTER any actual operation
             if (connector != null) {
@@ -602,17 +600,17 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                 : task.getOldConnObjectKey();
 
         List<MappingItem> linkingMappingItems = new ArrayList<>();
-        for (VirSchema schema : virSchemaDAO.findByProvision(provision)) {
+        virSchemaDAO.findByProvision(provision).forEach(schema -> {
             linkingMappingItems.add(schema.asLinkingMappingItem());
-        }
+        });
 
         ConnectorObject obj = null;
         try {
             obj = connector.getObject(
                     new ObjectClass(task.getObjectClassName()),
                     AttributeBuilder.build(
-                            MappingUtils.getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey),
-                    MappingUtils.buildOperationOptions(IteratorUtils.chainedIterator(
+                            MappingUtils.getConnObjectKeyItem(provision).get().getExtAttrName(), connObjectKey),
+                    MappingUtils.buildOperationOptions(new IteratorChain<>(
                             MappingUtils.getPropagationItems(provision).iterator(),
                             linkingMappingItems.iterator())));
 
@@ -658,7 +656,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         ConnectorObject obj = null;
         try {
             obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
-                    AttributeBuilder.build(orgUnit.getConnObjectKeyItem().getExtAttrName(), connObjectKey),
+                    AttributeBuilder.build(orgUnit.getConnObjectKeyItem().get().getExtAttrName(), connObjectKey),
                     MappingUtils.buildOperationOptions(MappingUtils.getPropagationItems(orgUnit).iterator()));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
index 7d81f11..a40d9b2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
@@ -19,9 +19,8 @@
 package org.apache.syncope.core.provisioning.java.propagation;
 
 import java.util.HashSet;
+import java.util.Optional;
 import java.util.Set;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -86,19 +85,13 @@ public class DBPasswordPropagationActions implements PropagationActions {
     }
 
     private String getCipherAlgorithm(final ConnInstance connInstance) {
-        ConnConfProperty cipherAlgorithm =
-                IterableUtils.find(connInstance.getConf(), new Predicate<ConnConfProperty>() {
-
-                    @Override
-                    public boolean evaluate(final ConnConfProperty property) {
-                        return "cipherAlgorithm".equals(property.getSchema().getName())
-                                && property.getValues() != null && !property.getValues().isEmpty();
-                    }
-                });
-
-        return cipherAlgorithm == null
-                ? CLEARTEXT
-                : (String) cipherAlgorithm.getValues().get(0);
+        Optional<ConnConfProperty> cipherAlgorithm = connInstance.getConf().stream().
+                filter(property -> "cipherAlgorithm".equals(property.getSchema().getName())
+                && property.getValues() != null && !property.getValues().isEmpty()).findFirst();
+
+        return cipherAlgorithm.isPresent()
+                ? (String) cipherAlgorithm.get().getValues().get(0)
+                : CLEARTEXT;
     }
 
     private boolean cipherAlgorithmMatches(final String connectorAlgorithm, final CipherAlgorithm userAlgorithm) {
@@ -111,11 +104,7 @@ public class DBPasswordPropagationActions implements PropagationActions {
         }
 
         // Special check for "SHA" (user sync'd from LDAP)
-        if ("SHA1".equals(connectorAlgorithm) && "SHA".equals(userAlgorithm.name())) {
-            return true;
-        }
-
-        return false;
+        return "SHA1".equals(connectorAlgorithm) && "SHA".equals(userAlgorithm.name());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
index 635c015..6e58281 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
@@ -22,8 +22,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
+import java.util.Optional;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
@@ -44,13 +43,7 @@ public class DefaultPropagationReporter implements PropagationReporter {
     protected final List<PropagationStatus> statuses = new ArrayList<>();
 
     protected boolean add(final PropagationStatus status) {
-        return IterableUtils.matchesAny(statuses, new Predicate<PropagationStatus>() {
-
-            @Override
-            public boolean evaluate(final PropagationStatus item) {
-                return item.getResource().equals(status.getResource());
-            }
-        })
+        return statuses.stream().anyMatch(item -> item.getResource().equals(status.getResource()))
                 ? false
                 : statuses.add(status);
     }
@@ -83,23 +76,18 @@ public class DefaultPropagationReporter implements PropagationReporter {
     public void onPriorityResourceFailure(final String failingResource, final Collection<PropagationTask> tasks) {
         LOG.debug("Propagation error: {} priority resource failed to propagate", failingResource);
 
-        final PropagationTask propagationTask = IterableUtils.find(tasks, new Predicate<PropagationTask>() {
-
-            @Override
-            public boolean evaluate(final PropagationTask task) {
-                return task.getResource().getKey().equals(failingResource);
-            }
-        });
+        Optional<PropagationTask> propagationTask = tasks.stream().
+                filter(task -> task.getResource().getKey().equals(failingResource)).findFirst();
 
-        if (propagationTask == null) {
-            LOG.error("Could not find {} for {}", PropagationTask.class.getName(), failingResource);
-        } else {
+        if (propagationTask.isPresent()) {
             PropagationStatus status = new PropagationStatus();
-            status.setResource(propagationTask.getResource().getKey());
+            status.setResource(propagationTask.get().getResource().getKey());
             status.setStatus(PropagationTaskExecStatus.FAILURE);
             status.setFailureReason(
                     "Propagation error: " + failingResource + " priority resource failed to propagate.");
             add(status);
+        } else {
+            LOG.error("Could not find {} for {}", PropagationTask.class.getName(), failingResource);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index b3d05f4..58fc0d3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java.propagation;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import org.apache.commons.jexl3.JexlContext;
 import org.apache.commons.jexl3.MapContext;
@@ -75,32 +76,30 @@ public class LDAPMembershipPropagationActions implements PropagationActions {
     @Transactional(readOnly = true)
     @Override
     public void before(final PropagationTask task, final ConnectorObject beforeObj) {
-        Provision provision = task.getResource().getProvision(anyTypeDAO.findGroup());
+        Optional<? extends Provision> provision = task.getResource().getProvision(anyTypeDAO.findGroup());
         if (AnyTypeKind.USER == task.getAnyTypeKind()
-                && provision != null && provision.getMapping() != null
-                && StringUtils.isNotBlank(provision.getMapping().getConnObjectLink())) {
+                && provision.isPresent() && provision.get().getMapping() != null
+                && StringUtils.isNotBlank(provision.get().getMapping().getConnObjectLink())) {
 
             User user = userDAO.find(task.getEntityKey());
             if (user != null) {
                 List<String> groupConnObjectLinks = new ArrayList<>();
-                for (String groupKey : userDAO.findAllGroupKeys(user)) {
+                userDAO.findAllGroupKeys(user).forEach(groupKey -> {
                     Group group = groupDAO.find(groupKey);
                     if (group != null && groupDAO.findAllResourceKeys(groupKey).contains(task.getResource().getKey())) {
                         LOG.debug("Evaluating connObjectLink for {}", group);
-
                         JexlContext jexlContext = new MapContext();
                         JexlUtils.addFieldsToContext(group, jexlContext);
                         JexlUtils.addPlainAttrsToContext(group.getPlainAttrs(), jexlContext);
                         JexlUtils.addDerAttrsToContext(group, jexlContext);
-
                         String groupConnObjectLinkLink =
-                                JexlUtils.evaluate(provision.getMapping().getConnObjectLink(), jexlContext);
+                                JexlUtils.evaluate(provision.get().getMapping().getConnObjectLink(), jexlContext);
                         LOG.debug("ConnObjectLink for {} is '{}'", group, groupConnObjectLinkLink);
                         if (StringUtils.isNotBlank(groupConnObjectLinkLink)) {
                             groupConnObjectLinks.add(groupConnObjectLinkLink);
                         }
                     }
-                }
+                });
                 LOG.debug("Group connObjectLinks to propagate for membership: {}", groupConnObjectLinks);
 
                 Set<Attribute> attributes = new HashSet<>(task.getAttributes());
@@ -108,9 +107,9 @@ public class LDAPMembershipPropagationActions implements PropagationActions {
                 Set<String> groups = new HashSet<>(groupConnObjectLinks);
                 Attribute ldapGroups = AttributeUtil.find(getGroupMembershipAttrName(), attributes);
                 if (ldapGroups != null) {
-                    for (Object obj : ldapGroups.getValue()) {
+                    ldapGroups.getValue().forEach(obj -> {
                         groups.add(obj.toString());
-                    }
+                    });
                     attributes.remove(ldapGroups);
                 }
                 attributes.add(AttributeBuilder.build(getGroupMembershipAttrName(), groups));

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
index 5dcdf98..ea4f37d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
@@ -19,9 +19,8 @@
 package org.apache.syncope.core.provisioning.java.propagation;
 
 import java.util.HashSet;
+import java.util.Optional;
 import java.util.Set;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -92,19 +91,13 @@ public class LDAPPasswordPropagationActions implements PropagationActions {
     }
 
     private String getCipherAlgorithm(final ConnInstance connInstance) {
-        ConnConfProperty cipherAlgorithm =
-                IterableUtils.find(connInstance.getConf(), new Predicate<ConnConfProperty>() {
-
-                    @Override
-                    public boolean evaluate(final ConnConfProperty property) {
-                        return "passwordHashAlgorithm".equals(property.getSchema().getName())
-                                && property.getValues() != null && !property.getValues().isEmpty();
-                    }
-                });
-
-        return cipherAlgorithm == null
-                ? CLEARTEXT
-                : (String) cipherAlgorithm.getValues().get(0);
+        Optional<ConnConfProperty> cipherAlgorithm = connInstance.getConf().stream().
+                filter(property -> "passwordHashAlgorithm".equals(property.getSchema().getName())
+                && property.getValues() != null && !property.getValues().isEmpty()).findFirst();
+
+        return cipherAlgorithm.isPresent()
+                ? (String) cipherAlgorithm.get().getValues().get(0)
+                : CLEARTEXT;
     }
 
     private boolean cipherAlgorithmMatches(final String connectorAlgorithm, final CipherAlgorithm userAlgorithm) {
@@ -117,11 +110,7 @@ public class LDAPPasswordPropagationActions implements PropagationActions {
         }
 
         // Special check for "SHA" (user sync'd from LDAP)
-        if ("SHA".equals(connectorAlgorithm) && "SHA1".equals(userAlgorithm.name())) {
-            return true;
-        }
-
-        return false;
+        return "SHA".equals(connectorAlgorithm) && "SHA1".equals(userAlgorithm.name());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/74ee038a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
index 5fc32e1..8322635 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.provisioning.java.propagation;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -32,9 +31,8 @@ import java.util.concurrent.CompletionService;
 import java.util.concurrent.ExecutorCompletionService;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 import javax.annotation.Resource;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
@@ -84,21 +82,17 @@ public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExec
             final PropagationReporter reporter,
             final boolean nullPriorityAsync) {
 
-        List<PropagationTask> prioritizedTasks = CollectionUtils.select(tasks, new Predicate<PropagationTask>() {
-
-            @Override
-            public boolean evaluate(final PropagationTask task) {
-                return task.getResource().getPropagationPriority() != null;
-            }
-        }, new ArrayList<PropagationTask>());
+        List<PropagationTask> prioritizedTasks = tasks.stream().
+                filter(task -> task.getResource().getPropagationPriority() != null).collect(Collectors.toList());
         Collections.sort(prioritizedTasks, new PriorityComparator());
         LOG.debug("Propagation tasks sorted by priority, for serial execution: {}", prioritizedTasks);
 
-        Collection<PropagationTask> concurrentTasks = CollectionUtils.subtract(tasks, prioritizedTasks);
+        Collection<PropagationTask> concurrentTasks = tasks.stream().
+                filter(task -> !prioritizedTasks.contains(task)).collect(Collectors.toSet());
         LOG.debug("Propagation tasks for concurrent execution: {}", concurrentTasks);
 
         // first process priority resources sequentially and fail as soon as any propagation failure is reported
-        for (PropagationTask task : prioritizedTasks) {
+        prioritizedTasks.forEach(task -> {
             TaskExec execution = null;
             PropagationTaskExecStatus execStatus;
             try {
@@ -112,12 +106,12 @@ public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExec
                 throw new PropagationException(
                         task.getResource().getKey(), execution == null ? null : execution.getMessage());
             }
-        }
+        });
 
         // then process non-priority resources concurrently...
         final CompletionService<TaskExec> completionService = new ExecutorCompletionService<>(executor);
         Map<PropagationTask, Future<TaskExec>> nullPriority = new HashMap<>(concurrentTasks.size());
-        for (PropagationTask task : concurrentTasks) {
+        concurrentTasks.forEach(task -> {
             try {
                 nullPriority.put(
                         task,
@@ -125,36 +119,32 @@ public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExec
             } catch (Exception e) {
                 LOG.error("Unexpected exception", e);
             }
-        }
+        });
         // ...waiting for all callables to complete, if async processing was not required
         if (!nullPriority.isEmpty()) {
             if (nullPriorityAsync) {
-                for (Map.Entry<PropagationTask, Future<TaskExec>> entry : nullPriority.entrySet()) {
+                nullPriority.entrySet().forEach(entry -> {
                     reporter.onSuccessOrNonPriorityResourceFailures(
                             entry.getKey(), PropagationTaskExecStatus.CREATED, null, null, null);
-                }
+                });
             } else {
                 final Set<Future<TaskExec>> nullPriorityFutures = new HashSet<>(nullPriority.values());
                 try {
-                    executor.submit(new Runnable() {
-
-                        @Override
-                        public void run() {
-                            while (!nullPriorityFutures.isEmpty()) {
-                                try {
-                                    nullPriorityFutures.remove(completionService.take());
-                                } catch (Exception e) {
-                                    LOG.error("Unexpected exception", e);
-                                }
+                    executor.submit(() -> {
+                        while (!nullPriorityFutures.isEmpty()) {
+                            try {
+                                nullPriorityFutures.remove(completionService.take());
+                            } catch (Exception e) {
+                                LOG.error("Unexpected exception", e);
                             }
                         }
                     }).get(60, TimeUnit.SECONDS);
                 } catch (Exception e) {
                     LOG.error("Unexpected exception", e);
                 } finally {
-                    for (Future<TaskExec> future : nullPriorityFutures) {
+                    nullPriorityFutures.forEach(future -> {
                         future.cancel(true);
-                    }
+                    });
                     nullPriorityFutures.clear();
                     nullPriority.clear();
                 }