http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/content.xml 
b/core/persistence-jpa/src/test/resources/content.xml
index b61cb95..7b11faa 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -124,9 +124,9 @@ under the License.
   <AnyTypeClass name="minimal group"/>
   <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal 
group"/>
   
-  <AnyType name="OTHER" kind="ANY_OBJECT"/>
-  <AnyTypeClass name="minimal other"/>
-  <AnyType_AnyTypeClass anyType_name="OTHER" anyTypeClass_name="minimal 
other"/>
+  <AnyType name="PRINTER" kind="ANY_OBJECT"/>
+  <AnyTypeClass name="minimal printer"/>
+  <AnyType_AnyTypeClass anyType_name="PRINTER" anyTypeClass_name="minimal 
printer"/>
       
   <AnyTypeClass name="csv"/>
 
@@ -135,10 +135,10 @@ under the License.
   <Realm id="3" name="even" parent_id="1"/>
   <Realm id="4" name="two" parent_id="3" accountPolicy_id="5" 
passwordPolicy_id="2"/>
   
-  <AnyObject id="1" realm_id="1" type_name="OTHER"
+  <AnyObject id="1" realm_id="1" type_name="PRINTER"
              creator="admin" lastModifier="admin" 
              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 
11:00:00"/>
-  <AnyObject id="2" realm_id="1" type_name="OTHER"
+  <AnyObject id="2" realm_id="1" type_name="PRINTER"
              creator="admin" lastModifier="admin" 
              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 
11:00:00"/>
 
@@ -286,7 +286,7 @@ under the License.
                conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
   <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" 
readonly="1"/>
-  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="minimal other" 
+  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="other" 
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" 
readonly="0"/>
   <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" 
readonly="0"
@@ -347,9 +347,21 @@ under the License.
 
   <VirSchema name="mvirtualdata"/>
         
-  <APlainAttr id="1" owner_id="2" schema_name="cool"/>
-  <APlainAttrValue id="1" attribute_id="1" booleanValue="1"/>
-  
+  <PlainSchema name="model" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" 
readonly="0"/>
+  <PlainSchema name="location" type="String" anyTypeClass_name="minimal 
printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" 
readonly="0"/>
+    
+  <APlainAttr id="1" owner_id="1" schema_name="model"/>
+  <APlainAttrValue id="1" attribute_id="1" stringValue="Canon MFC8030"/>
+  <APlainAttr id="2" owner_id="1" schema_name="location"/>
+  <APlainAttrValue id="2" attribute_id="2" stringValue="1st floor"/>
+    
+  <APlainAttr id="3" owner_id="2" schema_name="model"/>
+  <APlainAttrValue id="3" attribute_id="3" stringValue="HP Laserjet 1300n"/>
+  <APlainAttr id="4" owner_id="2" schema_name="location"/>
+  <APlainAttrValue id="4" attribute_id="4" stringValue="2nd floor"/>
+
   <UPlainAttr id="99" owner_id="1" schema_name="type"/>
   <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
   <UPlainAttr id="100" owner_id="1" schema_name="fullname"/>
@@ -473,7 +485,7 @@ under the License.
                 
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 bundleName="net.tirasa.connid.bundles.db.table"
                 
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.db.table.version}"
+                version="${connid.database.version}"
                 
jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValu
 
es":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required
 
":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]}]'/>
   <ConnInstance_capabilities ConnInstance_id="101" capability="AUTHENTICATE"/>
   <ConnInstance_capabilities ConnInstance_id="101" 
capability="ONE_PHASE_CREATE"/>
@@ -536,7 +548,7 @@ under the License.
                 
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 bundleName="net.tirasa.connid.bundles.db.table"
                 
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.db.table.version}"
+                version="${connid.database.version}"
                 
jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"
 
defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"java.lang.Boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityco
 
nnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test2"]}]'/>
   <ConnInstance_capabilities ConnInstance_id="106" 
capability="ONE_PHASE_CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="106" 
capability="ONE_PHASE_UPDATE"/>
@@ -546,7 +558,7 @@ under the License.
   <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
                 
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 
connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
-                displayName="H2-testsync" version="${connid.db.table.version}"
+                displayName="H2-testsync" version="${connid.database.version}"
                 
jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column 
(Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The 
change log column store the latest change time. Providing this value the Sync 
capabilities are 
activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native
 Timestamps ","helpMessage":"&lt;b&gt;Native 
Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the 
columns in java.sql.Timestamp format from the database 
table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password
 cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used 
to encode password before to store it onto the database table.\nSpecify one of 
th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation 
identified by its class 
name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled
 Status Value","helpMessage":"&lt;b&gt;Enabled Status 
Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled 
status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve
 password","helpMessage":"Specify if password must be retrieved by 
default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource
 Path","helpMessage":"&lt;b&gt;JDBC Data Source 
Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to 
the Or
 acle server. If specified, connector will only try to connect using Datasource 
and ignore other resource parameters specified.&lt;br&gt;the example value is: 
&lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All
 native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to 
retrieve all data type of the columns in a native format from the database 
table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter
 the name of the mandatory Database user with permission to account 
table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower 
case","helpMessage":"Force password encoding to lower 
case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC
 Connection URL","helpMessage":"&lt;b&gt;JDBC Connection 
URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle 
template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL 
template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC 
driver documentation.&lt;br&gt;Could be empty if datasource is 
provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key
 Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory 
column value will be used as the unique identi
 fier for rows in the 
table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate
 Connection Query","helpMessage":"&lt;b&gt;Validate Connection 
Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive 
query. If empty, default implementation will test it using the switch on/off 
the autocommit. Some select 1 from dummy table could be more 
efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow
 all SQLExceptions","helpMessage":"If this is not checked, SQL statements which 
throw SQLExceptions with a 0 ErrorCode will be have the exception caught and 
suppressed. Check it to have exceptions with 0 ErrorCodes 
rethrown.","type":"boolean","required":false,"order":17,"confid
 
ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password
 Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the 
name of the column in the table that will hold the password values. If empty, 
no validation on resource and passwords are 
activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial
 JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI 
Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial 
context factory, context provider in a format: key = 
value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User
 Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a 
user account tha
 t has permission to access accounts 
table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter
 the name of the host where the database is 
running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP
 Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening 
on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status
 Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the 
name of the column in the table that will hold the status values. If empty 
enabled and
  disabled operation wont be 
performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force
 password encoding to upper case","helpMessage":"Force password encoding to 
upper 
case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable
 writing empty string","helpMessage":"&lt;b&gt;Enable writing empty 
string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty 
strings, instead of a NULL value, in character based columns defined as 
not-null in the table schema. This option does not influence the way strings 
are written for Oracle based tables. By default empty strings are written as a 
NULL 
value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 
values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter
 the name of the database on the database server that contains the 
table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default
 Status Value","helpMessage":"&lt;b&gt;Default Status 
Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not 
specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter
 the name of the table in the database that contains the 
accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status 
Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter 
the value for disabled 
status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC
 Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the 
JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is 
org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is 
provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name
 Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select 
whether database column names for this resource should be quoted, and the 
quoting characters. By default, database column names are not quoted (None). 
For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between 
single quotes, double quotes, back quotes, or brackets in the SQL generated to 
access the 
database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password
 cipher key","helpMessage":"Specify key in case of reversible 
algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
   <ConnInstance_capabilities ConnInstance_id="107" 
capability="ONE_PHASE_CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="107" 
capability="TWO_PHASES_CREATE"/>
@@ -556,6 +568,17 @@ under the License.
   <ConnInstance_capabilities ConnInstance_id="107" 
capability="TWO_PHASES_DELETE"/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="SEARCH"/>
   
+  <ConnInstance id="108" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
+                
location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                
connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
+                displayName="Scripted SQL" version="${connid.database.version}"
+                
jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScript&quot;,&quot;displayName&quot;:&quot;testScript&quot;,&quot;helpMessage&quot;:&quot;testScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;host&quot;,&quot;displayName&quot;:&quot;Host&quot;,&quot;helpMessage&quot;:&quot;&lt;b
 &gt;Host&lt;/b&gt;&lt;br/&gt;Enter the name of the host where the database is 
running.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;localhost&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;port&quot;,&quot;displayName&quot;:&quot;Port&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;TCP
 Port&lt;/b&gt;&lt;br/&gt;Enter the port number the database server is 
listening 
on.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;3306&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;database&quot;,&quot;displayName&quot;:&quot;Database&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Database&lt;/b&gt;&lt;br/&gt;Enter
 the name of the database on the database server that contains the 
table.&quot;,&quot;type&
 
quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;createScript&quot;,&quot;displayName&quot;:&quot;createScript&quot;,&quot;helpMessage&quot;:&quot;createScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcUrlTemplate&quot;,&quot;displayName&quot;:&quot;JDBC
 Connection URL&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Connection 
URL&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver Connection URL.&lt;br/&gt; 
Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br/&gt;  
MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read 
the JDBC driver documentati
 on.&lt;br/&gt;Could be empty if datasource is 
provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;jdbc:mysql://%h:%p/%d&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.url}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jndiProperties&quot;,&quot;displayName&quot;:&quot;Initial
 JNDI Properties&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Initial JNDI 
Properties&lt;/b&gt;&lt;br/&gt;Could be empty or enter the JDBC JNDI Initial 
context factory, context provider in a format: key = 
value.&quot;,&quot;type&quot;:&quot;[Ljava.lang.String;&quot;,&quot;required&quot;:false,&quot;order&quot;:21,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;enableEmptyString&quot;,&quot;displayName&quot;:&quot;Enable
 writing empty string&quot;,&quot;
 helpMessage&quot;:&quot;&lt;b&gt;Enable writing empty 
string&lt;/b&gt;&lt;br/&gt;Select to enable support for writing an empty 
strings, instead of a NULL value, in character based columns defined as 
not-null in the table schema. This option does not influence the way strings 
are written for Oracle based tables. By default empty strings are written as a 
NULL 
value.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;allNative&quot;,&quot;displayName&quot;:&quot;All
 native&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;All 
native&lt;/b&gt;&lt;br/&gt;Select to retrieve all data type of the columns in a 
native format from the database 
table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:16,&quot;confidential&quot;:false,&quot;defaul
 
tValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;User
 Password&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User 
Password&lt;/b&gt;&lt;br/&gt;Enter a user account that has permission to access 
accounts 
table.&quot;,&quot;type&quot;:&quot;org.identityconnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:5,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.password}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;validConnectionQuery&quot;,&quot;displayName&quot;:&quot;Validate
 Connection Query&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Validate 
Connection Query&lt;/b&gt;&lt;br/&gt;There can be specified the check 
connection alive query. If empty, default implementation will test it using the 
switch on/off the autocommit. Some select 1 from dummy tab
 le could be more 
efficient.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;reloadScriptOnExecution&quot;,&quot;displayName&quot;:&quot;reloadScriptOnExecution&quot;,&quot;helpMessage&quot;:&quot;reloadScriptOnExecution&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;true&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScriptFileName&quot;,&quot;displayName&quot;:&quot;schemaScriptFileName&quot;,&quot;helpMessage&quot;:&quot;schemaScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&qu
 
ot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcDriver&quot;,&quot;displayName&quot;:&quot;JDBC
 Driver&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC 
Driver&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver class name. Oracle is 
oracle.jdbc.driver.OracleDriver. MySQL is 
org.gjt.mm.mysql.Driver.&lt;br/&gt;Could be empty if datasource is 
provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;com.mysql.jdbc.Driver&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.driver}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScriptFileName&quot;,&quot;displayName&quot;:&quot;testScriptFileName&quot;,&quot;helpMessage&quot;:&quot;testScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&qu
 
ot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;quoting&quot;,&quot;displayName&quot;:&quot;Name
 Quoting&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Name 
Quoting&lt;/b&gt;&lt;br/&gt;Select whether database column names for this 
resource should be quoted, and the quoting characters. By default, database 
column names are not quoted (None). For other selections (Single, Double, Back, 
or Brackets), column names will appear between single quotes, double quotes, 
back quotes, or brackets in the SQL generated to access the 
database.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quo
 
t;createScriptFileName&quot;,&quot;displayName&quot;:&quot;createScriptFileName&quot;,&quot;helpMessage&quot;:&quot;createScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;clearTextPasswordToScript&quot;,&quot;displayName&quot;:&quot;clearTextPasswordToScript&quot;,&quot;helpMessage&quot;:&quot;clearTextPasswordToScript&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;nativeTimestamps&quot;,&quot;displayName&quot;:&quot;Native
 Timestamps&quot;,&quot;helpMessage&quot;:&quot;&lt;
 b&gt;Native Timestamps&lt;/b&gt;&lt;br/&gt;Select to retrieve Timestamp data 
type of the columns in java.sql.Timestamp format from the database 
table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScript&quot;,&quot;displayName&quot;:&quot;syncScript&quot;,&quot;helpMessage&quot;:&quot;syncScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;autoCommit&quot;,&quot;displayName&quot;:&quot;autoCommit&quot;,&quot;helpMessage&quot;:&quot;autoCommit&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential
 
&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;scriptingLanguage&quot;,&quot;displayName&quot;:&quot;scriptingLanguage&quot;,&quot;helpMessage&quot;:&quot;scriptingLanguage&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;GROOVY&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;GROOVY&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;datasource&quot;,&quot;displayName&quot;:&quot;Datasource
 Path&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Data Source 
Name/Path&lt;/b&gt;&lt;br/&gt;Enter the JDBC Data Source Name/Path to connect 
to the Oracle server. If specified, connector will only try to connect using 
Datasource and ignore other resource parameters specified.&lt;br/&gt;the 
example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;&quot;,&q
 
uot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:20,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScript&quot;,&quot;displayName&quot;:&quot;deleteScript&quot;,&quot;helpMessage&quot;:&quot;deleteScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;rethrowAllSQLExceptions&quot;,&quot;displayName&quot;:&quot;Rethrow
 all SQLExceptions&quot;,&quot;helpMessage&quot;:&quot;If this is not checked, 
SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the 
exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes 
rethrown.&quot;,&quot;type&quot;:&quot;boolean&quot;,
 
&quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScriptFileName&quot;,&quot;displayName&quot;:&quot;syncScriptFileName&quot;,&quot;helpMessage&quot;:&quot;syncScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SyncScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScript&quot;,&quot;displayName&quot;:&quot;updateScript&quot;,&quot;helpMessage&quot;:&quot;updateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&q
 
uot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;user&quot;,&quot;displayName&quot;:&quot;User&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User&lt;/b&gt;&lt;br/&gt;Enter
 the name of the mandatory Database user with permission to account 
table.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.username}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScriptFileName&quot;,&quot;displayName&quot;:&quot;deleteScriptFileName&quot;,&quot;helpMessage&quot;:&quot;deleteScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;n
 
ame&quot;:&quot;searchScriptFileName&quot;,&quot;displayName&quot;:&quot;searchScriptFileName&quot;,&quot;helpMessage&quot;:&quot;searchScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SearchScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;searchScript&quot;,&quot;displayName&quot;:&quot;searchScript&quot;,&quot;helpMessage&quot;:&quot;searchScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="108" 
capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" 
capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" 
capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="SYNC"/>
+  
   <ExternalResource name="ws-target-resource-1" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" 
propagationMode="TWO_PHASES"
                     propagationPriority="0" propagationPrimary="1" 
createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" 
syncTraceLevel="ALL"
@@ -657,6 +680,13 @@ under the License.
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" 
lastChangeDate="2010-10-20 11:00:00"/>
 
+  <ExternalResource name="resource-db-scripted" connector_id="108"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" 
deleteTraceLevel="ALL" syncTraceLevel="ALL" updateTraceLevel="ALL"
+                    enforceMandatoryCondition="0"
+                    propagationMode="ONE_PHASE" propagationPrimary="0" 
propagationPriority="0"
+                    creator="admin" lastModifier="admin" 
+                    creationDate="2010-10-20 11:00:00" 
lastChangeDate="2010-10-20 11:00:00"/>
+
   <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
   <Policy_ExternalResource accountPolicy_id="5" 
resource_name="resource-testdb"/>
     
@@ -817,7 +847,7 @@ under the License.
                intAttrName="rderToBePropagated" 
intMappingType="GroupDerivedSchema" mandatoryCondition="false"
                connObjectKey="0" password="0" purpose="PROPAGATION"/>
   <MappingItem id="209" extAttrName="membership" mapping_id="9"
-               intAttrName="mderToBePropagated" 
intMappingType="AnyDerivedSchema" mandatoryCondition="false"
+               intAttrName="mderToBePropagated" 
intMappingType="AnyObjectDerivedSchema" mandatoryCondition="false"
                connObjectKey="0" password="0" purpose="PROPAGATION"/>
                          
   <Provision id="10" resource_name="ws-target-resource-update-resetsynctoken" 
anyType_name="USER" objectClass="__ACCOUNT__"
@@ -924,7 +954,16 @@ under the License.
   <MappingItem id="334" mapping_id="19" extAttrName="userId" 
                intMappingType="Username" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  
+
+  <Provision id="21" resource_name="resource-db-scripted" 
anyType_name="PRINTER" objectClass="__PRINTER__"/>
+  <Mapping id="21" provision_id="21"/>
+  <MappingItem id="405" mapping_id="21" extAttrName="id" 
+               intMappingType="AnyObjectKey" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="BOTH"/>
+  <MappingItem id="406" mapping_id="21" extAttrName="location" 
+               intAttrName="location" intMappingType="AnyObjectPlainSchema"
+               mandatoryCondition="false" connObjectKey="0" password="0" 
purpose="BOTH"/>
+    
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="1" 
propagationMode="TWO_PHASES" propagationOperation="UPDATE"
         objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" 
anyTypeKind="USER" anyKey="1"
         
xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
@@ -1055,6 +1094,9 @@ under the License.
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="27" 
propagationMode="ONE_PHASE" propagationOperation="CREATE"
         objectClassName="__ACCOUNT__" resource_name="resource-testdb" 
anyTypeKind="USER" anyKey="1"
         
xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
+  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="28" name="Scripted SQL" 
resource_name="resource-db-scripted"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" 
performDelete="1" syncStatus="0" fullReconciliation="0"
+        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" 
unmatchingRule="PROVISION" matchingRule="UPDATE"/>
 
   <Notification id="1" active="1" recipientAttrName="email" 
recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
                 sender="[email protected]" subject="Password Reset 
request" template="requestPasswordReset" 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 cc49d62..e23143a 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
@@ -67,9 +67,6 @@ import org.springframework.util.ClassUtils;
 
 public class ConnectorFacadeProxy implements Connector {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = 
LoggerFactory.getLogger(ConnectorFacadeProxy.class);
 
     /**
@@ -138,7 +135,7 @@ public class ConnectorFacadeProxy implements Connector {
         Uid result = null;
 
         if 
(activeConnInstance.getCapabilities().contains(ConnectorCapability.AUTHENTICATE))
 {
-            final Future<Uid> future = asyncFacade.authenticate(
+            Future<Uid> future = asyncFacade.authenticate(
                     connector, username, new 
GuardedString(password.toCharArray()), options);
             try {
                 result = 
future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -173,7 +170,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("create");
 
-            final Future<Uid> future = asyncFacade.create(connector, 
objectClass, attrs, options);
+            Future<Uid> future = asyncFacade.create(connector, objectClass, 
attrs, options);
             try {
                 result = 
future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
             } catch (java.util.concurrent.TimeoutException e) {
@@ -207,7 +204,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("update");
 
-            final Future<Uid> future = asyncFacade.update(connector, 
objectClass, uid, attrs, options);
+            Future<Uid> future = asyncFacade.update(connector, objectClass, 
uid, attrs, options);
 
             try {
                 result = 
future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -241,7 +238,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("delete");
 
-            final Future<Uid> future = asyncFacade.delete(connector, 
objectClass, uid, options);
+            Future<Uid> future = asyncFacade.delete(connector, objectClass, 
uid, options);
 
             try {
                 future.get(activeConnInstance.getConnRequestTimeout(), 
TimeUnit.SECONDS);
@@ -279,7 +276,7 @@ public class ConnectorFacadeProxy implements Connector {
         SyncToken result = null;
 
         if 
(activeConnInstance.getCapabilities().contains(ConnectorCapability.SYNC)) {
-            final Future<SyncToken> future = 
asyncFacade.getLatestSyncToken(connector, objectClass);
+            Future<SyncToken> future = 
asyncFacade.getLatestSyncToken(connector, objectClass);
 
             try {
                 result = 
future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -350,7 +347,9 @@ public class ConnectorFacadeProxy implements Connector {
         try {
             return future == null ? null : 
future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
-            future.cancel(true);
+            if (future != null) {
+                future.cancel(true);
+            }
             throw new TimeoutException("Request timeout");
         } catch (Exception e) {
             LOG.error("Connector request execution failure", e);
@@ -363,8 +362,8 @@ public class ConnectorFacadeProxy implements Connector {
     }
 
     @Override
-    public List<ConnectorObject> search(final ObjectClass objectClass, final 
Filter filter,
-            final OperationOptions options) {
+    public List<ConnectorObject> search(
+            final ObjectClass objectClass, final Filter filter, final 
OperationOptions options) {
 
         final List<ConnectorObject> result = new ArrayList<>();
 
@@ -401,8 +400,8 @@ public class ConnectorFacadeProxy implements Connector {
     public Attribute getObjectAttribute(final ObjectClass objectClass, final 
Uid uid, final OperationOptions options,
             final String attributeName) {
 
-        final Future<Attribute> future = 
asyncFacade.getObjectAttribute(connector, objectClass, uid, options,
-                attributeName);
+        Future<Attribute> future = asyncFacade.getObjectAttribute(
+                connector, objectClass, uid, options, attributeName);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), 
TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -422,7 +421,7 @@ public class ConnectorFacadeProxy implements Connector {
     public Set<Attribute> getObjectAttributes(final ObjectClass objectClass, 
final Uid uid,
             final OperationOptions options) {
 
-        final Future<Set<Attribute>> future = 
asyncFacade.getObjectAttributes(connector, objectClass, uid, options);
+        Future<Set<Attribute>> future = 
asyncFacade.getObjectAttributes(connector, objectClass, uid, options);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), 
TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -440,7 +439,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public Set<String> getSchemaNames(final boolean includeSpecial) {
-        final Future<Set<String>> future = 
asyncFacade.getSchemaNames(connector, includeSpecial);
+        Future<Set<String>> future = asyncFacade.getSchemaNames(connector, 
includeSpecial);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), 
TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -458,7 +457,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public Set<ObjectClass> getSupportedObjectClasses() {
-        final Future<Set<ObjectClass>> future = 
asyncFacade.getSupportedObjectClasses(connector);
+        Future<Set<ObjectClass>> future = 
asyncFacade.getSupportedObjectClasses(connector);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), 
TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -476,7 +475,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public void validate() {
-        final Future<String> future = asyncFacade.test(connector);
+        Future<String> future = asyncFacade.test(connector);
         try {
             future.get(activeConnInstance.getConnRequestTimeout(), 
TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -494,7 +493,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public void test() {
-        final Future<String> future = asyncFacade.test(connector);
+        Future<String> future = asyncFacade.test(connector);
         try {
             future.get(activeConnInstance.getConnRequestTimeout(), 
TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
index 888329c..b43e911 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
@@ -282,7 +282,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
                 ? IntMappingType.UserVirtualSchema
                 : any.getType().getKind() == AnyTypeKind.GROUP
                         ? IntMappingType.GroupVirtualSchema
-                        : IntMappingType.AnyVirtualSchema;
+                        : IntMappingType.AnyObjectVirtualSchema;
 
         Map<String, ConnectorObject> resources = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 90f5e91..92a9bd3 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
@@ -93,7 +93,7 @@ abstract class AbstractAnyDataBinder {
     protected static final Logger LOG = 
LoggerFactory.getLogger(AbstractAnyDataBinder.class);
 
     private static final IntMappingType[] FOR_MANDATORY = new IntMappingType[] 
{
-        IntMappingType.AnyPlainSchema, IntMappingType.AnyDerivedSchema,
+        IntMappingType.AnyObjectPlainSchema, 
IntMappingType.AnyObjectDerivedSchema,
         IntMappingType.UserPlainSchema, IntMappingType.UserDerivedSchema,
         IntMappingType.GroupPlainSchema, IntMappingType.GroupDerivedSchema };
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 462a488..237792b 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
@@ -33,14 +33,18 @@ import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.RelationshipTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 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.provisioning.api.data.AnyObjectDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -53,6 +57,9 @@ public class AnyObjectDataBinderImpl extends 
AbstractAnyDataBinder implements An
         "plainAttrs", "derAttrs", "virAttrs", "resources"
     };
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Transactional(readOnly = true)
     @Override
     public AnyObjectTO getAnyObjectTO(final Long key) {
@@ -62,6 +69,7 @@ public class AnyObjectDataBinderImpl extends 
AbstractAnyDataBinder implements An
     @Override
     public AnyObjectTO getAnyObjectTO(final AnyObject anyObject) {
         AnyObjectTO anyObjectTO = new AnyObjectTO();
+        anyObjectTO.setType(anyObject.getType().getKey());
 
         BeanUtils.copyProperties(anyObject, anyObjectTO, IGNORE_PROPERTIES);
 
@@ -103,6 +111,14 @@ public class AnyObjectDataBinderImpl extends 
AbstractAnyDataBinder implements An
 
     @Override
     public void create(final AnyObject anyObject, final AnyObjectTO 
anyObjectTO) {
+        AnyType type = anyTypeDAO.find(anyObjectTO.getType());
+        if (type == null) {
+            SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+            sce.getElements().add(anyObjectTO.getType());
+            throw sce;
+        }
+        anyObject.setType(type);
+
         SyncopeClientCompositeException scce = 
SyncopeClientException.buildComposite();
 
         // relationships

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index 59f8994..a73f5b9 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -70,6 +70,7 @@ public class PropagationManagerImpl implements 
PropagationManager {
 
     protected static final Logger LOG = 
LoggerFactory.getLogger(PropagationManager.class);
 
+    @Autowired
     protected AnyObjectDAO anyObjectDAO;
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
index 479d342..c52c3cf 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
@@ -29,14 +29,12 @@ import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.job.SyncJob;
 import 
org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
-import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.SyncResultsHandler;
 import org.identityconnectors.framework.common.objects.SyncToken;
 import org.quartz.JobExecutionException;
@@ -133,8 +131,8 @@ public class SyncJobImpl extends 
AbstractProvisioningJob<SyncTask, SyncActions>
             }
         }
 
-        try {
-            for (Provision provision : syncTask.getResource().getProvisions()) 
{
+        for (Provision provision : syncTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
                 SyncResultsHandler handler;
                 switch (provision.getAnyType().getKind()) {
                     case USER:
@@ -150,37 +148,32 @@ public class SyncJobImpl extends 
AbstractProvisioningJob<SyncTask, SyncActions>
                         handler = ahandler;
                 }
 
-                SyncToken latestSyncToken = null;
-                if (provision.getMapping() != null && 
!syncTask.isFullReconciliation()) {
-                    latestSyncToken = 
connector.getLatestSyncToken(ObjectClass.ACCOUNT);
-                }
+                try {
+                    SyncToken latestSyncToken = null;
+                    if (!syncTask.isFullReconciliation()) {
+                        latestSyncToken = 
connector.getLatestSyncToken(provision.getObjectClass());
+                    }
 
-                if (syncTask.isFullReconciliation()) {
-                    if (provision.getMapping() != null) {
+                    if (syncTask.isFullReconciliation()) {
                         connector.getAllObjects(provision.getObjectClass(), 
handler,
                                 
connector.getOperationOptions(provision.getMapping().getItems()));
-                    }
-                } else {
-                    if (provision.getMapping() != null) {
+                    } else {
                         connector.sync(provision.getObjectClass(), 
provision.getSyncToken(), handler,
                                 
connector.getOperationOptions(provision.getMapping().getItems()));
                     }
-                }
 
-                if (!dryRun && !syncTask.isFullReconciliation()) {
-                    try {
-                        ExternalResource resource = 
resourceDAO.find(syncTask.getResource().getKey());
-                        if (provision.getMapping() != null) {
+                    if (!dryRun && !syncTask.isFullReconciliation()) {
+                        try {
                             provision.setSyncToken(latestSyncToken);
+                            resourceDAO.save(provision.getResource());
+                        } catch (Exception e) {
+                            throw new JobExecutionException("While updating 
SyncToken", e);
                         }
-                        resourceDAO.save(resource);
-                    } catch (Exception e) {
-                        throw new JobExecutionException("While updating 
SyncToken", e);
                     }
+                } catch (Throwable t) {
+                    throw new JobExecutionException("While syncing on 
connector", t);
                 }
             }
-        } catch (Throwable t) {
-            throw new JobExecutionException("While syncing on connector", t);
         }
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
index 14c94f70..c3d11a9 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
@@ -167,7 +167,7 @@ public class SyncUtils {
         switch (connObjectKeyItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case AnyPlainSchema:
+            case AnyObjectPlainSchema:
                 PlainAttrValue value = anyUtils.newPlainAttrValue();
 
                 PlainSchema schema = 
plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
@@ -191,7 +191,7 @@ public class SyncUtils {
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
-            case AnyDerivedSchema:
+            case AnyObjectDerivedSchema:
                 anys = 
getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(),
 uid);
                 for (Any<?, ?, ?> any : anys) {
                     result.add(any.getKey());
@@ -200,7 +200,7 @@ public class SyncUtils {
 
             case UserKey:
             case GroupKey:
-            case AnyKey:
+            case AnyObjectKey:
                 Any<?, ?, ?> any = 
getAnyDAO(connObjectKeyItem).find(Long.parseLong(uid));
                 if (any != null) {
                     result.add(any.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
new file mode 100644
index 0000000..7cf4a08
--- /dev/null
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -0,0 +1,290 @@
+/*
+ * 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.rest.cxf.service;
+
+import static org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl.LOG;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.service.AnyService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+
+public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
+        extends AbstractServiceImpl
+        implements AnyService<TO, MOD> {
+
+    protected abstract AbstractAnyLogic<TO, MOD> getAnyLogic();
+
+    @Override
+    public TO read(final Long key) {
+        return getAnyLogic().read(key);
+    }
+
+    @Override
+    public PagedResult<TO> list(final AnyListQuery listQuery) {
+        CollectionUtils.transform(listQuery.getRealms(), new 
Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, 
SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        return buildPagedResult(
+                getAnyLogic().list(
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                getAnyLogic().count(listQuery.getRealms()));
+    }
+
+    @Override
+    public PagedResult<TO> search(final AnySearchQuery searchQuery) {
+        CollectionUtils.transform(searchQuery.getRealms(), new 
Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, 
SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        SearchCond cond = getSearchCond(searchQuery.getFiql());
+        return buildPagedResult(
+                getAnyLogic().search(
+                        cond,
+                        searchQuery.getPage(),
+                        searchQuery.getSize(),
+                        getOrderByClauses(searchQuery.getOrderBy()),
+                        searchQuery.getRealms()),
+                searchQuery.getPage(),
+                searchQuery.getSize(),
+                getAnyLogic().searchCount(cond, searchQuery.getRealms()));
+    }
+
+    @Override
+    public Response create(final TO anyTO) {
+        TO created = getAnyLogic().create(anyTO);
+        return createResponse(created.getKey(), created);
+    }
+
+    @Override
+    public Response update(final Long key, final MOD anyMod) {
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        anyMod.setKey(key);
+        TO updated = getAnyLogic().update(anyMod);
+        return modificationResponse(updated);
+    }
+
+    @Override
+    public Response delete(final Long key) {
+        TO group = getAnyLogic().read(key);
+
+        checkETag(group.getETagValue());
+
+        TO deleted = getAnyLogic().delete(key);
+        return modificationResponse(deleted);
+    }
+
+    @Override
+    public Response bulkDeassociation(
+            final Long key, final ResourceDeassociationActionType type, final 
List<ResourceKey> resourceNames) {
+
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        TO updated;
+        switch (type) {
+            case UNLINK:
+                updated = getAnyLogic().unlink(key, 
CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case UNASSIGN:
+                updated = getAnyLogic().unassign(key, 
CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case DEPROVISION:
+                updated = getAnyLogic().deprovision(key, 
CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            default:
+                updated = getAnyLogic().read(key);
+        }
+
+        BulkActionResult result = new BulkActionResult();
+
+        if (type == ResourceDeassociationActionType.UNLINK) {
+            for (ResourceKey resourceName : resourceNames) {
+                result.getResults().put(resourceName.getElement(),
+                        
updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : 
updated.getPropagationStatusTOs()) {
+                result.getResults().put(propagationStatusTO.getResource(),
+                        
BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
+            }
+        }
+
+        return modificationResponse(result);
+    }
+
+    @Override
+    public Response bulkAssociation(
+            final Long key, final ResourceAssociationActionType type, final 
ResourceAssociationMod associationMod) {
+
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        TO updated;
+        switch (type) {
+            case LINK:
+                updated = getAnyLogic().link(
+                        key,
+                        
CollectionWrapper.unwrap(associationMod.getTargetResources()));
+                break;
+
+            case ASSIGN:
+                updated = getAnyLogic().assign(
+                        key,
+                        
CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            case PROVISION:
+                updated = getAnyLogic().provision(
+                        key,
+                        
CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            default:
+                updated = getAnyLogic().read(key);
+        }
+
+        BulkActionResult result = new BulkActionResult();
+
+        if (type == ResourceAssociationActionType.LINK) {
+            for (ResourceKey resourceName : 
associationMod.getTargetResources()) {
+                result.getResults().put(resourceName.getElement(),
+                        
updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : 
updated.getPropagationStatusTOs()) {
+                result.getResults().put(propagationStatusTO.getResource(),
+                        
BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
+            }
+        }
+
+        return modificationResponse(result);
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        AbstractAnyLogic<TO, MOD> logic = getAnyLogic();
+
+        BulkActionResult result = new BulkActionResult();
+
+        switch (bulkAction.getOperation()) {
+            case DELETE:
+                for (String key : bulkAction.getTargets()) {
+                    try {
+                        result.getResults().put(
+                                
String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
+                                BulkActionResult.Status.SUCCESS);
+                    } catch (Exception e) {
+                        LOG.error("Error performing delete for user {}", key, 
e);
+                        result.getResults().put(key, 
BulkActionResult.Status.FAILURE);
+                    }
+                }
+                break;
+
+            case SUSPEND:
+                if (logic instanceof UserLogic) {
+                    for (String key : bulkAction.getTargets()) {
+                        StatusMod statusMod = new StatusMod();
+                        statusMod.setKey(Long.valueOf(key));
+                        statusMod.setType(StatusMod.ModType.SUSPEND);
+                        try {
+                            result.getResults().put(
+                                    String.valueOf(((UserLogic) 
logic).status(statusMod).getKey()),
+                                    BulkActionResult.Status.SUCCESS);
+                        } catch (Exception e) {
+                            LOG.error("Error performing suspend for user {}", 
key, e);
+                            result.getResults().put(key, 
BulkActionResult.Status.FAILURE);
+                        }
+                    }
+                }
+                break;
+
+            case REACTIVATE:
+                for (String key : bulkAction.getTargets()) {
+                    StatusMod statusMod = new StatusMod();
+                    statusMod.setKey(Long.valueOf(key));
+                    statusMod.setType(StatusMod.ModType.REACTIVATE);
+                    try {
+                        result.getResults().put(
+                                String.valueOf(((UserLogic) 
logic).status(statusMod).getKey()),
+                                BulkActionResult.Status.SUCCESS);
+                    } catch (Exception e) {
+                        LOG.error("Error performing reactivate for user {}", 
key, e);
+                        result.getResults().put(key, 
BulkActionResult.Status.FAILURE);
+                    }
+                }
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
new file mode 100644
index 0000000..ce6390a
--- /dev/null
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
@@ -0,0 +1,71 @@
+/*
+ * 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.rest.cxf.service;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.AnyObjectLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AnyObjectServiceImpl extends AbstractAnyService<AnyObjectTO, 
AnyObjectMod> implements AnyObjectService {
+
+    @Autowired
+    private AnyObjectLogic logic;
+
+    @Override
+    protected AbstractAnyLogic<AnyObjectTO, AnyObjectMod> getAnyLogic() {
+        return logic;
+    }
+
+    @Override
+    public PagedResult<AnyObjectTO> list(final String type, final AnyListQuery 
listQuery) {
+        if (StringUtils.isBlank(type)) {
+            return super.list(listQuery);
+        }
+
+        CollectionUtils.transform(listQuery.getRealms(), new 
Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, 
SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        return buildPagedResult(
+                logic.list(
+                        type,
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                getAnyLogic().count(listQuery.getRealms()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index bd24f22..d80caf9 100644
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -27,11 +27,12 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.wrap.BooleanWrap;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.core.logic.ConnectorLogic;
@@ -87,17 +88,12 @@ public class ConnectorServiceImpl extends 
AbstractServiceImpl implements Connect
     }
 
     @Override
-    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final Long key,
+    public List<ConnIdObjectClass> getSupportedObjectClasses(final Long key,
             final ConnInstanceTO connInstanceTO) {
 
         connInstanceTO.setKey(key);
 
-        List<String> objectClasses = 
logic.getSupportedObjectClasses(connInstanceTO);
-        List<ConnIdObjectClassTO> result = new 
ArrayList<>(objectClasses.size());
-        for (String objectClass : objectClasses) {
-            result.add(new ConnIdObjectClassTO(objectClass));
-        }
-        return result;
+        return 
CollectionWrapper.wrap(logic.getSupportedObjectClasses(connInstanceTO), 
ConnIdObjectClass.class);
     }
 
     @Override

Reply via email to