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 2015/08/13 17:17:53 UTC

[11/26] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/Two.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/Two.properties b/core/persistence-jpa/src/test/resources/domains/Two.properties
new file mode 100644
index 0000000..b37a969
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/Two.properties
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+Two.driverClassName=org.h2.Driver
+Two.url=jdbc:h2:file:${project.build.directory}/test-classes/syncopetwo.db;DB_CLOSE_DELAY=-1
+Two.schema=
+Two.username=sa
+Two.password=
+Two.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
+Two.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Two.pool.validationQuery=SELECT 1
+
+Two.audit.sql=audit.sql

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
new file mode 100644
index 0000000..92216fd
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<dataset>
+  <Realm id="1" name="/"/>
+
+  <SyncopeConf id="1" 
+               creator="admin" lastModifier="admin"
+               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
+
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
+  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
+
+  <!-- notificationjob.cronExpression:
+  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
+  + provided as empty string: NotificationJob disabled
+  + provided as non-empty string: NotificationJob runs according to the given value -->
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
+  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
+
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
+  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
+
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
+  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
+
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
+  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
+
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
+  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
+  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
+
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
+  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
+  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
+
+  <!-- Save user login date upon successful authentication -->
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
+  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
+
+  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
+  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="BaseUser"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="BaseUser"/>
+
+  <AnyType name="GROUP" kind="GROUP"/>
+  
+  <!-- For usage with admin console -->
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+        
+  <PlainSchema name="email" type="String" anyTypeClass_name="BaseUser"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  
+  <!-- Password reset notifications -->
+  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <AnyAbout id="1" anyType_name="USER" notification_id="1" about="token!=$null"/>
+  <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
+  
+  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
+
+</dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
new file mode 100644
index 0000000..c7e7a9b
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd                           
+                           http://www.springframework.org/schema/tx
+                           http://www.springframework.org/schema/tx/spring-tx.xsd
+                           http://www.springframework.org/schema/util
+                           http://www.springframework.org/schema/util/spring-util.xsd">
+  
+  <bean id="TwoContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
+    <property name="fallback" value="classpath:domains/TwoContent.xml"/>
+  </bean>
+  <bean id="TwoProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/Two.properties"/>
+    <property name="fallback" value="classpath:domains/Two.properties"/>
+  </bean>
+  <bean id="TwoDatabaseSchema" class="java.lang.String">
+    <constructor-arg value="${Two.schema}"/>
+  </bean>
+
+  <!-- Use JNDI datasource as default but, when not available, revert to
+  local datasource, with different properties for execution and testing. 
+  In any case, get all JDBC connections with a determined isolation level. -->
+  <bean id="TwoDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+    <property name="jndiName" value="java:comp/env/jdbc/syncopeTwoDataSource"/>
+    <property name="defaultObject" ref="localTwoDataSource"/>
+  </bean>
+
+  <bean id="localTwoDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
+    <property name="driverClassName" value="${Two.driverClassName}"/>
+    <property name="url" value="${Two.url}"/>
+    <property name="username" value="${Two.username}"/>
+    <property name="password" value="${Two.password}"/>
+    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
+    <property name="defaultTransactionIsolation">
+      <util:constant static-field="${Two.pool.defaultTransactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
+    </property>
+    <!-- connection pool configuration - default values taken from BasicDataSource default values -->
+    <property name="initialSize" value="${Two.pool.initialSize:0}"/>
+    <property name="maxTotal" value="${Two.pool.maxActive:8}"/>
+    <property name="maxIdle" value="${Two.pool.maxIdle:8}"/>
+    <property name="minIdle" value="${Two.pool.minIdle:0}"/>
+    <property name="maxWaitMillis" value="${Two.pool.maxWait:-1}"/>
+    <!--<property name="validationQuery" value="${Two.pool.validationQuery}"/>-->
+    <property name="validationQueryTimeout" value="${Two.pool.validationQueryTimeout:-1}"/>
+    <property name="testOnBorrow" value="${Two.pool.testOnBorrow:true}"/>
+    <property name="testOnReturn" value="${Two.pool.testOnReturn:false}"/>
+    <property name="testWhileIdle" value="${Two.pool.testWhileIdle:false}"/>
+    <property name="timeBetweenEvictionRunsMillis" value="${Two.pool.timeBetweenEvictionRunsMillis:-1}"/>
+    <property name="numTestsPerEvictionRun" value="${Two.pool.numTestsPerEvictionRun:3}"/>
+    <property name="minEvictableIdleTimeMillis" value="${Two.pool.minEvictableIdleTimeMillis:1800000}"/>
+    <property name="removeAbandonedOnBorrow" value="${Two.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedOnMaintenance" value="${Two.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedTimeout" value="${Two.pool.removeAbandonedTimeout:300}"/>
+    <property name="logAbandoned" value="${Two.pool.logAbandoned:false}"/>
+  </bean>
+  
+  <bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
+    <property name="dataSource" ref="TwoDataSource"/>
+    <property name="enabled" value="true"/>
+    <property name="databasePopulator">
+      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
+        <property name="continueOnError" value="true"/>
+        <property name="ignoreFailedDrops" value="true"/>
+        <property name="sqlScriptEncoding" value="UTF-8"/>
+        <property name="scripts">
+          <array>
+            <value type="org.springframework.core.io.Resource">
+              classpath:/audit/${Two.audit.sql}
+            </value>
+          </array>
+        </property>
+      </bean>
+    </property>
+  </bean>
+  
+  <bean id="TwoEntityManagerFactory"
+        class="org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean">
+    <property name="mappingResources">
+      <list>
+        <value>${Two.orm}</value>
+      </list>
+    </property>
+    <property name="persistenceUnitName" value="Two"/>
+    <property name="dataSource" ref="TwoDataSource"/>
+    <property name="jpaVendorAdapter">
+      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
+        <property name="showSql" value="false"/>
+        <property name="generateDdl" value="true"/>
+        <property name="databasePlatform" value="${Two.databasePlatform}"/>
+      </bean>
+    </property>
+    <property name="commonEntityManagerFactoryConf" ref="commonEMFConf"/>
+  </bean>  
+
+  <bean id="TwoTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+    <property name="entityManagerFactory" ref="TwoEntityManagerFactory"/>
+    <qualifier value="Two"/>
+  </bean>
+  
+  <tx:annotation-driven transaction-manager="TwoTransactionManager"/>
+
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistence.properties b/core/persistence-jpa/src/test/resources/persistence.properties
deleted file mode 100644
index 31ea1b0..0000000
--- a/core/persistence-jpa/src/test/resources/persistence.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-content.directory=${conf.directory}
-jpa.driverClassName=org.h2.Driver
-jpa.url=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1
-jpa.username=sa
-jpa.password=
-jpa.dialect=org.apache.openjpa.jdbc.sql.H2Dictionary
-jpa.pool.validationQuery=SELECT 1
-jpa.orm=META-INF/spring-orm.xml
-# note: other connection pool settings can also be configured here, see persistenceContext.xml
-quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-quartz.scheduler.idleWaitTime=5000
-quartz.sql=tables_h2.sql
-audit.sql=audit.sql
-database.schema=
-

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/test/resources/persistenceTest.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistenceTest.xml b/core/persistence-jpa/src/test/resources/persistenceTest.xml
index a87172b..da8f321 100644
--- a/core/persistence-jpa/src/test/resources/persistenceTest.xml
+++ b/core/persistence-jpa/src/test/resources/persistenceTest.xml
@@ -29,6 +29,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
       </list>
     </property>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
index 6928ffd..5645979 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
@@ -18,8 +18,13 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
+import java.util.List;
 import org.apache.syncope.common.lib.mod.AnyObjectMod;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
 
 public interface AnyObjectProvisioningManager extends ProvisioningManager<AnyObjectTO, AnyObjectMod> {
+
+    List<PropagationStatus> provision(Long key, Collection<String> resources);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
index 1dce013..c74b5df 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -31,4 +32,6 @@ public interface GroupProvisioningManager extends ProvisioningManager<GroupTO, G
     Pair<Long, List<PropagationStatus>> create(
             GroupTO groupTO, Map<Long, String> groupOwnerMap, Set<String> excludedResources);
 
+    List<PropagationStatus> provision(Long key, Collection<String> resources);
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
index 810a788..3378707 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
@@ -30,11 +31,11 @@ import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 
 public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserMod> {
 
-    Pair<Long, List<PropagationStatus>> activate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> activate(StatusMod statusMod);
 
-    Pair<Long, List<PropagationStatus>> reactivate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> reactivate(StatusMod statusMod);
 
-    Pair<Long, List<PropagationStatus>> suspend(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> suspend(StatusMod statusMod);
 
     void innerSuspend(User user, boolean propagate);
 
@@ -48,6 +49,8 @@ public interface UserProvisioningManager extends ProvisioningManager<UserTO, Use
 
     void requestPasswordReset(Long key);
 
-    void confirmPasswordReset(User user, String token, String password);
+    void confirmPasswordReset(Long key, String token, String password);
+
+    List<PropagationStatus> provision(Long key, boolean changePwd, String password, Collection<String> resources);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
index 7434976..14f0c83 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
@@ -19,20 +19,20 @@
 package org.apache.syncope.core.provisioning.api.job;
 
 import java.text.ParseException;
+import java.util.Map;
 import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.quartz.SchedulerException;
 
 public interface JobInstanceLoader {
 
-    void registerJob(Task task, String jobClassName, String cronExpression)
-            throws ClassNotFoundException, SchedulerException, ParseException;
+    String DOMAIN = "domain";
 
-    void registerJob(Report report) throws SchedulerException, ParseException;
+    Map<String, Object> registerJob(final SchedTask task, final long interruptMaxRetries)
+            throws SchedulerException, ParseException;
 
-    void registerReportJob(Long reportKey) throws SchedulerException, ParseException;
-
-    void registerTaskJob(Long taskKey) throws ClassNotFoundException, SchedulerException, ParseException;
+    void registerJob(final Report report) throws SchedulerException, ParseException;
 
     void unregisterJob(Task task);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
index 9ddf563..22d7b54 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
@@ -29,7 +29,7 @@ public final class JobNamer {
 
     private static final Logger LOG = LoggerFactory.getLogger(JobNamer.class);
 
-    private static Long getIdFromJobName(final String name, final String pattern, final int prefixLength) {
+    private static Long getKeyFromJobName(final String name, final String pattern, final int prefixLength) {
         Long result = null;
 
         Matcher jobMatcher = Pattern.compile(pattern).matcher(name);
@@ -45,17 +45,15 @@ public final class JobNamer {
     }
 
     public static Long getTaskKeyFromJobName(final String name) {
-        return getIdFromJobName(name, "taskJob[0-9]+", 7);
+        return getKeyFromJobName(name, "taskJob[0-9]+", 7);
     }
 
     public static Long getReportKeyFromJobName(final String name) {
-        return getIdFromJobName(name, "reportJob[0-9]+", 9);
+        return getKeyFromJobName(name, "reportJob[0-9]+", 9);
     }
 
     public static String getJobName(final Task task) {
-        return task == null
-                ? "taskNotificationJob"
-                : "taskJob" + task.getKey();
+        return "taskJob" + task.getKey();
     }
 
     public static String getJobName(final Report report) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
deleted file mode 100644
index 9a6386f..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
-
-public interface ProvisioningJob<T extends ProvisioningTask, A extends ProvisioningActions> extends TaskJob {
-
-    void setActions(List<A> actions);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
deleted file mode 100644
index 388d780..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-
-public interface PushJob extends ProvisioningJob<PushTask, PushActions> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
new file mode 100644
index 0000000..74e9247
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.job;
+
+import org.quartz.JobExecutionException;
+
+public interface SchedTaskJobDelegate {
+
+    void execute(Long taskKey, boolean dryRun) throws JobExecutionException;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
deleted file mode 100644
index 147daa5..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-
-public interface SyncJob extends ProvisioningJob<SyncTask, SyncActions> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
deleted file mode 100644
index 3df89bc..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.job;
-
-import org.quartz.DisallowConcurrentExecution;
-import org.quartz.InterruptableJob;
-
-/**
- * Interface for Quartz jobs bound to a given Task.
- */
-@DisallowConcurrentExecution
-public interface TaskJob extends InterruptableJob {
-
-    String DRY_RUN_JOBDETAIL_KEY = "dryRun";
-
-    /**
-     * Task execution status.
-     */
-    public enum Status {
-
-        SUCCESS,
-        FAILURE
-
-    }
-
-    void setTaskId(Long taskId);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
index cf8cde4..3155223 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
@@ -27,7 +27,6 @@ import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 
@@ -149,12 +148,12 @@ public interface PropagationManager {
     /**
      * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter.
      *
-     * @param user to be propagated
+     * @param key to be propagated
      * @param enable whether user must be enabled or not
      * @param noPropResourceNames external resource names not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserUpdateTasks(User user, Boolean enable, Collection<String> noPropResourceNames);
+    List<PropagationTask> getUserUpdateTasks(Long key, Boolean enable, Collection<String> noPropResourceNames);
 
     /**
      * Performs update on each resource associated to the user.

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index a1dc161..85ea59f 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -150,6 +150,13 @@ under the License.
         <filtering>true</filtering>
       </testResource>
       <testResource>
+        <directory>${basedir}/../persistence-jpa/src/main/resources</directory>
+        <includes>
+          <include>persistence.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </testResource>
+      <testResource>
         <directory>${basedir}/../persistence-jpa/src/test/resources</directory>
         <filtering>true</filtering>
       </testResource>

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
index e23143a..bcea03d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
@@ -95,7 +95,7 @@ public class ConnectorFacadeProxy implements Connector {
         this.activeConnInstance = connInstance;
 
         ConnIdBundleManager connIdBundleManager =
-                ApplicationContextProvider.getApplicationContext().getBean(ConnIdBundleManager.class);
+                ApplicationContextProvider.getBeanFactory().getBean(ConnIdBundleManager.class);
         ConnectorInfo info = connIdBundleManager.getConnectorInfo(connInstance);
 
         // create default configuration

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index 7d0cf2f..38b3f2a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -25,13 +25,13 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.identityconnectors.common.l10n.CurrentLocale;
 import org.identityconnectors.framework.api.ConnectorFacadeFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
index fd6bcf1..9722adb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
@@ -81,7 +82,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
         List<PropagationTask> tasks = propagationManager.getAnyObjectCreateTasks(
                 created, anyObjectTO.getVirAttrs(), excludedResources);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -118,7 +119,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -130,20 +131,20 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyObjectKey) {
-        return delete(anyObjectKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         List<PropagationTask> tasks = new ArrayList<>();
 
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        AnyObject anyObject = anyObjectDAO.authFind(key);
         if (anyObject != null) {
             tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey()));
         }
 
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -152,7 +153,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        awfAdapter.delete(anyObjectKey);
+        awfAdapter.delete(key);
 
         return propagationReporter.getStatuses();
     }
@@ -168,15 +169,36 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PropagationByResource propByRes = new PropagationByResource();
+        for (String resource : resources) {
+            propByRes.add(ResourceOperation.UPDATE, resource);
+        }
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        AnyObject anyObject = anyObjectDAO.authFind(key);
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(anyObject.getResourceNames(), resources);
 
         List<PropagationTask> tasks = propagationManager.getAnyObjectDeleteTasks(
-                anyObjectKey, new HashSet<>(resources), noPropResourceName);
+                key, new HashSet<>(resources), noPropResourceName);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index 5661df4..457f74d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -38,6 +38,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
@@ -81,8 +82,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
                 created, groupTO.getVirAttrs(), excludedResources);
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(
-                PropagationReporter.class);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -98,6 +99,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             final GroupTO groupTO, final Map<Long, String> groupOwnerMap, final Set<String> excludedResources) {
 
         WorkflowResult<Long> created = gwfAdapter.create(groupTO);
+
+        // see ConnObjectUtils#getAnyTOFromConnObject for GroupOwnerSchema
         AttrTO groupOwner = groupTO.getPlainAttrMap().get(StringUtils.EMPTY);
         if (groupOwner != null) {
             groupOwnerMap.put(created.getResult(), groupOwner.getValues().iterator().next());
@@ -105,15 +108,21 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
                 created, groupTO.getVirAttrs(), excludedResources);
-
-        taskExecutor.execute(tasks);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
 
         return new ImmutablePair<>(created.getResult(), null);
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> update(final GroupMod groupObjectMod) {
-        return update(groupObjectMod, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> update(final GroupMod groupMod) {
+        return update(groupMod, Collections.<String>emptySet());
     }
 
     @Override
@@ -137,7 +146,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -149,15 +158,15 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long groupObjectKey) {
-        return delete(groupObjectKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long groupKey, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         List<PropagationTask> tasks = new ArrayList<>();
 
-        Group group = groupDAO.authFind(groupKey);
+        Group group = groupDAO.authFind(key);
         if (group != null) {
             // Generate propagation tasks for deleting users from group resources, if they are on those resources only
             // because of the reason being deleted (see SYNCOPE-357)
@@ -180,7 +189,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             tasks.addAll(propagationManager.getGroupDeleteTasks(group.getKey()));
         }
 
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -189,7 +198,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        gwfAdapter.delete(groupKey);
+        gwfAdapter.delete(key);
 
         return propagationReporter.getStatuses();
     }
@@ -201,15 +210,34 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long groupKey, final Collection<String> resources) {
-        Group group = groupDAO.authFind(groupKey);
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        Group group = groupDAO.authFind(key);
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(group.getResourceNames(), resources);
 
         List<PropagationTask> tasks = propagationManager.getGroupDeleteTasks(
-                groupKey, new HashSet<>(resources), noPropResourceName);
+                key, new HashSet<>(resources), noPropResourceName);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index 656bc75..0809607 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -37,6 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
@@ -87,12 +88,8 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
             final boolean disablePwdPolicyCheck, final Boolean enabled, final Set<String> excludedResources) {
 
-        WorkflowResult<Pair<Long, Boolean>> created;
-        try {
-            created = uwfAdapter.create(userTO, disablePwdPolicyCheck, enabled, storePassword);
-        } catch (PropagationException e) {
-            throw e;
-        }
+        WorkflowResult<Pair<Long, Boolean>> created =
+                uwfAdapter.create(userTO, disablePwdPolicyCheck, enabled, storePassword);
 
         List<PropagationTask> tasks = propagationManager.getUserCreateTasks(
                 created.getResult().getKey(),
@@ -102,7 +99,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 userTO.getVirAttrs(),
                 excludedResources);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -129,7 +126,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                     ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());
         }
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         if (!tasks.isEmpty()) {
             try {
@@ -140,9 +137,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             }
         }
 
-        Pair<Long, List<PropagationStatus>> result = new ImmutablePair<>(
-                updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
-        return result;
+        return new ImmutablePair<>(updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
     }
 
     @Override
@@ -191,7 +186,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
                 updated, updated.getResult().getKey().getPassword() != null, excludedResources);
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -204,21 +199,21 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long userKey) {
-        return delete(userKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyId, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         // Note here that we can only notify about "delete", not any other
         // task defined in workflow process definition: this because this
         // information could only be available after uwfAdapter.delete(), which
         // will also effectively remove user from db, thus making virtually
         // impossible by NotificationManager to fetch required user information
-        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(anyId, excludedResources);
+        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(key, excludedResources);
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -227,7 +222,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         }
 
         try {
-            uwfAdapter.delete(anyId);
+            uwfAdapter.delete(key);
         } catch (PropagationException e) {
             throw e;
         }
@@ -247,40 +242,40 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> activate(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.activate(user.getKey(), statusMod.getToken())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.activate(statusMod.getKey(), statusMod.getToken())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> reactivate(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.reactivate(user.getKey())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.reactivate(statusMod.getKey())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> suspend(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.suspend(user.getKey())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.suspend(statusMod.getKey())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
-    protected List<PropagationStatus> propagateStatus(final User user, final StatusMod statusMod) {
-        Collection<String> noPropResourceNames =
-                CollectionUtils.removeAll(userDAO.findAllResourceNames(user), statusMod.getResourceNames());
+    protected List<PropagationStatus> propagateStatus(final StatusMod statusMod) {
+        Collection<String> noPropResourceNames = CollectionUtils.removeAll(
+                userDAO.findAllResourceNames(userDAO.find(statusMod.getKey())), statusMod.getResourceNames());
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                user, statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
+                statusMod.getKey(), statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {
@@ -311,15 +306,50 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long userKey, final Collection<String> resources) {
-        final User user = userDAO.authFind(userKey);
+    public List<PropagationStatus> provision(
+            final Long key, final boolean changePwd, final String password, final Collection<String> resources) {
+
+        UserMod userMod = new UserMod();
+        userMod.setKey(key);
+        userMod.getResourcesToAdd().addAll(resources);
+
+        if (changePwd) {
+            StatusMod statusMod = new StatusMod();
+            statusMod.setOnSyncope(false);
+            statusMod.getResourceNames().addAll(resources);
+            userMod.setPwdPropRequest(statusMod);
+            userMod.setPassword(password);
+        }
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Pair<UserMod, Boolean>> wfResult = new WorkflowResult<Pair<UserMod, Boolean>>(
+                ImmutablePair.of(userMod, (Boolean) null), propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(wfResult, changePwd, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        User user = userDAO.authFind(key);
 
         List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(
-                userKey,
+                key,
                 new HashSet<>(resources),
                 CollectionUtils.removeAll(userDAO.findAllResourceNames(user), resources));
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -331,16 +361,16 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public void requestPasswordReset(final Long id) {
-        uwfAdapter.requestPasswordReset(id);
+    public void requestPasswordReset(final Long key) {
+        uwfAdapter.requestPasswordReset(key);
     }
 
     @Override
-    public void confirmPasswordReset(final User user, final String token, final String password) {
-        uwfAdapter.confirmPasswordReset(user.getKey(), token, password);
+    public void confirmPasswordReset(final Long key, final String token, final String password) {
+        uwfAdapter.confirmPasswordReset(key, token, password);
 
         UserMod userMod = new UserMod();
-        userMod.setKey(user.getKey());
+        userMod.setKey(key);
         userMod.setPassword(password);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
@@ -348,7 +378,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                         new ImmutablePair<UserMod, Boolean>(userMod, null), null, "confirmPasswordReset"),
                 true, null);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
index bec5e28..7ff9e84 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
-import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 92a9bd3..689037b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -345,8 +345,8 @@ abstract class AbstractAnyDataBinder {
         Set<ExternalResource> resources = getAllResources(any);
 
         // 5. attributes to be removed
-        for (String attributeToBeRemoved : anyMod.getPlainAttrsToRemove()) {
-            PlainSchema schema = getPlainSchema(attributeToBeRemoved);
+        for (String attrToRemove : anyMod.getPlainAttrsToRemove()) {
+            PlainSchema schema = getPlainSchema(attrToRemove);
             if (schema != null) {
                 PlainAttr<?> attr = any.getPlainAttr(schema.getKey());
                 if (attr == null) {
@@ -388,8 +388,8 @@ abstract class AbstractAnyDataBinder {
         LOG.debug("Attributes to be removed:\n{}", propByRes);
 
         // 6. attributes to be updated
-        for (AttrMod attributeMod : anyMod.getPlainAttrsToUpdate()) {
-            PlainSchema schema = getPlainSchema(attributeMod.getSchema());
+        for (AttrMod attrMod : anyMod.getPlainAttrsToUpdate()) {
+            PlainSchema schema = getPlainSchema(attrMod.getSchema());
             PlainAttr attr = null;
             if (schema != null) {
                 attr = any.getPlainAttr(schema.getKey());
@@ -407,7 +407,7 @@ abstract class AbstractAnyDataBinder {
 
                 // 1.1 remove values
                 Set<Long> valuesToBeRemoved = new HashSet<>();
-                for (String valueToBeRemoved : attributeMod.getValuesToBeRemoved()) {
+                for (String valueToBeRemoved : attrMod.getValuesToBeRemoved()) {
                     if (attr.getSchema().isUniqueConstraint()) {
                         if (attr.getUniqueValue() != null
                                 && valueToBeRemoved.equals(attr.getUniqueValue().getValueAsString())) {
@@ -422,17 +422,17 @@ abstract class AbstractAnyDataBinder {
                         }
                     }
                 }
-                for (Long attributeValueId : valuesToBeRemoved) {
-                    plainAttrValueDAO.delete(attributeValueId, anyUtils.plainAttrValueClass());
+                for (Long attrValueKey : valuesToBeRemoved) {
+                    plainAttrValueDAO.delete(attrValueKey, anyUtils.plainAttrValueClass());
                 }
 
                 // 1.2 add values
-                List<String> valuesToBeAdded = attributeMod.getValuesToBeAdded();
+                List<String> valuesToBeAdded = attrMod.getValuesToBeAdded();
                 if (valuesToBeAdded != null && !valuesToBeAdded.isEmpty()
                         && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null
                         || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) {
 
-                    fillAttribute(attributeMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues);
+                    fillAttribute(attrMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues);
                 }
 
                 // if no values are in, the attribute can be safely removed

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 258e713..08c7e1d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
-
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
index 3cf65fd..fe135b2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
-
 import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder;
 import java.util.Collections;
 import java.util.List;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index 762cca5..2295753 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -61,6 +61,8 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.Trigger;
@@ -147,6 +149,8 @@ public class TaskDataBinderImpl implements TaskDataBinder {
             final PushTask pushTask = (PushTask) task;
             final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
 
+            pushTask.setJobDelegateClassName(PushJobDelegate.class.getName());
+
             pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
                     ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
             pushTask.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
@@ -181,6 +185,8 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             syncTask.setDestinationRealm(realmDAO.find(syncTaskTO.getDestinationRealm()));
 
+            syncTask.setJobDelegateClassName(SyncJobDelegate.class.getName());
+
             syncTask.setMatchingRule(syncTaskTO.getMatchingRule() == null
                     ? MatchingRule.UPDATE : syncTaskTO.getMatchingRule());
             syncTask.setUnmatchingRule(syncTaskTO.getUnmatchingRule() == null
@@ -239,7 +245,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
         task.setDescription(taskTO.getDescription());
 
         if (taskUtils.getType() == TaskType.SCHEDULED) {
-            task.setJobClassName(taskTO.getJobClassName());
+            task.setJobDelegateClassName(taskTO.getJobDelegateClassName());
         } else if (taskTO instanceof AbstractProvisioningTaskTO) {
             AbstractProvisioningTaskTO provisioningTaskTO = (AbstractProvisioningTaskTO) taskTO;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
new file mode 100644
index 0000000..3042239
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.job;
+
+import java.util.Date;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+public abstract class AbstractSchedTaskJobDelegate implements SchedTaskJobDelegate {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(SchedTaskJobDelegate.class);
+
+    /**
+     * The actual task to be executed.
+     */
+    protected Task task;
+
+    /**
+     * Task execution DAO.
+     */
+    @Autowired
+    protected TaskExecDAO taskExecDAO;
+
+    /**
+     * Task DAO.
+     */
+    @Autowired
+    protected TaskDAO taskDAO;
+
+    @Autowired
+    protected EntityFactory entityFactory;
+
+    /**
+     * Notification manager.
+     */
+    @Autowired
+    protected NotificationManager notificationManager;
+
+    /**
+     * Audit manager.
+     */
+    @Autowired
+    protected AuditManager auditManager;
+
+    @Transactional
+    @Override
+    public void execute(final Long taskKey, final boolean dryRun) throws JobExecutionException {
+        task = taskDAO.find(taskKey);
+        if (task == null) {
+            throw new JobExecutionException("Task " + taskKey + " not found");
+        }
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setStartDate(new Date());
+        execution.setTask(task);
+
+        AuditElements.Result result;
+
+        try {
+            execution.setMessage(doExecute(dryRun));
+            execution.setStatus(TaskJob.Status.SUCCESS.name());
+            result = AuditElements.Result.SUCCESS;
+        } catch (JobExecutionException e) {
+            LOG.error("While executing task " + taskKey, e);
+            result = AuditElements.Result.FAILURE;
+
+            execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
+            execution.setStatus(TaskJob.Status.FAILURE.name());
+        }
+        execution.setEndDate(new Date());
+
+        if (hasToBeRegistered(execution)) {
+            taskExecDAO.saveAndAdd(taskKey, execution);
+        }
+        task = taskDAO.save(task);
+
+        notificationManager.createTasks(
+                AuditElements.EventCategoryType.TASK,
+                this.getClass().getSimpleName(),
+                null,
+                this.getClass().getSimpleName(), // searching for before object is too much expensive ...
+                result,
+                task,
+                execution);
+
+        auditManager.audit(
+                AuditElements.EventCategoryType.TASK,
+                task.getClass().getSimpleName(),
+                null,
+                null, // searching for before object is too much expensive ...
+                result,
+                task,
+                (Object[]) null);
+    }
+
+    /**
+     * The actual execution, delegated to child classes.
+     *
+     * @param dryRun whether to actually touch the data
+     * @return the task execution status to be set
+     * @throws JobExecutionException if anything goes wrong
+     */
+    protected abstract String doExecute(boolean dryRun) throws JobExecutionException;
+
+    /**
+     * Template method to determine whether this job's task execution has to be persisted or not.
+     *
+     * @param execution task execution
+     * @return wether to persist or not
+     */
+    protected boolean hasToBeRegistered(final TaskExec execution) {
+        return false;
+    }
+
+}