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 2016/01/26 13:04:32 UTC

[01/21] syncope git commit: Downgrading H2 to 1.4.190 since 1.4.191 seems to be slow

Repository: syncope
Updated Branches:
  refs/heads/master bf1c0fd90 -> 17d5d8928


Downgrading H2 to 1.4.190 since 1.4.191 seems to be slow


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/6f356218
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/6f356218
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/6f356218

Branch: refs/heads/master
Commit: 6f35621893e768fdbbd8de1794be2e947cbfc4b8
Parents: 6d56c7e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jan 26 11:06:06 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jan 26 11:40:59 2016 +0100

----------------------------------------------------------------------
 .../syncope/common/lib/to/AnyTypeClassTO.java   | 12 ++++++------
 .../common/lib/types/ClientExceptionType.java   |  1 -
 .../persistence/api/entity/AnyTypeClass.java    |  2 --
 .../persistence/jpa/entity/JPAAnyTypeClass.java |  6 ------
 .../java/data/AnyTypeClassDataBinderImpl.java   | 20 +-------------------
 .../fit/core/reference/AnyTypeITCase.java       | 14 +++-----------
 pom.xml                                         |  2 +-
 7 files changed, 11 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/6f356218/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
index 815b800..7ed12bd 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
@@ -36,7 +36,7 @@ public class AnyTypeClassTO extends AbstractBaseBean implements EntityTO<String>
 
     private String key;
 
-    private final List<String> types = new ArrayList<>();
+    private final List<String> inUseByTypes = new ArrayList<>();
 
     private final List<String> plainSchemas = new ArrayList<>();
 
@@ -55,11 +55,11 @@ public class AnyTypeClassTO extends AbstractBaseBean implements EntityTO<String>
         this.key = key;
     }
 
-    @XmlElementWrapper(name = "types")
-    @XmlElement(name = "type")
-    @JsonProperty("types")
-    public List<String> getTypes() {
-        return types;
+    @XmlElementWrapper(name = "inUseByTypes")
+    @XmlElement(name = "anyTypeClass")
+    @JsonProperty("inUseByTypes")
+    public List<String> getInUseByTypes() {
+        return inUseByTypes;
     }
 
     @XmlElementWrapper(name = "plainSchemas")

http://git-wip-us.apache.org/repos/asf/syncope/blob/6f356218/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index d72d3d2..dfc5fe2 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -43,7 +43,6 @@ public enum ClientExceptionType {
     InvalidRelationship(Response.Status.BAD_REQUEST),
     InvalidRelationshipType(Response.Status.BAD_REQUEST),
     InvalidAnyType(Response.Status.BAD_REQUEST),
-    InvalidAnyTypeClass(Response.Status.BAD_REQUEST),
     InvalidAnyObject(Response.Status.BAD_REQUEST),
     InvalidGroup(Response.Status.BAD_REQUEST),
     InvalidSchemaDefinition(Response.Status.BAD_REQUEST),

http://git-wip-us.apache.org/repos/asf/syncope/blob/6f356218/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
index f6682b5..1908b69 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
@@ -24,8 +24,6 @@ public interface AnyTypeClass extends Entity<String> {
 
     void setKey(String key);
 
-    List<? extends AnyType> getTypes();
-
     boolean add(PlainSchema schema);
 
     List<? extends PlainSchema> getPlainSchemas();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6f356218/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
index b823f49..58d5eb1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
@@ -27,7 +27,6 @@ import javax.persistence.Id;
 import javax.persistence.ManyToMany;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
@@ -68,11 +67,6 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     }
 
     @Override
-    public List<? extends AnyType> getTypes() {
-        return types;
-    }
-
-    @Override
     public boolean add(final PlainSchema schema) {
         checkType(schema, JPAPlainSchema.class);
         return this.plainSchemas.add((JPAPlainSchema) schema);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6f356218/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
index b5bc11a..e8ae693 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
@@ -19,11 +19,7 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.util.Collections;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
@@ -73,20 +69,6 @@ public class AnyTypeClassDataBinderImpl implements AnyTypeClassDataBinder {
             anyTypeClass.setKey(anyTypeClassTO.getKey());
         }
 
-        if (!CollectionUtils.disjunction(
-                CollectionUtils.collect(anyTypeClass.getTypes(), new Transformer<AnyType, String>() {
-
-                    @Override
-                    public String transform(final AnyType anyType) {
-                        return anyType.getKey();
-                    }
-                }), anyTypeClassTO.getTypes()).isEmpty()) {
-
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyTypeClass);
-            sce.getElements().add("Cannot update types from classes, do the other way round");
-            throw sce;
-        }
-
         for (PlainSchema schema : plainSchemaDAO.findByAnyTypeClasses(Collections.singletonList(anyTypeClass))) {
             schema.setAnyTypeClass(null);
         }
@@ -140,7 +122,7 @@ public class AnyTypeClassDataBinderImpl implements AnyTypeClassDataBinder {
         anyTypeClassTO.setKey(anyTypeClass.getKey());
 
         for (AnyType anyType : anyTypeDAO.findByTypeClass(anyTypeClass)) {
-            anyTypeClassTO.getTypes().add(anyType.getKey());
+            anyTypeClassTO.getInUseByTypes().add(anyType.getKey());
         }
 
         for (PlainSchema schema : anyTypeClass.getPlainSchemas()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6f356218/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
index b82aabd..704370e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
@@ -182,17 +182,9 @@ public class AnyTypeITCase extends AbstractITCase {
             assertTrue(group.getClasses().contains("other"));
 
             other = anyTypeClassService.read("other");
-            assertEquals(2, other.getTypes().size());
-            assertTrue(other.getTypes().contains(AnyTypeKind.USER.name()));
-            assertTrue(other.getTypes().contains(AnyTypeKind.GROUP.name()));
-
-            other.getTypes().remove(AnyTypeKind.GROUP.name());
-            try {
-                anyTypeClassService.update(other);
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.InvalidAnyTypeClass, e.getType());
-            }
+            assertEquals(2, other.getInUseByTypes().size());
+            assertTrue(other.getInUseByTypes().contains(AnyTypeKind.USER.name()));
+            assertTrue(other.getInUseByTypes().contains(AnyTypeKind.GROUP.name()));
         } finally {
             group.getClasses().remove("other");
             anyTypeService.update(group);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6f356218/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bf6cff2..98a2a7e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -365,7 +365,7 @@ under the License.
     <commons-collection.version>4.1</commons-collection.version>
     <commons-logging.version>1.1.3</commons-logging.version>
 
-    <h2.version>1.4.191</h2.version>
+    <h2.version>1.4.190</h2.version>
 
     <junit.version>4.12</junit.version>
 


[11/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CLIITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CLIITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CLIITCase.java
deleted file mode 100644
index 746459f..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CLIITCase.java
+++ /dev/null
@@ -1,276 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.SystemUtils;
-import org.apache.syncope.client.cli.Command;
-import org.apache.syncope.client.cli.commands.connector.ConnectorCommand;
-import org.apache.syncope.client.cli.commands.entitlement.EntitlementCommand;
-import org.apache.syncope.client.cli.commands.group.GroupCommand;
-import org.apache.syncope.client.cli.commands.install.InstallCommand;
-import org.apache.syncope.client.cli.commands.policy.PolicyCommand;
-import org.apache.syncope.client.cli.commands.report.ReportCommand;
-import org.apache.syncope.client.cli.commands.role.RoleCommand;
-import org.apache.syncope.client.cli.commands.user.UserCommand;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class CLIITCase extends AbstractITCase {
-
-    private static final String SCRIPT_FILENAME = "syncopeadm";
-
-    private static ProcessBuilder PROCESS_BUILDER;
-
-    @BeforeClass
-    public static void install() {
-        Properties props = new Properties();
-        InputStream propStream = null;
-        try {
-            propStream = ExceptionMapperITCase.class.getResourceAsStream("/cli-test.properties");
-            props.load(propStream);
-
-            File workDir = new File(props.getProperty("cli-work.dir"));
-            PROCESS_BUILDER = new ProcessBuilder();
-            PROCESS_BUILDER.directory(workDir);
-
-            PROCESS_BUILDER.command(getCommand(
-                    new InstallCommand().getClass().getAnnotation(Command.class).name(),
-                    InstallCommand.Options.SETUP_DEBUG.getOptionName()));
-            Process process = PROCESS_BUILDER.start();
-            process.waitFor();
-
-            File cliPropertiesFile = new File(workDir + File.separator + "cli.properties");
-            assertTrue(cliPropertiesFile.exists());
-        } catch (IOException | InterruptedException e) {
-            fail(e.getMessage());
-        } finally {
-            IOUtils.closeQuietly(propStream);
-        }
-    }
-
-    private static String[] getCommand(final String... arguments) {
-        List<String> command = new ArrayList<>();
-
-        if (SystemUtils.IS_OS_WINDOWS) {
-            command.add("cmd");
-            command.add(SCRIPT_FILENAME + ".bat");
-        } else {
-            command.add("/bin/bash");
-            command.add(SCRIPT_FILENAME + ".sh");
-        }
-
-        CollectionUtils.addAll(command, arguments);
-
-        return command.toArray(new String[command.size()]);
-    }
-
-    @Test
-    public void runScriptWithoutOptions() {
-        try {
-            PROCESS_BUILDER.command(getCommand());
-            Process process = PROCESS_BUILDER.start();
-
-            String result = IOUtils.toString(process.getInputStream());
-            assertTrue(result.startsWith("\nUsage: Main [options]"));
-            assertTrue(result.contains(
-                    new EntitlementCommand().getClass().getAnnotation(Command.class).name()
-                    + " "
-                    + EntitlementCommand.EntitlementOptions.HELP.getOptionName()));
-            assertTrue(result.contains(
-                    new GroupCommand().getClass().getAnnotation(Command.class).name()
-                    + " "
-                    + GroupCommand.GroupOptions.HELP.getOptionName()));
-            process.destroy();
-        } catch (IOException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void entitlementCount() {
-        try {
-            PROCESS_BUILDER.command(getCommand(
-                    new EntitlementCommand().getClass().getAnnotation(Command.class).name(),
-                    EntitlementCommand.EntitlementOptions.LIST.getOptionName()));
-            Process process = PROCESS_BUILDER.start();
-
-            long entitlements = IterableUtils.countMatches(IOUtils.readLines(process.getInputStream()),
-                    new Predicate<String>() {
-
-                        @Override
-                        public boolean evaluate(final String line) {
-                            return line.startsWith("-");
-                        }
-                    });
-            assertEquals(syncopeService.info().getEntitlements().size(), entitlements);
-
-            process.destroy();
-        } catch (IOException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void connectorCount() {
-        try {
-            PROCESS_BUILDER.command(getCommand(
-                    new ConnectorCommand().getClass().getAnnotation(Command.class).name(),
-                    ConnectorCommand.ConnectorOptions.LIST_BUNDLES.getOptionName()));
-            Process process = PROCESS_BUILDER.start();
-
-            long bundles = IterableUtils.countMatches(IOUtils.readLines(process.getInputStream()),
-                    new Predicate<String>() {
-
-                        @Override
-                        public boolean evaluate(final String line) {
-                            return line.startsWith(" > BUNDLE NAME:");
-                        }
-                    });
-            assertEquals(connectorService.getBundles(null).size(), bundles);
-
-            process.destroy();
-        } catch (IOException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void userRead() {
-        final long userId1 = 1;
-        final long userId2 = 2;
-        final long userId3 = 3;
-        final long userId4 = 4;
-        final long userId5 = 5;
-        try {
-            PROCESS_BUILDER.command(getCommand(
-                    new UserCommand().getClass().getAnnotation(Command.class).name(),
-                    UserCommand.UserOptions.READ_BY_ID.getOptionName(),
-                    String.valueOf(userId1)));
-            Process process = PROCESS_BUILDER.start();
-            String result = IOUtils.toString(process.getInputStream());
-            assertTrue(result.contains("username: " + userService.read(userId1).getUsername()));
-            process.destroy();
-
-            PROCESS_BUILDER.command(getCommand(
-                    new UserCommand().getClass().getAnnotation(Command.class).name(),
-                    UserCommand.UserOptions.READ_BY_ID.getOptionName(),
-                    String.valueOf(userId1), String.valueOf(userId2),
-                    String.valueOf(userId3), String.valueOf(userId4), String.valueOf(userId5)));
-            Process process2 = PROCESS_BUILDER.start();
-            long users = IterableUtils.countMatches(IOUtils.readLines(process2.getInputStream()),
-                    new Predicate<String>() {
-
-                        @Override
-                        public boolean evaluate(final String line) {
-                            return line.startsWith(" > USER ID:");
-                        }
-                    });
-            assertEquals(5, users);
-
-            process2.destroy();
-
-            PROCESS_BUILDER.command(getCommand(
-                    new UserCommand().getClass().getAnnotation(Command.class).name(),
-                    UserCommand.UserOptions.READ_BY_ID.getOptionName(),
-                    String.valueOf(userId1), String.valueOf(userId2),
-                    String.valueOf(userId3), String.valueOf(userId4), String.valueOf(userId5)));
-            Process process3 = PROCESS_BUILDER.start();
-            String result3 = IOUtils.toString(process3.getInputStream());
-            assertTrue(
-                    result3.contains("username: " + userService.read(userId1).getUsername())
-                    && result3.contains("username: " + userService.read(userId2).getUsername())
-                    && result3.contains("username: " + userService.read(userId3).getUsername())
-                    && result3.contains("username: " + userService.read(userId4).getUsername())
-                    && result3.contains("username: " + userService.read(userId5).getUsername()));
-            process3.destroy();
-        } catch (IOException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void roleRead() {
-        final String roleId = "Search for realm evenTwo";
-        try {
-            PROCESS_BUILDER.command(getCommand(
-                    new RoleCommand().getClass().getAnnotation(Command.class).name(),
-                    RoleCommand.RoleOptions.READ.getOptionName(),
-                    roleId));
-            final Process process = PROCESS_BUILDER.start();
-            final String result = IOUtils.toString(process.getInputStream());
-            assertTrue(result.contains(roleService.read(roleId).getEntitlements().iterator().next()));
-
-            process.destroy();
-        } catch (IOException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void reportNotExists() {
-        try {
-            PROCESS_BUILDER.command(getCommand(
-                    new ReportCommand().getClass().getAnnotation(Command.class).name(),
-                    ReportCommand.ReportOptions.READ.getOptionName(),
-                    "2"));
-            final Process process = PROCESS_BUILDER.start();
-            final String result = IOUtils.toString(process.getInputStream());
-            assertTrue(result.contains("- Report 2 doesn't exist"));
-
-            process.destroy();
-        } catch (IOException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void policyError() {
-        try {
-            PROCESS_BUILDER.command(getCommand(
-                    new PolicyCommand().getClass().getAnnotation(Command.class).name(),
-                    PolicyCommand.PolicyOptions.READ.getOptionName(),
-                    "wrong"));
-            final Process process = PROCESS_BUILDER.start();
-            final String result = IOUtils.toString(process.getInputStream());
-            assertTrue(result.contains(
-                    "- Error reading wrong. It isn't a valid policy value because it isn't a boolean value"));
-
-            process.destroy();
-        } catch (IOException e) {
-            fail(e.getMessage());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
deleted file mode 100644
index 0021922..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
+++ /dev/null
@@ -1,36 +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.fit.core.reference;
-
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-
-public class CamelDetector {
-
-    public static boolean isCamelEnabledForUsers(final SyncopeService syncopeService) {
-        return syncopeService.info().getUserProvisioningManager().indexOf("Camel") != -1;
-    }
-
-    public static boolean isCamelEnabledForGroups(final SyncopeService syncopeService) {
-        return syncopeService.info().getGroupProvisioningManager().indexOf("Camel") != -1;
-    }
-
-    public static boolean isCamelEnabledForAnyObjects(final SyncopeService syncopeService) {
-        return syncopeService.info().getAnyObjectProvisioningManager().indexOf("Camel") != -1;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
deleted file mode 100644
index 0ef0dd5..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
+++ /dev/null
@@ -1,175 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.List;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.CamelRouteTO;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.junit.Assume;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class CamelRouteITCase extends AbstractITCase {
-
-    @Test
-    public void userRoutes() {
-        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
-
-        List<CamelRouteTO> userRoutes = camelRouteService.list(AnyTypeKind.USER);
-        assertNotNull(userRoutes);
-        assertEquals(16, userRoutes.size());
-        for (CamelRouteTO route : userRoutes) {
-            assertNotNull(route.getContent());
-        }
-    }
-
-    @Test
-    public void groupRoutes() {
-        Assume.assumeTrue(CamelDetector.isCamelEnabledForGroups(syncopeService));
-
-        List<CamelRouteTO> groupRoutes = camelRouteService.list(AnyTypeKind.GROUP);
-        assertNotNull(groupRoutes);
-        assertEquals(8, groupRoutes.size());
-        for (CamelRouteTO route : groupRoutes) {
-            assertNotNull(route.getContent());
-        }
-    }
-
-    private CamelRouteTO doUpdate(final String key, final String content) {
-        CamelRouteTO route = camelRouteService.read(key);
-        route.setContent(content);
-        camelRouteService.update(route);
-        // getting new route definition
-        return camelRouteService.read(key);
-    }
-
-    @Test
-    public void update() {
-        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
-
-        CamelRouteTO oldRoute = camelRouteService.read("createUser");
-        assertNotNull(oldRoute);
-        String routeContent = "<route id=\"createUser\">\n"
-                + "  <from uri=\"direct:createUser\"/>\n"
-                + "  <setProperty propertyName=\"actual\">\n"
-                + "    <simple>${body}</simple>\n"
-                + "  </setProperty>\n"
-                + "  <doTry>\n"
-                + "    <bean ref=\"uwfAdapter\" method=\"create(${body},${property.disablePwdPolicyCheck},\n"
-                + "                             ${property.enabled},${property.storePassword})\"/>\n"
-                + "    <process ref=\"userCreateProcessor\" />\n"
-                + "    <to uri=\"direct:createPort\"/>\n"
-                + "    <to uri=\"log:myLog\"/>\n"
-                + "    <doCatch>        \n"
-                + "      <exception>java.lang.RuntimeException</exception>\n"
-                + "      <handled>\n"
-                + "        <constant>false</constant>\n"
-                + "      </handled>\n"
-                + "      <to uri=\"direct:createPort\"/>\n"
-                + "    </doCatch>\n"
-                + "  </doTry>\n"
-                + "</route>";
-        try {
-            CamelRouteTO route = doUpdate("createUser", routeContent);
-            assertEquals(routeContent, route.getContent());
-        } finally {
-            doUpdate(oldRoute.getKey(), oldRoute.getContent());
-        }
-    }
-
-    @Test
-    public void scriptingUpdate() {
-        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
-
-        CamelRouteTO oldRoute = camelRouteService.read("createUser");
-        // updating route content including new attribute management
-
-        String routeContent = ""
-                + "  <route id=\"createUser\">\n"
-                + "    <from uri=\"direct:createUser\"/>\n"
-                + "    <setProperty propertyName=\"actual\">\n"
-                + "      <simple>${body}</simple>\n"
-                + "    </setProperty>\n"
-                + "    <setBody>\n"
-                + "     <groovy>\n"
-                + "       org.apache.commons.collections4."
-                + "CollectionUtils.get(request.body.getPlainAttrs(), 3).getValues().set(0,\"true\")\n"
-                + "       return request.body\n"
-                + "     </groovy>\n"
-                + "    </setBody>\n"
-                + "    <doTry>\n"
-                + "      <bean ref=\"uwfAdapter\" method=\"create(${body},${property.disablePwdPolicyCheck},\n"
-                + "                                     ${property.enabled},${property.storePassword})\"/>\n"
-                + "      <process ref=\"userCreateProcessor\"/>\n"
-                + "      <to uri=\"direct:createPort\"/>\n"
-                + "      <doCatch>        \n"
-                + "        <exception>java.lang.RuntimeException</exception>\n"
-                + "        <handled>\n"
-                + "          <constant>false</constant>\n"
-                + "        </handled>\n"
-                + "        <to uri=\"direct:createPort\"/>\n"
-                + "      </doCatch>\n"
-                + "    </doTry>\n"
-                + "  </route> ";
-        try {
-            doUpdate("createUser", routeContent);
-
-            // creating new schema attribute for user
-            PlainSchemaTO schemaTO = new PlainSchemaTO();
-            schemaTO.setKey("camelAttribute");
-            schemaTO.setType(AttrSchemaType.String);
-            createSchema(SchemaType.PLAIN, schemaTO);
-
-            AnyTypeClassTO typeClass = new AnyTypeClassTO();
-            typeClass.setKey("camelAttribute");
-            typeClass.getPlainSchemas().add(schemaTO.getKey());
-            anyTypeClassService.create(typeClass);
-
-            UserTO userTO = new UserTO();
-            userTO.setRealm(SyncopeConstants.ROOT_REALM);
-            userTO.getAuxClasses().add(typeClass.getKey());
-            String userId = getUUIDString() + "camelUser@syncope.apache.org";
-            userTO.setUsername(userId);
-            userTO.setPassword("password123");
-            userTO.getPlainAttrs().add(attrTO("userId", userId));
-            userTO.getPlainAttrs().add(attrTO("fullname", userId));
-            userTO.getPlainAttrs().add(attrTO("surname", userId));
-            userTO.getPlainAttrs().add(attrTO("camelAttribute", "false"));
-
-            userTO = createUser(userTO).getAny();
-            assertNotNull(userTO);
-            assertEquals("true", IterableUtils.get(userTO.getPlainAttrs(), 3).getValues().get(0));
-        } finally {
-            doUpdate(oldRoute.getKey(), oldRoute.getContent());
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
deleted file mode 100644
index 1fb3221..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
+++ /dev/null
@@ -1,172 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.List;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class ConfigurationITCase extends AbstractITCase {
-
-    @Test
-    public void create() {
-        PlainSchemaTO testKey = new PlainSchemaTO();
-        testKey.setKey("testKey" + getUUIDString());
-        testKey.setType(AttrSchemaType.String);
-        createSchema(SchemaType.PLAIN, testKey);
-
-        AttrTO conf = new AttrTO.Builder().schema(testKey.getKey()).value("testValue").build();
-
-        configurationService.set(conf);
-
-        AttrTO actual = configurationService.get(conf.getSchema());
-        assertEquals(actual, conf);
-    }
-
-    @Test
-    public void createRequired() {
-        PlainSchemaTO testKey = new PlainSchemaTO();
-        testKey.setKey("testKey" + getUUIDString());
-        testKey.setType(AttrSchemaType.String);
-        testKey.setMandatoryCondition("true");
-        createSchema(SchemaType.PLAIN, testKey);
-
-        AttrTO conf = new AttrTO.Builder().schema(testKey.getKey()).build();
-        try {
-            configurationService.set(conf);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-
-        conf.getValues().add("testValue");
-        configurationService.set(conf);
-
-        AttrTO actual = configurationService.get(conf.getSchema());
-        assertEquals(actual, conf);
-    }
-
-    @Test
-    public void delete() throws UnsupportedEncodingException {
-        try {
-            configurationService.delete("nonExistent");
-            fail("The delete operation should throw an exception because of nonExistent schema");
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-
-        AttrTO tokenLength = configurationService.get("token.length");
-
-        configurationService.delete("token.length");
-
-        AttrTO actual = configurationService.get(tokenLength.getSchema());
-        assertNotEquals(actual, tokenLength);
-
-        configurationService.set(tokenLength);
-
-        actual = configurationService.get(tokenLength.getSchema());
-        assertEquals(actual, tokenLength);
-    }
-
-    @Test
-    public void list() {
-        List<AttrTO> wholeConf = configurationService.list();
-        assertNotNull(wholeConf);
-        for (AttrTO conf : wholeConf) {
-            assertNotNull(conf);
-        }
-    }
-
-    @Test
-    public void read() {
-        AttrTO conf = configurationService.get("token.expireTime");
-        assertNotNull(conf);
-    }
-
-    @Test
-    public void update() {
-        AttrTO expireTime = configurationService.get("token.expireTime");
-        int value = Integer.parseInt(expireTime.getValues().get(0));
-        value++;
-        expireTime.getValues().set(0, value + "");
-
-        configurationService.set(expireTime);
-
-        AttrTO newConfigurationTO = configurationService.get(expireTime.getSchema());
-        assertEquals(expireTime, newConfigurationTO);
-    }
-
-    @Test
-    public void dbExport() throws IOException {
-        Response response = configurationService.export();
-        assertNotNull(response);
-        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
-        assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
-        String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
-        assertNotNull(contentDisposition);
-
-        Object entity = response.getEntity();
-        assertTrue(entity instanceof InputStream);
-        String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
-        assertFalse(configExport.isEmpty());
-        assertTrue(configExport.length() > 1000);
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        PlainSchemaTO failing = new PlainSchemaTO();
-        failing.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-        failing.setType(AttrSchemaType.String);
-
-        try {
-            createSchema(SchemaType.PLAIN, failing);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-
-            assertNotNull(e.getElements());
-            assertEquals(1, e.getElements().size());
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
deleted file mode 100644
index 82f6f02..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
+++ /dev/null
@@ -1,746 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.BulkAction;
-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.ConnPoolConfTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ConnConfPropSchema;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.rest.api.service.ConnectorService;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class ConnectorITCase extends AbstractITCase {
-
-    private static String connectorServerLocation;
-
-    private static String connidSoapVersion;
-
-    private static String connidDbTableVersion;
-
-    private static String testJDBCURL;
-
-    @BeforeClass
-    public static void setUpConnIdBundles() throws IOException {
-        InputStream propStream = null;
-        try {
-            Properties props = new Properties();
-            propStream = ConnectorITCase.class.getResourceAsStream("/connid.properties");
-            props.load(propStream);
-
-            for (String location : props.getProperty("connid.locations").split(",")) {
-                if (!location.startsWith("file")) {
-                    connectorServerLocation = location;
-                }
-            }
-
-            connidSoapVersion = props.getProperty("connid.soap.version");
-            connidDbTableVersion = props.getProperty("connid.database.version");
-
-            testJDBCURL = props.getProperty("testdb.url");
-        } catch (Exception e) {
-            LOG.error("Could not load /connid.properties", e);
-        } finally {
-            IOUtils.closeQuietly(propStream);
-        }
-        assertNotNull(connectorServerLocation);
-        assertNotNull(connidSoapVersion);
-        assertNotNull(connidDbTableVersion);
-        assertNotNull(testJDBCURL);
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void createWithException() {
-        ConnInstanceTO connectorTO = new ConnInstanceTO();
-
-        Response response = connectorService.create(connectorTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
-        }
-    }
-
-    @Test
-    public void create() {
-        ConnInstanceTO connectorTO = new ConnInstanceTO();
-        connectorTO.setLocation(connectorService.read(100L, Locale.ENGLISH.getLanguage()).getLocation());
-        connectorTO.setVersion(connidSoapVersion);
-        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
-        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
-        connectorTO.setDisplayName("Display name");
-        connectorTO.setConnRequestTimeout(15);
-
-        // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<>();
-
-        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
-        endpointSchema.setName("endpoint");
-        endpointSchema.setType(String.class.getName());
-        endpointSchema.setRequired(true);
-        ConnConfProperty endpoint = new ConnConfProperty();
-        endpoint.setSchema(endpointSchema);
-        endpoint.getValues().add("http://localhost:8888/wssample/services");
-        endpoint.getValues().add("Provisioning");
-        conf.add(endpoint);
-
-        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
-        servicenameSchema.setName("servicename");
-        servicenameSchema.setType(String.class.getName());
-        servicenameSchema.setRequired(true);
-        ConnConfProperty servicename = new ConnConfProperty();
-        servicename.setSchema(servicenameSchema);
-        conf.add(servicename);
-
-        // set connector configuration
-        connectorTO.getConf().addAll(conf);
-
-        // set connector capabilities
-        connectorTO.getCapabilities().add(ConnectorCapability.CREATE);
-        connectorTO.getCapabilities().add(ConnectorCapability.UPDATE);
-
-        // set connector pool conf
-        ConnPoolConfTO cpc = new ConnPoolConfTO();
-        cpc.setMaxObjects(1534);
-        connectorTO.setPoolConf(cpc);
-
-        Response response = connectorService.create(connectorTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
-        }
-
-        ConnInstanceTO actual = getObject(
-                response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
-        assertNotNull(actual);
-
-        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
-        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
-        assertEquals(actual.getVersion(), connectorTO.getVersion());
-        assertEquals("Display name", actual.getDisplayName());
-        assertEquals(Integer.valueOf(15), actual.getConnRequestTimeout());
-        assertEquals(connectorTO.getCapabilities(), actual.getCapabilities());
-        assertNotNull(actual.getPoolConf());
-        assertEquals(1534, actual.getPoolConf().getMaxObjects(), 0);
-        assertEquals(10, actual.getPoolConf().getMaxIdle(), 0);
-
-        Throwable t = null;
-
-        // check update
-        actual.getCapabilities().remove(ConnectorCapability.UPDATE);
-        actual.getPoolConf().setMaxObjects(null);
-
-        try {
-            connectorService.update(actual);
-            actual = connectorService.read(actual.getKey(), Locale.ENGLISH.getLanguage());
-        } catch (SyncopeClientException e) {
-            LOG.error("update failed", e);
-            t = e;
-        }
-
-        assertNull(t);
-        assertNotNull(actual);
-        assertEquals(EnumSet.of(ConnectorCapability.CREATE), actual.getCapabilities());
-        assertEquals(10, actual.getPoolConf().getMaxObjects(), 0);
-
-        // check also for the deletion of the created object
-        try {
-            connectorService.delete(actual.getKey());
-        } catch (SyncopeClientException e) {
-            LOG.error("delete failed", e);
-            t = e;
-        }
-
-        assertNull(t);
-
-        // check the non existence
-        try {
-            connectorService.read(actual.getKey(), Locale.ENGLISH.getLanguage());
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void update() {
-        ConnInstanceTO connectorTO = new ConnInstanceTO();
-
-        // set connector instance id
-        connectorTO.setKey(103L);
-
-        // set connector version
-        connectorTO.setVersion(connidSoapVersion);
-
-        // set connector name
-        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
-
-        // set bundle name
-        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
-
-        connectorTO.setConnRequestTimeout(20);
-
-        // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<>();
-
-        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
-        endpointSchema.setName("endpoint");
-        endpointSchema.setType(String.class.getName());
-        endpointSchema.setRequired(true);
-        ConnConfProperty endpoint = new ConnConfProperty();
-        endpoint.setSchema(endpointSchema);
-        endpoint.getValues().add("http://localhost:8888/wssample/services");
-        conf.add(endpoint);
-
-        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
-        servicenameSchema.setName("servicename");
-        servicenameSchema.setType(String.class.getName());
-        servicenameSchema.setRequired(true);
-        ConnConfProperty servicename = new ConnConfProperty();
-        servicename.setSchema(servicenameSchema);
-        servicename.getValues().add("Provisioning");
-        conf.add(servicename);
-
-        // set connector configuration
-        connectorTO.getConf().addAll(conf);
-
-        connectorService.update(connectorTO);
-        ConnInstanceTO actual = connectorService.read(connectorTO.getKey(), Locale.ENGLISH.getLanguage());
-
-        assertNotNull(actual);
-
-        actual = connectorService.read(actual.getKey(), Locale.ENGLISH.getLanguage());
-
-        assertNotNull(actual);
-        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
-        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
-        assertEquals(actual.getVersion(), connectorTO.getVersion());
-        assertEquals(Integer.valueOf(20), actual.getConnRequestTimeout());
-    }
-
-    private List<ResourceTO> filter(final List<ResourceTO> input, final Long connectorKey) {
-        List<ResourceTO> result = new ArrayList<>();
-
-        for (ResourceTO resource : input) {
-            if (connectorKey.equals(resource.getConnector())) {
-                result.add(resource);
-            }
-        }
-
-        return result;
-    }
-
-    @Test
-    public void issueSYNCOPE10() {
-        // ----------------------------------
-        // Copy resource and connector in order to create new objects.
-        // ----------------------------------
-        // Retrieve a connector instance template.
-        ConnInstanceTO connInstanceTO = connectorService.read(103L, Locale.ENGLISH.getLanguage());
-        assertNotNull(connInstanceTO);
-
-        // check for resource
-        List<ResourceTO> resources = filter(resourceService.list(), 103L);
-        assertEquals(4, resources.size());
-
-        // Retrieve a resource TO template.
-        ResourceTO resourceTO = resources.get(0);
-
-        // Make it new.
-        resourceTO.setKey("newAbout103" + getUUIDString());
-
-        // Make it new.
-        connInstanceTO.setKey(0L);
-        connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
-        // ----------------------------------
-
-        // ----------------------------------
-        // Create a new connector instance.
-        // ----------------------------------
-        Response response = connectorService.create(connInstanceTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
-        }
-
-        connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
-        assertNotNull(connInstanceTO);
-        assertFalse(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
-
-        long connId = connInstanceTO.getKey();
-
-        // Link resourceTO to the new connector instance.
-        resourceTO.setConnector(connId);
-        // ----------------------------------
-
-        // ----------------------------------
-        // Check for connector instance update after resource creation.
-        // ----------------------------------
-        response = resourceService.create(resourceTO);
-        resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-
-        assertNotNull(resourceTO);
-
-        resources = filter(resourceService.list(), connId);
-        assertEquals(1, resources.size());
-        // ----------------------------------
-
-        // ----------------------------------
-        // Check for spring bean.
-        // ----------------------------------
-        ConnInstanceTO connInstanceBean = connectorService.readByResource(
-                resourceTO.getKey(), Locale.ENGLISH.getLanguage());
-        assertNotNull(connInstanceBean);
-        assertFalse(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
-        // ----------------------------------
-
-        // ----------------------------------
-        // Check for spring bean update after connector instance update.
-        // ----------------------------------
-        connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE);
-
-        connectorService.update(connInstanceTO);
-        ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey(), Locale.ENGLISH.getLanguage());
-        assertNotNull(actual);
-        assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
-
-        // check for spring bean update
-        connInstanceBean = connectorService.readByResource(resourceTO.getKey(), Locale.ENGLISH.getLanguage());
-        assertTrue(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
-        // ----------------------------------
-    }
-
-    @Test
-    public void deleteWithException() {
-        try {
-            connectorService.delete(0L);
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void list() {
-        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list(null);
-        assertNotNull(connectorInstanceTOs);
-        assertFalse(connectorInstanceTOs.isEmpty());
-        for (ConnInstanceTO instance : connectorInstanceTOs) {
-            assertNotNull(instance);
-        }
-    }
-
-    @Test
-    public void read() {
-        ConnInstanceTO connectorInstanceTO = connectorService.read(100L, Locale.ENGLISH.getLanguage());
-        assertNotNull(connectorInstanceTO);
-    }
-
-    @Test
-    public void getBundles() {
-        List<ConnBundleTO> bundles = connectorService.getBundles(Locale.ENGLISH.getLanguage());
-        assertNotNull(bundles);
-        assertFalse(bundles.isEmpty());
-        for (ConnBundleTO bundle : bundles) {
-            assertNotNull(bundle);
-        }
-    }
-
-    @Test
-    public void getConnectorConfiguration() {
-        Set<ConnConfProperty> props = connectorService.read(104L, Locale.ENGLISH.getLanguage()).getConf();
-        assertNotNull(props);
-        assertFalse(props.isEmpty());
-    }
-
-    @Test
-    public void checkHiddenProperty() {
-        ConnInstanceTO connInstanceTO = connectorService.read(100L, Locale.ENGLISH.getLanguage());
-
-        boolean check = false;
-
-        for (ConnConfProperty prop : connInstanceTO.getConf()) {
-            if ("receiveTimeout".equals(prop.getSchema().getName())) {
-                check = true;
-            }
-        }
-        assertTrue(check);
-    }
-
-    @Test
-    public void checkSelectedLanguage() {
-        // 1. Check Italian
-        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list("it");
-
-        Map<String, ConnConfProperty> instanceConfMap;
-        for (ConnInstanceTO instance : connectorInstanceTOs) {
-            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
-                instanceConfMap = instance.getConfMap();
-                assertEquals("Utente", instanceConfMap.get("user").getSchema().getDisplayName());
-            }
-        }
-
-        // 2. Check English (default)
-        connectorInstanceTOs = connectorService.list(null);
-
-        for (ConnInstanceTO instance : connectorInstanceTOs) {
-            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
-                instanceConfMap = instance.getConfMap();
-                assertEquals("User", instanceConfMap.get("user").getSchema().getDisplayName());
-            }
-        }
-    }
-
-    @Test
-    public void validate() {
-        ConnInstanceTO connectorTO = new ConnInstanceTO();
-        connectorTO.setLocation(connectorServerLocation);
-        connectorTO.setVersion(connidDbTableVersion);
-        connectorTO.setConnectorName("net.tirasa.connid.bundles.db.table.DatabaseTableConnector");
-        connectorTO.setBundleName("net.tirasa.connid.bundles.db.table");
-        connectorTO.setDisplayName("H2Test");
-
-        // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<>();
-
-        ConnConfPropSchema jdbcDriverSchema = new ConnConfPropSchema();
-        jdbcDriverSchema.setName("jdbcDriver");
-        jdbcDriverSchema.setType(String.class.getName());
-        jdbcDriverSchema.setRequired(true);
-        ConnConfProperty jdbcDriver = new ConnConfProperty();
-        jdbcDriver.setSchema(jdbcDriverSchema);
-        jdbcDriver.getValues().add("org.h2.Driver");
-        conf.add(jdbcDriver);
-
-        ConnConfPropSchema jdbcUrlTemplateSchema = new ConnConfPropSchema();
-        jdbcUrlTemplateSchema.setName("jdbcUrlTemplate");
-        jdbcUrlTemplateSchema.setType(String.class.getName());
-        jdbcUrlTemplateSchema.setRequired(true);
-        ConnConfProperty jdbcUrlTemplate = new ConnConfProperty();
-        jdbcUrlTemplate.setSchema(jdbcUrlTemplateSchema);
-        jdbcUrlTemplate.getValues().add(testJDBCURL);
-        conf.add(jdbcUrlTemplate);
-
-        ConnConfPropSchema userSchema = new ConnConfPropSchema();
-        userSchema.setName("user");
-        userSchema.setType(String.class.getName());
-        userSchema.setRequired(false);
-        ConnConfProperty user = new ConnConfProperty();
-        user.setSchema(userSchema);
-        user.getValues().add("sa");
-        conf.add(user);
-
-        ConnConfPropSchema passwordSchema = new ConnConfPropSchema();
-        passwordSchema.setName("password");
-        passwordSchema.setType(GuardedString.class.getName());
-        passwordSchema.setRequired(true);
-        ConnConfProperty password = new ConnConfProperty();
-        password.setSchema(passwordSchema);
-        password.getValues().add("sa");
-        conf.add(password);
-
-        ConnConfPropSchema tableSchema = new ConnConfPropSchema();
-        tableSchema.setName("table");
-        tableSchema.setType(String.class.getName());
-        tableSchema.setRequired(true);
-        ConnConfProperty table = new ConnConfProperty();
-        table.setSchema(tableSchema);
-        table.getValues().add("test");
-        conf.add(table);
-
-        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
-        keyColumnSchema.setName("keyColumn");
-        keyColumnSchema.setType(String.class.getName());
-        keyColumnSchema.setRequired(true);
-        ConnConfProperty keyColumn = new ConnConfProperty();
-        keyColumn.setSchema(keyColumnSchema);
-        keyColumn.getValues().add("id");
-        conf.add(keyColumn);
-
-        ConnConfPropSchema passwordColumnSchema = new ConnConfPropSchema();
-        passwordColumnSchema.setName("passwordColumn");
-        passwordColumnSchema.setType(String.class.getName());
-        passwordColumnSchema.setRequired(true);
-        ConnConfProperty passwordColumn = new ConnConfProperty();
-        passwordColumn.setSchema(passwordColumnSchema);
-        passwordColumn.getValues().add("password");
-        conf.add(passwordColumn);
-
-        // set connector configuration
-        connectorTO.getConf().addAll(conf);
-
-        try {
-            connectorService.check(connectorTO);
-        } catch (Exception e) {
-            fail(ExceptionUtils.getStackTrace(e));
-        }
-
-        conf.remove(password);
-        password.getValues().clear();
-        password.getValues().add("password");
-        conf.add(password);
-
-        try {
-            connectorService.check(connectorTO);
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void buildObjectClassInfo() {
-        ConnInstanceTO ws = connectorService.read(102L, Locale.ENGLISH.getLanguage());
-        assertNotNull(ws);
-
-        List<ConnIdObjectClassTO> objectClassInfo = connectorService.buildObjectClassInfo(ws, true);
-        assertNotNull(objectClassInfo);
-        assertEquals(1, objectClassInfo.size());
-        assertEquals(ObjectClass.ACCOUNT_NAME, objectClassInfo.get(0).getType());
-        assertTrue(objectClassInfo.get(0).getAttributes().contains("promoThirdPartyDisclaimer"));
-
-        ConnInstanceTO ldap = connectorService.read(105L, Locale.ENGLISH.getLanguage());
-        assertNotNull(ldap);
-
-        objectClassInfo = connectorService.buildObjectClassInfo(ldap, true);
-        assertNotNull(objectClassInfo);
-        assertEquals(2, objectClassInfo.size());
-
-        Collection<String> objectClasses = CollectionUtils.collect(objectClassInfo,
-                new Transformer<ConnIdObjectClassTO, String>() {
-
-                    @Override
-                    public String transform(final ConnIdObjectClassTO info) {
-                        return info.getType();
-                    }
-
-                });
-        assertEquals(2, objectClasses.size());
-        assertTrue(objectClasses.contains(ObjectClass.ACCOUNT_NAME));
-        assertTrue(objectClasses.contains(ObjectClass.GROUP_NAME));
-    }
-
-    @Test
-    public void issueSYNCOPE112() {
-        // ----------------------------------------
-        // Create a new connector
-        // ----------------------------------------
-        ConnInstanceTO connectorTO = new ConnInstanceTO();
-
-        connectorTO.setLocation(connectorService.read(100L, Locale.ENGLISH.getLanguage()).getLocation());
-
-        // set connector version
-        connectorTO.setVersion(connidSoapVersion);
-
-        // set connector name
-        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
-
-        // set bundle name
-        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
-
-        // set display name
-        connectorTO.setDisplayName("WSSoap");
-
-        // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<>();
-
-        ConnConfPropSchema userSchema = new ConnConfPropSchema();
-        userSchema.setName("endpoint");
-        userSchema.setType(String.class.getName());
-        userSchema.setRequired(true);
-        ConnConfProperty endpoint = new ConnConfProperty();
-        endpoint.setSchema(userSchema);
-        endpoint.getValues().add("http://localhost:9080/does_not_work");
-        endpoint.setOverridable(true);
-
-        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
-        keyColumnSchema.setName("servicename");
-        keyColumnSchema.setType(String.class.getName());
-        keyColumnSchema.setRequired(true);
-        ConnConfProperty servicename = new ConnConfProperty();
-        servicename.setSchema(keyColumnSchema);
-        servicename.getValues().add("net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning");
-        servicename.setOverridable(false);
-
-        conf.add(endpoint);
-        conf.add(servicename);
-
-        // set connector configuration
-        connectorTO.getConf().addAll(conf);
-
-        try {
-            try {
-                connectorService.check(connectorTO);
-                fail();
-            } catch (Exception e) {
-                assertNotNull(e);
-            }
-
-            Response response = connectorService.create(connectorTO);
-            if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-                throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
-            }
-
-            connectorTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
-            assertNotNull(connectorTO);
-            // ----------------------------------------
-
-            // ----------------------------------------
-            // create a resourceTO
-            // ----------------------------------------
-            String resourceName = "checkForPropOverriding";
-            ResourceTO resourceTO = new ResourceTO();
-
-            resourceTO.setKey(resourceName);
-            resourceTO.setConnector(connectorTO.getKey());
-
-            conf = new HashSet<>();
-            endpoint.getValues().clear();
-            endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning");
-            conf.add(endpoint);
-
-            resourceTO.getConfOverride().addAll(conf);
-
-            ProvisionTO provisionTO = new ProvisionTO();
-            provisionTO.setAnyType(AnyTypeKind.USER.name());
-            provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-            resourceTO.getProvisions().add(provisionTO);
-
-            MappingTO mapping = new MappingTO();
-            provisionTO.setMapping(mapping);
-
-            MappingItemTO mapItem = new MappingItemTO();
-            mapItem.setExtAttrName("uid");
-            mapItem.setIntAttrName("userId");
-            mapItem.setIntMappingType(IntMappingType.UserPlainSchema);
-            mapItem.setConnObjectKey(true);
-            mapping.setConnObjectKeyItem(mapItem);
-            // ----------------------------------------
-
-            // ----------------------------------------
-            // Check connection without saving the resource ....
-            // ----------------------------------------
-            try {
-                resourceService.check(resourceTO);
-            } catch (Exception e) {
-                fail(ExceptionUtils.getStackTrace(e));
-            }
-            // ----------------------------------------
-        } finally {
-            // Remove connector from db to make test re-runnable
-            connectorService.delete(connectorTO.getKey());
-        }
-    }
-
-    @Test
-    public void reload() {
-        connectorService.reload();
-    }
-
-    @Test
-    public void bulkAction() {
-        BulkAction bulkAction = new BulkAction();
-        bulkAction.setType(BulkAction.Type.DELETE);
-
-        ConnInstanceTO conn = connectorService.read(101L, Locale.ENGLISH.getLanguage());
-
-        conn.setKey(0L);
-        conn.setDisplayName("forBulk1");
-
-        bulkAction.getTargets().add(String.valueOf(getObject(
-                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
-
-        conn.setDisplayName("forBulk2");
-
-        bulkAction.getTargets().add(String.valueOf(getObject(
-                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
-
-        Iterator<String> iter = bulkAction.getTargets().iterator();
-
-        assertNotNull(connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage()));
-        assertNotNull(connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage()));
-
-        connectorService.bulk(bulkAction);
-
-        iter = bulkAction.getTargets().iterator();
-
-        try {
-            connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertNotNull(e);
-        }
-
-        try {
-            connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE605() {
-        ConnInstanceTO connectorInstanceTO = connectorService.read(103L, Locale.ENGLISH.getLanguage());
-        assertTrue(connectorInstanceTO.getCapabilities().isEmpty());
-
-        connectorInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH);
-        connectorService.update(connectorInstanceTO);
-
-        ConnInstanceTO updatedCapabilities = connectorService.read(
-                connectorInstanceTO.getKey(), Locale.ENGLISH.getLanguage());
-        assertNotNull(updatedCapabilities.getCapabilities());
-        assertTrue(updatedCapabilities.getCapabilities().size() == 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
deleted file mode 100644
index 6221f45..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
+++ /dev/null
@@ -1,147 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.DerSchemaTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.rest.api.beans.SchemaQuery;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class DerSchemaITCase extends AbstractITCase {
-
-    @Test
-    public void list() {
-        List<DerSchemaTO> derSchemas = schemaService.list(new SchemaQuery.Builder().type(SchemaType.DERIVED).build());
-        assertFalse(derSchemas.isEmpty());
-        for (DerSchemaTO derivedSchemaTO : derSchemas) {
-            assertNotNull(derivedSchemaTO);
-        }
-    }
-
-    @Test
-    public void read() {
-        DerSchemaTO derivedSchemaTO = schemaService.read(SchemaType.DERIVED, "cn");
-        assertNotNull(derivedSchemaTO);
-    }
-
-    @Test
-    public void create() {
-        DerSchemaTO schema = new DerSchemaTO();
-        schema.setKey("derived");
-        schema.setExpression("derived_sx + '_' + derived_dx");
-
-        DerSchemaTO actual = createSchema(SchemaType.DERIVED, schema);
-        assertNotNull(actual);
-
-        actual = schemaService.read(SchemaType.DERIVED, actual.getKey());
-        assertNotNull(actual);
-        assertEquals(actual.getExpression(), "derived_sx + '_' + derived_dx");
-    }
-
-    @Test
-    public void delete() {
-        DerSchemaTO schema = schemaService.read(SchemaType.DERIVED, "rderiveddata");
-        assertNotNull(schema);
-
-        schemaService.delete(SchemaType.DERIVED, schema.getKey());
-
-        try {
-            schemaService.read(SchemaType.DERIVED, "rderiveddata");
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        } finally {
-            // Recreate schema to make test re-runnable
-            schema = createSchema(SchemaType.DERIVED, schema);
-            assertNotNull(schema);
-        }
-    }
-
-    @Test
-    public void update() {
-        DerSchemaTO schema = schemaService.read(SchemaType.DERIVED, "mderiveddata");
-        assertNotNull(schema);
-        assertEquals("mderived_sx + '-' + mderived_dx", schema.getExpression());
-        try {
-            schema.setExpression("mderived_sx + '.' + mderived_dx");
-
-            schemaService.update(SchemaType.DERIVED, schema);
-
-            schema = schemaService.read(SchemaType.DERIVED, "mderiveddata");
-            assertNotNull(schema);
-            assertEquals("mderived_sx + '.' + mderived_dx", schema.getExpression());
-        } finally {
-            // Set updated back to make test re-runnable
-            schema.setExpression("mderived_sx + '-' + mderived_dx");
-            schemaService.update(SchemaType.DERIVED, schema);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE323() {
-        DerSchemaTO actual = schemaService.read(SchemaType.DERIVED, "rderiveddata");
-        assertNotNull(actual);
-
-        try {
-            createSchema(SchemaType.DERIVED, actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.EntityExists, e.getType());
-        }
-
-        actual.setKey(null);
-        try {
-            createSchema(SchemaType.DERIVED, actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        DerSchemaTO schema = new DerSchemaTO();
-        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-        schema.setExpression("derived_sx + '_' + derived_dx");
-
-        try {
-            createSchema(SchemaType.DERIVED, schema);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidDerSchema, e.getType());
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
deleted file mode 100644
index 728379a..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DomainITCase.java
+++ /dev/null
@@ -1,120 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.security.AccessControlException;
-import java.util.List;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.DomainTO;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class DomainITCase extends AbstractITCase {
-
-    @Test
-    public void list() {
-        List<DomainTO> domains = domainService.list();
-        assertNotNull(domains);
-        assertFalse(domains.isEmpty());
-        for (DomainTO domain : domains) {
-            assertNotNull(domain);
-        }
-    }
-
-    @Test
-    public void create() {
-        DomainTO domain = new DomainTO();
-        domain.setKey("last");
-        domain.setAdminCipherAlgorithm(CipherAlgorithm.SSHA512);
-        domain.setAdminPwd("password");
-
-        try {
-            domainService.create(domain);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    private void restoreTwo() {
-        DomainTO two = new DomainTO();
-        two.setKey("Two");
-        two.setAdminCipherAlgorithm(CipherAlgorithm.SHA);
-        two.setAdminPwd("password2");
-        domainService.create(two);
-    }
-
-    @Test
-    public void update() {
-        DomainTO two = domainService.read("Two");
-        assertNotNull(two);
-
-        try {
-            // 1. change admin pwd for domain Two
-            two.setAdminCipherAlgorithm(CipherAlgorithm.AES);
-            two.setAdminPwd("password3");
-            domainService.update(two);
-
-            // 2. attempt to access with old pwd -> fail
-            try {
-                new SyncopeClientFactoryBean().
-                        setAddress(ADDRESS).setDomain("Two").setContentType(clientFactory.getContentType()).
-                        create(ADMIN_UNAME, "password2").self();
-            } catch (AccessControlException e) {
-                assertNotNull(e);
-            }
-
-            // 3. access with new pwd -> succeed
-            new SyncopeClientFactoryBean().
-                    setAddress(ADDRESS).setDomain("Two").setContentType(clientFactory.getContentType()).
-                    create(ADMIN_UNAME, "password3").self();
-        } finally {
-            restoreTwo();
-        }
-    }
-
-    @Test
-    public void delete() {
-        DomainTO two = domainService.read("Two");
-        assertNotNull(two);
-
-        try {
-            domainService.delete(two.getKey());
-
-            try {
-                domainService.read(two.getKey());
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.NotFound, e.getType());
-            }
-        } finally {
-            restoreTwo();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
deleted file mode 100644
index 2679196..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
+++ /dev/null
@@ -1,153 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.SyncopeClientCompositeException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class ExceptionMapperITCase extends AbstractITCase {
-
-    private static final Properties ERROR_MESSAGES = new Properties();
-
-    @BeforeClass
-    public static void setUpErrorMessages() throws IOException {
-        InputStream propStream = null;
-        try {
-            propStream = ExceptionMapperITCase.class.getResourceAsStream("/errorMessages.properties");
-            ERROR_MESSAGES.load(propStream);
-        } catch (Exception e) {
-            LOG.error("Could not load /errorMessages.properties", e);
-        } finally {
-            IOUtils.closeQuietly(propStream);
-        }
-    }
-
-    @Test
-    public void uniqueSchemaConstraint() {
-        // 1. create an user schema with unique constraint
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        String schemaUID = getUUIDString();
-        schemaTO.setKey("unique" + schemaUID);
-        schemaTO.setType(AttrSchemaType.String);
-        schemaTO.setUniqueConstraint(true);
-        createSchema(SchemaType.PLAIN, schemaTO);
-
-        AnyTypeClassTO typeClass = new AnyTypeClassTO();
-        typeClass.setKey("camelAttribute" + getUUIDString());
-        typeClass.getPlainSchemas().add(schemaTO.getKey());
-        anyTypeClassService.create(typeClass);
-
-        // 2. create an user with mandatory attributes and unique
-        UserTO userTO1 = new UserTO();
-        userTO1.setRealm(SyncopeConstants.ROOT_REALM);
-        userTO1.getAuxClasses().add(typeClass.getKey());
-        String userId1 = getUUIDString() + "issue654_1@syncope.apache.org";
-        userTO1.setUsername(userId1);
-        userTO1.setPassword("password123");
-
-        userTO1.getPlainAttrs().add(attrTO("userId", userId1));
-        userTO1.getPlainAttrs().add(attrTO("fullname", userId1));
-        userTO1.getPlainAttrs().add(attrTO("surname", userId1));
-        userTO1.getPlainAttrs().add(attrTO("unique" + schemaUID, "unique" + schemaUID));
-
-        createUser(userTO1);
-
-        // 3. create an other user with mandatory attributes and unique with the same value of userTO1
-        UserTO userTO2 = new UserTO();
-        userTO2.setRealm(SyncopeConstants.ROOT_REALM);
-        userTO2.getAuxClasses().add(typeClass.getKey());
-        String userId2 = getUUIDString() + "issue654_2@syncope.apache.org";
-        userTO2.setUsername(userId2);
-        userTO2.setPassword("password123");
-
-        userTO2.getPlainAttrs().add(attrTO("userId", userId2));
-        userTO2.getPlainAttrs().add(attrTO("fullname", userId2));
-        userTO2.getPlainAttrs().add(attrTO("surname", userId2));
-        userTO2.getPlainAttrs().add(attrTO("unique" + schemaUID, "unique" + schemaUID));
-
-        try {
-            createUser(userTO2);
-            fail();
-        } catch (Exception e) {
-            String message = ERROR_MESSAGES.getProperty("errMessage.UniqueConstraintViolation");
-            assertEquals("EntityExists [" + message + "]", e.getMessage());
-        }
-    }
-
-    @Test
-    public void sameGroupName() {
-        String groupUUID = getUUIDString();
-
-        // Create the first group
-        GroupTO groupTO1 = new GroupTO();
-        groupTO1.setName("child1" + groupUUID);
-        groupTO1.setRealm(SyncopeConstants.ROOT_REALM);
-        createGroup(groupTO1);
-
-        // Create the second group, with the same name of groupTO1
-        GroupTO groupTO2 = new GroupTO();
-        groupTO2.setName("child1" + groupUUID);
-        groupTO2.setRealm(SyncopeConstants.ROOT_REALM);
-        try {
-            createGroup(groupTO2);
-            fail();
-        } catch (Exception e) {
-            String message = ERROR_MESSAGES.getProperty("errMessage.UniqueConstraintViolation");
-            assertEquals(e.getMessage(), "DataIntegrityViolation [" + message + "]");
-        }
-    }
-
-    @Test
-    public void headersMultiValue() {
-        UserTO userTO = new UserTO();
-        userTO.setRealm(SyncopeConstants.ROOT_REALM);
-        String userId = getUUIDString() + "issue654@syncope.apache.org";
-        userTO.setUsername(userId);
-        userTO.setPassword("password123");
-
-        userTO.getPlainAttrs().add(attrTO("userId", "issue654"));
-        userTO.getPlainAttrs().add(attrTO("fullname", userId));
-        userTO.getPlainAttrs().add(attrTO("surname", userId));
-
-        try {
-            createUser(userTO);
-            fail();
-        } catch (SyncopeClientCompositeException e) {
-            assertEquals(2, e.getExceptions().size());
-        }
-    }
-}


[12/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
deleted file mode 100644
index 9aaf034..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
+++ /dev/null
@@ -1,454 +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.fit.core.reference;
-
-import static org.junit.Assert.assertNotNull;
-
-import java.io.InputStream;
-import java.net.URI;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.UUID;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.naming.directory.InitialDirContext;
-import javax.sql.DataSource;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
-import org.apache.syncope.common.lib.to.AbstractSchemaTO;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.service.AnyObjectService;
-import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
-import org.apache.syncope.common.rest.api.service.AnyTypeService;
-import org.apache.syncope.common.rest.api.service.CamelRouteService;
-import org.apache.syncope.common.rest.api.service.ConfigurationService;
-import org.apache.syncope.common.rest.api.service.ConnectorService;
-import org.apache.syncope.common.rest.api.service.DomainService;
-import org.apache.syncope.common.rest.api.service.LoggerService;
-import org.apache.syncope.common.rest.api.service.NotificationService;
-import org.apache.syncope.common.rest.api.service.PolicyService;
-import org.apache.syncope.common.rest.api.service.ReportService;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.syncope.common.rest.api.service.GroupService;
-import org.apache.syncope.common.rest.api.service.RealmService;
-import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
-import org.apache.syncope.common.rest.api.service.RoleService;
-import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.common.rest.api.service.UserService;
-import org.apache.syncope.common.rest.api.service.UserWorkflowService;
-import org.apache.syncope.common.rest.api.service.WorkflowService;
-import org.identityconnectors.common.security.Encryptor;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = { "classpath:testJDBCContext.xml" })
-public abstract class AbstractITCase {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractITCase.class);
-
-    protected static final String ADMIN_UNAME = "admin";
-
-    protected static final String ADMIN_PWD = "password";
-
-    protected static final String ADDRESS = "http://localhost:9080/syncope/rest";
-
-    protected static final String ENV_KEY_CONTENT_TYPE = "jaxrsContentType";
-
-    protected static final String RESOURCE_NAME_WS1 = "ws-target-resource-1";
-
-    protected static final String RESOURCE_NAME_WS2 = "ws-target-resource-2";
-
-    protected static final String RESOURCE_NAME_LDAP = "resource-ldap";
-
-    protected static final String RESOURCE_NAME_TESTDB = "resource-testdb";
-
-    protected static final String RESOURCE_NAME_TESTDB2 = "resource-testdb2";
-
-    protected static final String RESOURCE_NAME_CSV = "resource-csv";
-
-    protected static final String RESOURCE_NAME_DBSYNC = "resource-db-sync";
-
-    protected static final String RESOURCE_NAME_DBVIRATTR = "resource-db-virattr";
-
-    protected static final String RESOURCE_NAME_NOPROPAGATION = "ws-target-resource-nopropagation";
-
-    protected static final String RESOURCE_NAME_NOPROPAGATION2 = "ws-target-resource-nopropagation2";
-
-    protected static final String RESOURCE_NAME_NOPROPAGATION3 = "ws-target-resource-nopropagation3";
-
-    protected static final String RESOURCE_NAME_NOPROPAGATION4 = "ws-target-resource-nopropagation4";
-
-    protected static final String RESOURCE_NAME_RESETSYNCTOKEN = "ws-target-resource-update-resetsynctoken";
-
-    protected static final String RESOURCE_NAME_TIMEOUT = "ws-target-resource-timeout";
-
-    protected static final String RESOURCE_NAME_MAPPINGS1 = "ws-target-resource-list-mappings-1";
-
-    protected static final String RESOURCE_NAME_MAPPINGS2 = "ws-target-resource-list-mappings-2";
-
-    protected static final String RESOURCE_NAME_CREATE = "ws-target-resource-create";
-
-    protected static final String RESOURCE_NAME_CREATE_SINGLE = "ws-target-resource-create-single";
-
-    protected static final String RESOURCE_NAME_CREATE_WRONG = "ws-target-resource-create-wrong";
-
-    protected static final String RESOURCE_NAME_DELETE = "ws-target-resource-delete";
-
-    protected static final String RESOURCE_NAME_UPDATE = "ws-target-resource-update";
-
-    protected static final String RESOURCE_NAME_CREATE_NONE = "ws-target-resource-create-none";
-
-    protected static final String RESOURCE_NAME_DBSCRIPTED = "resource-db-scripted";
-
-    protected static String ANONYMOUS_UNAME;
-
-    protected static String ANONYMOUS_KEY;
-
-    protected static SyncopeClientFactoryBean clientFactory;
-
-    protected static SyncopeClient adminClient;
-
-    protected static SyncopeService syncopeService;
-
-    protected static DomainService domainService;
-
-    protected static AnyTypeClassService anyTypeClassService;
-
-    protected static AnyTypeService anyTypeService;
-
-    protected static RelationshipTypeService relationshipTypeService;
-
-    protected static RealmService realmService;
-
-    protected static AnyObjectService anyObjectService;
-
-    protected static RoleService roleService;
-
-    protected static UserService userService;
-
-    protected static UserSelfService userSelfService;
-
-    protected static UserWorkflowService userWorkflowService;
-
-    protected static GroupService groupService;
-
-    protected static ResourceService resourceService;
-
-    protected static ConfigurationService configurationService;
-
-    protected static ConnectorService connectorService;
-
-    protected static LoggerService loggerService;
-
-    protected static ReportService reportService;
-
-    protected static TaskService taskService;
-
-    protected static WorkflowService workflowService;
-
-    protected static NotificationService notificationService;
-
-    protected static SchemaService schemaService;
-
-    protected static PolicyService policyService;
-
-    protected static SecurityQuestionService securityQuestionService;
-
-    protected static CamelRouteService camelRouteService;
-
-    @Autowired
-    protected DataSource testDataSource;
-
-    @BeforeClass
-    public static void securitySetup() {
-        InputStream propStream = null;
-        try {
-            propStream = Encryptor.class.getResourceAsStream("/security.properties");
-            Properties props = new Properties();
-            props.load(propStream);
-
-            ANONYMOUS_UNAME = props.getProperty("anonymousUser");
-            ANONYMOUS_KEY = props.getProperty("anonymousKey");
-        } catch (Exception e) {
-            LOG.error("Could not read secretKey", e);
-        } finally {
-            IOUtils.closeQuietly(propStream);
-        }
-
-        assertNotNull(ANONYMOUS_UNAME);
-        assertNotNull(ANONYMOUS_KEY);
-    }
-
-    @BeforeClass
-    public static void restSetup() {
-        clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
-
-        String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
-        if (StringUtils.isNotBlank(envContentType)) {
-            clientFactory.setContentType(envContentType);
-        }
-        LOG.info("Performing IT with content type {}", clientFactory.getContentType().getMediaType());
-
-        adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
-
-        syncopeService = adminClient.getService(SyncopeService.class);
-        domainService = adminClient.getService(DomainService.class);
-        anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
-        anyTypeService = adminClient.getService(AnyTypeService.class);
-        relationshipTypeService = adminClient.getService(RelationshipTypeService.class);
-        realmService = adminClient.getService(RealmService.class);
-        anyObjectService = adminClient.getService(AnyObjectService.class);
-        roleService = adminClient.getService(RoleService.class);
-        userService = adminClient.getService(UserService.class);
-        userSelfService = adminClient.getService(UserSelfService.class);
-        userWorkflowService = adminClient.getService(UserWorkflowService.class);
-        groupService = adminClient.getService(GroupService.class);
-        resourceService = adminClient.getService(ResourceService.class);
-        configurationService = adminClient.getService(ConfigurationService.class);
-        connectorService = adminClient.getService(ConnectorService.class);
-        loggerService = adminClient.getService(LoggerService.class);
-        reportService = adminClient.getService(ReportService.class);
-        taskService = adminClient.getService(TaskService.class);
-        policyService = adminClient.getService(PolicyService.class);
-        workflowService = adminClient.getService(WorkflowService.class);
-        notificationService = adminClient.getService(NotificationService.class);
-        schemaService = adminClient.getService(SchemaService.class);
-        securityQuestionService = adminClient.getService(SecurityQuestionService.class);
-        camelRouteService = adminClient.getService(CamelRouteService.class);
-    }
-
-    protected static String getUUIDString() {
-        return UUID.randomUUID().toString().substring(0, 8);
-    }
-
-    protected static AttrTO attrTO(final String schema, final String value) {
-        return new AttrTO.Builder().schema(schema).value(value).build();
-    }
-
-    protected static AttrPatch attrAddReplacePatch(final String schema, final String value) {
-        return new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).attrTO(attrTO(schema, value)).build();
-    }
-
-    public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) {
-        WebClient webClient = WebClient.fromClient(WebClient.client(adminClient.getService(serviceClass)));
-        webClient.accept(clientFactory.getContentType().getMediaType()).to(location.toASCIIString(), false);
-
-        return webClient.get(resultClass);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected <T extends AbstractSchemaTO> T createSchema(final SchemaType type, final T schemaTO) {
-        Response response = schemaService.create(type, schemaTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
-            if (ex != null) {
-                throw (RuntimeException) ex;
-            }
-        }
-
-        return (T) getObject(response.getLocation(), SchemaService.class, schemaTO.getClass());
-    }
-
-    protected RoleTO createRole(final RoleTO roleTO) {
-        Response response = roleService.create(roleTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
-            if (ex != null) {
-                throw (RuntimeException) ex;
-            }
-        }
-        return getObject(response.getLocation(), RoleService.class, RoleTO.class);
-    }
-
-    protected UserTO readUser(final String username) {
-        return userService.read(Long.valueOf(userService.getUserKey(username).getHeaderString(RESTHeaders.USER_KEY)));
-    }
-
-    protected ProvisioningResult<UserTO> createUser(final UserTO userTO) {
-        return createUser(userTO, true);
-    }
-
-    protected ProvisioningResult<UserTO> createUser(final UserTO userTO, final boolean storePassword) {
-        Response response = userService.create(userTO, storePassword);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
-            if (ex != null) {
-                throw (RuntimeException) ex;
-            }
-        }
-        return response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        });
-    }
-
-    protected ProvisioningResult<UserTO> updateUser(final UserPatch userPatch) {
-        return userService.update(userPatch).
-                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-                });
-    }
-
-    protected ProvisioningResult<UserTO> deleteUser(final Long key) {
-        return userService.delete(key).
-                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-                });
-    }
-
-    protected ProvisioningResult<AnyObjectTO> createAnyObject(final AnyObjectTO anyObjectTO) {
-        Response response = anyObjectService.create(anyObjectTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
-            if (ex != null) {
-                throw (RuntimeException) ex;
-            }
-        }
-        return response.readEntity(new GenericType<ProvisioningResult<AnyObjectTO>>() {
-        });
-    }
-
-    protected ProvisioningResult<AnyObjectTO> updateAnyObject(final AnyObjectPatch anyObjectPatch) {
-        return anyObjectService.update(anyObjectPatch).
-                readEntity(new GenericType<ProvisioningResult<AnyObjectTO>>() {
-                });
-    }
-
-    protected ProvisioningResult<AnyObjectTO> deleteAnyObject(final Long key) {
-        return anyObjectService.delete(key).
-                readEntity(new GenericType<ProvisioningResult<AnyObjectTO>>() {
-                });
-    }
-
-    protected ProvisioningResult<GroupTO> createGroup(final GroupTO groupTO) {
-        Response response = groupService.create(groupTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
-            if (ex != null) {
-                throw (RuntimeException) ex;
-            }
-        }
-        return response.readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
-        });
-    }
-
-    protected ProvisioningResult<GroupTO> updateGroup(final GroupPatch groupPatch) {
-        return groupService.update(groupPatch).
-                readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
-                });
-    }
-
-    protected ProvisioningResult<GroupTO> deleteGroup(final Long key) {
-        return groupService.delete(key).
-                readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
-                });
-    }
-
-    @SuppressWarnings("unchecked")
-    protected <T extends AbstractPolicyTO> T createPolicy(final T policy) {
-        Response response = policyService.create(policy);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
-            if (ex != null) {
-                throw (RuntimeException) ex;
-            }
-        }
-        return (T) getObject(response.getLocation(), PolicyService.class, policy.getClass());
-    }
-
-    protected ResourceTO createResource(final ResourceTO resourceTO) {
-        Response response = resourceService.create(resourceTO);
-        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
-            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
-            if (ex != null) {
-                throw (RuntimeException) ex;
-            }
-        }
-        return getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes", "UseOfObsoleteCollectionType" })
-    protected InitialDirContext getLdapResourceDirContext(final String bindDn, final String bindPwd)
-            throws NamingException {
-        ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP);
-        final Map<String, ConnConfProperty> ldapConnConf =
-                connectorService.read(ldapRes.getConnector(), Locale.ENGLISH.getLanguage()).getConfMap();
-
-        Properties env = new Properties();
-        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
-        env.put(Context.PROVIDER_URL, "ldap://" + ldapConnConf.get("host").getValues().get(0)
-                + ":" + ldapConnConf.get("port").getValues().get(0) + "/");
-        env.put(Context.SECURITY_AUTHENTICATION, "simple");
-        env.put(Context.SECURITY_PRINCIPAL,
-                bindDn == null ? ldapConnConf.get("principal").getValues().get(0) : bindDn);
-        env.put(Context.SECURITY_CREDENTIALS,
-                bindPwd == null ? ldapConnConf.get("credentials").getValues().get(0) : bindPwd);
-
-        return new InitialDirContext(env);
-    }
-
-    protected Object getLdapRemoteObject(final String bindDn, final String bindPwd, final String objectDn) {
-        InitialDirContext ctx = null;
-        try {
-            ctx = getLdapResourceDirContext(bindDn, bindPwd);
-            return ctx.lookup(objectDn);
-        } catch (Exception e) {
-            return null;
-        } finally {
-            if (ctx != null) {
-                try {
-                    ctx.close();
-                } catch (NamingException e) {
-                    // ignore
-                }
-            }
-        }
-    }
-
-    protected Object getLdapRemoteObject(final String objectDn) {
-        return getLdapRemoteObject(null, null, objectDn);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
deleted file mode 100644
index 8a20ea9..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
+++ /dev/null
@@ -1,183 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.NotificationTaskTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.core.logic.notification.NotificationJob;
-
-public abstract class AbstractTaskITCase extends AbstractITCase {
-
-    protected static final Long SYNC_TASK_ID = 4L;
-
-    protected static final Long SCHED_TASK_ID = 5L;
-
-    protected static class ThreadExec implements Callable<TaskExecTO> {
-
-        private final TaskService taskService;
-
-        private final Long taskKey;
-
-        private final int maxWaitSeconds;
-
-        private final boolean dryRun;
-
-        public ThreadExec(
-                final TaskService taskService, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
-
-            this.taskService = taskService;
-            this.taskKey = taskKey;
-            this.maxWaitSeconds = maxWaitSeconds;
-            this.dryRun = dryRun;
-        }
-
-        @Override
-        public TaskExecTO call() throws Exception {
-            return execProvisioningTask(taskService, taskKey, maxWaitSeconds, dryRun);
-        }
-    }
-
-    /**
-     * Remove initial and synchronized users to make test re-runnable.
-     */
-    protected void removeTestUsers() {
-        for (int i = 0; i < 10; i++) {
-            String cUserName = "test" + i;
-            try {
-                UserTO cUserTO = readUser(cUserName);
-                userService.delete(cUserTO.getKey());
-            } catch (Exception e) {
-                // Ignore
-            }
-        }
-    }
-
-    protected static TaskExecTO execTask(final TaskService taskService, final Long taskKey, final String initialStatus,
-            final int maxWaitSeconds, final boolean dryRun) {
-
-        AbstractTaskTO taskTO = taskService.read(taskKey, true);
-        assertNotNull(taskTO);
-        assertNotNull(taskTO.getExecutions());
-
-        int preSyncSize = taskTO.getExecutions().size();
-        TaskExecTO execution = taskService.execute(
-                new ExecuteQuery.Builder().key(taskTO.getKey()).dryRun(dryRun).build());
-        assertEquals(initialStatus, execution.getStatus());
-
-        int i = 0;
-        int maxit = maxWaitSeconds;
-
-        // wait for completion (executions incremented)
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-            }
-
-            taskTO = taskService.read(taskTO.getKey(), true);
-
-            assertNotNull(taskTO);
-            assertNotNull(taskTO.getExecutions());
-
-            i++;
-        } while (preSyncSize == taskTO.getExecutions().size() && i < maxit);
-        if (i == maxit) {
-            fail("Timeout when executing task " + taskKey);
-        }
-        return taskTO.getExecutions().get(taskTO.getExecutions().size() - 1);
-    }
-
-    public static TaskExecTO execProvisioningTask(
-            final TaskService taskService, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
-
-        return execTask(taskService, taskKey, "JOB_FIRED", maxWaitSeconds, dryRun);
-    }
-
-    protected static TaskExecTO execNotificationTask(
-            final TaskService taskService, final Long taskKey, final int maxWaitSeconds) {
-
-        return execTask(taskService, taskKey, NotificationJob.Status.SENT.name(), maxWaitSeconds, false);
-    }
-
-    protected Map<Long, TaskExecTO> execProvisioningTasks(final TaskService taskService,
-            final Set<Long> taskKeys, final int maxWaitSeconds, final boolean dryRun) throws Exception {
-
-        ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
-        List<Future<TaskExecTO>> futures = new ArrayList<>();
-
-        for (Long key : taskKeys) {
-            futures.add(service.submit(new ThreadExec(taskService, key, maxWaitSeconds, dryRun)));
-            // avoid flooding the test server
-            try {
-                Thread.sleep(2000);
-            } catch (InterruptedException e) {
-            }
-        }
-
-        Map<Long, TaskExecTO> res = new HashMap<>();
-
-        for (Future<TaskExecTO> future : futures) {
-            TaskExecTO taskExecTO = future.get(100, TimeUnit.SECONDS);
-            res.put(taskExecTO.getTask(), taskExecTO);
-        }
-
-        service.shutdownNow();
-
-        return res;
-    }
-
-    protected NotificationTaskTO findNotificationTaskBySender(final String sender) {
-        PagedResult<NotificationTaskTO> tasks =
-                taskService.list(new TaskQuery.Builder().type(TaskType.NOTIFICATION).build());
-        assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
-
-        return IterableUtils.find(tasks.getResult(), new Predicate<NotificationTaskTO>() {
-
-            @Override
-            public boolean evaluate(final NotificationTaskTO task) {
-                return sender.equals(task.getSender());
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
deleted file mode 100644
index 6182e2a..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
+++ /dev/null
@@ -1,36 +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.fit.core.reference;
-
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-
-public class ActivitiDetector {
-
-    public static boolean isActivitiEnabledForUsers(final SyncopeService syncopeService) {
-        return syncopeService.info().getUserWorkflowAdapter().indexOf("Activiti") != -1;
-    }
-
-    public static boolean isActivitiEnabledForGroups(final SyncopeService syncopeService) {
-        return syncopeService.info().getGroupWorkflowAdapter().indexOf("Activiti") != -1;
-    }
-
-    public static boolean isActivitiEnabledForAnyObjects(final SyncopeService syncopeService) {
-        return syncopeService.info().getAnyObjectWorkflowAdapter().indexOf("Activiti") != -1;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
deleted file mode 100644
index 6cbcf39..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
+++ /dev/null
@@ -1,209 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-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.SchemaType;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class AnyObjectITCase extends AbstractITCase {
-
-    public static AnyObjectTO getSampleTO(final String location) {
-        AnyObjectTO anyObjectTO = new AnyObjectTO();
-        anyObjectTO.setRealm(SyncopeConstants.ROOT_REALM);
-        anyObjectTO.setType("PRINTER");
-        anyObjectTO.getPlainAttrs().add(attrTO("location", location + getUUIDString()));
-
-        anyObjectTO.getResources().add(RESOURCE_NAME_DBSCRIPTED);
-        return anyObjectTO;
-    }
-
-    @Test
-    public void create() {
-        AnyObjectTO anyObjectTO = getSampleTO("create");
-
-        anyObjectTO = createAnyObject(anyObjectTO).getAny();
-        assertNotNull(anyObjectTO);
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
-        assertNotNull(connObjectTO);
-        assertNotNull(connObjectTO.getPlainAttrMap().get("location"));
-        assertEquals(anyObjectTO.getPlainAttrMap().get("location"), connObjectTO.getPlainAttrMap().get("location"));
-    }
-
-    @Test
-    public void createInvalidMembership() {
-        // 1. create anyObject in realm /odd and attempt to assign group 15, from realm /even => exception
-        AnyObjectTO anyObjectTO = getSampleTO("createInvalidMembership");
-        anyObjectTO.setRealm("/odd");
-        anyObjectTO.getMemberships().add(new MembershipTO.Builder().group(15L).build());
-
-        try {
-            createAnyObject(anyObjectTO);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidMembership, e.getType());
-        }
-
-        // 2. change anyObject's realm to /even/two, now it works
-        anyObjectTO.setRealm("/even/two");
-
-        anyObjectTO = createAnyObject(anyObjectTO).getAny();
-        assertTrue(anyObjectTO.getMembershipMap().containsKey(15L));
-    }
-
-    @Test
-    public void delete() {
-        try {
-            anyObjectService.delete(0L);
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-
-        AnyObjectTO anyObjectTO = getSampleTO("deletable");
-        anyObjectTO.setRealm("/even");
-
-        anyObjectTO = createAnyObject(anyObjectTO).getAny();
-        assertNotNull(anyObjectTO);
-
-        AnyObjectTO deletedAnyObject = deleteAnyObject(anyObjectTO.getKey()).getAny();
-        assertNotNull(deletedAnyObject);
-
-        try {
-            anyObjectService.read(deletedAnyObject.getKey());
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void list() {
-        PagedResult<AnyObjectTO> anyObjectTOs = anyObjectService.list(
-                "PRINTER", new AnyListQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
-        assertNotNull(anyObjectTOs);
-        assertTrue(anyObjectTOs.getResult().size() >= 2);
-        for (AnyObjectTO anyObjectTO : anyObjectTOs.getResult()) {
-            assertNotNull(anyObjectTO);
-        }
-    }
-
-    @Test
-    public void read() {
-        AnyObjectTO anyObjectTO = anyObjectService.read(1L);
-        assertNotNull(anyObjectTO);
-        assertNotNull(anyObjectTO.getPlainAttrs());
-        assertFalse(anyObjectTO.getPlainAttrs().isEmpty());
-    }
-
-    @Test
-    public void update() {
-        AnyObjectTO anyObjectTO = getSampleTO("update");
-        anyObjectTO = createAnyObject(anyObjectTO).getAny();
-
-        assertEquals(1, anyObjectTO.getPlainAttrs().size());
-
-        AnyObjectPatch anyObjectPatch = new AnyObjectPatch();
-        anyObjectPatch.setKey(anyObjectTO.getKey());
-        String newLocation = "new" + getUUIDString();
-        anyObjectPatch.getPlainAttrs().add(attrAddReplacePatch("location", newLocation));
-
-        anyObjectTO = updateAnyObject(anyObjectPatch).getAny();
-
-        assertEquals(newLocation, anyObjectTO.getPlainAttrMap().get("location").getValues().get(0));
-    }
-
-    @Test
-    public void readAttrs() {
-        AnyObjectTO anyObjectTO = getSampleTO("readAttrs");
-        anyObjectTO = createAnyObject(anyObjectTO).getAny();
-        assertNotNull(anyObjectTO);
-
-        Set<AttrTO> attrs = anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN);
-        assertEquals(anyObjectTO.getPlainAttrs(), attrs);
-
-        AttrTO location = anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
-        assertEquals(anyObjectTO.getPlainAttrMap().get("location"), location);
-    }
-
-    @Test
-    public void updateAttr() {
-        AnyObjectTO anyObjectTO = getSampleTO("updateAttr");
-        anyObjectTO = createAnyObject(anyObjectTO).getAny();
-        assertNotNull(anyObjectTO);
-
-        AttrTO updated = attrTO("location", "newlocation");
-        anyObjectService.update(anyObjectTO.getKey(), SchemaType.PLAIN, updated);
-
-        AttrTO location = anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
-        assertEquals(updated, location);
-    }
-
-    @Test
-    public void deleteAttr() {
-        AnyObjectTO anyObjectTO = getSampleTO("deleteAttr");
-        anyObjectTO = createAnyObject(anyObjectTO).getAny();
-        assertNotNull(anyObjectTO);
-        assertNotNull(anyObjectTO.getPlainAttrMap().get("location"));
-
-        anyObjectService.delete(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
-
-        try {
-            anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE756() {
-        AnyObjectTO anyObjectTO = getSampleTO("issueSYNCOPE756");
-        anyObjectTO.getRelationships().add(new RelationshipTO.Builder().right(AnyTypeKind.USER.name(), 1).build());
-
-        try {
-            createAnyObject(anyObjectTO).getAny();
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
deleted file mode 100644
index 7bc9349..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
+++ /dev/null
@@ -1,153 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.DerSchemaTO;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class AnyTypeClassITCase extends AbstractITCase {
-
-    @Test
-    public void read() {
-        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
-        assertNotNull(minimalGroup);
-
-        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
-        assertFalse(minimalGroup.getDerSchemas().isEmpty());
-        assertFalse(minimalGroup.getVirSchemas().isEmpty());
-    }
-
-    @Test
-    public void list() {
-        List<AnyTypeClassTO> list = anyTypeClassService.list();
-        assertFalse(list.isEmpty());
-    }
-
-    @Test
-    public void crud() {
-        // 1. create sample schemas
-        PlainSchemaTO plainSchema = new PlainSchemaTO();
-        plainSchema.setKey("new_plain_schema" + getUUIDString());
-        plainSchema.setType(AttrSchemaType.String);
-        plainSchema = createSchema(SchemaType.PLAIN, plainSchema);
-
-        DerSchemaTO derSchema = new DerSchemaTO();
-        derSchema.setKey("new_der_schema" + getUUIDString());
-        derSchema.setExpression(plainSchema.getKey() + " + '_' + derived_dx");
-        derSchema = createSchema(SchemaType.DERIVED, derSchema);
-
-        // 2. actual CRUD
-        AnyTypeClassTO newClass = new AnyTypeClassTO();
-        newClass.setKey("new class" + getUUIDString());
-        newClass.getPlainSchemas().add(plainSchema.getKey());
-
-        Response response = anyTypeClassService.create(newClass);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-
-        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
-        assertNotNull(newClass);
-        assertFalse(newClass.getPlainSchemas().isEmpty());
-        assertTrue(newClass.getDerSchemas().isEmpty());
-        assertTrue(newClass.getVirSchemas().isEmpty());
-
-        newClass.getDerSchemas().add(derSchema.getKey());
-        anyTypeClassService.update(newClass);
-
-        newClass = anyTypeClassService.read(newClass.getKey());
-        assertNotNull(newClass);
-        assertFalse(newClass.getPlainSchemas().isEmpty());
-        assertFalse(newClass.getDerSchemas().isEmpty());
-        assertTrue(newClass.getVirSchemas().isEmpty());
-
-        assertEquals(newClass.getKey(), schemaService.read(SchemaType.PLAIN, plainSchema.getKey()).getAnyTypeClass());
-        assertEquals(newClass.getKey(), schemaService.read(SchemaType.DERIVED, derSchema.getKey()).getAnyTypeClass());
-
-        anyTypeClassService.delete(newClass.getKey());
-
-        try {
-            anyTypeClassService.read(newClass.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-
-        assertNull(schemaService.read(SchemaType.PLAIN, plainSchema.getKey()).getAnyTypeClass());
-        assertNull(schemaService.read(SchemaType.DERIVED, derSchema.getKey()).getAnyTypeClass());
-    }
-
-    @Test
-    public void deleteSchema() {
-        PlainSchemaTO newSchema = new PlainSchemaTO();
-        newSchema.setKey("newSchema" + getUUIDString());
-        newSchema.setType(AttrSchemaType.Date);
-        createSchema(SchemaType.PLAIN, newSchema);
-
-        AnyTypeClassTO newClass = new AnyTypeClassTO();
-        newClass.setKey("new class" + getUUIDString());
-        newClass.getPlainSchemas().add(newSchema.getKey());
-
-        Response response = anyTypeClassService.create(newClass);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-
-        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
-        assertNotNull(newClass);
-        assertTrue(newClass.getPlainSchemas().contains(newSchema.getKey()));
-
-        schemaService.delete(SchemaType.PLAIN, newSchema.getKey());
-
-        newClass = anyTypeClassService.read(newClass.getKey());
-        assertNotNull(newClass);
-        assertFalse(newClass.getPlainSchemas().contains(newSchema.getKey()));
-    }
-
-    @Test
-    public void issueSYNCOPE759() {
-        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
-        assertNotNull(minimalGroup);
-
-        AnyTypeClassTO newAnyTypeClass = new AnyTypeClassTO();
-        newAnyTypeClass.setKey(minimalGroup.getKey());
-
-        try {
-            anyTypeClassService.create(newAnyTypeClass);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.EntityExists, e.getType());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
deleted file mode 100644
index 704370e..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
+++ /dev/null
@@ -1,193 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.AnyTypeTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
-import org.apache.syncope.common.rest.api.service.AnyTypeService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class AnyTypeITCase extends AbstractITCase {
-
-    @Test
-    public void read() {
-        AnyTypeTO userType = anyTypeService.read(AnyTypeKind.USER.name());
-        assertNotNull(userType);
-        assertEquals(AnyTypeKind.USER, userType.getKind());
-        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
-        assertFalse(userType.getClasses().isEmpty());
-
-        AnyTypeTO groupType = anyTypeService.read(AnyTypeKind.GROUP.name());
-        assertNotNull(groupType);
-        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
-        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
-        assertFalse(groupType.getClasses().isEmpty());
-
-        AnyTypeTO otherType = anyTypeService.read("PRINTER");
-        assertNotNull(otherType);
-        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
-        assertEquals("PRINTER", otherType.getKey());
-    }
-
-    @Test
-    public void list() {
-        List<AnyTypeTO> list = anyTypeService.list();
-        assertFalse(list.isEmpty());
-    }
-
-    @Test
-    public void crud() {
-        AnyTypeTO newType = new AnyTypeTO();
-        newType.setKey("new type");
-        newType.setKind(AnyTypeKind.ANY_OBJECT);
-        newType.getClasses().add("generic membership");
-        newType.getClasses().add("csv");
-
-        Response response = anyTypeService.create(newType);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-
-        newType = getObject(response.getLocation(), AnyTypeService.class, AnyTypeTO.class);
-        assertNotNull(newType);
-        assertEquals(2, newType.getClasses().size());
-        assertTrue(newType.getClasses().contains("generic membership"));
-        assertTrue(newType.getClasses().contains("csv"));
-
-        newType.getClasses().remove("generic membership");
-        anyTypeService.update(newType);
-
-        newType = anyTypeService.read(newType.getKey());
-        assertNotNull(newType);
-        assertEquals(1, newType.getClasses().size());
-        assertTrue(newType.getClasses().contains("csv"));
-
-        anyTypeService.delete(newType.getKey());
-
-        try {
-            anyTypeService.read(newType.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void createInvalidKind() {
-        AnyTypeTO newType = new AnyTypeTO();
-        newType.setKey("new type");
-        newType.setKind(AnyTypeKind.USER);
-        try {
-            anyTypeService.create(newType);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
-        }
-    }
-
-    @Test
-    public void createInvalidName() {
-        AnyTypeTO newType = new AnyTypeTO();
-        newType.setKey("group");
-        newType.setKind(AnyTypeKind.ANY_OBJECT);
-        try {
-            anyTypeService.create(newType);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
-        }
-    }
-
-    @Test
-    public void deleteInvalid() {
-        try {
-            anyTypeService.delete(AnyTypeKind.USER.name());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
-        }
-    }
-
-    @Test
-    public void deleteTypeClass() {
-        AnyTypeClassTO newClass = new AnyTypeClassTO();
-        newClass.setKey("new class" + getUUIDString());
-        newClass.getDerSchemas().add("cn");
-
-        Response response = anyTypeClassService.create(newClass);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-
-        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
-        assertNotNull(newClass);
-
-        AnyTypeTO other = anyTypeService.read("PRINTER");
-        assertNotNull(other);
-
-        other.getClasses().add(newClass.getKey());
-        anyTypeService.update(other);
-
-        other = anyTypeService.read(other.getKey());
-        assertNotNull(other);
-        assertTrue(other.getClasses().contains(newClass.getKey()));
-
-        anyTypeClassService.delete(newClass.getKey());
-
-        other = anyTypeService.read(other.getKey());
-        assertNotNull(other);
-        assertFalse(other.getClasses().contains(newClass.getKey()));
-    }
-
-    @Test
-    public void issueSYNCOPE754() {
-        AnyTypeClassTO other = anyTypeClassService.read("other");
-        assertNotNull(other);
-
-        AnyTypeTO group = anyTypeService.read(AnyTypeKind.GROUP.name());
-        try {
-            assertFalse(group.getClasses().contains("other"));
-            group.getClasses().add("other");
-
-            anyTypeService.update(group);
-
-            group = anyTypeService.read(AnyTypeKind.GROUP.name());
-            assertTrue(group.getClasses().contains("other"));
-
-            other = anyTypeClassService.read("other");
-            assertEquals(2, other.getInUseByTypes().size());
-            assertTrue(other.getInUseByTypes().contains(AnyTypeKind.USER.name()));
-            assertTrue(other.getInUseByTypes().contains(AnyTypeKind.GROUP.name()));
-        } finally {
-            group.getClasses().remove("other");
-            anyTypeService.update(group);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
deleted file mode 100644
index a7f74ee..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ /dev/null
@@ -1,564 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.security.AccessControlException;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.patch.DeassociationPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.StatusPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.AnyTypeTO;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.common.lib.types.StatusPatchType;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
-import org.apache.syncope.common.rest.api.service.AnyObjectService;
-import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.apache.syncope.common.rest.api.service.UserService;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.junit.Assume;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class AuthenticationITCase extends AbstractITCase {
-
-    private int getFailedLogins(final UserService userService, final long userId) {
-        UserTO readUserTO = userService.read(userId);
-        assertNotNull(readUserTO);
-        assertNotNull(readUserTO.getFailedLogins());
-        return readUserTO.getFailedLogins();
-    }
-
-    private void assertReadFails(final SyncopeClient client) {
-        try {
-            client.self();
-            fail("access should not work");
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void testReadEntitlements() {
-        // 1. as not authenticated (not allowed)
-        try {
-            clientFactory.create().self();
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        // 2. as anonymous
-        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).self();
-        assertEquals(1, self.getKey().size());
-        assertTrue(self.getKey().keySet().contains(StandardEntitlement.ANONYMOUS));
-        assertEquals(ANONYMOUS_UNAME, self.getValue().getUsername());
-
-        // 3. as admin
-        self = adminClient.self();
-        assertEquals(syncopeService.info().getEntitlements().size(), self.getKey().size());
-        assertFalse(self.getKey().keySet().contains(StandardEntitlement.ANONYMOUS));
-        assertEquals(ADMIN_UNAME, self.getValue().getUsername());
-
-        // 4. as user
-        self = clientFactory.create("bellini", ADMIN_PWD).self();
-        assertFalse(self.getKey().isEmpty());
-        assertFalse(self.getKey().keySet().contains(StandardEntitlement.ANONYMOUS));
-        assertEquals("bellini", self.getValue().getUsername());
-    }
-
-    @Test
-    public void testUserSchemaAuthorization() {
-        String schemaName = "authTestSchema" + getUUIDString();
-
-        // 1. create a schema (as admin)
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey(schemaName);
-        schemaTO.setMandatoryCondition("false");
-        schemaTO.setType(AttrSchemaType.String);
-
-        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertEquals(schemaTO, newPlainSchemaTO);
-
-        // 2. create an user with the role created above (as admin)
-        UserTO userTO = UserITCase.getUniqueSampleTO("auth@test.org");
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        // 3. read the schema created above (as admin) - success
-        schemaTO = schemaService.read(SchemaType.PLAIN, schemaName);
-        assertNotNull(schemaTO);
-
-        // 4. read the schema created above (as user) - success
-        SchemaService schemaService2 = clientFactory.create(userTO.getUsername(), "password123").
-                getService(SchemaService.class);
-        schemaTO = schemaService2.read(SchemaType.PLAIN, schemaName);
-        assertNotNull(schemaTO);
-
-        // 5. update the schema create above (as user) - failure
-        try {
-            schemaService2.update(SchemaType.PLAIN, schemaTO);
-            fail("Schemaupdate as user should not work");
-        } catch (AccessControlException e) {
-            // CXF Service will throw this exception
-            assertNotNull(e);
-        }
-
-        assertEquals(0, getFailedLogins(userService, userTO.getKey()));
-    }
-
-    @Test
-    public void testUserRead() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("testuserread@test.org");
-        userTO.getRoles().add("User manager");
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
-                getService(UserService.class);
-
-        UserTO readUserTO = userService2.read(1L);
-        assertNotNull(readUserTO);
-
-        UserService userService3 = clientFactory.create("puccini", ADMIN_PWD).getService(UserService.class);
-
-        try {
-            userService3.read(3L);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertNotNull(e);
-            assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
-        }
-    }
-
-    @Test
-    public void testUserSearch() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("testusersearch@test.org");
-        userTO.getRoles().add("User reviewer");
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        // 1. user assigned to role 1, with search entitlement on realms /odd and /even: won't find anything with 
-        // root realm
-        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
-                getService(UserService.class);
-
-        PagedResult<UserTO> matchedUsers = userService2.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("key").query()).build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
-        Set<Long> matchedUserKeys = CollectionUtils.collect(matchedUsers.getResult(),
-                new Transformer<UserTO, Long>() {
-
-            @Override
-            public Long transform(final UserTO input) {
-                return input.getKey();
-            }
-        }, new HashSet<Long>());
-        assertTrue(matchedUserKeys.contains(1L));
-        assertFalse(matchedUserKeys.contains(2L));
-        assertFalse(matchedUserKeys.contains(5L));
-
-        // 2. user assigned to role 4, with search entitlement on realm /even/two
-        UserService userService3 = clientFactory.create("puccini", ADMIN_PWD).getService(UserService.class);
-
-        matchedUsers = userService3.search(
-                new AnySearchQuery.Builder().realm("/even/two").
-                fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query()).build());
-        assertNotNull(matchedUsers);
-        assertTrue(IterableUtils.matchesAll(matchedUsers.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO matched) {
-                return "/even/two".equals(matched.getRealm());
-            }
-        }));
-    }
-
-    @Test
-    public void delegatedUserCRUD() {
-        String roleKey = null;
-        Long delegatedAdminKey = null;
-        try {
-            // 1. create role for full user administration, under realm /even/two
-            RoleTO role = new RoleTO();
-            role.setKey("Delegated user admin");
-            role.getEntitlements().add(StandardEntitlement.USER_CREATE);
-            role.getEntitlements().add(StandardEntitlement.USER_UPDATE);
-            role.getEntitlements().add(StandardEntitlement.USER_DELETE);
-            role.getEntitlements().add(StandardEntitlement.USER_LIST);
-            role.getEntitlements().add(StandardEntitlement.USER_READ);
-            role.getRealms().add("/even/two");
-
-            roleKey = roleService.create(role).getHeaderString(RESTHeaders.RESOURCE_KEY);
-            assertNotNull(roleKey);
-
-            // 2. as admin, create delegated admin user, and assign the role just created
-            UserTO delegatedAdmin = UserITCase.getUniqueSampleTO("admin@syncope.apache.org");
-            delegatedAdmin.getRoles().add(roleKey);
-            delegatedAdmin = createUser(delegatedAdmin).getAny();
-            delegatedAdminKey = delegatedAdmin.getKey();
-
-            // 3. instantiate a delegate user service client, for further operatins
-            UserService delegatedUserService =
-                    clientFactory.create(delegatedAdmin.getUsername(), "password123").getService(UserService.class);
-
-            // 4. as delegated, create user under realm / -> fail
-            UserTO user = UserITCase.getUniqueSampleTO("delegated@syncope.apache.org");
-            try {
-                delegatedUserService.create(user);
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
-            }
-
-            // 5. set realm to /even/two -> succeed
-            user.setRealm("/even/two");
-
-            Response response = delegatedUserService.create(user);
-            assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
-
-            user = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-            }).getAny();
-            assertEquals("surname", user.getPlainAttrMap().get("surname").getValues().get(0));
-
-            // 5. as delegated, update user attempting to move under realm / -> fail
-            UserPatch userPatch = new UserPatch();
-            userPatch.setKey(user.getKey());
-            userPatch.setRealm(new StringReplacePatchItem.Builder().value("/odd").build());
-            userPatch.getPlainAttrs().add(attrAddReplacePatch("surname", "surname2"));
-
-            try {
-                delegatedUserService.update(userPatch);
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
-            }
-
-            // 6. revert realm change -> succeed
-            userPatch.setRealm(null);
-
-            response = delegatedUserService.update(userPatch);
-            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
-
-            user = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-            }).getAny();
-            assertEquals("surname2", user.getPlainAttrMap().get("surname").getValues().get(0));
-
-            // 7. as delegated, delete user
-            delegatedUserService.delete(user.getKey());
-
-            try {
-                userService.read(user.getKey());
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.NotFound, e.getType());
-            }
-        } finally {
-            if (roleKey != null) {
-                roleService.delete(roleKey);
-            }
-            if (delegatedAdminKey != null) {
-                userService.delete(delegatedAdminKey);
-            }
-        }
-    }
-
-    @Test
-    public void checkFailedLogins() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("checkFailedLogin@syncope.apache.org");
-        userTO.getRoles().add("User manager");
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        long userId = userTO.getKey();
-
-        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
-                getService(UserService.class);
-        assertEquals(0, getFailedLogins(userService2, userId));
-
-        // authentications failed ...
-        SyncopeClient badPwdClient = clientFactory.create(userTO.getUsername(), "wrongpwd1");
-        assertReadFails(badPwdClient);
-        assertReadFails(badPwdClient);
-
-        assertEquals(2, getFailedLogins(userService, userId));
-
-        UserService userService4 = clientFactory.create(userTO.getUsername(), "password123").
-                getService(UserService.class);
-        assertEquals(0, getFailedLogins(userService4, userId));
-    }
-
-    @Test
-    public void checkUserSuspension() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("checkSuspension@syncope.apache.org");
-        userTO.setRealm("/odd");
-        userTO.getRoles().add("User manager");
-
-        userTO = createUser(userTO).getAny();
-        long userKey = userTO.getKey();
-        assertNotNull(userTO);
-
-        assertEquals(0, getFailedLogins(userService, userKey));
-
-        // authentications failed ...
-        SyncopeClient badPwdClient = clientFactory.create(userTO.getUsername(), "wrongpwd1");
-        assertReadFails(badPwdClient);
-        assertReadFails(badPwdClient);
-        assertReadFails(badPwdClient);
-
-        assertEquals(3, getFailedLogins(userService, userKey));
-
-        // last authentication before suspension
-        assertReadFails(badPwdClient);
-
-        userTO = userService.read(userTO.getKey());
-        assertNotNull(userTO);
-        assertNotNull(userTO.getFailedLogins());
-        assertEquals(3, userTO.getFailedLogins(), 0);
-        assertEquals("suspended", userTO.getStatus());
-
-        // Access with correct credentials should fail as user is suspended
-        SyncopeClient goodPwdClient = clientFactory.create(userTO.getUsername(), "password123");
-        assertReadFails(goodPwdClient);
-
-        StatusPatch reactivate = new StatusPatch();
-        reactivate.setKey(userTO.getKey());
-        reactivate.setType(StatusPatchType.REACTIVATE);
-        userTO = userService.status(reactivate).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-        assertEquals("active", userTO.getStatus());
-
-        assertEquals(0, goodPwdClient.self().getValue().getFailedLogins(), 0);
-    }
-
-    @Test
-    public void anyTypeEntitlement() {
-        final String anyTypeKey = "FOLDER " + getUUIDString();
-
-        // 1. no entitlement exists (yet) for the any type to be created
-        assertFalse(IterableUtils.matchesAny(syncopeService.info().getEntitlements(), new Predicate<String>() {
-
-            @Override
-            public boolean evaluate(final String entitlement) {
-                return entitlement.contains(anyTypeKey);
-            }
-        }));
-
-        // 2. create plain schema, any type class and any type
-        PlainSchemaTO path = new PlainSchemaTO();
-        path.setKey("path" + getUUIDString());
-        path.setType(AttrSchemaType.String);
-        path = createSchema(SchemaType.PLAIN, path);
-
-        AnyTypeClassTO anyTypeClass = new AnyTypeClassTO();
-        anyTypeClass.setKey("folder" + getUUIDString());
-        anyTypeClass.getPlainSchemas().add(path.getKey());
-        anyTypeClassService.create(anyTypeClass);
-
-        AnyTypeTO anyTypeTO = new AnyTypeTO();
-        anyTypeTO.setKey(anyTypeKey);
-        anyTypeTO.setKind(AnyTypeKind.ANY_OBJECT);
-        anyTypeTO.getClasses().add(anyTypeClass.getKey());
-        anyTypeService.create(anyTypeTO);
-
-        // 2. now entitlement exists for the any type just created
-        assertTrue(IterableUtils.matchesAny(syncopeService.info().getEntitlements(), new Predicate<String>() {
-
-            @Override
-            public boolean evaluate(final String entitlement) {
-                return entitlement.contains(anyTypeKey);
-            }
-        }));
-
-        // 3. attempt to create an instance of the type above: fail because no entitlement was assigned
-        AnyObjectTO folder = new AnyObjectTO();
-        folder.setRealm(SyncopeConstants.ROOT_REALM);
-        folder.setType(anyTypeKey);
-        folder.getPlainAttrs().add(attrTO(path.getKey(), "/home"));
-
-        SyncopeClient belliniClient = clientFactory.create("bellini", ADMIN_PWD);
-        try {
-            belliniClient.getService(AnyObjectService.class).create(folder);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
-        }
-
-        // 4. give create entitlement for the any type just created
-        RoleTO role = new RoleTO();
-        role.setKey("role" + getUUIDString());
-        role.getRealms().add(SyncopeConstants.ROOT_REALM);
-        role.getEntitlements().add(anyTypeKey + "_READ");
-        role.getEntitlements().add(anyTypeKey + "_CREATE");
-        role = createRole(role);
-
-        UserTO bellini = readUser("bellini");
-        UserPatch patch = new UserPatch();
-        patch.setKey(bellini.getKey());
-        patch.getRoles().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(role.getKey()).build());
-        bellini = updateUser(patch).getAny();
-        assertTrue(bellini.getRoles().contains(role.getKey()));
-
-        // 5. now the instance of the type above can be created successfully
-        belliniClient.getService(AnyObjectService.class).create(folder);
-    }
-
-    @Test
-    public void issueSYNCOPE434() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        // 1. create user with group 9 (users with group 9 are defined in workflow as subject to approval)
-        UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
-        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals("createApproval", userTO.getStatus());
-
-        // 2. try to authenticate: fail
-        try {
-            clientFactory.create(userTO.getUsername(), "password123").self();
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        // 3. approve user
-        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
-        form = userWorkflowService.claimForm(form.getTaskId());
-        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
-        props.get("approve").setValue(Boolean.TRUE.toString());
-        form.getProperties().clear();
-        form.getProperties().addAll(props.values());
-        userTO = userWorkflowService.submitForm(form);
-        assertNotNull(userTO);
-        assertEquals("active", userTO.getStatus());
-
-        // 4. try to authenticate again: success
-        Pair<Map<String, Set<String>>, UserTO> self =
-                clientFactory.create(userTO.getUsername(), "password123").self();
-        assertNotNull(self);
-        assertNotNull(self.getKey());
-        assertNotNull(self.getValue());
-    }
-
-    @Test
-    public void issueSYNCOPE164() throws Exception {
-        // 1. create user with db resource
-        UserTO user = UserITCase.getUniqueSampleTO("syncope164@syncope.apache.org");
-        user.setRealm("/even/two");
-        user.setPassword("password123");
-        user.getResources().add(RESOURCE_NAME_TESTDB);
-        user = createUser(user).getAny();
-        assertNotNull(user);
-
-        // 2. unlink the resource from the created user
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(user.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-        deassociationPatch.getResources().add(RESOURCE_NAME_TESTDB);
-        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        // 3. change password on Syncope
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(user.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("password234").build());
-        user = updateUser(userPatch).getAny();
-        assertNotNull(user);
-
-        // 4. check that the db resource has still the initial password value
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        String value = jdbcTemplate.queryForObject(
-                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
-        assertEquals(Encryptor.getInstance().encode("password123", CipherAlgorithm.SHA1), value.toUpperCase());
-
-        // 5. successfully authenticate with old (on db resource) and new (on internal storage) password values
-        Pair<Map<String, Set<String>>, UserTO> self =
-                clientFactory.create(user.getUsername(), "password123").self();
-        assertNotNull(self);
-        self = clientFactory.create(user.getUsername(), "password234").self();
-        assertNotNull(self);
-    }
-
-    @Test
-    public void issueSYNCOPE706() {
-        String username = getUUIDString();
-        try {
-            userService.getUserKey(username);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-
-        try {
-            clientFactory.create(username, "anypassword").self();
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e.getMessage());
-        }
-    }
-}


[05/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
deleted file mode 100644
index 7145b3c..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
+++ /dev/null
@@ -1,383 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.security.AccessControlException;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.core.GenericType;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.patch.BooleanReplacePatchItem;
-import org.apache.syncope.common.lib.patch.MembershipPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.common.rest.api.service.UserService;
-import org.junit.Assume;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class UserSelfITCase extends AbstractITCase {
-
-    @Test
-    public void selfRegistrationAllowed() {
-        assertTrue(syncopeService.info().isSelfRegAllowed());
-    }
-
-    @Test
-    public void create() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        // 1. self-registration as admin: failure
-        try {
-            userSelfService.create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true);
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        // 2. self-registration as anonymous: works
-        SyncopeClient anonClient = clientFactory.create();
-        UserTO self = anonClient.getService(UserSelfService.class).
-                create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true).
-                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-                }).getAny();
-        assertNotNull(self);
-        assertEquals("createApproval", self.getStatus());
-    }
-
-    @Test
-    public void createAndApprove() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        // self-create user with membership: goes 'createApproval' with resources and membership but no propagation
-        UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
-        userTO.getMemberships().add(new MembershipTO.Builder().group(3L).build());
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        SyncopeClient anonClient = clientFactory.create();
-        userTO = anonClient.getService(UserSelfService.class).
-                create(userTO, true).
-                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-                }).getAny();
-        assertNotNull(userTO);
-        assertEquals("createApproval", userTO.getStatus());
-        assertFalse(userTO.getMemberships().isEmpty());
-        assertFalse(userTO.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-
-        // now approve and verify that propagation has happened
-        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
-        form = userWorkflowService.claimForm(form.getTaskId());
-        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
-        props.get("approve").setValue(Boolean.TRUE.toString());
-        form.getProperties().clear();
-        form.getProperties().addAll(props.values());
-        userTO = userWorkflowService.submitForm(form);
-        assertNotNull(userTO);
-        assertEquals("active", userTO.getStatus());
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey()));
-    }
-
-    @Test
-    public void read() {
-        UserService userService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserService.class);
-
-        try {
-            userService2.read(1L);
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create("rossini", ADMIN_PWD).self();
-        assertEquals("rossini", self.getValue().getUsername());
-    }
-
-    @Test
-    public void updateWithoutApproval() {
-        // 1. create user as admin
-        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org")).getAny();
-        assertNotNull(created);
-        assertFalse(created.getUsername().endsWith("XX"));
-
-        // 2. self-update (username) - works
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(created.getKey());
-        userPatch.setUsername(new StringReplacePatchItem.Builder().value(created.getUsername() + "XX").build());
-
-        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
-        UserTO updated = authClient.getService(UserSelfService.class).update(userPatch).
-                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-                }).getAny();
-        assertNotNull(updated);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
-                ? "active" : "created", updated.getStatus());
-        assertTrue(updated.getUsername().endsWith("XX"));
-    }
-
-    @Test
-    public void updateWithApproval() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        // 1. create user as admin
-        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org")).getAny();
-        assertNotNull(created);
-        assertFalse(created.getUsername().endsWith("XX"));
-
-        // 2. self-update (username + memberships + resource) - works but needs approval
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(created.getKey());
-        userPatch.setUsername(new StringReplacePatchItem.Builder().value(created.getUsername() + "XX").build());
-        userPatch.getMemberships().add(new MembershipPatch.Builder().
-                operation(PatchOperation.ADD_REPLACE).
-                membershipTO(new MembershipTO.Builder().group(7L).build()).
-                build());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
-        userPatch.setPassword(new PasswordPatch.Builder().
-                value("newPassword123").onSyncope(false).resource(RESOURCE_NAME_TESTDB).build());
-
-        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
-        UserTO updated = authClient.getService(UserSelfService.class).update(userPatch).
-                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-                }).getAny();
-        assertNotNull(updated);
-        assertEquals("updateApproval", updated.getStatus());
-        assertFalse(updated.getUsername().endsWith("XX"));
-        assertTrue(updated.getMemberships().isEmpty());
-
-        // no propagation happened
-        assertTrue(updated.getResources().isEmpty());
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-
-        // 3. approve self-update as admin
-        WorkflowFormTO form = userWorkflowService.getFormForUser(updated.getKey());
-        form = userWorkflowService.claimForm(form.getTaskId());
-        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
-        props.get("approve").setValue(Boolean.TRUE.toString());
-        form.getProperties().clear();
-        form.getProperties().addAll(props.values());
-        updated = userWorkflowService.submitForm(form);
-        assertNotNull(updated);
-        assertEquals("active", updated.getStatus());
-        assertTrue(updated.getUsername().endsWith("XX"));
-        assertEquals(1, updated.getMemberships().size());
-
-        // check that propagation also happened
-        assertTrue(updated.getResources().contains(RESOURCE_NAME_TESTDB));
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey()));
-    }
-
-    @Test
-    public void delete() {
-        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org")).getAny();
-        assertNotNull(created);
-
-        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
-        UserTO deleted = authClient.getService(UserSelfService.class).delete().readEntity(
-                new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(deleted);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
-                ? "deleteApproval" : null, deleted.getStatus());
-    }
-
-    @Test
-    public void issueSYNCOPE373() {
-        UserTO userTO = adminClient.self().getValue();
-        assertEquals(ADMIN_UNAME, userTO.getUsername());
-    }
-
-    @Test
-    public void passwordReset() {
-        // 0. ensure that password request DOES require security question
-        configurationService.set(attrTO("passwordReset.securityQuestion", "true"));
-
-        // 1. create an user with security question and answer
-        UserTO user = UserITCase.getUniqueSampleTO("pwdReset@syncope.apache.org");
-        user.setSecurityQuestion(1L);
-        user.setSecurityAnswer("Rossi");
-        user.getResources().add(RESOURCE_NAME_TESTDB);
-        createUser(user);
-
-        // verify propagation (including password) on external db
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        String pwdOnResource = jdbcTemplate.queryForObject("SELECT password FROM test WHERE id=?", String.class,
-                user.getUsername());
-        assertTrue(StringUtils.isNotBlank(pwdOnResource));
-
-        // 2. verify that new user is able to authenticate
-        SyncopeClient authClient = clientFactory.create(user.getUsername(), "password123");
-        UserTO read = authClient.self().getValue();
-        assertNotNull(read);
-
-        // 3. request password reset (as anonymous) providing the expected security answer
-        SyncopeClient anonClient = clientFactory.create();
-        try {
-            anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "WRONG");
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidSecurityAnswer, e.getType());
-        }
-        anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "Rossi");
-
-        // 4. get token (normally sent via e-mail, now reading as admin)
-        String token = userService.read(read.getKey()).getToken();
-        assertNotNull(token);
-
-        // 5. confirm password reset
-        try {
-            anonClient.getService(UserSelfService.class).confirmPasswordReset("WRONG TOKEN", "newPassword");
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-            assertTrue(e.getMessage().contains("WRONG TOKEN"));
-        }
-        anonClient.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword123");
-
-        // 6. verify that password was reset and token removed
-        authClient = clientFactory.create(user.getUsername(), "newPassword123");
-        read = authClient.self().getValue();
-        assertNotNull(read);
-        assertNull(read.getToken());
-
-        // 7. verify that password was changed on external resource
-        String newPwdOnResource = jdbcTemplate.queryForObject("SELECT password FROM test WHERE id=?", String.class,
-                user.getUsername());
-        assertTrue(StringUtils.isNotBlank(newPwdOnResource));
-        assertNotEquals(pwdOnResource, newPwdOnResource);
-    }
-
-    @Test
-    public void passwordResetWithoutSecurityQuestion() {
-        // 0. disable security question for password reset
-        configurationService.set(attrTO("passwordReset.securityQuestion", "false"));
-
-        // 1. create an user with security question and answer
-        UserTO user = UserITCase.getUniqueSampleTO("pwdResetNoSecurityQuestion@syncope.apache.org");
-        createUser(user);
-
-        // 2. verify that new user is able to authenticate
-        SyncopeClient authClient = clientFactory.create(user.getUsername(), "password123");
-        UserTO read = authClient.self().getValue();
-        assertNotNull(read);
-
-        // 3. request password reset (as anonymous) with no security answer
-        SyncopeClient anonClient = clientFactory.create();
-        anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), null);
-
-        // 4. get token (normally sent via e-mail, now reading as admin)
-        String token = userService.read(read.getKey()).getToken();
-        assertNotNull(token);
-
-        // 5. confirm password reset
-        try {
-            anonClient.getService(UserSelfService.class).confirmPasswordReset("WRONG TOKEN", "newPassword");
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-            assertTrue(e.getMessage().contains("WRONG TOKEN"));
-        }
-        anonClient.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword123");
-
-        // 6. verify that password was reset and token removed
-        authClient = clientFactory.create(user.getUsername(), "newPassword123");
-        read = authClient.self().getValue();
-        assertNotNull(read);
-        assertNull(read.getToken());
-
-        // 7. re-enable security question for password reset
-        configurationService.set(attrTO("passwordReset.securityQuestion", "true"));
-    }
-
-    @Test
-    public void mustChangePassword() {
-        // PRE: reset vivaldi's password
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(3L);
-        userPatch.setPassword(new PasswordPatch.Builder().value("password321").build());
-        userService.update(userPatch);
-
-        // 0. access as vivaldi -> succeed
-        SyncopeClient vivaldiClient = clientFactory.create("vivaldi", "password321");
-        Pair<Map<String, Set<String>>, UserTO> self = vivaldiClient.self();
-        assertFalse(self.getRight().isMustChangePassword());
-
-        // 1. update user vivaldi (3) requirig password update
-        userPatch = new UserPatch();
-        userPatch.setKey(3L);
-        userPatch.setMustChangePassword(new BooleanReplacePatchItem.Builder().value(true).build());
-        UserTO vivaldi = updateUser(userPatch).getAny();
-        assertTrue(vivaldi.isMustChangePassword());
-
-        // 2. attempt to access -> fail
-        try {
-            vivaldiClient.getService(ResourceService.class).list();
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-            assertEquals("Please change your password first", e.getMessage());
-        }
-
-        // 3. change password
-        vivaldiClient.getService(UserSelfService.class).changePassword("password123");
-
-        // 4. verify it worked
-        self = clientFactory.create("vivaldi", "password123").self();
-        assertFalse(self.getRight().isMustChangePassword());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
deleted file mode 100644
index 02a2c7a..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
+++ /dev/null
@@ -1,306 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.rest.api.service.UserWorkflowService;
-import org.junit.Assume;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class UserWorkflowITCase extends AbstractITCase {
-
-    @Test
-    public void createWithReject() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        // User with group 9 are defined in workflow as subject to approval
-        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
-
-        // 1. create user with group 9
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals(1, userTO.getMemberships().size());
-        assertEquals(9, userTO.getMemberships().get(0).getRightKey());
-        assertEquals("createApproval", userTO.getStatus());
-
-        // 2. request if there is any pending task for user just created
-        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
-        assertNotNull(form);
-        assertNotNull(form.getUserKey());
-        assertEquals(userTO.getKey(), form.getUserKey(), 0);
-        assertNotNull(form.getTaskId());
-        assertNull(form.getOwner());
-
-        // 3. claim task as rossini, with role "User manager" granting entitlement to claim forms but not in group 7,
-        // designated for approval in workflow definition: fail
-        UserTO rossini = userService.read(1L);
-        if (!rossini.getRoles().contains("User manager")) {
-            UserPatch userPatch = new UserPatch();
-            userPatch.setKey(1L);
-            userPatch.getRoles().add(new StringPatchItem.Builder().
-                    operation(PatchOperation.ADD_REPLACE).value("User manager").build());
-            rossini = updateUser(userPatch).getAny();
-        }
-        assertTrue(rossini.getRoles().contains("User manager"));
-
-        UserWorkflowService userService2 = clientFactory.create("rossini", ADMIN_PWD).
-                getService(UserWorkflowService.class);
-        try {
-            userService2.claimForm(form.getTaskId());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.Workflow, e.getType());
-        }
-
-        // 4. claim task from bellini, with role "User manager" and in group 7
-        UserWorkflowService userService3 = clientFactory.create("bellini", ADMIN_PWD).
-                getService(UserWorkflowService.class);
-        form = userService3.claimForm(form.getTaskId());
-        assertNotNull(form);
-        assertNotNull(form.getTaskId());
-        assertNotNull(form.getOwner());
-
-        // 5. reject user
-        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
-        props.get("approve").setValue(Boolean.FALSE.toString());
-        props.get("rejectReason").setValue("I don't like him.");
-        form.getProperties().clear();
-        form.getProperties().addAll(props.values());
-        userTO = userService3.submitForm(form);
-        assertNotNull(userTO);
-        assertEquals("rejected", userTO.getStatus());
-
-        // 6. check that rejected user was not propagated to external resource (SYNCOPE-364)
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        Exception exception = null;
-        try {
-            jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
-                    new String[] { userTO.getUsername() }, Integer.class);
-        } catch (EmptyResultDataAccessException e) {
-            exception = e;
-        }
-        assertNotNull(exception);
-    }
-
-    @Test
-    public void createWithApproval() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        // read forms *before* any operation
-        List<WorkflowFormTO> forms = userWorkflowService.getForms();
-        assertNotNull(forms);
-        int preForms = forms.size();
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("createWithApproval@syncope.apache.org");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        // User with group 9 are defined in workflow as subject to approval
-        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
-
-        // 1. create user with group 9 (and verify that no propagation occurred)
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertNotNull(result);
-        userTO = result.getAny();
-        assertEquals(1, userTO.getMemberships().size());
-        assertEquals(9, userTO.getMemberships().get(0).getRightKey());
-        assertEquals("createApproval", userTO.getStatus());
-        assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
-
-        assertTrue(result.getPropagationStatuses().isEmpty());
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-        Exception exception = null;
-        try {
-            jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
-                    new String[] { userTO.getUsername() }, Integer.class);
-        } catch (EmptyResultDataAccessException e) {
-            exception = e;
-        }
-        assertNotNull(exception);
-
-        // 2. request if there is any pending form for user just created
-        forms = userWorkflowService.getForms();
-        assertNotNull(forms);
-        assertEquals(preForms + 1, forms.size());
-
-        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
-        assertNotNull(form);
-        assertNotNull(form.getTaskId());
-        assertNull(form.getOwner());
-
-        // 4. claim task (from admin)
-        form = userWorkflowService.claimForm(form.getTaskId());
-        assertNotNull(form);
-        assertNotNull(form.getTaskId());
-        assertNotNull(form.getOwner());
-
-        // 5. approve user (and verify that propagation occurred)
-        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
-        props.get("approve").setValue(Boolean.TRUE.toString());
-        form.getProperties().clear();
-        form.getProperties().addAll(props.values());
-        userTO = userWorkflowService.submitForm(form);
-        assertNotNull(userTO);
-        assertEquals("active", userTO.getStatus());
-        assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
-
-        exception = null;
-        try {
-            final String username = jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class,
-                    userTO.getUsername());
-            assertEquals(userTO.getUsername(), username);
-        } catch (EmptyResultDataAccessException e) {
-            exception = e;
-        }
-        assertNull(exception);
-
-        // 6. update user
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-    }
-
-    @Test
-    public void issueSYNCOPE15() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        // read forms *before* any operation
-        List<WorkflowFormTO> forms = userWorkflowService.getForms();
-        assertNotNull(forms);
-        int preForms = forms.size();
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("issueSYNCOPE15@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getMemberships().clear();
-
-        // User with group 9 are defined in workflow as subject to approval
-        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
-
-        // 1. create user with group 9 (and verify that no propagation occurred)
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertNotEquals(0L, userTO.getKey(), 0);
-        assertNotNull(userTO.getCreationDate());
-        assertNotNull(userTO.getCreator());
-        assertNotNull(userTO.getLastChangeDate());
-        assertNotNull(userTO.getLastModifier());
-        assertEquals(userTO.getCreationDate(), userTO.getLastChangeDate());
-
-        // 2. request if there is any pending form for user just created
-        forms = userWorkflowService.getForms();
-        assertEquals(preForms + 1, forms.size());
-
-        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
-        assertNotNull(form);
-
-        // 3. first claim ny bellini ....
-        UserWorkflowService userService3 = clientFactory.create("bellini", ADMIN_PWD).
-                getService(UserWorkflowService.class);
-        form = userService3.claimForm(form.getTaskId());
-        assertNotNull(form);
-        assertNotNull(form.getTaskId());
-        assertNotNull(form.getOwner());
-
-        // 4. second claim task by admin
-        form = userWorkflowService.claimForm(form.getTaskId());
-        assertNotNull(form);
-
-        // 5. approve user
-        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
-        props.get("approve").setValue(Boolean.TRUE.toString());
-        form.getProperties().clear();
-        form.getProperties().addAll(props.values());
-
-        // 6. submit approve
-        userTO = userWorkflowService.submitForm(form);
-        assertNotNull(userTO);
-        assertEquals(preForms, userWorkflowService.getForms().size());
-        assertNull(userWorkflowService.getFormForUser(userTO.getKey()));
-
-        // 7. search approval into the history as well
-        forms = userWorkflowService.getFormsByName(userTO.getKey(), "Create approval");
-        assertFalse(forms.isEmpty());
-
-        int count = 0;
-        for (WorkflowFormTO hform : forms) {
-            if (form.getTaskId().equals(hform.getTaskId())) {
-                count++;
-
-                assertEquals("createApproval", hform.getKey());
-                assertNotNull(hform.getCreateTime());
-                assertNotNull(hform.getDueDate());
-                assertTrue(Boolean.parseBoolean(hform.getPropertyMap().get("approve").getValue()));
-                assertNull(hform.getPropertyMap().get("rejectReason").getValue());
-            }
-        }
-        assertEquals(1, count);
-
-        userService.delete(userTO.getKey());
-
-        try {
-            userService.read(userTO.getKey());
-            fail();
-        } catch (Exception ignore) {
-            assertNotNull(ignore);
-        }
-
-        try {
-            userWorkflowService.getFormsByName(userTO.getKey(), "Create approval");
-            fail();
-        } catch (Exception ignore) {
-            assertNotNull(ignore);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
deleted file mode 100644
index db297f3..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
+++ /dev/null
@@ -1,677 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Locale;
-import java.util.Map;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.StatusPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.VirSchemaTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.StatusPatchType;
-import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class VirAttrITCase extends AbstractITCase {
-
-    @Test
-    public void issueSYNCOPE16() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("issue16@apache.org");
-        userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
-        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
-        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-
-        // 1. create user
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        // 2. check for virtual attribute value
-        userTO = userService.read(userTO.getKey());
-        assertNotNull(userTO);
-        assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getVirAttrs().add(attrTO("virtualdata", "virtualupdated"));
-
-        // 3. update virtual attribute
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-
-        // 4. check for virtual attribute value
-        userTO = userService.read(userTO.getKey());
-        assertNotNull(userTO);
-        assertEquals("virtualupdated", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-    }
-
-    @Test
-    public void issueSYNCOPE260() {
-        // create new virtual schema for the resource below
-        ResourceTO ws2 = resourceService.read(RESOURCE_NAME_WS2);
-        ProvisionTO provision = ws2.getProvision(AnyTypeKind.USER.name());
-        assertNotNull(provision);
-
-        VirSchemaTO virSchema = new VirSchemaTO();
-        virSchema.setKey("syncope260" + getUUIDString());
-        virSchema.setExtAttrName("companyName");
-        virSchema.setProvision(provision.getKey());
-        virSchema = createSchema(SchemaType.VIRTUAL, virSchema);
-        assertNotNull(virSchema);
-
-        AnyTypeClassTO newClass = new AnyTypeClassTO();
-        newClass.setKey("syncope260" + getUUIDString());
-        newClass.getVirSchemas().add(virSchema.getKey());
-        Response response = anyTypeClassService.create(newClass);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
-
-        // ----------------------------------
-        // create user and check virtual attribute value propagation
-        // ----------------------------------
-        UserTO userTO = UserITCase.getUniqueSampleTO("260@a.com");
-        userTO.getAuxClasses().add(newClass.getKey());
-        userTO.getVirAttrs().add(attrTO(virSchema.getKey(), "virtualvalue"));
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertNotNull(result);
-        assertFalse(result.getPropagationStatuses().isEmpty());
-        assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().get(0).getResource());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        userTO = result.getAny();
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
-        assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
-        // ----------------------------------
-
-        // ----------------------------------
-        // update user virtual attribute and check virtual attribute value update propagation
-        // ----------------------------------
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getVirAttrs().add(attrTO(virSchema.getKey(), "virtualvalue2"));
-
-        result = updateUser(userPatch);
-        assertNotNull(result);
-        assertFalse(result.getPropagationStatuses().isEmpty());
-        assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().get(0).getResource());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        userTO = result.getAny();
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
-        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
-        // ----------------------------------
-
-        // ----------------------------------
-        // suspend/reactivate user and check virtual attribute value (unchanged)
-        // ----------------------------------
-        StatusPatch statusPatch = new StatusPatch();
-        statusPatch.setKey(userTO.getKey());
-        statusPatch.setType(StatusPatchType.SUSPEND);
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertEquals("suspended", userTO.getStatus());
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
-        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
-
-        statusPatch = new StatusPatch();
-        statusPatch.setKey(userTO.getKey());
-        statusPatch.setType(StatusPatchType.REACTIVATE);
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertEquals("active", userTO.getStatus());
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
-        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
-        // ----------------------------------
-
-        // ----------------------------------
-        // update user attribute and check virtual attribute value (unchanged)
-        // ----------------------------------
-        userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("surname", "Surname2"));
-
-        result = updateUser(userPatch);
-        assertNotNull(result);
-        assertFalse(result.getPropagationStatuses().isEmpty());
-        assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().get(0).getResource());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        userTO = result.getAny();
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
-        assertEquals("Surname2", connObjectTO.getPlainAttrMap().get("SURNAME").getValues().get(0));
-
-        // virtual attribute value did not change
-        assertFalse(connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().isEmpty());
-        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
-        // ----------------------------------
-    }
-
-    @Test
-    public void virAttrCache() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("virattrcache@apache.org");
-        userTO.getVirAttrs().clear();
-
-        AttrTO virAttrTO = new AttrTO();
-        virAttrTO.setSchema("virtualdata");
-        virAttrTO.getValues().add("virattrcache");
-        userTO.getVirAttrs().add(virAttrTO);
-
-        userTO.getMemberships().clear();
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
-
-        // 1. create user
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-
-        // 2. check for virtual attribute value
-        actual = userService.read(actual.getKey());
-        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // 3. update virtual attribute directly
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-        String value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
-        assertEquals("virattrcache", value);
-
-        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
-
-        value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
-        assertEquals("virattrcache2", value);
-
-        // 4. check for cached attribute value
-        actual = userService.read(actual.getKey());
-        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(actual.getKey());
-        userPatch.getVirAttrs().add(attrTO("virtualdata", "virtualupdated"));
-
-        // 5. update virtual attribute
-        actual = updateUser(userPatch).getAny();
-        assertNotNull(actual);
-
-        // 6. check for virtual attribute value
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertEquals("virtualupdated", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
-    }
-
-    @Test
-    public void issueSYNCOPE397() {
-        ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
-
-        // change mapping of resource-csv
-        MappingTO origMapping = SerializationUtils.clone(csv.getProvisions().get(0).getMapping());
-        try {
-            // remove this mapping
-            CollectionUtils.filterInverse(csv.getProvisions().get(0).getMapping().getItems(),
-                    new Predicate<MappingItemTO>() {
-
-                        @Override
-                        public boolean evaluate(final MappingItemTO item) {
-                            return "email".equals(item.getIntAttrName());
-                        }
-                    });
-
-            resourceService.update(csv);
-            csv = resourceService.read(RESOURCE_NAME_CSV);
-            assertNotNull(csv.getProvisions().get(0).getMapping());
-
-            // create new virtual schema for the resource below
-            ProvisionTO provision = csv.getProvision(AnyTypeKind.USER.name());
-            assertNotNull(provision);
-
-            VirSchemaTO virSchema = new VirSchemaTO();
-            virSchema.setKey("syncope397" + getUUIDString());
-            virSchema.setExtAttrName("email");
-            virSchema.setProvision(provision.getKey());
-            virSchema = createSchema(SchemaType.VIRTUAL, virSchema);
-            assertNotNull(virSchema);
-
-            AnyTypeClassTO newClass = new AnyTypeClassTO();
-            newClass.setKey("syncope397" + getUUIDString());
-            newClass.getVirSchemas().add(virSchema.getKey());
-            Response response = anyTypeClassService.create(newClass);
-            assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-            newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
-
-            // create a new user
-            UserTO userTO = UserITCase.getUniqueSampleTO("397@syncope.apache.org");
-            userTO.getAuxClasses().add("csv");
-            userTO.getAuxClasses().add(newClass.getKey());
-            userTO.getResources().clear();
-            userTO.getMemberships().clear();
-            userTO.getDerAttrs().clear();
-            userTO.getVirAttrs().clear();
-
-            userTO.getDerAttrs().add(attrTO("csvuserid", null));
-            userTO.getDerAttrs().add(attrTO("cn", null));
-            userTO.getVirAttrs().add(attrTO(virSchema.getKey(), "test@testone.org"));
-            // assign resource-csv to user
-            userTO.getResources().add(RESOURCE_NAME_CSV);
-            // save user
-            userTO = createUser(userTO).getAny();
-            // make std controls about user
-            assertNotNull(userTO);
-            assertTrue(RESOURCE_NAME_CSV.equals(userTO.getResources().iterator().next()));
-            assertEquals("test@testone.org", userTO.getVirAttrs().iterator().next().getValues().get(0));
-
-            // update user
-            UserTO toBeUpdated = userService.read(userTO.getKey());
-            UserPatch userPatch = new UserPatch();
-            userPatch.setKey(toBeUpdated.getKey());
-            userPatch.setPassword(new PasswordPatch.Builder().value("password234").build());
-            // assign new resource to user
-            userPatch.getResources().add(new StringPatchItem.Builder().
-                    operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build());
-            // modify virtual attribute
-            userPatch.getVirAttrs().add(attrTO(virSchema.getKey(), "test@testoneone.com"));
-
-            // check Syncope change password
-            userPatch.setPassword(new PasswordPatch.Builder().
-                    value("password234").
-                    onSyncope(true).
-                    resource(RESOURCE_NAME_WS2).
-                    build());
-
-            ProvisioningResult<UserTO> result = updateUser(userPatch);
-            assertNotNull(result);
-            toBeUpdated = result.getAny();
-            assertTrue(toBeUpdated.getVirAttrs().iterator().next().getValues().contains("test@testoneone.com"));
-            // check if propagates correctly with assertEquals on size of tasks list
-            assertEquals(2, result.getPropagationStatuses().size());
-        } finally {
-            // restore mapping of resource-csv
-            csv.getProvisions().get(0).setMapping(origMapping);
-            resourceService.update(csv);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE442() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope442@apache.org");
-        userTO.getVirAttrs().clear();
-
-        AttrTO virAttrTO = new AttrTO();
-        virAttrTO.setSchema("virtualdata");
-        virAttrTO.getValues().add("virattrcache");
-        userTO.getVirAttrs().add(virAttrTO);
-
-        userTO.getMemberships().clear();
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
-
-        // 1. create user
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        // 2. check for virtual attribute value
-        userTO = userService.read(userTO.getKey());
-        assertEquals("virattrcache", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // ----------------------------------------
-        // 3. change connector URL so that we are sure that any provided value will come from virtual cache
-        // ----------------------------------------
-        String jdbcURL = null;
-        ConnInstanceTO connInstanceTO = connectorService.readByResource(
-                RESOURCE_NAME_DBVIRATTR, Locale.ENGLISH.getLanguage());
-        for (ConnConfProperty prop : connInstanceTO.getConf()) {
-            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
-                jdbcURL = prop.getValues().iterator().next().toString();
-                prop.getValues().clear();
-                prop.getValues().add("jdbc:h2:tcp://localhost:9092/xxx");
-            }
-        }
-
-        connectorService.update(connInstanceTO);
-        // ----------------------------------------
-
-        // ----------------------------------------
-        // 4. update value on external resource
-        // ----------------------------------------
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-        String value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
-        assertEquals("virattrcache", value);
-
-        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", userTO.getKey());
-
-        value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
-        assertEquals("virattrcache2", value);
-        // ----------------------------------------
-
-        userTO = userService.read(userTO.getKey());
-        assertEquals("virattrcache", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // ----------------------------------------
-        // 5. restore connector URL, values can be read again from external resource
-        // ----------------------------------------
-        for (ConnConfProperty prop : connInstanceTO.getConf()) {
-            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
-                prop.getValues().clear();
-                prop.getValues().add(jdbcURL);
-            }
-        }
-
-        connectorService.update(connInstanceTO);
-        // ----------------------------------------
-
-        // cached value still in place...
-        userTO = userService.read(userTO.getKey());
-        assertEquals("virattrcache", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // force cache update by adding a resource which has virtualdata mapped for propagation
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build());
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-
-        userTO = userService.read(userTO.getKey());
-        assertEquals("virattrcache2", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-    }
-
-    @Test
-    public void issueSYNCOPE436() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope436@syncope.apache.org");
-        userTO.getMemberships().clear();
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_LDAP);
-        userTO.getVirAttrs().add(attrTO("virtualReadOnly", "readOnly"));
-        userTO = createUser(userTO).getAny();
-        // finding no values because the virtual attribute is readonly 
-        assertTrue(userTO.getVirAttrMap().get("virtualReadOnly").getValues().isEmpty());
-    }
-
-    @Test
-    public void issueSYNCOPE453() {
-        final String resourceName = "issueSYNCOPE453-Res-" + getUUIDString();
-        final String groupName = "issueSYNCOPE453-Group-" + getUUIDString();
-
-        // -------------------------------------------
-        // Create a resource ad-hoc
-        // -------------------------------------------
-        ResourceTO resourceTO = new ResourceTO();
-
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(107L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntAttrName("aLong");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setExtAttrName("ID");
-        item.setPurpose(MappingPurpose.PROPAGATION);
-        item.setConnObjectKey(true);
-        mapping.setConnObjectKeyItem(item);
-
-        item = new MappingItemTO();
-        item.setExtAttrName("USERNAME");
-        item.setIntAttrName("username");
-        item.setIntMappingType(IntMappingType.Username);
-        item.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.getItems().add(item);
-
-        item = new MappingItemTO();
-        item.setExtAttrName("EMAIL");
-        item.setIntAttrName("rvirtualdata");
-        item.setIntMappingType(IntMappingType.GroupVirtualSchema);
-        item.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.getItems().add(item);
-
-        assertNotNull(getObject(
-                resourceService.create(resourceTO).getLocation(), ResourceService.class, ResourceTO.class));
-        // -------------------------------------------
-
-        // -------------------------------------------
-        // Create a VirAttrITCase ad-hoc
-        // -------------------------------------------
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName(groupName);
-        groupTO.setRealm("/");
-        groupTO.getVirAttrs().add(attrTO("rvirtualdata", "ml@group.it"));
-        groupTO.getResources().add(RESOURCE_NAME_LDAP);
-        groupTO = createGroup(groupTO).getAny();
-        assertEquals(1, groupTO.getVirAttrs().size());
-        assertEquals("ml@group.it", groupTO.getVirAttrs().iterator().next().getValues().get(0));
-        // -------------------------------------------
-
-        // -------------------------------------------
-        // Create new user
-        // -------------------------------------------
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope453@syncope.apache.org");
-        userTO.getPlainAttrs().add(attrTO("aLong", "123"));
-        userTO.getResources().clear();
-        userTO.getResources().add(resourceName);
-        userTO.getVirAttrs().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getMemberships().clear();
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertEquals(2, result.getPropagationStatuses().size());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(1).getStatus());
-        userTO = result.getAny();
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-        final Map<String, Object> actuals = jdbcTemplate.queryForMap(
-                "SELECT id, surname, email FROM testsync WHERE id=?",
-                new Object[] { Integer.parseInt(userTO.getPlainAttrMap().get("aLong").getValues().get(0)) });
-
-        assertEquals(userTO.getPlainAttrMap().get("aLong").getValues().get(0), actuals.get("id").toString());
-        assertEquals("ml@group.it", actuals.get("email"));
-        // -------------------------------------------
-
-        // -------------------------------------------
-        // Delete resource and group ad-hoc
-        // -------------------------------------------
-        resourceService.delete(resourceName);
-        groupService.delete(groupTO.getKey());
-        // -------------------------------------------
-    }
-
-    @Test
-    public void issueSYNCOPE459() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope459@apache.org");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_LDAP);
-        userTO.getMemberships().clear();
-        userTO.getVirAttrs().clear();
-
-        userTO = createUser(userTO).getAny();
-
-        assertNotNull(userTO.getVirAttrMap().get("virtualReadOnly"));
-    }
-
-    @Test
-    public void issueSYNCOPE501() {
-        // 1. create user and propagate him on resource-db-virattr
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope501@apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getVirAttrs().clear();
-
-        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
-
-        // virtualdata is mapped with username
-        userTO.getVirAttrs().add(attrTO("virtualdata", "syncope501@apache.org"));
-
-        userTO = createUser(userTO).getAny();
-
-        assertNotNull(userTO.getVirAttrMap().get("virtualdata"));
-        assertEquals("syncope501@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // 2. update virtual attribute
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        // change virtual attribute value
-        userPatch.getVirAttrs().add(attrTO("virtualdata", "syncope501_updated@apache.org"));
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-
-        // 3. check that user virtual attribute has really been updated 
-        assertFalse(userTO.getVirAttrMap().get("virtualdata").getValues().isEmpty());
-        assertEquals("syncope501_updated@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-    }
-
-    @Test
-    public void issueSYNCOPE691() {
-        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
-        try {
-            ProvisionTO provision = ldap.getProvision(AnyTypeKind.USER.name());
-            assertNotNull(provision);
-            CollectionUtils.filterInverse(provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
-
-                @Override
-                public boolean evaluate(final MappingItemTO item) {
-                    return "mail".equals(item.getExtAttrName());
-                }
-            });
-            provision.getVirSchemas().clear();
-
-            ldap.setKey(RESOURCE_NAME_LDAP + "691" + getUUIDString());
-            resourceService.create(ldap);
-
-            ldap = resourceService.read(ldap.getKey());
-            provision = ldap.getProvision(AnyTypeKind.USER.name());
-            assertNotNull(provision);
-
-            // create new virtual schema for the resource below
-            VirSchemaTO virSchema = new VirSchemaTO();
-            virSchema.setKey("syncope691" + getUUIDString());
-            virSchema.setExtAttrName("mail");
-            virSchema.setProvision(provision.getKey());
-            virSchema = createSchema(SchemaType.VIRTUAL, virSchema);
-            assertNotNull(virSchema);
-
-            AnyTypeClassTO newClass = new AnyTypeClassTO();
-            newClass.setKey("syncope691" + getUUIDString());
-            newClass.getVirSchemas().add(virSchema.getKey());
-            Response response = anyTypeClassService.create(newClass);
-            assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-            newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
-
-            // create a new user
-            UserTO userTO = UserITCase.getUniqueSampleTO("syncope691@syncope.apache.org");
-            userTO.getAuxClasses().add(newClass.getKey());
-            userTO.getResources().clear();
-            userTO.getMemberships().clear();
-            userTO.getDerAttrs().clear();
-            userTO.getVirAttrs().clear();
-
-            AttrTO emailTO = new AttrTO();
-            emailTO.setSchema(virSchema.getKey());
-            emailTO.getValues().add("test@issue691.dom1.org");
-            emailTO.getValues().add("test@issue691.dom2.org");
-
-            userTO.getVirAttrs().add(emailTO);
-            // assign resource-ldap691 to user
-            userTO.getResources().add(ldap.getKey());
-            // save user
-            userTO = createUser(userTO).getAny();
-            // make std controls about user
-            assertNotNull(userTO);
-            assertTrue(ldap.getKey().equals(userTO.getResources().iterator().next()));
-
-            assertEquals(2, userTO.getVirAttrs().iterator().next().getValues().size(), 0);
-            assertTrue(userTO.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom1.org"));
-            assertTrue(userTO.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom2.org"));
-
-            // update user
-            UserPatch userPatch = new UserPatch();
-            userPatch.setKey(userTO.getKey());
-            // modify virtual attribute
-            userPatch.getVirAttrs().add(
-                    new AttrTO.Builder().schema(virSchema.getKey()).
-                    value("test@issue691.dom3.org").
-                    value("test@issue691.dom4.org").
-                    build());
-
-            UserTO updated = updateUser(userPatch).getAny();
-            assertNotNull(updated);
-            assertEquals(2, updated.getVirAttrs().iterator().next().getValues().size(), 0);
-            assertTrue(updated.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom3.org"));
-            assertTrue(updated.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom4.org"));
-        } finally {
-            try {
-                resourceService.delete(ldap.getKey());
-            } catch (Exception ignore) {
-                // ignore
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
deleted file mode 100644
index a6a2444..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
+++ /dev/null
@@ -1,151 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.security.AccessControlException;
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.VirSchemaTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.rest.api.beans.SchemaQuery;
-import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class VirSchemaITCase extends AbstractITCase {
-
-    @Test
-    public void list() {
-        List<VirSchemaTO> vSchemas = schemaService.list(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build());
-        assertFalse(vSchemas.isEmpty());
-        for (VirSchemaTO vSchemaTO : vSchemas) {
-            assertNotNull(vSchemaTO);
-        }
-    }
-
-    @Test
-    public void crud() {
-        ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
-        assertNotNull(csv);
-        assertEquals(1, csv.getProvisions().size());
-        assertTrue(csv.getProvisions().get(0).getVirSchemas().isEmpty());
-
-        VirSchemaTO schema = new VirSchemaTO();
-        schema.setKey("virtualTest" + getUUIDString());
-        schema.setExtAttrName("name");
-        schema.setProvision(csv.getProvisions().get(0).getKey());
-
-        schema = createSchema(SchemaType.VIRTUAL, schema);
-        assertNotNull(schema);
-        assertEquals(csv.getProvisions().get(0).getKey(), schema.getProvision(), 0);
-
-        csv = resourceService.read(RESOURCE_NAME_CSV);
-        assertNotNull(csv);
-        assertEquals(1, csv.getProvisions().size());
-        assertFalse(csv.getProvisions().get(0).getVirSchemas().isEmpty());
-
-        schema = schemaService.read(SchemaType.VIRTUAL, schema.getKey());
-        assertNotNull(schema);
-
-        schemaService.delete(SchemaType.VIRTUAL, schema.getKey());
-
-        try {
-            schemaService.read(SchemaType.VIRTUAL, schema.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-
-        csv = resourceService.read(RESOURCE_NAME_CSV);
-        assertNotNull(csv);
-        assertEquals(1, csv.getProvisions().size());
-        assertTrue(csv.getProvisions().get(0).getVirSchemas().isEmpty());
-    }
-
-    @Test
-    public void anonymous() {
-        SchemaService unauthenticated = clientFactory.create().getService(SchemaService.class);
-        try {
-            unauthenticated.list(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build());
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        SchemaService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(SchemaService.class);
-        assertFalse(anonymous.list(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build()).isEmpty());
-    }
-
-    @Test
-    public void issueSYNCOPE323() {
-        VirSchemaTO actual = schemaService.read(SchemaType.VIRTUAL, "virtualdata");
-        assertNotNull(actual);
-
-        try {
-            createSchema(SchemaType.VIRTUAL, actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.EntityExists, e.getType());
-        }
-
-        actual.setKey(null);
-        try {
-            createSchema(SchemaType.VIRTUAL, actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        ResourceTO ws1 = resourceService.read(RESOURCE_NAME_WS1);
-        assertNotNull(ws1);
-        assertEquals(1, ws1.getProvisions().size());
-        assertTrue(ws1.getProvisions().get(0).getVirSchemas().isEmpty());
-
-        VirSchemaTO schema = new VirSchemaTO();
-        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-        schema.setExtAttrName("name");
-        schema.setProvision(ws1.getProvisions().get(0).getKey());
-
-        try {
-            createSchema(SchemaType.VIRTUAL, schema);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidVirSchema, e.getType());
-
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java
deleted file mode 100644
index 9c9dd06..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java
+++ /dev/null
@@ -1,75 +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.fit.core.reference;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-
-import java.io.IOException;
-import java.io.InputStream;
-import javax.ws.rs.core.Response;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.junit.Assume;
-import org.junit.Test;
-
-public class WorkflowITCase extends AbstractITCase {
-
-    private void exportDefinition(final AnyTypeKind type) throws IOException {
-        Response response = workflowService.exportDefinition(type);
-        assertTrue(response.getMediaType().toString().
-                startsWith(clientFactory.getContentType().getMediaType().toString()));
-        assertTrue(response.getEntity() instanceof InputStream);
-        String definition = IOUtils.toString((InputStream) response.getEntity());
-        assertNotNull(definition);
-        assertFalse(definition.isEmpty());
-    }
-
-    @Test
-    public void exportUserDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-        exportDefinition(AnyTypeKind.USER);
-    }
-
-    @Test
-    public void getGroupDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForGroups(syncopeService));
-        exportDefinition(AnyTypeKind.GROUP);
-    }
-
-    private void importDefinition(final AnyTypeKind type) throws IOException {
-        Response response = workflowService.exportDefinition(type);
-        String definition = IOUtils.toString((InputStream) response.getEntity());
-
-        workflowService.importDefinition(type, definition);
-    }
-
-    @Test
-    public void updateUserDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-        importDefinition(AnyTypeKind.USER);
-    }
-
-    @Test
-    public void updateGroupDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForGroups(syncopeService));
-        importDefinition(AnyTypeKind.GROUP);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/resources/console.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/console.properties b/fit/core-reference/src/test/resources/console.properties
new file mode 100644
index 0000000..be99423
--- /dev/null
+++ b/fit/core-reference/src/test/resources/console.properties
@@ -0,0 +1,31 @@
+# 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.
+console.directory=${conf.directory}
+
+version=${syncope.version}
+site=${project.parent.url}
+license=${licenseUrl}
+
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
+
+scheme=http
+host=localhost
+port=9080
+rootPath=/syncope/rest/
+
+activitiModelerDirectory=${activiti-modeler.directory}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/log4j2.xml b/fit/core-reference/src/test/resources/log4j2.xml
index 61b388d..924edbd 100644
--- a/fit/core-reference/src/test/resources/log4j2.xml
+++ b/fit/core-reference/src/test/resources/log4j2.xml
@@ -19,15 +19,19 @@ under the License.
 -->
 <configuration status="WARN" shutdownHook="disable">
   <appenders>
-    <console name="Console" target="SYSTEM_OUT">
+    <console name="main" target="SYSTEM_OUT">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
       </PatternLayout>
     </console>
   </appenders>
   <loggers>
-    <root level="debug">
-      <appenderRef ref="Console" />
+    <asyncLogger name="org.apache.syncope.fit" additivity="false" level="DEBUG">
+      <appender-ref ref="main"/>
+    </asyncLogger>
+    
+    <root level="DEBUG">
+      <appenderRef ref="main"/>
     </root>
   </loggers>
 </configuration>
\ No newline at end of file


[04/21] syncope git commit: Clean up: removing some not necessary methods from persistence-api and adjusting accordingly

Posted by il...@apache.org.
Clean up: removing some not necessary methods from persistence-api and adjusting accordingly


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/6d56c7ed
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/6d56c7ed
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/6d56c7ed

Branch: refs/heads/master
Commit: 6d56c7ed63f7701d3039e3fb57e38f5d9eb062a6
Parents: bf1c0fd
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jan 25 14:16:35 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jan 26 11:40:59 2016 +0100

----------------------------------------------------------------------
 .../client/console/SyncopeConsoleSession.java   | 11 ++----
 .../syncope/client/console/pages/Realms.java    |  2 +-
 .../console/panels/AnyTypeDetailsPanel.java     | 12 ++----
 .../console/panels/ConnectorConfPanel.java      | 33 ++++++++--------
 .../console/panels/ConnectorDetailsPanel.java   | 14 +++----
 .../client/console/panels/ConnectorModal.java   |  2 +-
 .../panels/ParametersCreateWizardPanel.java     |  6 ++-
 .../client/console/panels/ParametersPanel.java  |  6 +--
 .../panels/SecurityQuestionsModalPanel.java     |  2 +-
 .../client/console/panels/VirSchemaDetails.java | 13 ++-----
 .../panels/search/AbstractSearchPanel.java      | 26 +++++--------
 .../client/console/rest/SchemaRestClient.java   | 12 ++----
 .../wizards/any/AnyObjectWizardBuilder.java     |  2 +-
 .../console/wizards/any/AnyWizardBuilder.java   |  4 +-
 .../client/console/wizards/any/AuxClasses.java  | 14 +++----
 .../client/console/wizards/any/DerAttrs.java    | 13 ++-----
 .../console/wizards/any/GroupWizardBuilder.java |  5 ++-
 .../client/console/wizards/any/PlainAttrs.java  | 22 ++++-------
 .../console/wizards/any/Relationships.java      | 34 +++++++---------
 .../client/console/wizards/any/Resources.java   | 14 ++-----
 .../client/console/wizards/any/Roles.java       | 14 ++-----
 .../console/wizards/any/UserWizardBuilder.java  |  5 ++-
 .../client/console/wizards/any/VirAttrs.java    | 15 +++----
 .../provision/ProvisionWizardBuilder.java       | 12 ++----
 .../syncope/common/lib/AnyOperations.java       |  6 ++-
 .../syncope/common/lib/EntityTOUtils.java       | 41 ++++++++++++++++++++
 .../syncope/common/lib/to/AbstractExecTO.java   | 10 +++--
 .../syncope/common/lib/to/AbstractSchemaTO.java |  4 +-
 .../syncope/common/lib/to/AbstractTaskTO.java   | 10 +++--
 .../syncope/common/lib/to/AnyObjectTO.java      |  7 +++-
 .../org/apache/syncope/common/lib/to/AnyTO.java | 10 +++--
 .../syncope/common/lib/to/AnyTypeClassTO.java   |  4 +-
 .../apache/syncope/common/lib/to/AnyTypeTO.java |  4 +-
 .../syncope/common/lib/to/ConnInstanceTO.java   | 10 +++--
 .../apache/syncope/common/lib/to/DomainTO.java  |  4 +-
 .../apache/syncope/common/lib/to/EntityTO.java  | 28 +++++++++++++
 .../syncope/common/lib/to/GroupableTO.java      | 31 +++++++++++++++
 .../syncope/common/lib/to/MappingItemTO.java    |  4 +-
 .../syncope/common/lib/to/NotificationTO.java   |  4 +-
 .../syncope/common/lib/to/ProvisionTO.java      | 10 +++--
 .../apache/syncope/common/lib/to/RealmTO.java   | 10 +++--
 .../syncope/common/lib/to/RelatableTO.java      | 30 ++++++++++++++
 .../common/lib/to/RelationshipTypeTO.java       |  4 +-
 .../apache/syncope/common/lib/to/ReportTO.java  | 10 +++--
 .../syncope/common/lib/to/ResourceTO.java       |  4 +-
 .../apache/syncope/common/lib/to/RoleTO.java    |  4 +-
 .../common/lib/to/SecurityQuestionTO.java       | 10 +++--
 .../apache/syncope/common/lib/to/UserTO.java    | 11 ++++--
 .../syncope/core/misc/utils/EntityUtils.java    | 41 ++++++++++++++++++++
 .../syncope/core/misc/utils/TemplateUtils.java  |  2 +-
 .../core/persistence/api/entity/Any.java        |  6 ---
 .../core/persistence/api/entity/AnyType.java    |  2 -
 .../persistence/api/entity/AnyTypeClass.java    |  6 ---
 .../persistence/api/entity/ConnInstance.java    |  2 -
 .../persistence/api/entity/DynMembership.java   |  2 -
 .../persistence/api/entity/Notification.java    |  2 -
 .../core/persistence/api/entity/PlainAttr.java  |  2 -
 .../core/persistence/api/entity/Realm.java      |  2 -
 .../core/persistence/api/entity/Report.java     |  2 -
 .../core/persistence/api/entity/Role.java       |  2 -
 .../api/entity/anyobject/AnyObject.java         |  4 --
 .../core/persistence/api/entity/conf/Conf.java  |  3 --
 .../persistence/api/entity/group/Group.java     |  7 ----
 .../api/entity/group/TypeExtension.java         |  2 -
 .../api/entity/policy/AccountPolicy.java        |  2 -
 .../api/entity/resource/ExternalResource.java   |  2 -
 .../api/entity/resource/Mapping.java            |  2 -
 .../persistence/api/entity/task/PushTask.java   |  2 -
 .../persistence/api/entity/task/SyncTask.java   |  2 -
 .../core/persistence/api/entity/task/Task.java  |  4 +-
 .../core/persistence/api/entity/user/User.java  |  9 -----
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    | 20 +++-------
 .../persistence/jpa/dao/JPAAnySearchDAO.java    | 11 ++----
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |  6 +--
 .../core/persistence/jpa/dao/JPAConfDAO.java    |  4 +-
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |  2 +-
 .../jpa/dao/JPAExternalResourceDAO.java         | 10 ++---
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |  8 ++--
 .../persistence/jpa/dao/JPAPlainAttrDAO.java    | 14 +++----
 .../jpa/dao/JPAPlainAttrValueDAO.java           | 34 ++++++++--------
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  | 10 ++---
 .../jpa/dao/JPARelationshipTypeDAO.java         |  8 ++--
 .../persistence/jpa/dao/JPAReportExecDAO.java   |  2 +-
 .../core/persistence/jpa/dao/JPARoleDAO.java    |  4 +-
 .../persistence/jpa/dao/JPATaskExecDAO.java     |  4 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |  4 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    | 10 ++---
 .../persistence/jpa/entity/AbstractAny.java     | 41 ++------------------
 .../core/persistence/jpa/entity/JPAAnyType.java |  6 ---
 .../persistence/jpa/entity/JPAAnyTypeClass.java | 18 ---------
 .../persistence/jpa/entity/JPAConnInstance.java |  8 +---
 .../persistence/jpa/entity/JPANotification.java |  7 ----
 .../core/persistence/jpa/entity/JPARealm.java   |  6 ---
 .../core/persistence/jpa/entity/JPAReport.java  |  6 ---
 .../core/persistence/jpa/entity/JPARole.java    |  6 ---
 .../anyobject/JPAADynGroupMembership.java       |  6 ---
 .../jpa/entity/anyobject/JPAAPlainAttr.java     |  6 ---
 .../jpa/entity/anyobject/JPAAnyObject.java      | 24 ------------
 .../jpa/entity/conf/JPACPlainAttr.java          |  6 ---
 .../persistence/jpa/entity/conf/JPAConf.java    | 16 --------
 .../jpa/entity/group/JPAGPlainAttr.java         |  6 ---
 .../persistence/jpa/entity/group/JPAGroup.java  | 24 ------------
 .../jpa/entity/group/JPATypeExtension.java      |  6 ---
 .../jpa/entity/policy/JPAAccountPolicy.java     | 16 ++------
 .../entity/resource/JPAExternalResource.java    |  6 ---
 .../jpa/entity/resource/JPAMapping.java         |  6 ---
 .../jpa/entity/task/AbstractTask.java           |  8 +---
 .../jpa/entity/task/JPAPushTask.java            |  6 ---
 .../jpa/entity/task/JPASyncTask.java            |  6 ---
 .../jpa/entity/user/AbstractUDynMembership.java |  6 ---
 .../jpa/entity/user/JPAUPlainAttr.java          |  6 ---
 .../persistence/jpa/entity/user/JPAUser.java    | 30 --------------
 .../persistence/jpa/inner/TaskExecTest.java     |  2 +-
 .../core/persistence/jpa/outer/GroupTest.java   | 21 +++-------
 .../persistence/jpa/outer/ResourceTest.java     |  2 +-
 .../core/persistence/jpa/outer/RoleTest.java    | 12 ++----
 .../core/persistence/jpa/outer/TaskTest.java    |  6 +--
 .../core/persistence/jpa/outer/UserTest.java    |  4 +-
 .../api/data/ConnInstanceDataBinder.java        |  2 +-
 .../java/data/AbstractAnyDataBinder.java        | 15 +++----
 .../java/data/AnyObjectDataBinderImpl.java      | 15 +++----
 .../java/data/ConnInstanceDataBinderImpl.java   | 21 +++++-----
 .../java/data/GroupDataBinderImpl.java          |  4 +-
 .../java/data/SchemaDataBinderImpl.java         |  6 +--
 .../java/data/UserDataBinderImpl.java           | 41 +++++++-------------
 .../notification/NotificationManagerImpl.java   |  2 +-
 .../AbstractPropagationTaskExecutor.java        |  2 +-
 .../fit/core/reference/ConnectorITCase.java     |  4 +-
 .../core/reference/PropagationTaskITCase.java   |  4 +-
 .../syncope/fit/core/reference/RealmITCase.java |  2 +-
 .../fit/core/reference/ReportITCase.java        |  6 +--
 .../fit/core/reference/SchedTaskITCase.java     |  4 +-
 .../fit/core/reference/SearchITCase.java        |  6 +--
 .../syncope/fit/core/reference/UserITCase.java  |  4 +-
 .../fit/core/reference/UserWorkflowITCase.java  |  4 +-
 .../fit/core/reference/VirSchemaITCase.java     |  2 +-
 136 files changed, 533 insertions(+), 764 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index 28665a9..9430676 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -29,13 +29,13 @@ import java.util.Set;
 import javax.ws.rs.core.EntityTag;
 import javax.ws.rs.core.MediaType;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.DomainTO;
 import org.apache.syncope.common.lib.to.SyncopeTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -91,13 +91,8 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
         domains = new ArrayList<>();
         domains.add(SyncopeConstants.MASTER_DOMAIN);
         CollectionUtils.collect(anonymousClient.getService(DomainService.class).list(),
-                new Transformer<DomainTO, String>() {
-
-                    @Override
-                    public String transform(final DomainTO domain) {
-                        return domain.getKey();
-                    }
-                }, domains);
+                EntityTOUtils.<String, DomainTO>keyTransformer(),
+                domains);
     }
 
     public SyncopeTO getSyncopeTO() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index 25a2064..9c6c2e8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -141,7 +141,7 @@ public class Realms extends BasePage {
             @Override
             protected void onClickDelete(final AjaxRequestTarget target, final RealmTO realmTO) {
                 try {
-                    if (realmTO.getKey() == 0) {
+                    if (realmTO.getKey() == null || realmTO.getKey() == 0) {
                         throw new Exception("Root realm cannot be deleted");
                     }
                     realmRestClient.delete(realmTO.getFullPath());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeDetailsPanel.java
index c83da38..c32b507 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeDetailsPanel.java
@@ -22,11 +22,11 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -74,12 +74,8 @@ public class AnyTypeDetailsPanel extends Panel {
     }
 
     private List<String> getAvailableAnyTypeClasses() {
-        return CollectionUtils.collect(new AnyTypeClassRestClient().list(), new Transformer<AnyTypeClassTO, String>() {
-
-            @Override
-            public String transform(final AnyTypeClassTO input) {
-                return input.getKey();
-            }
-        }, new ArrayList<String>());
+        return CollectionUtils.collect(new AnyTypeClassRestClient().list(),
+                EntityTOUtils.<String, AnyTypeClassTO>keyTransformer(),
+                new ArrayList<String>());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java
index 3447a97..a487ee8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java
@@ -50,7 +50,7 @@ public abstract class ConnectorConfPanel extends AbstractConnectorConfPanel<Conn
     }
 
     /**
-     * Ge available configuration properties.
+     * Get available configuration properties.
      *
      * @param instance connector instance.
      * @return configuration properties.
@@ -62,24 +62,25 @@ public abstract class ConnectorConfPanel extends AbstractConnectorConfPanel<Conn
                 ConnectorModal.getBundle(instance, bundles).getProperties(),
                 new Transformer<ConnConfPropSchema, ConnConfProperty>() {
 
-                    @Override
-                    public ConnConfProperty transform(final ConnConfPropSchema key) {
-                        final ConnConfProperty property = new ConnConfProperty();
-                        property.setSchema(key);
+            @Override
+            public ConnConfProperty transform(final ConnConfPropSchema key) {
+                final ConnConfProperty property = new ConnConfProperty();
+                property.setSchema(key);
 
-                        if (instance.getKey() != 0 && instance.getConfMap().containsKey(key.getName())
+                if (instance.getKey() != null 
+                        && instance.getConfMap().containsKey(key.getName())
                         && instance.getConfMap().get(key.getName()).getValues() != null) {
-                            property.getValues().addAll(instance.getConfMap().get(key.getName()).getValues());
-                            property.setOverridable(instance.getConfMap().get(key.getName()).isOverridable());
-                        }
 
-                        if (property.getValues().isEmpty() && !key.getDefaultValues().isEmpty()) {
-                            property.getValues().addAll(key.getDefaultValues());
-                        }
-                        return property;
-                    }
-                },
-                new ArrayList<ConnConfProperty>());
+                    property.getValues().addAll(instance.getConfMap().get(key.getName()).getValues());
+                    property.setOverridable(instance.getConfMap().get(key.getName()).isOverridable());
+                }
+
+                if (property.getValues().isEmpty() && !key.getDefaultValues().isEmpty()) {
+                    property.getValues().addAll(key.getDefaultValues());
+                }
+                return property;
+            }
+        }, new ArrayList<ConnConfProperty>());
 
         return res;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java
index f7544c3..776a195 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java
@@ -92,7 +92,7 @@ public class ConnectorDetailsPanel extends Panel {
         bundleName.setRequired(true);
         bundleName.addRequiredLabel();
         bundleName.setOutputMarkupId(true);
-        bundleName.setEnabled(model.getObject().getKey() == 0);
+        bundleName.setEnabled(model.getObject().getKey() == null || model.getObject().getKey() == 0);
         bundleName.getField().setOutputMarkupId(true);
         add(bundleName);
 
@@ -184,14 +184,14 @@ public class ConnectorDetailsPanel extends Panel {
                     @Override
                     public boolean evaluate(final ConnBundleTO object) {
                         return object.getLocation().equals(connInstanceTO.getLocation())
-                        && object.getBundleName().equals(connInstanceTO.getBundleName());
+                                && object.getBundleName().equals(connInstanceTO.getBundleName());
                     }
                 }), new Transformer<ConnBundleTO, String>() {
 
-                    @Override
-                    public String transform(final ConnBundleTO input) {
-                        return input.getVersion();
-                    }
-                }, new HashSet<String>()));
+            @Override
+            public String transform(final ConnBundleTO input) {
+                return input.getVersion();
+            }
+        }, new HashSet<String>()));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
index 17cfbe0..751bc24 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
@@ -151,7 +151,7 @@ public class ConnectorModal extends AbstractResourceModal<Serializable> {
         }
 
         try {
-            if (connInstanceTO.getKey() == 0) {
+            if (connInstanceTO.getKey() == null || connInstanceTO.getKey() == 0) {
                 final ConnInstanceTO actual = connectorRestClient.create(connInstanceTO);
                 send(pageRef.getPage(), Broadcast.BREADTH, new CreateEvent(
                         actual.getKey(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardPanel.java
index 04d6973..09f7aae 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersCreateWizardPanel.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import static org.apache.syncope.client.console.panels.AbstractSearchResultPanel.LOG;
-
 import java.io.Serializable;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
@@ -30,11 +28,15 @@ import org.apache.syncope.common.rest.api.service.ConfigurationService;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.extensions.wizard.WizardModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ParametersCreateWizardPanel extends AjaxWizardBuilder<ParametersCreateWizardPanel.ParametersForm> {
 
     private static final long serialVersionUID = -2868592590785581481L;
 
+    private static final Logger LOG = LoggerFactory.getLogger(ParametersCreateWizardPanel.class);
+
     public ParametersCreateWizardPanel(final String id, final ParametersForm defaultItem, final PageReference pageRef) {
         super(id, defaultItem, pageRef);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
index b67305c..34ce06c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import static org.apache.wicket.Component.ENABLE;
-
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.lang.reflect.Field;
@@ -211,8 +209,8 @@ public class ParametersPanel extends AbstractSearchResultPanel<
 
                 final AttrTO attrTO = model.getObject();
 
-                final ActionLinksPanel.Builder<Serializable> actionLinks
-                        = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<Serializable> actionLinks =
+                        ActionLinksPanel.builder(page.getPageReference());
                 actionLinks.setDisableIndicator(true);
                 ActionLinksPanel.Builder<Serializable> addWithRoles = actionLinks
                         .addWithRoles(new ActionLink<Serializable>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
index 773c8de..4b18b96 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
@@ -50,7 +50,7 @@ public class SecurityQuestionsModalPanel extends AbstractModalPanel<SecurityQues
     @Override
     public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
         try {
-            if (securityQuestionTO.getKey() == 0) {
+            if (securityQuestionTO.getKey() == null || securityQuestionTO.getKey() == 0) {
                 SyncopeConsoleSession.get().getService(SecurityQuestionService.class).create(securityQuestionTO);
             } else {
                 SyncopeConsoleSession.get().getService(SecurityQuestionService.class).update(securityQuestionTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
index 69bf8a3..0fbc7a6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
@@ -22,12 +22,12 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -58,14 +58,9 @@ public class VirSchemaDetails extends AbstractSchemaDetailsPanel {
 
         final AjaxDropDownChoicePanel<String> resource = new AjaxDropDownChoicePanel<>(
                 "resource", getString("resource"), new PropertyModel<String>(schemaTO, "resource"));
-        resource.setChoices(
-                CollectionUtils.collect(resourceRestClient.getAll(), new Transformer<ResourceTO, String>() {
-
-                    @Override
-                    public String transform(final ResourceTO input) {
-                        return input.getKey();
-                    }
-                }, new ArrayList<String>()));
+        resource.setChoices(CollectionUtils.collect(resourceRestClient.getAll(),
+                EntityTOUtils.<String, ResourceTO>keyTransformer(),
+                new ArrayList<String>()));
 
         resource.setOutputMarkupId(true);
         resource.addRequiredLabel();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
index 329fd26..c23cd79 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
@@ -22,12 +22,12 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.rest.SchemaRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.search.SearchableFields;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -163,15 +163,11 @@ public abstract class AbstractSearchPanel extends Panel {
 
             @Override
             protected List<String> load() {
-                return CollectionUtils.collect(schemaRestClient.getSchemas(SchemaType.PLAIN,
-                        anyTypeRestClient.get(type).getClasses().toArray(new String[] {})),
-                        new Transformer<AbstractSchemaTO, String>() {
-
-                    @Override
-                    public String transform(final AbstractSchemaTO input) {
-                        return input.getKey();
-                    }
-                }, new ArrayList<String>());
+                return CollectionUtils.collect(
+                        schemaRestClient.getSchemas(SchemaType.PLAIN, anyTypeRestClient.get(type).getClasses().
+                                toArray(new String[] {})),
+                        EntityTOUtils.<String, AbstractSchemaTO>keyTransformer(),
+                        new ArrayList<String>());
             }
         };
 
@@ -181,13 +177,9 @@ public abstract class AbstractSearchPanel extends Panel {
 
             @Override
             protected List<String> load() {
-                return CollectionUtils.collect(resourceRestClient.getAll(), new Transformer<ResourceTO, String>() {
-
-                    @Override
-                    public String transform(final ResourceTO input) {
-                        return input.getKey();
-                    }
-                }, new ArrayList<String>());
+                return CollectionUtils.collect(resourceRestClient.getAll(),
+                        EntityTOUtils.<String, ResourceTO>keyTransformer(),
+                        new ArrayList<String>());
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
index f9765c2..2e3f037 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
@@ -23,9 +23,9 @@ import java.util.Collection;
 import java.util.List;
 import java.util.ListIterator;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
@@ -77,13 +77,9 @@ public class SchemaRestClient extends BaseRestClient {
         List<String> schemaNames = new ArrayList<>();
 
         try {
-            CollectionUtils.collect(getSchemas(schemaType), new Transformer<AbstractSchemaTO, String>() {
-
-                @Override
-                public String transform(final AbstractSchemaTO schemaTO) {
-                    return schemaTO.getKey();
-                }
-            }, schemaNames);
+            CollectionUtils.collect(getSchemas(schemaType),
+                    EntityTOUtils.<String, AbstractSchemaTO>keyTransformer(),
+                    schemaNames);
         } catch (SyncopeClientException e) {
             LOG.error("While getting all user schema names", e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
index 9ccbd2e..7ba0deb 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
@@ -51,7 +51,7 @@ public class AnyObjectWizardBuilder extends AnyWizardBuilder<AnyObjectTO> implem
 
         final ProvisioningResult<AnyObjectTO> actual;
 
-        if (inner.getKey() == 0) {
+        if (inner.getKey() == null || inner.getKey() == 0) {
             actual = anyObjectRestClient.create(AnyObjectTO.class.cast(inner));
         } else {
             final AnyObjectPatch patch = AnyOperations.diff(inner, getOriginalItem().getInnerObject(), false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index 45426b6..d40541b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -73,7 +73,7 @@ public abstract class AnyWizardBuilder<T extends AnyTO> extends AjaxWizardBuilde
 
     @Override
     protected WizardModel buildModelSteps(final AnyHandler<T> modelObject, final WizardModel wizardModel) {
-        final String[] clazzes = anyTypeClasses.toArray(new String[]{});
+        final String[] clazzes = anyTypeClasses.toArray(new String[] {});
         // optional details panel step
         addOptionalDetailsPanel(modelObject, wizardModel);
 
@@ -111,7 +111,7 @@ public abstract class AnyWizardBuilder<T extends AnyTO> extends AjaxWizardBuilde
 
     protected AnyWizardBuilder<T> addOptionalDetailsPanel(
             final AnyHandler<T> modelObject, final WizardModel wizardModel) {
-        if (modelObject.getInnerObject().getKey() > 0) {
+        if (modelObject.getInnerObject().getKey() != null && modelObject.getInnerObject().getKey() > 0) {
             wizardModel.add(new Details<>(
                     modelObject, new ListModel<>(Collections.<StatusBean>emptyList()), pageRef, true));
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java
index 7c7d60e..a38090b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java
@@ -28,12 +28,11 @@ import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.GroupableTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.html.form.IChoiceRenderer;
@@ -60,12 +59,9 @@ public class AuxClasses extends WizardStep {
             final List<MembershipTO> memberships;
             final List<Long> dyngroups;
 
-            if (entityTO instanceof UserTO) {
-                memberships = UserTO.class.cast(entityTO).getMemberships();
-                dyngroups = UserTO.class.cast(entityTO).getDynGroups();
-            } else if (entityTO instanceof AnyObjectTO) {
-                memberships = AnyObjectTO.class.cast(entityTO).getMemberships();
-                dyngroups = AnyObjectTO.class.cast(entityTO).getDynGroups();
+            if (entityTO instanceof GroupableTO) {
+                memberships = GroupableTO.class.cast(entityTO).getMemberships();
+                dyngroups = GroupableTO.class.cast(entityTO).getDynGroups();
             } else {
                 memberships = Collections.<MembershipTO>emptyList();
                 dyngroups = Collections.<Long>emptyList();
@@ -74,7 +70,7 @@ public class AuxClasses extends WizardStep {
             final AjaxPalettePanel.Builder<MembershipTO> builder =
                     new AjaxPalettePanel.Builder<MembershipTO>().setRenderer(new IChoiceRenderer<MembershipTO>() {
 
-                        private static final long serialVersionUID = 1L;
+                        private static final long serialVersionUID = -3086661086073628855L;
 
                         @Override
                         public Object getDisplayValue(final MembershipTO object) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
index 3ad0232..0404a7c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
@@ -26,6 +26,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AttrTO;
@@ -57,15 +58,9 @@ public class DerAttrs extends AbstractAttrs {
 
             @Override
             protected List<AttrTO> load() {
-                final List<String> classes = CollectionUtils.collect(
-                        anyTypeClassRestClient.list(getAllAuxClasses()),
-                        new Transformer<AnyTypeClassTO, String>() {
-
-                    @Override
-                    public String transform(final AnyTypeClassTO input) {
-                        return input.getKey();
-                    }
-                }, new ArrayList<>(Arrays.asList(anyTypeClass)));
+                final List<String> classes = CollectionUtils.collect(anyTypeClassRestClient.list(getAllAuxClasses()),
+                        EntityTOUtils.<String, AnyTypeClassTO>keyTransformer(),
+                        new ArrayList<>(Arrays.asList(anyTypeClass)));
 
                 final List<DerSchemaTO> derSchemas =
                         schemaRestClient.getSchemas(SchemaType.DERIVED, classes.toArray(new String[] {}));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
index 4763ec7..4503df5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
@@ -70,7 +70,7 @@ public class GroupWizardBuilder extends AnyWizardBuilder<GroupTO> {
                 ? GroupHandler.class.cast(modelObject).fillDynamicConditions()
                 : modelObject.getInnerObject();
 
-        if (toBeProcessed.getKey() == 0) {
+        if (toBeProcessed.getKey() == null || toBeProcessed.getKey() == 0) {
             actual = groupRestClient.create(toBeProcessed);
         } else {
             final GroupPatch patch = AnyOperations.diff(toBeProcessed, getOriginalItem().getInnerObject(), false);
@@ -92,7 +92,8 @@ public class GroupWizardBuilder extends AnyWizardBuilder<GroupTO> {
         wizardModel.add(new GroupDetails(
                 GroupHandler.class.cast(modelObject),
                 new ListModel<>(Collections.<StatusBean>emptyList()),
-                false, pageRef, modelObject.getInnerObject().getKey() > 0));
+                false, pageRef,
+                modelObject.getInnerObject().getKey() != null && modelObject.getInnerObject().getKey() > 0));
         return this;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
index 9c8a83e..0088163 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
@@ -28,7 +28,6 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.commons.JexlHelpUtils;
 import org.apache.syncope.client.console.commons.Mode;
@@ -41,6 +40,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPane
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AttrTO;
@@ -79,15 +79,9 @@ public class PlainAttrs extends AbstractAttrs {
 
             @Override
             protected List<AttrTO> load() {
-                setSchemas(CollectionUtils.collect(
-                        anyTypeClassRestClient.list(getAllAuxClasses()),
-                        new Transformer<AnyTypeClassTO, String>() {
-
-                    @Override
-                    public String transform(final AnyTypeClassTO input) {
-                        return input.getKey();
-                    }
-                }, new ArrayList<>(Arrays.asList(anyTypeClass))));
+                setSchemas(CollectionUtils.collect(anyTypeClassRestClient.list(getAllAuxClasses()),
+                        EntityTOUtils.<String, AnyTypeClassTO>keyTransformer(),
+                        new ArrayList<>(Arrays.asList(anyTypeClass))));
                 setAttrs();
                 return new ArrayList<>(entityTO.getPlainAttrs());
             }
@@ -98,7 +92,7 @@ public class PlainAttrs extends AbstractAttrs {
             private static final long serialVersionUID = 9101744072914090143L;
 
             @Override
-            @SuppressWarnings({"unchecked", "rawtypes"})
+            @SuppressWarnings({ "unchecked", "rawtypes" })
             protected void populateItem(final ListItem<AttrTO> item) {
                 final AttrTO attributeTO = (AttrTO) item.getDefaultModelObject();
 
@@ -131,8 +125,8 @@ public class PlainAttrs extends AbstractAttrs {
     private void setSchemas(final List<String> anyTypeClasses) {
 
         AttrTO attrLayout = null;
-        final List<PlainSchemaTO> schemaTOs
-                = schemaRestClient.getSchemas(SchemaType.PLAIN, anyTypeClasses.toArray(new String[]{}));
+        final List<PlainSchemaTO> schemaTOs =
+                schemaRestClient.getSchemas(SchemaType.PLAIN, anyTypeClasses.toArray(new String[] {}));
 
         schemas.clear();
 
@@ -189,7 +183,7 @@ public class PlainAttrs extends AbstractAttrs {
         entityTO.getPlainAttrs().addAll(entityData);
     }
 
-    @SuppressWarnings({"rawtypes", "unchecked"})
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     private FieldPanel getFieldPanel(final PlainSchemaTO schemaTO) {
         final boolean required = mode == Mode.TEMPLATE
                 ? false

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index 2411c16..7919bfe 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -48,12 +48,13 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPane
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.to.RelatableTO;
 import org.apache.syncope.common.lib.to.RelationshipTO;
 import org.apache.syncope.common.lib.to.RelationshipTypeTO;
-import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyEntitlement;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
@@ -83,6 +84,7 @@ public class Relationships extends WizardStep {
     private final PageReference pageRef;
 
     private final AnyTypeRestClient anyTypeRestClient = new AnyTypeRestClient();
+
     private final AnyTypeClassRestClient anyTypeClassRestClient = new AnyTypeClassRestClient();
 
     private final AnyTO anyTO;
@@ -170,13 +172,14 @@ public class Relationships extends WizardStep {
     }
 
     private List<RelationshipTO> getCurrentRelationships() {
-        return anyTO instanceof UserTO ? UserTO.class.cast(anyTO).getRelationships() : anyTO instanceof AnyObjectTO
-                ? AnyObjectTO.class.cast(anyTO).getRelationships()
+        return anyTO instanceof RelatableTO
+                ? RelatableTO.class.cast(anyTO).getRelationships()
                 : Collections.<RelationshipTO>emptyList();
     }
 
     private void addRelationship(
             final Map<String, List<RelationshipTO>> relationships, final RelationshipTO... rels) {
+
         for (RelationshipTO relationship : rels) {
             final List<RelationshipTO> listrels;
             if (relationships.containsKey(relationship.getType())) {
@@ -226,15 +229,8 @@ public class Relationships extends WizardStep {
 
             final ArrayList<String> availableRels = CollectionUtils.collect(
                     SyncopeConsoleSession.get().getService(RelationshipTypeService.class).list(),
-                    new SerializableTransformer<RelationshipTypeTO, String>() {
-
-                private static final long serialVersionUID = 5498141517922697858L;
-
-                @Override
-                public String transform(final RelationshipTypeTO input) {
-                    return input.getKey();
-                }
-            }, new ArrayList<String>());
+                    EntityTOUtils.<String, RelationshipTypeTO>keyTransformer(),
+                    new ArrayList<String>());
 
             final AjaxDropDownChoicePanel<String> type = new AjaxDropDownChoicePanel<>(
                     "type", "type", new PropertyModel<String>(rel, "type"));
@@ -287,11 +283,11 @@ public class Relationships extends WizardStep {
 
                 @Override
                 public AnyTypeTO getObject(final String id, final IModel<? extends List<? extends AnyTypeTO>> choices) {
-                    return IterableUtils.find(choices.getObject(), new Predicate<Object>() {
+                    return IterableUtils.find(choices.getObject(), new Predicate<AnyTypeTO>() {
 
                         @Override
-                        public boolean evaluate(final Object object) {
-                            return id.equals(AnyTypeTO.class.cast(object).getKey());
+                        public boolean evaluate(final AnyTypeTO object) {
+                            return id.equals(object.getKey());
                         }
                     });
                 }
@@ -358,14 +354,14 @@ public class Relationships extends WizardStep {
         @Override
         public void onEvent(final IEvent<?> event) {
             if (event.getPayload() instanceof SearchClausePanel.SearchEvent) {
-                final AjaxRequestTarget target
-                        = SearchClausePanel.SearchEvent.class.cast(event.getPayload()).getTarget();
+                final AjaxRequestTarget target =
+                        SearchClausePanel.SearchEvent.class.cast(event.getPayload()).getTarget();
                 final String fiql = SearchUtils.buildFIQL(anyObjectSearchPanel.getModel().getObject(),
                         SyncopeClient.getAnyObjectSearchConditionBuilder(anyObjectSearchPanel.getBackObjectType()));
                 AnyObjectSearchResultPanel.class.cast(anyObjectSearchResultPanel).search(fiql, target);
             } else if (event.getPayload() instanceof AnySelectionSearchResultPanel.ItemSelection) {
-                final AjaxRequestTarget target
-                        = AnySelectionSearchResultPanel.ItemSelection.class.cast(event.getPayload()).getTarget();
+                final AjaxRequestTarget target =
+                        AnySelectionSearchResultPanel.ItemSelection.class.cast(event.getPayload()).getTarget();
 
                 AnyTO right = AnySelectionSearchResultPanel.ItemSelection.class.cast(event.getPayload()).getSelection();
                 rel.setRightKey(right.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
index 125af8e..c3412fd 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
@@ -21,9 +21,9 @@ package org.apache.syncope.client.console.wizards.any;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.wicket.extensions.wizard.WizardStep;
@@ -52,14 +52,8 @@ public class Resources extends WizardStep {
                 entityTO.getResources().clear();
                 entityTO.getResources().addAll(object);
             }
-        }, new ListModel<>(CollectionUtils.collect(
-                        new ResourceRestClient().getAll(),
-                        new Transformer<ResourceTO, String>() {
-
-                    @Override
-                    public String transform(final ResourceTO input) {
-                        return input.getKey();
-                    }
-                }, new ArrayList<String>()))).hideLabel().setOutputMarkupId(true));
+        }, new ListModel<>(CollectionUtils.collect(new ResourceRestClient().getAll(),
+                        EntityTOUtils.<String, ResourceTO>keyTransformer(),
+                        new ArrayList<String>()))).hideLabel().setOutputMarkupId(true));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
index 68fc49d..c21d4c0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
@@ -21,9 +21,9 @@ package org.apache.syncope.client.console.wizards.any;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.rest.RoleRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -38,15 +38,9 @@ public class Roles extends WizardStep {
     public <T extends AnyTO> Roles(final UserTO entityTO) {
         this.setOutputMarkupId(true);
 
-        final ArrayList<String> allRoles = CollectionUtils.collect(
-                new RoleRestClient().getAll(),
-                new Transformer<RoleTO, String>() {
-
-            @Override
-            public String transform(final RoleTO input) {
-                return input.getKey();
-            }
-        }, new ArrayList<String>());
+        final ArrayList<String> allRoles = CollectionUtils.collect(new RoleRestClient().getAll(),
+                EntityTOUtils.<String, RoleTO>keyTransformer(),
+                new ArrayList<String>());
 
         add(new AjaxPalettePanel.Builder<String>().build("roles",
                 new PropertyModel<List<String>>(entityTO, "roles"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index a554c88..21e430a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -62,7 +62,7 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> {
 
         final UserTO inner = modelObject.getInnerObject();
 
-        if (inner.getKey() == 0) {
+        if (inner.getKey() == null || inner.getKey() == 0) {
             actual = userRestClient.create(inner, StringUtils.isNotBlank(inner.getPassword()));
         } else {
             final UserPatch patch = AnyOperations.diff(inner, getOriginalItem().getInnerObject(), false);
@@ -86,7 +86,8 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> {
     protected UserWizardBuilder addOptionalDetailsPanel(
             final AnyHandler<UserTO> modelObject, final WizardModel wizardModel) {
         wizardModel.add(new UserDetails(
-                modelObject, statusModel, false, false, pageRef, modelObject.getInnerObject().getKey() > 0));
+                modelObject, statusModel, false, false, pageRef,
+                modelObject.getInnerObject().getKey() != null && modelObject.getInnerObject().getKey() > 0));
         return this;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java
index e818960..66cc123 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java
@@ -27,6 +27,7 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AttrTO;
@@ -55,15 +56,9 @@ public class VirAttrs extends AbstractAttrs {
 
             @Override
             protected List<AttrTO> load() {
-                final List<String> classes = CollectionUtils.collect(
-                        anyTypeClassRestClient.list(getAllAuxClasses()),
-                        new Transformer<AnyTypeClassTO, String>() {
-
-                    @Override
-                    public String transform(final AnyTypeClassTO input) {
-                        return input.getKey();
-                    }
-                }, new ArrayList<>(Arrays.asList(anyTypeClass)));
+                final List<String> classes = CollectionUtils.collect(anyTypeClassRestClient.list(getAllAuxClasses()),
+                        EntityTOUtils.<String, AnyTypeClassTO>keyTransformer(),
+                        new ArrayList<>(Arrays.asList(anyTypeClass)));
 
                 final List<VirSchemaTO> virSchemas =
                         schemaRestClient.getSchemas(SchemaType.VIRTUAL, classes.toArray(new String[] {}));
@@ -72,7 +67,7 @@ public class VirAttrs extends AbstractAttrs {
                 entityTO.getVirAttrs().clear();
 
                 // This conversion from set to lis is required by the ListView.
-                // Didn't performed by using collect parameter because entityTO change is required.
+                // Not performed by using collect parameter because entityTO change is required.
                 return new ArrayList<>(CollectionUtils.collect(virSchemas, new Transformer<VirSchemaTO, AttrTO>() {
 
                     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
index 06b14cf..79f6bc8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
@@ -30,6 +30,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -72,14 +73,9 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> imple
 
             final List<String> res = new ArrayList<>();
 
-            CollectionUtils.filter(
-                    CollectionUtils.collect(new AnyTypeRestClient().list(), new Transformer<AnyTypeTO, String>() {
-
-                        @Override
-                        public String transform(final AnyTypeTO anyTypeTO) {
-                            return anyTypeTO.getKey();
-                        }
-                    }, res), new Predicate<String>() {
+            CollectionUtils.filter(CollectionUtils.collect(new AnyTypeRestClient().list(),
+                            EntityTOUtils.<String, AnyTypeTO>keyTransformer(), res),
+                    new Predicate<String>() {
 
                 @Override
                 public boolean evaluate(final String key) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
index 591e135..b72a127 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
@@ -78,7 +78,9 @@ public final class AnyOperations {
             final AnyTO updated, final AnyTO original, final AnyPatch result, final boolean incremental) {
 
         // check same key
-        if (updated.getKey() != original.getKey()) {
+        if (updated.getKey() == null && original.getKey() != null
+                || (updated.getKey() != null && !updated.getKey().equals(original.getKey()))) {
+
             throw new IllegalArgumentException("AnyTO's key must be the same");
         }
         result.setKey(updated.getKey());
@@ -380,7 +382,7 @@ public final class AnyOperations {
 
     private static <T extends AnyTO, K extends AnyPatch> void patch(final T to, final K patch, final T result) {
         // check same key
-        if (to.getKey() != patch.getKey()) {
+        if (to.getKey() == null || to.getKey() != patch.getKey()) {
             throw new IllegalArgumentException(
                     to.getClass().getSimpleName() + " and " + patch.getClass().getSimpleName()
                     + " keys must be the same");

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java b/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java
new file mode 100644
index 0000000..b2d9c7e
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java
@@ -0,0 +1,41 @@
+/*
+ * 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.common.lib;
+
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.to.EntityTO;
+
+public final class EntityTOUtils {
+
+    public static <KEY, E extends EntityTO<KEY>> Transformer<E, KEY> keyTransformer() {
+        return new Transformer<E, KEY>() {
+
+            @Override
+            public KEY transform(final E input) {
+                return input.getKey();
+            }
+        };
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private EntityTOUtils() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractExecTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractExecTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractExecTO.java
index c4b5fe5..c9165dc 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractExecTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractExecTO.java
@@ -21,21 +21,23 @@ package org.apache.syncope.common.lib.to;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlType
-public class AbstractExecTO extends AbstractStartEndBean {
+public class AbstractExecTO extends AbstractStartEndBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = -4621191979198357081L;
 
-    private long key;
+    private Long key;
 
     private String status;
 
     private String message;
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
index f426f8c..f6e3536 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 @XmlType
 @XmlSeeAlso({ PlainSchemaTO.class, DerSchemaTO.class, VirSchemaTO.class })
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public abstract class AbstractSchemaTO extends AbstractBaseBean {
+public abstract class AbstractSchemaTO extends AbstractBaseBean implements EntityTO<String> {
 
     private static final long serialVersionUID = 4088388951694301759L;
 
@@ -37,11 +37,13 @@ public abstract class AbstractSchemaTO extends AbstractBaseBean {
 
     private String anyTypeClass;
 
+    @Override
     public String getKey() {
         return key;
     }
 
     @PathParam("key")
+    @Override
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
index 21e665b..f6606e3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
@@ -34,22 +34,24 @@ import javax.xml.bind.annotation.XmlType;
 @XmlType
 @XmlSeeAlso({ PropagationTaskTO.class, SchedTaskTO.class, NotificationTaskTO.class })
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public abstract class AbstractTaskTO extends AbstractStartEndBean {
+public abstract class AbstractTaskTO extends AbstractStartEndBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = 386450127003321197L;
 
-    private long key;
+    private Long key;
 
     private String latestExecStatus;
 
     private final List<TaskExecTO> executions = new ArrayList<>();
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
     @PathParam("key")
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
index 6c368ee..35b796b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
@@ -33,7 +33,7 @@ import org.apache.commons.lang3.tuple.Pair;
 
 @XmlRootElement(name = "anyObject")
 @XmlType
-public class AnyObjectTO extends AnyTO {
+public class AnyObjectTO extends AnyTO implements RelatableTO, GroupableTO {
 
     private static final long serialVersionUID = 8841697496476959639L;
 
@@ -46,11 +46,13 @@ public class AnyObjectTO extends AnyTO {
     @XmlElementWrapper(name = "relationships")
     @XmlElement(name = "relationship")
     @JsonProperty("relationships")
+    @Override
     public List<RelationshipTO> getRelationships() {
         return relationships;
     }
 
     @JsonIgnore
+    @Override
     public Map<Pair<String, Long>, RelationshipTO> getRelationshipMap() {
         Map<Pair<String, Long>, RelationshipTO> result = new HashMap<>(getRelationships().size());
         for (RelationshipTO relationship : getRelationships()) {
@@ -64,11 +66,13 @@ public class AnyObjectTO extends AnyTO {
     @XmlElementWrapper(name = "memberships")
     @XmlElement(name = "membership")
     @JsonProperty("memberships")
+    @Override
     public List<MembershipTO> getMemberships() {
         return memberships;
     }
 
     @JsonIgnore
+    @Override
     public Map<Long, MembershipTO> getMembershipMap() {
         Map<Long, MembershipTO> result = new HashMap<>(getMemberships().size());
         for (MembershipTO membership : getMemberships()) {
@@ -82,6 +86,7 @@ public class AnyObjectTO extends AnyTO {
     @XmlElementWrapper(name = "dynGroups")
     @XmlElement(name = "role")
     @JsonProperty("dynGroups")
+    @Override
     public List<Long> getDynGroups() {
         return dynGroups;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
index ce4a58f..3a40431 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
@@ -38,11 +38,11 @@ import javax.xml.bind.annotation.XmlType;
 @XmlType
 @XmlSeeAlso({ UserTO.class, GroupTO.class, AnyObjectTO.class })
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public abstract class AnyTO extends ConnObjectTO {
+public abstract class AnyTO extends ConnObjectTO implements EntityTO<Long> {
 
     private static final long serialVersionUID = -754311920679872084L;
 
-    private long key;
+    private Long key;
 
     private String type;
 
@@ -58,11 +58,13 @@ public abstract class AnyTO extends ConnObjectTO {
 
     private final Set<String> resources = new HashSet<>();
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
index 8e515a8..815b800 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
@@ -30,7 +30,7 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "anyTypeClass")
 @XmlType
-public class AnyTypeClassTO extends AbstractBaseBean {
+public class AnyTypeClassTO extends AbstractBaseBean implements EntityTO<String> {
 
     private static final long serialVersionUID = -591757688607551266L;
 
@@ -44,11 +44,13 @@ public class AnyTypeClassTO extends AbstractBaseBean {
 
     private final List<String> virSchemas = new ArrayList<>();
 
+    @Override
     public String getKey() {
         return key;
     }
 
     @PathParam("key")
+    @Override
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
index a5a7104..9a4d44a 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
@@ -31,7 +31,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 @XmlRootElement(name = "anyType")
 @XmlType
-public class AnyTypeTO extends AbstractBaseBean {
+public class AnyTypeTO extends AbstractBaseBean implements EntityTO<String> {
 
     private static final long serialVersionUID = 6771657557616874373L;
 
@@ -41,11 +41,13 @@ public class AnyTypeTO extends AbstractBaseBean {
 
     private final List<String> classes = new ArrayList<>();
 
+    @Override
     public String getKey() {
         return key;
     }
 
     @PathParam("key")
+    @Override
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
index 257f2ed..f44cb62 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
@@ -37,11 +37,11 @@ import org.apache.syncope.common.lib.types.ConnectorCapability;
 
 @XmlRootElement(name = "connInstance")
 @XmlType
-public class ConnInstanceTO extends AbstractBaseBean {
+public class ConnInstanceTO extends AbstractBaseBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = 2707778645445168671L;
 
-    private long key;
+    private Long key;
 
     private String location;
 
@@ -61,12 +61,14 @@ public class ConnInstanceTO extends AbstractBaseBean {
 
     private ConnPoolConfTO poolConf;
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
     @PathParam("key")
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java
index 3f05e19..faeedce 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DomainTO.java
@@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.types.CipherAlgorithm;
 
 @XmlRootElement(name = "domain")
 @XmlType
-public class DomainTO extends AbstractBaseBean {
+public class DomainTO extends AbstractBaseBean implements EntityTO<String> {
 
     private static final long serialVersionUID = -7938075259986084934L;
 
@@ -35,10 +35,12 @@ public class DomainTO extends AbstractBaseBean {
 
     private CipherAlgorithm adminCipherAlgorithm;
 
+    @Override
     public String getKey() {
         return key;
     }
 
+    @Override
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/EntityTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/EntityTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/EntityTO.java
new file mode 100644
index 0000000..493753d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/EntityTO.java
@@ -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.
+ */
+package org.apache.syncope.common.lib.to;
+
+import java.io.Serializable;
+
+public interface EntityTO<KEY> extends Serializable {
+
+    KEY getKey();
+
+    void setKey(KEY key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupableTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupableTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupableTO.java
new file mode 100644
index 0000000..014e897
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupableTO.java
@@ -0,0 +1,31 @@
+/*
+ * 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.common.lib.to;
+
+import java.util.List;
+import java.util.Map;
+
+public interface GroupableTO {
+
+    Map<Long, MembershipTO> getMembershipMap();
+
+    List<MembershipTO> getMemberships();
+
+    List<Long> getDynGroups();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
index b838f6e..a3409ca 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
@@ -28,7 +28,7 @@ import org.apache.syncope.common.lib.types.MappingPurpose;
 
 @XmlRootElement(name = "mappingItem")
 @XmlType
-public class MappingItemTO extends AbstractBaseBean {
+public class MappingItemTO extends AbstractBaseBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = 2983498836767176862L;
 
@@ -88,10 +88,12 @@ public class MappingItemTO extends AbstractBaseBean {
         this.extAttrName = extAttrName;
     }
 
+    @Override
     public Long getKey() {
         return key;
     }
 
+    @Override
     public void setKey(final Long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
index cd3f7ce..9b241be 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.types.TraceLevel;
 
 @XmlRootElement(name = "notification")
 @XmlType
-public class NotificationTO extends AbstractBaseBean {
+public class NotificationTO extends AbstractBaseBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = -6145117115632592612L;
 
@@ -90,11 +90,13 @@ public class NotificationTO extends AbstractBaseBean {
         return staticRecipients;
     }
 
+    @Override
     public Long getKey() {
         return key;
     }
 
     @PathParam("key")
+    @Override
     public void setKey(final Long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
index da23a59..b39d543 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
@@ -29,11 +29,11 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "provision")
 @XmlType
-public class ProvisionTO extends AbstractBaseBean {
+public class ProvisionTO extends AbstractBaseBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = 8298910216218007927L;
 
-    private long key;
+    private Long key;
 
     private String anyType;
 
@@ -45,11 +45,13 @@ public class ProvisionTO extends AbstractBaseBean {
 
     private final List<String> virSchemas = new ArrayList<>();
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
index 0c03798..6c0853d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
@@ -35,11 +35,11 @@ import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 
 @XmlRootElement(name = "realm")
 @XmlType
-public class RealmTO extends AbstractBaseBean {
+public class RealmTO extends AbstractBaseBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = 516330662956254391L;
 
-    private long key;
+    private Long key;
 
     private String name;
 
@@ -57,11 +57,13 @@ public class RealmTO extends AbstractBaseBean {
     @JsonIgnore
     private final Map<String, AnyTO> templates = new HashMap<>();
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelatableTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelatableTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelatableTO.java
new file mode 100644
index 0000000..1ff7232
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelatableTO.java
@@ -0,0 +1,30 @@
+/*
+ * 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.common.lib.to;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+
+public interface RelatableTO {
+
+    Map<Pair<String, Long>, RelationshipTO> getRelationshipMap();
+
+    List<RelationshipTO> getRelationships();
+}


[19/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TestPage.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TestPage.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TestPage.java
new file mode 100644
index 0000000..9dc19ea
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TestPage.java
@@ -0,0 +1,88 @@
+/*
+ * 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.fit.console;
+
+import java.io.Serializable;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.IMarkupResourceStreamProvider;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
+
+public class TestPage<T extends Serializable, S extends Panel>
+        extends WebPage implements IMarkupResourceStreamProvider {
+
+    private static final long serialVersionUID = 483736530078975170L;
+
+    public static String FIELD = "field";
+
+    private final Form<T> form;
+
+    private final S fieldPanel;
+
+    private TestPage(S field, final Builder<T, S> builder) {
+
+        this.form = builder.form;
+        this.fieldPanel = field;
+
+        field.setOutputMarkupId(builder.outputMarkupId);
+        add(form);
+        form.add(field);
+    }
+
+    public Form<T> getForm() {
+        return form;
+    }
+
+    public S getFieldPanel() {
+        return fieldPanel;
+    }
+
+    public static class Builder<T extends Serializable, S extends Panel> implements Serializable {
+
+        private static final long serialVersionUID = 4882978420728876617L;
+
+        private final Form<T> form;
+
+        private boolean outputMarkupId;
+
+        public Builder() {
+            this.form = new Form<>("form");
+
+        }
+
+        public Builder<T, S> setOutputMarkupId(final boolean outputMarkupId) {
+            this.outputMarkupId = outputMarkupId;
+            return this;
+        }
+
+        public TestPage<T, S> build(final S field) {
+            return new TestPage<>(field, this);
+        }
+    }
+
+    @Override
+    public IResourceStream getMarkupResourceStream(final MarkupContainer container,
+            final Class<?> containerClass) {
+        return new StringResourceStream("<html><body>"
+                + "<form wicket:id=\"form\"><span wicket:id=\"field\"></span></form></body></html>");
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
new file mode 100644
index 0000000..b9ec955
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
@@ -0,0 +1,184 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.core.logic.notification.NotificationJob;
+import org.apache.syncope.fit.AbstractITCase;
+
+public abstract class AbstractTaskITCase extends AbstractITCase {
+
+    protected static final Long SYNC_TASK_ID = 4L;
+
+    protected static final Long SCHED_TASK_ID = 5L;
+
+    protected static class ThreadExec implements Callable<TaskExecTO> {
+
+        private final TaskService taskService;
+
+        private final Long taskKey;
+
+        private final int maxWaitSeconds;
+
+        private final boolean dryRun;
+
+        public ThreadExec(
+                final TaskService taskService, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+
+            this.taskService = taskService;
+            this.taskKey = taskKey;
+            this.maxWaitSeconds = maxWaitSeconds;
+            this.dryRun = dryRun;
+        }
+
+        @Override
+        public TaskExecTO call() throws Exception {
+            return execProvisioningTask(taskService, taskKey, maxWaitSeconds, dryRun);
+        }
+    }
+
+    /**
+     * Remove initial and synchronized users to make test re-runnable.
+     */
+    protected void removeTestUsers() {
+        for (int i = 0; i < 10; i++) {
+            String cUserName = "test" + i;
+            try {
+                UserTO cUserTO = readUser(cUserName);
+                userService.delete(cUserTO.getKey());
+            } catch (Exception e) {
+                // Ignore
+            }
+        }
+    }
+
+    protected static TaskExecTO execTask(final TaskService taskService, final Long taskKey, final String initialStatus,
+            final int maxWaitSeconds, final boolean dryRun) {
+
+        AbstractTaskTO taskTO = taskService.read(taskKey, true);
+        assertNotNull(taskTO);
+        assertNotNull(taskTO.getExecutions());
+
+        int preSyncSize = taskTO.getExecutions().size();
+        TaskExecTO execution = taskService.execute(
+                new ExecuteQuery.Builder().key(taskTO.getKey()).dryRun(dryRun).build());
+        assertEquals(initialStatus, execution.getStatus());
+
+        int i = 0;
+        int maxit = maxWaitSeconds;
+
+        // wait for completion (executions incremented)
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            taskTO = taskService.read(taskTO.getKey(), true);
+
+            assertNotNull(taskTO);
+            assertNotNull(taskTO.getExecutions());
+
+            i++;
+        } while (preSyncSize == taskTO.getExecutions().size() && i < maxit);
+        if (i == maxit) {
+            fail("Timeout when executing task " + taskKey);
+        }
+        return taskTO.getExecutions().get(taskTO.getExecutions().size() - 1);
+    }
+
+    public static TaskExecTO execProvisioningTask(
+            final TaskService taskService, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+
+        return execTask(taskService, taskKey, "JOB_FIRED", maxWaitSeconds, dryRun);
+    }
+
+    protected static TaskExecTO execNotificationTask(
+            final TaskService taskService, final Long taskKey, final int maxWaitSeconds) {
+
+        return execTask(taskService, taskKey, NotificationJob.Status.SENT.name(), maxWaitSeconds, false);
+    }
+
+    protected Map<Long, TaskExecTO> execProvisioningTasks(final TaskService taskService,
+            final Set<Long> taskKeys, final int maxWaitSeconds, final boolean dryRun) throws Exception {
+
+        ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
+        List<Future<TaskExecTO>> futures = new ArrayList<>();
+
+        for (Long key : taskKeys) {
+            futures.add(service.submit(new ThreadExec(taskService, key, maxWaitSeconds, dryRun)));
+            // avoid flooding the test server
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+            }
+        }
+
+        Map<Long, TaskExecTO> res = new HashMap<>();
+
+        for (Future<TaskExecTO> future : futures) {
+            TaskExecTO taskExecTO = future.get(100, TimeUnit.SECONDS);
+            res.put(taskExecTO.getTask(), taskExecTO);
+        }
+
+        service.shutdownNow();
+
+        return res;
+    }
+
+    protected NotificationTaskTO findNotificationTaskBySender(final String sender) {
+        PagedResult<NotificationTaskTO> tasks =
+                taskService.list(new TaskQuery.Builder().type(TaskType.NOTIFICATION).build());
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        return IterableUtils.find(tasks.getResult(), new Predicate<NotificationTaskTO>() {
+
+            @Override
+            public boolean evaluate(final NotificationTaskTO task) {
+                return sender.equals(task.getSender());
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyObjectITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyObjectITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyObjectITCase.java
new file mode 100644
index 0000000..35521e2
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyObjectITCase.java
@@ -0,0 +1,210 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+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.SchemaType;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyObjectITCase extends AbstractITCase {
+
+    public static AnyObjectTO getSampleTO(final String location) {
+        AnyObjectTO anyObjectTO = new AnyObjectTO();
+        anyObjectTO.setRealm(SyncopeConstants.ROOT_REALM);
+        anyObjectTO.setType("PRINTER");
+        anyObjectTO.getPlainAttrs().add(attrTO("location", location + getUUIDString()));
+
+        anyObjectTO.getResources().add(RESOURCE_NAME_DBSCRIPTED);
+        return anyObjectTO;
+    }
+
+    @Test
+    public void create() {
+        AnyObjectTO anyObjectTO = getSampleTO("create");
+
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+        assertNotNull(anyObjectTO);
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
+        assertNotNull(connObjectTO);
+        assertNotNull(connObjectTO.getPlainAttrMap().get("location"));
+        assertEquals(anyObjectTO.getPlainAttrMap().get("location"), connObjectTO.getPlainAttrMap().get("location"));
+    }
+
+    @Test
+    public void createInvalidMembership() {
+        // 1. create anyObject in realm /odd and attempt to assign group 15, from realm /even => exception
+        AnyObjectTO anyObjectTO = getSampleTO("createInvalidMembership");
+        anyObjectTO.setRealm("/odd");
+        anyObjectTO.getMemberships().add(new MembershipTO.Builder().group(15L).build());
+
+        try {
+            createAnyObject(anyObjectTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidMembership, e.getType());
+        }
+
+        // 2. change anyObject's realm to /even/two, now it works
+        anyObjectTO.setRealm("/even/two");
+
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+        assertTrue(anyObjectTO.getMembershipMap().containsKey(15L));
+    }
+
+    @Test
+    public void delete() {
+        try {
+            anyObjectService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        AnyObjectTO anyObjectTO = getSampleTO("deletable");
+        anyObjectTO.setRealm("/even");
+
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+        assertNotNull(anyObjectTO);
+
+        AnyObjectTO deletedAnyObject = deleteAnyObject(anyObjectTO.getKey()).getAny();
+        assertNotNull(deletedAnyObject);
+
+        try {
+            anyObjectService.read(deletedAnyObject.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        PagedResult<AnyObjectTO> anyObjectTOs = anyObjectService.list(
+                "PRINTER", new AnyListQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
+        assertNotNull(anyObjectTOs);
+        assertTrue(anyObjectTOs.getResult().size() >= 2);
+        for (AnyObjectTO anyObjectTO : anyObjectTOs.getResult()) {
+            assertNotNull(anyObjectTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        AnyObjectTO anyObjectTO = anyObjectService.read(1L);
+        assertNotNull(anyObjectTO);
+        assertNotNull(anyObjectTO.getPlainAttrs());
+        assertFalse(anyObjectTO.getPlainAttrs().isEmpty());
+    }
+
+    @Test
+    public void update() {
+        AnyObjectTO anyObjectTO = getSampleTO("update");
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+
+        assertEquals(1, anyObjectTO.getPlainAttrs().size());
+
+        AnyObjectPatch anyObjectPatch = new AnyObjectPatch();
+        anyObjectPatch.setKey(anyObjectTO.getKey());
+        String newLocation = "new" + getUUIDString();
+        anyObjectPatch.getPlainAttrs().add(attrAddReplacePatch("location", newLocation));
+
+        anyObjectTO = updateAnyObject(anyObjectPatch).getAny();
+
+        assertEquals(newLocation, anyObjectTO.getPlainAttrMap().get("location").getValues().get(0));
+    }
+
+    @Test
+    public void readAttrs() {
+        AnyObjectTO anyObjectTO = getSampleTO("readAttrs");
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+        assertNotNull(anyObjectTO);
+
+        Set<AttrTO> attrs = anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN);
+        assertEquals(anyObjectTO.getPlainAttrs(), attrs);
+
+        AttrTO location = anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
+        assertEquals(anyObjectTO.getPlainAttrMap().get("location"), location);
+    }
+
+    @Test
+    public void updateAttr() {
+        AnyObjectTO anyObjectTO = getSampleTO("updateAttr");
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+        assertNotNull(anyObjectTO);
+
+        AttrTO updated = attrTO("location", "newlocation");
+        anyObjectService.update(anyObjectTO.getKey(), SchemaType.PLAIN, updated);
+
+        AttrTO location = anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
+        assertEquals(updated, location);
+    }
+
+    @Test
+    public void deleteAttr() {
+        AnyObjectTO anyObjectTO = getSampleTO("deleteAttr");
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+        assertNotNull(anyObjectTO);
+        assertNotNull(anyObjectTO.getPlainAttrMap().get("location"));
+
+        anyObjectService.delete(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
+
+        try {
+            anyObjectService.read(anyObjectTO.getKey(), SchemaType.PLAIN, "location");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE756() {
+        AnyObjectTO anyObjectTO = getSampleTO("issueSYNCOPE756");
+        anyObjectTO.getRelationships().add(new RelationshipTO.Builder().right(AnyTypeKind.USER.name(), 1).build());
+
+        try {
+            createAnyObject(anyObjectTO).getAny();
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java
new file mode 100644
index 0000000..bdce865
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java
@@ -0,0 +1,154 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyTypeClassITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
+        assertNotNull(minimalGroup);
+
+        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
+        assertFalse(minimalGroup.getDerSchemas().isEmpty());
+        assertFalse(minimalGroup.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void list() {
+        List<AnyTypeClassTO> list = anyTypeClassService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        // 1. create sample schemas
+        PlainSchemaTO plainSchema = new PlainSchemaTO();
+        plainSchema.setKey("new_plain_schema" + getUUIDString());
+        plainSchema.setType(AttrSchemaType.String);
+        plainSchema = createSchema(SchemaType.PLAIN, plainSchema);
+
+        DerSchemaTO derSchema = new DerSchemaTO();
+        derSchema.setKey("new_der_schema" + getUUIDString());
+        derSchema.setExpression(plainSchema.getKey() + " + '_' + derived_dx");
+        derSchema = createSchema(SchemaType.DERIVED, derSchema);
+
+        // 2. actual CRUD
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getPlainSchemas().add(plainSchema.getKey());
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertTrue(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+
+        newClass.getDerSchemas().add(derSchema.getKey());
+        anyTypeClassService.update(newClass);
+
+        newClass = anyTypeClassService.read(newClass.getKey());
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertFalse(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+
+        assertEquals(newClass.getKey(), schemaService.read(SchemaType.PLAIN, plainSchema.getKey()).getAnyTypeClass());
+        assertEquals(newClass.getKey(), schemaService.read(SchemaType.DERIVED, derSchema.getKey()).getAnyTypeClass());
+
+        anyTypeClassService.delete(newClass.getKey());
+
+        try {
+            anyTypeClassService.read(newClass.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+
+        assertNull(schemaService.read(SchemaType.PLAIN, plainSchema.getKey()).getAnyTypeClass());
+        assertNull(schemaService.read(SchemaType.DERIVED, derSchema.getKey()).getAnyTypeClass());
+    }
+
+    @Test
+    public void deleteSchema() {
+        PlainSchemaTO newSchema = new PlainSchemaTO();
+        newSchema.setKey("newSchema" + getUUIDString());
+        newSchema.setType(AttrSchemaType.Date);
+        createSchema(SchemaType.PLAIN, newSchema);
+
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getPlainSchemas().add(newSchema.getKey());
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+        assertTrue(newClass.getPlainSchemas().contains(newSchema.getKey()));
+
+        schemaService.delete(SchemaType.PLAIN, newSchema.getKey());
+
+        newClass = anyTypeClassService.read(newClass.getKey());
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().contains(newSchema.getKey()));
+    }
+
+    @Test
+    public void issueSYNCOPE759() {
+        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
+        assertNotNull(minimalGroup);
+
+        AnyTypeClassTO newAnyTypeClass = new AnyTypeClassTO();
+        newAnyTypeClass.setKey(minimalGroup.getKey());
+
+        try {
+            anyTypeClassService.create(newAnyTypeClass);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeITCase.java
new file mode 100644
index 0000000..f89e9a0
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeITCase.java
@@ -0,0 +1,194 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyTypeITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        AnyTypeTO userType = anyTypeService.read(AnyTypeKind.USER.name());
+        assertNotNull(userType);
+        assertEquals(AnyTypeKind.USER, userType.getKind());
+        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
+        assertFalse(userType.getClasses().isEmpty());
+
+        AnyTypeTO groupType = anyTypeService.read(AnyTypeKind.GROUP.name());
+        assertNotNull(groupType);
+        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
+        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
+        assertFalse(groupType.getClasses().isEmpty());
+
+        AnyTypeTO otherType = anyTypeService.read("PRINTER");
+        assertNotNull(otherType);
+        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
+        assertEquals("PRINTER", otherType.getKey());
+    }
+
+    @Test
+    public void list() {
+        List<AnyTypeTO> list = anyTypeService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        newType.getClasses().add("generic membership");
+        newType.getClasses().add("csv");
+
+        Response response = anyTypeService.create(newType);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newType = getObject(response.getLocation(), AnyTypeService.class, AnyTypeTO.class);
+        assertNotNull(newType);
+        assertEquals(2, newType.getClasses().size());
+        assertTrue(newType.getClasses().contains("generic membership"));
+        assertTrue(newType.getClasses().contains("csv"));
+
+        newType.getClasses().remove("generic membership");
+        anyTypeService.update(newType);
+
+        newType = anyTypeService.read(newType.getKey());
+        assertNotNull(newType);
+        assertEquals(1, newType.getClasses().size());
+        assertTrue(newType.getClasses().contains("csv"));
+
+        anyTypeService.delete(newType.getKey());
+
+        try {
+            anyTypeService.read(newType.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidKind() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.USER);
+        try {
+            anyTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidName() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("group");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        try {
+            anyTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteInvalid() {
+        try {
+            anyTypeService.delete(AnyTypeKind.USER.name());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteTypeClass() {
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getDerSchemas().add("cn");
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+
+        AnyTypeTO other = anyTypeService.read("PRINTER");
+        assertNotNull(other);
+
+        other.getClasses().add(newClass.getKey());
+        anyTypeService.update(other);
+
+        other = anyTypeService.read(other.getKey());
+        assertNotNull(other);
+        assertTrue(other.getClasses().contains(newClass.getKey()));
+
+        anyTypeClassService.delete(newClass.getKey());
+
+        other = anyTypeService.read(other.getKey());
+        assertNotNull(other);
+        assertFalse(other.getClasses().contains(newClass.getKey()));
+    }
+
+    @Test
+    public void issueSYNCOPE754() {
+        AnyTypeClassTO other = anyTypeClassService.read("other");
+        assertNotNull(other);
+
+        AnyTypeTO group = anyTypeService.read(AnyTypeKind.GROUP.name());
+        try {
+            assertFalse(group.getClasses().contains("other"));
+            group.getClasses().add("other");
+
+            anyTypeService.update(group);
+
+            group = anyTypeService.read(AnyTypeKind.GROUP.name());
+            assertTrue(group.getClasses().contains("other"));
+
+            other = anyTypeClassService.read("other");
+            assertEquals(2, other.getInUseByTypes().size());
+            assertTrue(other.getInUseByTypes().contains(AnyTypeKind.USER.name()));
+            assertTrue(other.getInUseByTypes().contains(AnyTypeKind.GROUP.name()));
+        } finally {
+            group.getClasses().remove("other");
+            anyTypeService.update(group);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
new file mode 100644
index 0000000..58b1b40
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
@@ -0,0 +1,567 @@
+/*
+ * 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.fit.core;
+
+import org.apache.syncope.fit.ActivitiDetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.patch.DeassociationPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.StatusPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.common.lib.types.StatusPatchType;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AuthenticationITCase extends AbstractITCase {
+
+    private int getFailedLogins(final UserService userService, final long userId) {
+        UserTO readUserTO = userService.read(userId);
+        assertNotNull(readUserTO);
+        assertNotNull(readUserTO.getFailedLogins());
+        return readUserTO.getFailedLogins();
+    }
+
+    private void assertReadFails(final SyncopeClient client) {
+        try {
+            client.self();
+            fail("access should not work");
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void testReadEntitlements() {
+        // 1. as not authenticated (not allowed)
+        try {
+            clientFactory.create().self();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        // 2. as anonymous
+        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).self();
+        assertEquals(1, self.getKey().size());
+        assertTrue(self.getKey().keySet().contains(StandardEntitlement.ANONYMOUS));
+        assertEquals(ANONYMOUS_UNAME, self.getValue().getUsername());
+
+        // 3. as admin
+        self = adminClient.self();
+        assertEquals(syncopeService.info().getEntitlements().size(), self.getKey().size());
+        assertFalse(self.getKey().keySet().contains(StandardEntitlement.ANONYMOUS));
+        assertEquals(ADMIN_UNAME, self.getValue().getUsername());
+
+        // 4. as user
+        self = clientFactory.create("bellini", ADMIN_PWD).self();
+        assertFalse(self.getKey().isEmpty());
+        assertFalse(self.getKey().keySet().contains(StandardEntitlement.ANONYMOUS));
+        assertEquals("bellini", self.getValue().getUsername());
+    }
+
+    @Test
+    public void testUserSchemaAuthorization() {
+        String schemaName = "authTestSchema" + getUUIDString();
+
+        // 1. create a schema (as admin)
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey(schemaName);
+        schemaTO.setMandatoryCondition("false");
+        schemaTO.setType(AttrSchemaType.String);
+
+        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
+        assertEquals(schemaTO, newPlainSchemaTO);
+
+        // 2. create an user with the role created above (as admin)
+        UserTO userTO = UserITCase.getUniqueSampleTO("auth@test.org");
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        // 3. read the schema created above (as admin) - success
+        schemaTO = schemaService.read(SchemaType.PLAIN, schemaName);
+        assertNotNull(schemaTO);
+
+        // 4. read the schema created above (as user) - success
+        SchemaService schemaService2 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(SchemaService.class);
+        schemaTO = schemaService2.read(SchemaType.PLAIN, schemaName);
+        assertNotNull(schemaTO);
+
+        // 5. update the schema create above (as user) - failure
+        try {
+            schemaService2.update(SchemaType.PLAIN, schemaTO);
+            fail("Schemaupdate as user should not work");
+        } catch (AccessControlException e) {
+            // CXF Service will throw this exception
+            assertNotNull(e);
+        }
+
+        assertEquals(0, getFailedLogins(userService, userTO.getKey()));
+    }
+
+    @Test
+    public void testUserRead() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("testuserread@test.org");
+        userTO.getRoles().add("User manager");
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(UserService.class);
+
+        UserTO readUserTO = userService2.read(1L);
+        assertNotNull(readUserTO);
+
+        UserService userService3 = clientFactory.create("puccini", ADMIN_PWD).getService(UserService.class);
+
+        try {
+            userService3.read(3L);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+            assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+        }
+    }
+
+    @Test
+    public void testUserSearch() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("testusersearch@test.org");
+        userTO.getRoles().add("User reviewer");
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        // 1. user assigned to role 1, with search entitlement on realms /odd and /even: won't find anything with 
+        // root realm
+        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(UserService.class);
+
+        PagedResult<UserTO> matchedUsers = userService2.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("key").query()).build());
+        assertNotNull(matchedUsers);
+        assertFalse(matchedUsers.getResult().isEmpty());
+        Set<Long> matchedUserKeys = CollectionUtils.collect(matchedUsers.getResult(),
+                new Transformer<UserTO, Long>() {
+
+            @Override
+            public Long transform(final UserTO input) {
+                return input.getKey();
+            }
+        }, new HashSet<Long>());
+        assertTrue(matchedUserKeys.contains(1L));
+        assertFalse(matchedUserKeys.contains(2L));
+        assertFalse(matchedUserKeys.contains(5L));
+
+        // 2. user assigned to role 4, with search entitlement on realm /even/two
+        UserService userService3 = clientFactory.create("puccini", ADMIN_PWD).getService(UserService.class);
+
+        matchedUsers = userService3.search(
+                new AnySearchQuery.Builder().realm("/even/two").
+                fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query()).build());
+        assertNotNull(matchedUsers);
+        assertTrue(IterableUtils.matchesAll(matchedUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO matched) {
+                return "/even/two".equals(matched.getRealm());
+            }
+        }));
+    }
+
+    @Test
+    public void delegatedUserCRUD() {
+        String roleKey = null;
+        Long delegatedAdminKey = null;
+        try {
+            // 1. create role for full user administration, under realm /even/two
+            RoleTO role = new RoleTO();
+            role.setKey("Delegated user admin");
+            role.getEntitlements().add(StandardEntitlement.USER_CREATE);
+            role.getEntitlements().add(StandardEntitlement.USER_UPDATE);
+            role.getEntitlements().add(StandardEntitlement.USER_DELETE);
+            role.getEntitlements().add(StandardEntitlement.USER_LIST);
+            role.getEntitlements().add(StandardEntitlement.USER_READ);
+            role.getRealms().add("/even/two");
+
+            roleKey = roleService.create(role).getHeaderString(RESTHeaders.RESOURCE_KEY);
+            assertNotNull(roleKey);
+
+            // 2. as admin, create delegated admin user, and assign the role just created
+            UserTO delegatedAdmin = UserITCase.getUniqueSampleTO("admin@syncope.apache.org");
+            delegatedAdmin.getRoles().add(roleKey);
+            delegatedAdmin = createUser(delegatedAdmin).getAny();
+            delegatedAdminKey = delegatedAdmin.getKey();
+
+            // 3. instantiate a delegate user service client, for further operatins
+            UserService delegatedUserService =
+                    clientFactory.create(delegatedAdmin.getUsername(), "password123").getService(UserService.class);
+
+            // 4. as delegated, create user under realm / -> fail
+            UserTO user = UserITCase.getUniqueSampleTO("delegated@syncope.apache.org");
+            try {
+                delegatedUserService.create(user);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+            }
+
+            // 5. set realm to /even/two -> succeed
+            user.setRealm("/even/two");
+
+            Response response = delegatedUserService.create(user);
+            assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+
+            user = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+            }).getAny();
+            assertEquals("surname", user.getPlainAttrMap().get("surname").getValues().get(0));
+
+            // 5. as delegated, update user attempting to move under realm / -> fail
+            UserPatch userPatch = new UserPatch();
+            userPatch.setKey(user.getKey());
+            userPatch.setRealm(new StringReplacePatchItem.Builder().value("/odd").build());
+            userPatch.getPlainAttrs().add(attrAddReplacePatch("surname", "surname2"));
+
+            try {
+                delegatedUserService.update(userPatch);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+            }
+
+            // 6. revert realm change -> succeed
+            userPatch.setRealm(null);
+
+            response = delegatedUserService.update(userPatch);
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+            user = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+            }).getAny();
+            assertEquals("surname2", user.getPlainAttrMap().get("surname").getValues().get(0));
+
+            // 7. as delegated, delete user
+            delegatedUserService.delete(user.getKey());
+
+            try {
+                userService.read(user.getKey());
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.NotFound, e.getType());
+            }
+        } finally {
+            if (roleKey != null) {
+                roleService.delete(roleKey);
+            }
+            if (delegatedAdminKey != null) {
+                userService.delete(delegatedAdminKey);
+            }
+        }
+    }
+
+    @Test
+    public void checkFailedLogins() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("checkFailedLogin@syncope.apache.org");
+        userTO.getRoles().add("User manager");
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        long userId = userTO.getKey();
+
+        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(UserService.class);
+        assertEquals(0, getFailedLogins(userService2, userId));
+
+        // authentications failed ...
+        SyncopeClient badPwdClient = clientFactory.create(userTO.getUsername(), "wrongpwd1");
+        assertReadFails(badPwdClient);
+        assertReadFails(badPwdClient);
+
+        assertEquals(2, getFailedLogins(userService, userId));
+
+        UserService userService4 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(UserService.class);
+        assertEquals(0, getFailedLogins(userService4, userId));
+    }
+
+    @Test
+    public void checkUserSuspension() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("checkSuspension@syncope.apache.org");
+        userTO.setRealm("/odd");
+        userTO.getRoles().add("User manager");
+
+        userTO = createUser(userTO).getAny();
+        long userKey = userTO.getKey();
+        assertNotNull(userTO);
+
+        assertEquals(0, getFailedLogins(userService, userKey));
+
+        // authentications failed ...
+        SyncopeClient badPwdClient = clientFactory.create(userTO.getUsername(), "wrongpwd1");
+        assertReadFails(badPwdClient);
+        assertReadFails(badPwdClient);
+        assertReadFails(badPwdClient);
+
+        assertEquals(3, getFailedLogins(userService, userKey));
+
+        // last authentication before suspension
+        assertReadFails(badPwdClient);
+
+        userTO = userService.read(userTO.getKey());
+        assertNotNull(userTO);
+        assertNotNull(userTO.getFailedLogins());
+        assertEquals(3, userTO.getFailedLogins(), 0);
+        assertEquals("suspended", userTO.getStatus());
+
+        // Access with correct credentials should fail as user is suspended
+        SyncopeClient goodPwdClient = clientFactory.create(userTO.getUsername(), "password123");
+        assertReadFails(goodPwdClient);
+
+        StatusPatch reactivate = new StatusPatch();
+        reactivate.setKey(userTO.getKey());
+        reactivate.setType(StatusPatchType.REACTIVATE);
+        userTO = userService.status(reactivate).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+
+        assertEquals(0, goodPwdClient.self().getValue().getFailedLogins(), 0);
+    }
+
+    @Test
+    public void anyTypeEntitlement() {
+        final String anyTypeKey = "FOLDER " + getUUIDString();
+
+        // 1. no entitlement exists (yet) for the any type to be created
+        assertFalse(IterableUtils.matchesAny(syncopeService.info().getEntitlements(), new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String entitlement) {
+                return entitlement.contains(anyTypeKey);
+            }
+        }));
+
+        // 2. create plain schema, any type class and any type
+        PlainSchemaTO path = new PlainSchemaTO();
+        path.setKey("path" + getUUIDString());
+        path.setType(AttrSchemaType.String);
+        path = createSchema(SchemaType.PLAIN, path);
+
+        AnyTypeClassTO anyTypeClass = new AnyTypeClassTO();
+        anyTypeClass.setKey("folder" + getUUIDString());
+        anyTypeClass.getPlainSchemas().add(path.getKey());
+        anyTypeClassService.create(anyTypeClass);
+
+        AnyTypeTO anyTypeTO = new AnyTypeTO();
+        anyTypeTO.setKey(anyTypeKey);
+        anyTypeTO.setKind(AnyTypeKind.ANY_OBJECT);
+        anyTypeTO.getClasses().add(anyTypeClass.getKey());
+        anyTypeService.create(anyTypeTO);
+
+        // 2. now entitlement exists for the any type just created
+        assertTrue(IterableUtils.matchesAny(syncopeService.info().getEntitlements(), new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String entitlement) {
+                return entitlement.contains(anyTypeKey);
+            }
+        }));
+
+        // 3. attempt to create an instance of the type above: fail because no entitlement was assigned
+        AnyObjectTO folder = new AnyObjectTO();
+        folder.setRealm(SyncopeConstants.ROOT_REALM);
+        folder.setType(anyTypeKey);
+        folder.getPlainAttrs().add(attrTO(path.getKey(), "/home"));
+
+        SyncopeClient belliniClient = clientFactory.create("bellini", ADMIN_PWD);
+        try {
+            belliniClient.getService(AnyObjectService.class).create(folder);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+        }
+
+        // 4. give create entitlement for the any type just created
+        RoleTO role = new RoleTO();
+        role.setKey("role" + getUUIDString());
+        role.getRealms().add(SyncopeConstants.ROOT_REALM);
+        role.getEntitlements().add(anyTypeKey + "_READ");
+        role.getEntitlements().add(anyTypeKey + "_CREATE");
+        role = createRole(role);
+
+        UserTO bellini = readUser("bellini");
+        UserPatch patch = new UserPatch();
+        patch.setKey(bellini.getKey());
+        patch.getRoles().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(role.getKey()).build());
+        bellini = updateUser(patch).getAny();
+        assertTrue(bellini.getRoles().contains(role.getKey()));
+
+        // 5. now the instance of the type above can be created successfully
+        belliniClient.getService(AnyObjectService.class).create(folder);
+    }
+
+    @Test
+    public void issueSYNCOPE434() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // 1. create user with group 9 (users with group 9 are defined in workflow as subject to approval)
+        UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
+        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals("createApproval", userTO.getStatus());
+
+        // 2. try to authenticate: fail
+        try {
+            clientFactory.create(userTO.getUsername(), "password123").self();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        // 3. approve user
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        form = userWorkflowService.claimForm(form.getTaskId());
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        props.get("approve").setValue(Boolean.TRUE.toString());
+        form.getProperties().clear();
+        form.getProperties().addAll(props.values());
+        userTO = userWorkflowService.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+
+        // 4. try to authenticate again: success
+        Pair<Map<String, Set<String>>, UserTO> self =
+                clientFactory.create(userTO.getUsername(), "password123").self();
+        assertNotNull(self);
+        assertNotNull(self.getKey());
+        assertNotNull(self.getValue());
+    }
+
+    @Test
+    public void issueSYNCOPE164() throws Exception {
+        // 1. create user with db resource
+        UserTO user = UserITCase.getUniqueSampleTO("syncope164@syncope.apache.org");
+        user.setRealm("/even/two");
+        user.setPassword("password123");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        user = createUser(user).getAny();
+        assertNotNull(user);
+
+        // 2. unlink the resource from the created user
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(user.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+        deassociationPatch.getResources().add(RESOURCE_NAME_TESTDB);
+        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        // 3. change password on Syncope
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(user.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("password234").build());
+        user = updateUser(userPatch).getAny();
+        assertNotNull(user);
+
+        // 4. check that the db resource has still the initial password value
+        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        String value = jdbcTemplate.queryForObject(
+                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+        assertEquals(Encryptor.getInstance().encode("password123", CipherAlgorithm.SHA1), value.toUpperCase());
+
+        // 5. successfully authenticate with old (on db resource) and new (on internal storage) password values
+        Pair<Map<String, Set<String>>, UserTO> self =
+                clientFactory.create(user.getUsername(), "password123").self();
+        assertNotNull(self);
+        self = clientFactory.create(user.getUsername(), "password234").self();
+        assertNotNull(self);
+    }
+
+    @Test
+    public void issueSYNCOPE706() {
+        String username = getUUIDString();
+        try {
+            userService.getUserKey(username);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+
+        try {
+            clientFactory.create(username, "anypassword").self();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/CamelRouteITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/CamelRouteITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/CamelRouteITCase.java
new file mode 100644
index 0000000..20c290f
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/CamelRouteITCase.java
@@ -0,0 +1,178 @@
+/*
+ * 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.fit.core;
+
+import org.apache.syncope.fit.CamelDetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.CamelRouteTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class CamelRouteITCase extends AbstractITCase {
+
+    @Test
+    public void userRoutes() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
+
+        List<CamelRouteTO> userRoutes = camelRouteService.list(AnyTypeKind.USER);
+        assertNotNull(userRoutes);
+        assertEquals(16, userRoutes.size());
+        for (CamelRouteTO route : userRoutes) {
+            assertNotNull(route.getContent());
+        }
+    }
+
+    @Test
+    public void groupRoutes() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForGroups(syncopeService));
+
+        List<CamelRouteTO> groupRoutes = camelRouteService.list(AnyTypeKind.GROUP);
+        assertNotNull(groupRoutes);
+        assertEquals(8, groupRoutes.size());
+        for (CamelRouteTO route : groupRoutes) {
+            assertNotNull(route.getContent());
+        }
+    }
+
+    private CamelRouteTO doUpdate(final String key, final String content) {
+        CamelRouteTO route = camelRouteService.read(key);
+        route.setContent(content);
+        camelRouteService.update(route);
+        // getting new route definition
+        return camelRouteService.read(key);
+    }
+
+    @Test
+    public void update() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
+
+        CamelRouteTO oldRoute = camelRouteService.read("createUser");
+        assertNotNull(oldRoute);
+        String routeContent = "<route id=\"createUser\">\n"
+                + "  <from uri=\"direct:createUser\"/>\n"
+                + "  <setProperty propertyName=\"actual\">\n"
+                + "    <simple>${body}</simple>\n"
+                + "  </setProperty>\n"
+                + "  <doTry>\n"
+                + "    <bean ref=\"uwfAdapter\" method=\"create(${body},${property.disablePwdPolicyCheck},\n"
+                + "                             ${property.enabled},${property.storePassword})\"/>\n"
+                + "    <process ref=\"userCreateProcessor\" />\n"
+                + "    <to uri=\"direct:createPort\"/>\n"
+                + "    <to uri=\"log:myLog\"/>\n"
+                + "    <doCatch>        \n"
+                + "      <exception>java.lang.RuntimeException</exception>\n"
+                + "      <handled>\n"
+                + "        <constant>false</constant>\n"
+                + "      </handled>\n"
+                + "      <to uri=\"direct:createPort\"/>\n"
+                + "    </doCatch>\n"
+                + "  </doTry>\n"
+                + "</route>";
+        try {
+            CamelRouteTO route = doUpdate("createUser", routeContent);
+            assertEquals(routeContent, route.getContent());
+        } finally {
+            doUpdate(oldRoute.getKey(), oldRoute.getContent());
+        }
+    }
+
+    @Test
+    public void scriptingUpdate() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
+
+        CamelRouteTO oldRoute = camelRouteService.read("createUser");
+        // updating route content including new attribute management
+
+        String routeContent = ""
+                + "  <route id=\"createUser\">\n"
+                + "    <from uri=\"direct:createUser\"/>\n"
+                + "    <setProperty propertyName=\"actual\">\n"
+                + "      <simple>${body}</simple>\n"
+                + "    </setProperty>\n"
+                + "    <setBody>\n"
+                + "     <groovy>\n"
+                + "       org.apache.commons.collections4."
+                + "CollectionUtils.get(request.body.getPlainAttrs(), 3).getValues().set(0,\"true\")\n"
+                + "       return request.body\n"
+                + "     </groovy>\n"
+                + "    </setBody>\n"
+                + "    <doTry>\n"
+                + "      <bean ref=\"uwfAdapter\" method=\"create(${body},${property.disablePwdPolicyCheck},\n"
+                + "                                     ${property.enabled},${property.storePassword})\"/>\n"
+                + "      <process ref=\"userCreateProcessor\"/>\n"
+                + "      <to uri=\"direct:createPort\"/>\n"
+                + "      <doCatch>        \n"
+                + "        <exception>java.lang.RuntimeException</exception>\n"
+                + "        <handled>\n"
+                + "          <constant>false</constant>\n"
+                + "        </handled>\n"
+                + "        <to uri=\"direct:createPort\"/>\n"
+                + "      </doCatch>\n"
+                + "    </doTry>\n"
+                + "  </route> ";
+        try {
+            doUpdate("createUser", routeContent);
+
+            // creating new schema attribute for user
+            PlainSchemaTO schemaTO = new PlainSchemaTO();
+            schemaTO.setKey("camelAttribute");
+            schemaTO.setType(AttrSchemaType.String);
+            createSchema(SchemaType.PLAIN, schemaTO);
+
+            AnyTypeClassTO typeClass = new AnyTypeClassTO();
+            typeClass.setKey("camelAttribute");
+            typeClass.getPlainSchemas().add(schemaTO.getKey());
+            anyTypeClassService.create(typeClass);
+
+            UserTO userTO = new UserTO();
+            userTO.setRealm(SyncopeConstants.ROOT_REALM);
+            userTO.getAuxClasses().add(typeClass.getKey());
+            String userId = getUUIDString() + "camelUser@syncope.apache.org";
+            userTO.setUsername(userId);
+            userTO.setPassword("password123");
+            userTO.getPlainAttrs().add(attrTO("userId", userId));
+            userTO.getPlainAttrs().add(attrTO("fullname", userId));
+            userTO.getPlainAttrs().add(attrTO("surname", userId));
+            userTO.getPlainAttrs().add(attrTO("camelAttribute", "false"));
+
+            userTO = createUser(userTO).getAny();
+            assertNotNull(userTO);
+            assertEquals("true", IterableUtils.get(userTO.getPlainAttrs(), 3).getValues().get(0));
+        } finally {
+            doUpdate(oldRoute.getKey(), oldRoute.getContent());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConfigurationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConfigurationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConfigurationITCase.java
new file mode 100644
index 0000000..574c147
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConfigurationITCase.java
@@ -0,0 +1,173 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ConfigurationITCase extends AbstractITCase {
+
+    @Test
+    public void create() {
+        PlainSchemaTO testKey = new PlainSchemaTO();
+        testKey.setKey("testKey" + getUUIDString());
+        testKey.setType(AttrSchemaType.String);
+        createSchema(SchemaType.PLAIN, testKey);
+
+        AttrTO conf = new AttrTO.Builder().schema(testKey.getKey()).value("testValue").build();
+
+        configurationService.set(conf);
+
+        AttrTO actual = configurationService.get(conf.getSchema());
+        assertEquals(actual, conf);
+    }
+
+    @Test
+    public void createRequired() {
+        PlainSchemaTO testKey = new PlainSchemaTO();
+        testKey.setKey("testKey" + getUUIDString());
+        testKey.setType(AttrSchemaType.String);
+        testKey.setMandatoryCondition("true");
+        createSchema(SchemaType.PLAIN, testKey);
+
+        AttrTO conf = new AttrTO.Builder().schema(testKey.getKey()).build();
+        try {
+            configurationService.set(conf);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+
+        conf.getValues().add("testValue");
+        configurationService.set(conf);
+
+        AttrTO actual = configurationService.get(conf.getSchema());
+        assertEquals(actual, conf);
+    }
+
+    @Test
+    public void delete() throws UnsupportedEncodingException {
+        try {
+            configurationService.delete("nonExistent");
+            fail("The delete operation should throw an exception because of nonExistent schema");
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        AttrTO tokenLength = configurationService.get("token.length");
+
+        configurationService.delete("token.length");
+
+        AttrTO actual = configurationService.get(tokenLength.getSchema());
+        assertNotEquals(actual, tokenLength);
+
+        configurationService.set(tokenLength);
+
+        actual = configurationService.get(tokenLength.getSchema());
+        assertEquals(actual, tokenLength);
+    }
+
+    @Test
+    public void list() {
+        List<AttrTO> wholeConf = configurationService.list();
+        assertNotNull(wholeConf);
+        for (AttrTO conf : wholeConf) {
+            assertNotNull(conf);
+        }
+    }
+
+    @Test
+    public void read() {
+        AttrTO conf = configurationService.get("token.expireTime");
+        assertNotNull(conf);
+    }
+
+    @Test
+    public void update() {
+        AttrTO expireTime = configurationService.get("token.expireTime");
+        int value = Integer.parseInt(expireTime.getValues().get(0));
+        value++;
+        expireTime.getValues().set(0, value + "");
+
+        configurationService.set(expireTime);
+
+        AttrTO newConfigurationTO = configurationService.get(expireTime.getSchema());
+        assertEquals(expireTime, newConfigurationTO);
+    }
+
+    @Test
+    public void dbExport() throws IOException {
+        Response response = configurationService.export();
+        assertNotNull(response);
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+        assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
+        String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+        assertNotNull(contentDisposition);
+
+        Object entity = response.getEntity();
+        assertTrue(entity instanceof InputStream);
+        String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
+        assertFalse(configExport.isEmpty());
+        assertTrue(configExport.length() > 1000);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        PlainSchemaTO failing = new PlainSchemaTO();
+        failing.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+        failing.setType(AttrSchemaType.String);
+
+        try {
+            createSchema(SchemaType.PLAIN, failing);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+            assertNotNull(e.getElements());
+            assertEquals(1, e.getElements().size());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+}


[18/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
new file mode 100644
index 0000000..1d30916
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
@@ -0,0 +1,747 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.BulkAction;
+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.ConnPoolConfTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ConnectorITCase extends AbstractITCase {
+
+    private static String connectorServerLocation;
+
+    private static String connidSoapVersion;
+
+    private static String connidDbTableVersion;
+
+    private static String testJDBCURL;
+
+    @BeforeClass
+    public static void setUpConnIdBundles() throws IOException {
+        InputStream propStream = null;
+        try {
+            Properties props = new Properties();
+            propStream = ConnectorITCase.class.getResourceAsStream("/connid.properties");
+            props.load(propStream);
+
+            for (String location : props.getProperty("connid.locations").split(",")) {
+                if (!location.startsWith("file")) {
+                    connectorServerLocation = location;
+                }
+            }
+
+            connidSoapVersion = props.getProperty("connid.soap.version");
+            connidDbTableVersion = props.getProperty("connid.database.version");
+
+            testJDBCURL = props.getProperty("testdb.url");
+        } catch (Exception e) {
+            LOG.error("Could not load /connid.properties", e);
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+        assertNotNull(connectorServerLocation);
+        assertNotNull(connidSoapVersion);
+        assertNotNull(connidDbTableVersion);
+        assertNotNull(testJDBCURL);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithException() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        Response response = connectorService.create(connectorTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+    }
+
+    @Test
+    public void create() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+        connectorTO.setLocation(connectorService.read(100L, Locale.ENGLISH.getLanguage()).getLocation());
+        connectorTO.setVersion(connidSoapVersion);
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+        connectorTO.setDisplayName("Display name");
+        connectorTO.setConnRequestTimeout(15);
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<>();
+
+        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+        endpointSchema.setName("endpoint");
+        endpointSchema.setType(String.class.getName());
+        endpointSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(endpointSchema);
+        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        endpoint.getValues().add("Provisioning");
+        conf.add(endpoint);
+
+        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+        servicenameSchema.setName("servicename");
+        servicenameSchema.setType(String.class.getName());
+        servicenameSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(servicenameSchema);
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConf().addAll(conf);
+
+        // set connector capabilities
+        connectorTO.getCapabilities().add(ConnectorCapability.CREATE);
+        connectorTO.getCapabilities().add(ConnectorCapability.UPDATE);
+
+        // set connector pool conf
+        ConnPoolConfTO cpc = new ConnPoolConfTO();
+        cpc.setMaxObjects(1534);
+        connectorTO.setPoolConf(cpc);
+
+        Response response = connectorService.create(connectorTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+
+        ConnInstanceTO actual = getObject(
+                response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+        assertNotNull(actual);
+
+        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+        assertEquals(actual.getVersion(), connectorTO.getVersion());
+        assertEquals("Display name", actual.getDisplayName());
+        assertEquals(Integer.valueOf(15), actual.getConnRequestTimeout());
+        assertEquals(connectorTO.getCapabilities(), actual.getCapabilities());
+        assertNotNull(actual.getPoolConf());
+        assertEquals(1534, actual.getPoolConf().getMaxObjects(), 0);
+        assertEquals(10, actual.getPoolConf().getMaxIdle(), 0);
+
+        Throwable t = null;
+
+        // check update
+        actual.getCapabilities().remove(ConnectorCapability.UPDATE);
+        actual.getPoolConf().setMaxObjects(null);
+
+        try {
+            connectorService.update(actual);
+            actual = connectorService.read(actual.getKey(), Locale.ENGLISH.getLanguage());
+        } catch (SyncopeClientException e) {
+            LOG.error("update failed", e);
+            t = e;
+        }
+
+        assertNull(t);
+        assertNotNull(actual);
+        assertEquals(EnumSet.of(ConnectorCapability.CREATE), actual.getCapabilities());
+        assertEquals(10, actual.getPoolConf().getMaxObjects(), 0);
+
+        // check also for the deletion of the created object
+        try {
+            connectorService.delete(actual.getKey());
+        } catch (SyncopeClientException e) {
+            LOG.error("delete failed", e);
+            t = e;
+        }
+
+        assertNull(t);
+
+        // check the non existence
+        try {
+            connectorService.read(actual.getKey(), Locale.ENGLISH.getLanguage());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void update() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        // set connector instance id
+        connectorTO.setKey(103L);
+
+        // set connector version
+        connectorTO.setVersion(connidSoapVersion);
+
+        // set connector name
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+        // set bundle name
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+        connectorTO.setConnRequestTimeout(20);
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<>();
+
+        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+        endpointSchema.setName("endpoint");
+        endpointSchema.setType(String.class.getName());
+        endpointSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(endpointSchema);
+        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        conf.add(endpoint);
+
+        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+        servicenameSchema.setName("servicename");
+        servicenameSchema.setType(String.class.getName());
+        servicenameSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(servicenameSchema);
+        servicename.getValues().add("Provisioning");
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConf().addAll(conf);
+
+        connectorService.update(connectorTO);
+        ConnInstanceTO actual = connectorService.read(connectorTO.getKey(), Locale.ENGLISH.getLanguage());
+
+        assertNotNull(actual);
+
+        actual = connectorService.read(actual.getKey(), Locale.ENGLISH.getLanguage());
+
+        assertNotNull(actual);
+        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+        assertEquals(actual.getVersion(), connectorTO.getVersion());
+        assertEquals(Integer.valueOf(20), actual.getConnRequestTimeout());
+    }
+
+    private List<ResourceTO> filter(final List<ResourceTO> input, final Long connectorKey) {
+        List<ResourceTO> result = new ArrayList<>();
+
+        for (ResourceTO resource : input) {
+            if (connectorKey.equals(resource.getConnector())) {
+                result.add(resource);
+            }
+        }
+
+        return result;
+    }
+
+    @Test
+    public void issueSYNCOPE10() {
+        // ----------------------------------
+        // Copy resource and connector in order to create new objects.
+        // ----------------------------------
+        // Retrieve a connector instance template.
+        ConnInstanceTO connInstanceTO = connectorService.read(103L, Locale.ENGLISH.getLanguage());
+        assertNotNull(connInstanceTO);
+
+        // check for resource
+        List<ResourceTO> resources = filter(resourceService.list(), 103L);
+        assertEquals(4, resources.size());
+
+        // Retrieve a resource TO template.
+        ResourceTO resourceTO = resources.get(0);
+
+        // Make it new.
+        resourceTO.setKey("newAbout103" + getUUIDString());
+
+        // Make it new.
+        connInstanceTO.setKey(0L);
+        connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
+        // ----------------------------------
+
+        // ----------------------------------
+        // Create a new connector instance.
+        // ----------------------------------
+        Response response = connectorService.create(connInstanceTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+
+        connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+        assertNotNull(connInstanceTO);
+        assertFalse(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+        long connId = connInstanceTO.getKey();
+
+        // Link resourceTO to the new connector instance.
+        resourceTO.setConnector(connId);
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for connector instance update after resource creation.
+        // ----------------------------------
+        response = resourceService.create(resourceTO);
+        resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+        assertNotNull(resourceTO);
+
+        resources = filter(resourceService.list(), connId);
+        assertEquals(1, resources.size());
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for spring bean.
+        // ----------------------------------
+        ConnInstanceTO connInstanceBean = connectorService.readByResource(
+                resourceTO.getKey(), Locale.ENGLISH.getLanguage());
+        assertNotNull(connInstanceBean);
+        assertFalse(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for spring bean update after connector instance update.
+        // ----------------------------------
+        connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE);
+
+        connectorService.update(connInstanceTO);
+        ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey(), Locale.ENGLISH.getLanguage());
+        assertNotNull(actual);
+        assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+        // check for spring bean update
+        connInstanceBean = connectorService.readByResource(resourceTO.getKey(), Locale.ENGLISH.getLanguage());
+        assertTrue(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+        // ----------------------------------
+    }
+
+    @Test
+    public void deleteWithException() {
+        try {
+            connectorService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list(null);
+        assertNotNull(connectorInstanceTOs);
+        assertFalse(connectorInstanceTOs.isEmpty());
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void read() {
+        ConnInstanceTO connectorInstanceTO = connectorService.read(100L, Locale.ENGLISH.getLanguage());
+        assertNotNull(connectorInstanceTO);
+    }
+
+    @Test
+    public void getBundles() {
+        List<ConnBundleTO> bundles = connectorService.getBundles(Locale.ENGLISH.getLanguage());
+        assertNotNull(bundles);
+        assertFalse(bundles.isEmpty());
+        for (ConnBundleTO bundle : bundles) {
+            assertNotNull(bundle);
+        }
+    }
+
+    @Test
+    public void getConnectorConfiguration() {
+        Set<ConnConfProperty> props = connectorService.read(104L, Locale.ENGLISH.getLanguage()).getConf();
+        assertNotNull(props);
+        assertFalse(props.isEmpty());
+    }
+
+    @Test
+    public void checkHiddenProperty() {
+        ConnInstanceTO connInstanceTO = connectorService.read(100L, Locale.ENGLISH.getLanguage());
+
+        boolean check = false;
+
+        for (ConnConfProperty prop : connInstanceTO.getConf()) {
+            if ("receiveTimeout".equals(prop.getSchema().getName())) {
+                check = true;
+            }
+        }
+        assertTrue(check);
+    }
+
+    @Test
+    public void checkSelectedLanguage() {
+        // 1. Check Italian
+        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list("it");
+
+        Map<String, ConnConfProperty> instanceConfMap;
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+                instanceConfMap = instance.getConfMap();
+                assertEquals("Utente", instanceConfMap.get("user").getSchema().getDisplayName());
+            }
+        }
+
+        // 2. Check English (default)
+        connectorInstanceTOs = connectorService.list(null);
+
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+                instanceConfMap = instance.getConfMap();
+                assertEquals("User", instanceConfMap.get("user").getSchema().getDisplayName());
+            }
+        }
+    }
+
+    @Test
+    public void validate() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+        connectorTO.setLocation(connectorServerLocation);
+        connectorTO.setVersion(connidDbTableVersion);
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.db.table.DatabaseTableConnector");
+        connectorTO.setBundleName("net.tirasa.connid.bundles.db.table");
+        connectorTO.setDisplayName("H2Test");
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<>();
+
+        ConnConfPropSchema jdbcDriverSchema = new ConnConfPropSchema();
+        jdbcDriverSchema.setName("jdbcDriver");
+        jdbcDriverSchema.setType(String.class.getName());
+        jdbcDriverSchema.setRequired(true);
+        ConnConfProperty jdbcDriver = new ConnConfProperty();
+        jdbcDriver.setSchema(jdbcDriverSchema);
+        jdbcDriver.getValues().add("org.h2.Driver");
+        conf.add(jdbcDriver);
+
+        ConnConfPropSchema jdbcUrlTemplateSchema = new ConnConfPropSchema();
+        jdbcUrlTemplateSchema.setName("jdbcUrlTemplate");
+        jdbcUrlTemplateSchema.setType(String.class.getName());
+        jdbcUrlTemplateSchema.setRequired(true);
+        ConnConfProperty jdbcUrlTemplate = new ConnConfProperty();
+        jdbcUrlTemplate.setSchema(jdbcUrlTemplateSchema);
+        jdbcUrlTemplate.getValues().add(testJDBCURL);
+        conf.add(jdbcUrlTemplate);
+
+        ConnConfPropSchema userSchema = new ConnConfPropSchema();
+        userSchema.setName("user");
+        userSchema.setType(String.class.getName());
+        userSchema.setRequired(false);
+        ConnConfProperty user = new ConnConfProperty();
+        user.setSchema(userSchema);
+        user.getValues().add("sa");
+        conf.add(user);
+
+        ConnConfPropSchema passwordSchema = new ConnConfPropSchema();
+        passwordSchema.setName("password");
+        passwordSchema.setType(GuardedString.class.getName());
+        passwordSchema.setRequired(true);
+        ConnConfProperty password = new ConnConfProperty();
+        password.setSchema(passwordSchema);
+        password.getValues().add("sa");
+        conf.add(password);
+
+        ConnConfPropSchema tableSchema = new ConnConfPropSchema();
+        tableSchema.setName("table");
+        tableSchema.setType(String.class.getName());
+        tableSchema.setRequired(true);
+        ConnConfProperty table = new ConnConfProperty();
+        table.setSchema(tableSchema);
+        table.getValues().add("test");
+        conf.add(table);
+
+        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+        keyColumnSchema.setName("keyColumn");
+        keyColumnSchema.setType(String.class.getName());
+        keyColumnSchema.setRequired(true);
+        ConnConfProperty keyColumn = new ConnConfProperty();
+        keyColumn.setSchema(keyColumnSchema);
+        keyColumn.getValues().add("id");
+        conf.add(keyColumn);
+
+        ConnConfPropSchema passwordColumnSchema = new ConnConfPropSchema();
+        passwordColumnSchema.setName("passwordColumn");
+        passwordColumnSchema.setType(String.class.getName());
+        passwordColumnSchema.setRequired(true);
+        ConnConfProperty passwordColumn = new ConnConfProperty();
+        passwordColumn.setSchema(passwordColumnSchema);
+        passwordColumn.getValues().add("password");
+        conf.add(passwordColumn);
+
+        // set connector configuration
+        connectorTO.getConf().addAll(conf);
+
+        try {
+            connectorService.check(connectorTO);
+        } catch (Exception e) {
+            fail(ExceptionUtils.getStackTrace(e));
+        }
+
+        conf.remove(password);
+        password.getValues().clear();
+        password.getValues().add("password");
+        conf.add(password);
+
+        try {
+            connectorService.check(connectorTO);
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void buildObjectClassInfo() {
+        ConnInstanceTO ws = connectorService.read(102L, Locale.ENGLISH.getLanguage());
+        assertNotNull(ws);
+
+        List<ConnIdObjectClassTO> objectClassInfo = connectorService.buildObjectClassInfo(ws, true);
+        assertNotNull(objectClassInfo);
+        assertEquals(1, objectClassInfo.size());
+        assertEquals(ObjectClass.ACCOUNT_NAME, objectClassInfo.get(0).getType());
+        assertTrue(objectClassInfo.get(0).getAttributes().contains("promoThirdPartyDisclaimer"));
+
+        ConnInstanceTO ldap = connectorService.read(105L, Locale.ENGLISH.getLanguage());
+        assertNotNull(ldap);
+
+        objectClassInfo = connectorService.buildObjectClassInfo(ldap, true);
+        assertNotNull(objectClassInfo);
+        assertEquals(2, objectClassInfo.size());
+
+        Collection<String> objectClasses = CollectionUtils.collect(objectClassInfo,
+                new Transformer<ConnIdObjectClassTO, String>() {
+
+                    @Override
+                    public String transform(final ConnIdObjectClassTO info) {
+                        return info.getType();
+                    }
+
+                });
+        assertEquals(2, objectClasses.size());
+        assertTrue(objectClasses.contains(ObjectClass.ACCOUNT_NAME));
+        assertTrue(objectClasses.contains(ObjectClass.GROUP_NAME));
+    }
+
+    @Test
+    public void issueSYNCOPE112() {
+        // ----------------------------------------
+        // Create a new connector
+        // ----------------------------------------
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        connectorTO.setLocation(connectorService.read(100L, Locale.ENGLISH.getLanguage()).getLocation());
+
+        // set connector version
+        connectorTO.setVersion(connidSoapVersion);
+
+        // set connector name
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+        // set bundle name
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+        // set display name
+        connectorTO.setDisplayName("WSSoap");
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<>();
+
+        ConnConfPropSchema userSchema = new ConnConfPropSchema();
+        userSchema.setName("endpoint");
+        userSchema.setType(String.class.getName());
+        userSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(userSchema);
+        endpoint.getValues().add("http://localhost:9080/does_not_work");
+        endpoint.setOverridable(true);
+
+        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+        keyColumnSchema.setName("servicename");
+        keyColumnSchema.setType(String.class.getName());
+        keyColumnSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(keyColumnSchema);
+        servicename.getValues().add("net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning");
+        servicename.setOverridable(false);
+
+        conf.add(endpoint);
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConf().addAll(conf);
+
+        try {
+            try {
+                connectorService.check(connectorTO);
+                fail();
+            } catch (Exception e) {
+                assertNotNull(e);
+            }
+
+            Response response = connectorService.create(connectorTO);
+            if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+                throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+            }
+
+            connectorTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+            assertNotNull(connectorTO);
+            // ----------------------------------------
+
+            // ----------------------------------------
+            // create a resourceTO
+            // ----------------------------------------
+            String resourceName = "checkForPropOverriding";
+            ResourceTO resourceTO = new ResourceTO();
+
+            resourceTO.setKey(resourceName);
+            resourceTO.setConnector(connectorTO.getKey());
+
+            conf = new HashSet<>();
+            endpoint.getValues().clear();
+            endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning");
+            conf.add(endpoint);
+
+            resourceTO.getConfOverride().addAll(conf);
+
+            ProvisionTO provisionTO = new ProvisionTO();
+            provisionTO.setAnyType(AnyTypeKind.USER.name());
+            provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+            resourceTO.getProvisions().add(provisionTO);
+
+            MappingTO mapping = new MappingTO();
+            provisionTO.setMapping(mapping);
+
+            MappingItemTO mapItem = new MappingItemTO();
+            mapItem.setExtAttrName("uid");
+            mapItem.setIntAttrName("userId");
+            mapItem.setIntMappingType(IntMappingType.UserPlainSchema);
+            mapItem.setConnObjectKey(true);
+            mapping.setConnObjectKeyItem(mapItem);
+            // ----------------------------------------
+
+            // ----------------------------------------
+            // Check connection without saving the resource ....
+            // ----------------------------------------
+            try {
+                resourceService.check(resourceTO);
+            } catch (Exception e) {
+                fail(ExceptionUtils.getStackTrace(e));
+            }
+            // ----------------------------------------
+        } finally {
+            // Remove connector from db to make test re-runnable
+            connectorService.delete(connectorTO.getKey());
+        }
+    }
+
+    @Test
+    public void reload() {
+        connectorService.reload();
+    }
+
+    @Test
+    public void bulkAction() {
+        BulkAction bulkAction = new BulkAction();
+        bulkAction.setType(BulkAction.Type.DELETE);
+
+        ConnInstanceTO conn = connectorService.read(101L, Locale.ENGLISH.getLanguage());
+
+        conn.setKey(0L);
+        conn.setDisplayName("forBulk1");
+
+        bulkAction.getTargets().add(String.valueOf(getObject(
+                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+        conn.setDisplayName("forBulk2");
+
+        bulkAction.getTargets().add(String.valueOf(getObject(
+                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+        Iterator<String> iter = bulkAction.getTargets().iterator();
+
+        assertNotNull(connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage()));
+        assertNotNull(connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage()));
+
+        connectorService.bulk(bulkAction);
+
+        iter = bulkAction.getTargets().iterator();
+
+        try {
+            connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+
+        try {
+            connectorService.read(Long.valueOf(iter.next()), Locale.ENGLISH.getLanguage());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE605() {
+        ConnInstanceTO connectorInstanceTO = connectorService.read(103L, Locale.ENGLISH.getLanguage());
+        assertTrue(connectorInstanceTO.getCapabilities().isEmpty());
+
+        connectorInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH);
+        connectorService.update(connectorInstanceTO);
+
+        ConnInstanceTO updatedCapabilities = connectorService.read(
+                connectorInstanceTO.getKey(), Locale.ENGLISH.getLanguage());
+        assertNotNull(updatedCapabilities.getCapabilities());
+        assertTrue(updatedCapabilities.getCapabilities().size() == 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DerSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DerSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DerSchemaITCase.java
new file mode 100644
index 0000000..8597974
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DerSchemaITCase.java
@@ -0,0 +1,148 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.beans.SchemaQuery;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class DerSchemaITCase extends AbstractITCase {
+
+    @Test
+    public void list() {
+        List<DerSchemaTO> derSchemas = schemaService.list(new SchemaQuery.Builder().type(SchemaType.DERIVED).build());
+        assertFalse(derSchemas.isEmpty());
+        for (DerSchemaTO derivedSchemaTO : derSchemas) {
+            assertNotNull(derivedSchemaTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        DerSchemaTO derivedSchemaTO = schemaService.read(SchemaType.DERIVED, "cn");
+        assertNotNull(derivedSchemaTO);
+    }
+
+    @Test
+    public void create() {
+        DerSchemaTO schema = new DerSchemaTO();
+        schema.setKey("derived");
+        schema.setExpression("derived_sx + '_' + derived_dx");
+
+        DerSchemaTO actual = createSchema(SchemaType.DERIVED, schema);
+        assertNotNull(actual);
+
+        actual = schemaService.read(SchemaType.DERIVED, actual.getKey());
+        assertNotNull(actual);
+        assertEquals(actual.getExpression(), "derived_sx + '_' + derived_dx");
+    }
+
+    @Test
+    public void delete() {
+        DerSchemaTO schema = schemaService.read(SchemaType.DERIVED, "rderiveddata");
+        assertNotNull(schema);
+
+        schemaService.delete(SchemaType.DERIVED, schema.getKey());
+
+        try {
+            schemaService.read(SchemaType.DERIVED, "rderiveddata");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        } finally {
+            // Recreate schema to make test re-runnable
+            schema = createSchema(SchemaType.DERIVED, schema);
+            assertNotNull(schema);
+        }
+    }
+
+    @Test
+    public void update() {
+        DerSchemaTO schema = schemaService.read(SchemaType.DERIVED, "mderiveddata");
+        assertNotNull(schema);
+        assertEquals("mderived_sx + '-' + mderived_dx", schema.getExpression());
+        try {
+            schema.setExpression("mderived_sx + '.' + mderived_dx");
+
+            schemaService.update(SchemaType.DERIVED, schema);
+
+            schema = schemaService.read(SchemaType.DERIVED, "mderiveddata");
+            assertNotNull(schema);
+            assertEquals("mderived_sx + '.' + mderived_dx", schema.getExpression());
+        } finally {
+            // Set updated back to make test re-runnable
+            schema.setExpression("mderived_sx + '-' + mderived_dx");
+            schemaService.update(SchemaType.DERIVED, schema);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        DerSchemaTO actual = schemaService.read(SchemaType.DERIVED, "rderiveddata");
+        assertNotNull(actual);
+
+        try {
+            createSchema(SchemaType.DERIVED, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createSchema(SchemaType.DERIVED, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        DerSchemaTO schema = new DerSchemaTO();
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+        schema.setExpression("derived_sx + '_' + derived_dx");
+
+        try {
+            createSchema(SchemaType.DERIVED, schema);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidDerSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DomainITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DomainITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DomainITCase.java
new file mode 100644
index 0000000..6b84092
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/DomainITCase.java
@@ -0,0 +1,121 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.List;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DomainTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class DomainITCase extends AbstractITCase {
+
+    @Test
+    public void list() {
+        List<DomainTO> domains = domainService.list();
+        assertNotNull(domains);
+        assertFalse(domains.isEmpty());
+        for (DomainTO domain : domains) {
+            assertNotNull(domain);
+        }
+    }
+
+    @Test
+    public void create() {
+        DomainTO domain = new DomainTO();
+        domain.setKey("last");
+        domain.setAdminCipherAlgorithm(CipherAlgorithm.SSHA512);
+        domain.setAdminPwd("password");
+
+        try {
+            domainService.create(domain);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    private void restoreTwo() {
+        DomainTO two = new DomainTO();
+        two.setKey("Two");
+        two.setAdminCipherAlgorithm(CipherAlgorithm.SHA);
+        two.setAdminPwd("password2");
+        domainService.create(two);
+    }
+
+    @Test
+    public void update() {
+        DomainTO two = domainService.read("Two");
+        assertNotNull(two);
+
+        try {
+            // 1. change admin pwd for domain Two
+            two.setAdminCipherAlgorithm(CipherAlgorithm.AES);
+            two.setAdminPwd("password3");
+            domainService.update(two);
+
+            // 2. attempt to access with old pwd -> fail
+            try {
+                new SyncopeClientFactoryBean().
+                        setAddress(ADDRESS).setDomain("Two").setContentType(clientFactory.getContentType()).
+                        create(ADMIN_UNAME, "password2").self();
+            } catch (AccessControlException e) {
+                assertNotNull(e);
+            }
+
+            // 3. access with new pwd -> succeed
+            new SyncopeClientFactoryBean().
+                    setAddress(ADDRESS).setDomain("Two").setContentType(clientFactory.getContentType()).
+                    create(ADMIN_UNAME, "password3").self();
+        } finally {
+            restoreTwo();
+        }
+    }
+
+    @Test
+    public void delete() {
+        DomainTO two = domainService.read("Two");
+        assertNotNull(two);
+
+        try {
+            domainService.delete(two.getKey());
+
+            try {
+                domainService.read(two.getKey());
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.NotFound, e.getType());
+            }
+        } finally {
+            restoreTwo();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ExceptionMapperITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ExceptionMapperITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ExceptionMapperITCase.java
new file mode 100644
index 0000000..e24941a
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ExceptionMapperITCase.java
@@ -0,0 +1,154 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ExceptionMapperITCase extends AbstractITCase {
+
+    private static final Properties ERROR_MESSAGES = new Properties();
+
+    @BeforeClass
+    public static void setUpErrorMessages() throws IOException {
+        InputStream propStream = null;
+        try {
+            propStream = ExceptionMapperITCase.class.getResourceAsStream("/errorMessages.properties");
+            ERROR_MESSAGES.load(propStream);
+        } catch (Exception e) {
+            LOG.error("Could not load /errorMessages.properties", e);
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+    }
+
+    @Test
+    public void uniqueSchemaConstraint() {
+        // 1. create an user schema with unique constraint
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        String schemaUID = getUUIDString();
+        schemaTO.setKey("unique" + schemaUID);
+        schemaTO.setType(AttrSchemaType.String);
+        schemaTO.setUniqueConstraint(true);
+        createSchema(SchemaType.PLAIN, schemaTO);
+
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("camelAttribute" + getUUIDString());
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
+        // 2. create an user with mandatory attributes and unique
+        UserTO userTO1 = new UserTO();
+        userTO1.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO1.getAuxClasses().add(typeClass.getKey());
+        String userId1 = getUUIDString() + "issue654_1@syncope.apache.org";
+        userTO1.setUsername(userId1);
+        userTO1.setPassword("password123");
+
+        userTO1.getPlainAttrs().add(attrTO("userId", userId1));
+        userTO1.getPlainAttrs().add(attrTO("fullname", userId1));
+        userTO1.getPlainAttrs().add(attrTO("surname", userId1));
+        userTO1.getPlainAttrs().add(attrTO("unique" + schemaUID, "unique" + schemaUID));
+
+        createUser(userTO1);
+
+        // 3. create an other user with mandatory attributes and unique with the same value of userTO1
+        UserTO userTO2 = new UserTO();
+        userTO2.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO2.getAuxClasses().add(typeClass.getKey());
+        String userId2 = getUUIDString() + "issue654_2@syncope.apache.org";
+        userTO2.setUsername(userId2);
+        userTO2.setPassword("password123");
+
+        userTO2.getPlainAttrs().add(attrTO("userId", userId2));
+        userTO2.getPlainAttrs().add(attrTO("fullname", userId2));
+        userTO2.getPlainAttrs().add(attrTO("surname", userId2));
+        userTO2.getPlainAttrs().add(attrTO("unique" + schemaUID, "unique" + schemaUID));
+
+        try {
+            createUser(userTO2);
+            fail();
+        } catch (Exception e) {
+            String message = ERROR_MESSAGES.getProperty("errMessage.UniqueConstraintViolation");
+            assertEquals("EntityExists [" + message + "]", e.getMessage());
+        }
+    }
+
+    @Test
+    public void sameGroupName() {
+        String groupUUID = getUUIDString();
+
+        // Create the first group
+        GroupTO groupTO1 = new GroupTO();
+        groupTO1.setName("child1" + groupUUID);
+        groupTO1.setRealm(SyncopeConstants.ROOT_REALM);
+        createGroup(groupTO1);
+
+        // Create the second group, with the same name of groupTO1
+        GroupTO groupTO2 = new GroupTO();
+        groupTO2.setName("child1" + groupUUID);
+        groupTO2.setRealm(SyncopeConstants.ROOT_REALM);
+        try {
+            createGroup(groupTO2);
+            fail();
+        } catch (Exception e) {
+            String message = ERROR_MESSAGES.getProperty("errMessage.UniqueConstraintViolation");
+            assertEquals(e.getMessage(), "DataIntegrityViolation [" + message + "]");
+        }
+    }
+
+    @Test
+    public void headersMultiValue() {
+        UserTO userTO = new UserTO();
+        userTO.setRealm(SyncopeConstants.ROOT_REALM);
+        String userId = getUUIDString() + "issue654@syncope.apache.org";
+        userTO.setUsername(userId);
+        userTO.setPassword("password123");
+
+        userTO.getPlainAttrs().add(attrTO("userId", "issue654"));
+        userTO.getPlainAttrs().add(attrTO("fullname", userId));
+        userTO.getPlainAttrs().add(attrTO("surname", userId));
+
+        try {
+            createUser(userTO);
+            fail();
+        } catch (SyncopeClientCompositeException e) {
+            assertEquals(2, e.getExceptions().size());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
new file mode 100644
index 0000000..91077a4
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
@@ -0,0 +1,939 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AssociationPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.DeassociationPatch;
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.patch.LongReplacePatchItem;
+import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.TypeExtensionTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
+import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
+import org.apache.syncope.common.lib.types.SchemaType;
+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.GroupService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class GroupITCase extends AbstractITCase {
+
+    public static GroupTO getBasicSampleTO(final String name) {
+        GroupTO groupTO = new GroupTO();
+        groupTO.setRealm(SyncopeConstants.ROOT_REALM);
+        groupTO.setName(name + getUUIDString());
+        return groupTO;
+    }
+
+    public static GroupTO getSampleTO(final String name) {
+        GroupTO groupTO = getBasicSampleTO(name);
+
+        groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
+
+        groupTO.getResources().add(RESOURCE_NAME_LDAP);
+        return groupTO;
+    }
+
+    @Test
+    public void create() {
+        GroupTO groupTO = getSampleTO("lastGroup");
+        groupTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
+        groupTO.setGroupOwner(8L);
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+
+        assertNotNull(groupTO.getVirAttrMap());
+        assertNotNull(groupTO.getVirAttrMap().get("rvirtualdata").getValues());
+        assertFalse(groupTO.getVirAttrMap().get("rvirtualdata").getValues().isEmpty());
+        assertEquals("rvirtualvalue", groupTO.getVirAttrMap().get("rvirtualdata").getValues().get(0));
+
+        assertTrue(groupTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
+        assertNotNull(connObjectTO);
+        assertNotNull(connObjectTO.getPlainAttrMap().get("owner"));
+
+        // SYNCOPE-515: remove ownership
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(groupTO.getKey());
+        groupPatch.setGroupOwner(new LongReplacePatchItem());
+
+        assertNull(updateGroup(groupPatch).getAny().getGroupOwner());
+    }
+
+    @Test
+    public void delete() {
+        try {
+            groupService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        GroupTO groupTO = new GroupTO();
+        groupTO.setName("toBeDeleted" + getUUIDString());
+        groupTO.setRealm("/even");
+
+        groupTO.getResources().add(RESOURCE_NAME_LDAP);
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+
+        GroupTO deletedGroup = deleteGroup(groupTO.getKey()).getAny();
+        assertNotNull(deletedGroup);
+
+        try {
+            groupService.read(deletedGroup.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        PagedResult<GroupTO> groupTOs =
+                groupService.list(new AnyListQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
+        assertNotNull(groupTOs);
+        assertTrue(groupTOs.getResult().size() >= 8);
+        for (GroupTO groupTO : groupTOs.getResult()) {
+            assertNotNull(groupTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        GroupTO groupTO = groupService.read(1L);
+
+        assertNotNull(groupTO);
+        assertNotNull(groupTO.getPlainAttrs());
+        assertFalse(groupTO.getPlainAttrs().isEmpty());
+    }
+
+    @Test
+    public void selfRead() {
+        UserTO userTO = userService.read(1L);
+        assertNotNull(userTO);
+
+        assertTrue(userTO.getMembershipMap().containsKey(1L));
+        assertFalse(userTO.getMembershipMap().containsKey(3L));
+
+        GroupService groupService2 = clientFactory.create("rossini", ADMIN_PWD).getService(GroupService.class);
+
+        try {
+            groupService2.read(3L);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
+        }
+
+        List<GroupTO> groups = groupService2.own();
+        assertNotNull(groups);
+        assertTrue(IterableUtils.matchesAny(groups, new Predicate<GroupTO>() {
+
+            @Override
+            public boolean evaluate(final GroupTO group) {
+                return 1L == group.getKey();
+            }
+        }));
+    }
+
+    @Test
+    public void update() {
+        GroupTO groupTO = getSampleTO("latestGroup" + getUUIDString());
+        groupTO = createGroup(groupTO).getAny();
+
+        assertEquals(1, groupTO.getPlainAttrs().size());
+
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(groupTO.getKey());
+        String modName = "finalGroup" + getUUIDString();
+        groupPatch.setName(new StringReplacePatchItem.Builder().value(modName).build());
+        groupPatch.getPlainAttrs().add(attrAddReplacePatch("show", "FALSE"));
+
+        groupTO = updateGroup(groupPatch).getAny();
+
+        assertEquals(modName, groupTO.getName());
+        assertEquals(2, groupTO.getPlainAttrs().size());
+
+        groupTO.getPlainAttrMap().get("show").getValues().clear();
+
+        groupTO = groupService.update(groupTO).readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
+        }).getAny();
+
+        assertFalse(groupTO.getPlainAttrMap().containsKey("show"));
+    }
+
+    @Test
+    public void patch() {
+        GroupTO original = getBasicSampleTO("patch");
+        original.setUDynMembershipCond("(($groups==3;$resources!=ws-target-resource-1);aLong==1)");
+        original.getADynMembershipConds().put(
+                "PRINTER",
+                "(($groups==7;cool==ss);$resources==ws-target-resource-2);$type==PRINTER");
+
+        GroupTO updated = createGroup(original).getAny();
+
+        updated.getPlainAttrs().add(new AttrTO.Builder().schema("icon").build());
+        updated.getPlainAttrs().add(new AttrTO.Builder().schema("show").build());
+        updated.getPlainAttrs().add(new AttrTO.Builder().schema("rderived_sx").value("sx").build());
+        updated.getPlainAttrs().add(new AttrTO.Builder().schema("rderived_dx").value("dx").build());
+        updated.getPlainAttrs().add(new AttrTO.Builder().schema("title").value("mr").build());
+
+        original = groupService.read(updated.getKey());
+
+        GroupPatch patch = AnyOperations.diff(updated, original, true);
+        GroupTO group = updateGroup(patch).getAny();
+
+        Map<String, AttrTO> attrs = group.getPlainAttrMap();
+        assertFalse(attrs.containsKey("icon"));
+        assertFalse(attrs.containsKey("show"));
+        assertEquals(Collections.singletonList("sx"), attrs.get("rderived_sx").getValues());
+        assertEquals(Collections.singletonList("dx"), attrs.get("rderived_dx").getValues());
+        assertEquals(Collections.singletonList("mr"), attrs.get("title").getValues());
+    }
+
+    @Test
+    public void updateAsGroupOwner() {
+        // 1. read group as admin
+        GroupTO groupTO = groupService.read(6L);
+
+        // issue SYNCOPE-15
+        assertNotNull(groupTO.getCreationDate());
+        assertNotNull(groupTO.getLastChangeDate());
+        assertEquals("admin", groupTO.getCreator());
+        assertEquals("admin", groupTO.getLastModifier());
+
+        // 2. prepare update
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(groupTO.getKey());
+        groupPatch.setName(new StringReplacePatchItem.Builder().value("Director").build());
+
+        // 3. try to update as verdi, not owner of group 6 - fail
+        GroupService groupService2 = clientFactory.create("verdi", ADMIN_PWD).getService(GroupService.class);
+
+        try {
+            groupService2.update(groupPatch);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        // 4. update as puccini, owner of group 6 - success
+        GroupService groupService3 = clientFactory.create("puccini", ADMIN_PWD).getService(GroupService.class);
+
+        groupTO = groupService3.update(groupPatch).readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
+        }).getAny();
+        assertEquals("Director", groupTO.getName());
+
+        // issue SYNCOPE-15
+        assertNotNull(groupTO.getCreationDate());
+        assertNotNull(groupTO.getLastChangeDate());
+        assertEquals("admin", groupTO.getCreator());
+        assertEquals("puccini", groupTO.getLastModifier());
+        assertTrue(groupTO.getCreationDate().before(groupTO.getLastChangeDate()));
+    }
+
+    @Test
+    public void unlink() {
+        GroupTO actual = createGroup(getSampleTO("unlink")).getAny();
+        assertNotNull(actual);
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
+    }
+
+    @Test
+    public void link() {
+        GroupTO groupTO = getSampleTO("link");
+        groupTO.getResources().clear();
+
+        GroupTO actual = createGroup(groupTO).getAny();
+        assertNotNull(actual);
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setAction(ResourceAssociationAction.LINK);
+        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertFalse(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void unassign() {
+        GroupTO actual = createGroup(getSampleTO("unassign")).getAny();
+        assertNotNull(actual);
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.UNASSIGN);
+        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void assign() {
+        GroupTO groupTO = getSampleTO("assign");
+        groupTO.getResources().clear();
+
+        GroupTO actual = createGroup(groupTO).getAny();
+        assertNotNull(actual);
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setAction(ResourceAssociationAction.ASSIGN);
+        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertFalse(actual.getResources().isEmpty());
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
+    }
+
+    @Test
+    public void deprovision() {
+        GroupTO actual = createGroup(getSampleTO("deprovision")).getAny();
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
+        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertNotNull(actual);
+        assertFalse(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void provision() {
+        GroupTO groupTO = getSampleTO("assign" + getUUIDString());
+        groupTO.getResources().clear();
+
+        GroupTO actual = createGroup(groupTO).getAny();
+        assertNotNull(actual);
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setAction(ResourceAssociationAction.PROVISION);
+        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertTrue(actual.getResources().isEmpty());
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
+    }
+
+    @Test
+    public void deprovisionUnlinked() {
+        GroupTO groupTO = getSampleTO("assign" + getUUIDString());
+        groupTO.getResources().clear();
+
+        GroupTO actual = createGroup(groupTO).getAny();
+        assertNotNull(actual);
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setAction(ResourceAssociationAction.PROVISION);
+        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertTrue(actual.getResources().isEmpty());
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
+        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+
+        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = groupService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void createWithMandatorySchema() {
+        // 1. create a mandatory schema
+        PlainSchemaTO badge = new PlainSchemaTO();
+        badge.setKey("badge" + getUUIDString());
+        badge.setMandatoryCondition("true");
+        schemaService.create(SchemaType.PLAIN, badge);
+
+        // 2. create a group *without* an attribute for that schema: it works
+        GroupTO groupTO = getSampleTO("lastGroup");
+        assertFalse(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+        assertFalse(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
+
+        // 3. add the new mandatory schema to the default group type
+        AnyTypeTO type = anyTypeService.read(AnyTypeKind.GROUP.name());
+        String typeClassName = type.getClasses().get(0);
+        AnyTypeClassTO typeClass = anyTypeClassService.read(typeClassName);
+        typeClass.getPlainSchemas().add(badge.getKey());
+        anyTypeClassService.update(typeClass);
+        typeClass = anyTypeClassService.read(typeClassName);
+        assertTrue(typeClass.getPlainSchemas().contains(badge.getKey()));
+
+        try {
+            // 4. update group: failure since no values are provided and it is mandatory
+            GroupPatch groupPatch = new GroupPatch();
+            groupPatch.setKey(groupTO.getKey());
+
+            try {
+                updateGroup(groupPatch);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+            }
+
+            // 5. also add an actual attribute for badge - it will work        
+            groupPatch.getPlainAttrs().add(attrAddReplacePatch(badge.getKey(), "xxxxxxxxxx"));
+
+            groupTO = updateGroup(groupPatch).getAny();
+            assertNotNull(groupTO);
+            assertTrue(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
+        } finally {
+            // restore the original group class
+            typeClass.getPlainSchemas().remove(badge.getKey());
+            anyTypeClassService.update(typeClass);
+            typeClass = anyTypeClassService.read(typeClassName);
+            assertFalse(typeClass.getPlainSchemas().contains(badge.getKey()));
+        }
+    }
+
+    @Test
+    public void anonymous() {
+        GroupService unauthenticated = clientFactory.create().getService(GroupService.class);
+        try {
+            unauthenticated.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        GroupService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(GroupService.class);
+        assertFalse(anonymous.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build()).
+                getResult().isEmpty());
+    }
+
+    @Test
+    public void uDynMembership() {
+        assertTrue(userService.read(4L).getDynGroups().isEmpty());
+
+        GroupTO group = getBasicSampleTO("uDynMembership");
+        group.setUDynMembershipCond("cool==true");
+        group = createGroup(group).getAny();
+        assertNotNull(group);
+
+        assertTrue(userService.read(4L).getDynGroups().contains(group.getKey()));
+
+        GroupPatch patch = new GroupPatch();
+        patch.setKey(group.getKey());
+        patch.setUDynMembershipCond("cool==false");
+        groupService.update(patch);
+
+        assertTrue(userService.read(4L).getDynGroups().isEmpty());
+    }
+
+    @Test
+    public void aDynMembership() {
+        String fiql = SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").is("location").notNullValue().query();
+
+        // 1. create group with a given aDynMembership condition
+        GroupTO group = getBasicSampleTO("aDynMembership");
+        group.getADynMembershipConds().put("PRINTER", fiql);
+        group = createGroup(group).getAny();
+        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
+
+        group = groupService.read(group.getKey());
+        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
+
+        // verify that the condition is dynamically applied
+        AnyObjectTO newAny = AnyObjectITCase.getSampleTO("aDynMembership");
+        newAny.getResources().clear();
+        newAny = createAnyObject(newAny).getAny();
+        assertNotNull(newAny.getPlainAttrMap().get("location"));
+        assertTrue(anyObjectService.read(1L).getDynGroups().contains(group.getKey()));
+        assertTrue(anyObjectService.read(2L).getDynGroups().contains(group.getKey()));
+        assertTrue(anyObjectService.read(newAny.getKey()).getDynGroups().contains(group.getKey()));
+
+        // 2. update group and change aDynMembership condition
+        fiql = SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").is("location").nullValue().query();
+
+        GroupPatch patch = new GroupPatch();
+        patch.setKey(group.getKey());
+        patch.getADynMembershipConds().put("PRINTER", fiql);
+
+        group = updateGroup(patch).getAny();
+        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
+
+        group = groupService.read(group.getKey());
+        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
+
+        // verify that the condition is dynamically applied
+        AnyObjectPatch anyPatch = new AnyObjectPatch();
+        anyPatch.setKey(newAny.getKey());
+        anyPatch.getPlainAttrs().add(new AttrPatch.Builder().
+                operation(PatchOperation.DELETE).
+                attrTO(new AttrTO.Builder().schema("location").build()).
+                build());
+        newAny = updateAnyObject(anyPatch).getAny();
+        assertNull(newAny.getPlainAttrMap().get("location"));
+        assertFalse(anyObjectService.read(1L).getDynGroups().contains(group.getKey()));
+        assertFalse(anyObjectService.read(2L).getDynGroups().contains(group.getKey()));
+        assertTrue(anyObjectService.read(newAny.getKey()).getDynGroups().contains(group.getKey()));
+    }
+
+    @Test
+    public void capabilitiesOverride() {
+        // resource with no capability override
+        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+        assertNotNull(ldap);
+        assertFalse(ldap.isOverrideCapabilities());
+        assertTrue(ldap.getCapabilitiesOverride().isEmpty());
+
+        // connector with all required for create and update
+        ConnInstanceTO conn = connectorService.read(ldap.getConnector(), null);
+        assertNotNull(conn);
+        assertTrue(conn.getCapabilities().contains(ConnectorCapability.CREATE));
+        assertTrue(conn.getCapabilities().contains(ConnectorCapability.UPDATE));
+
+        try {
+            // 1. create succeeds
+            GroupTO group = getSampleTO("syncope714");
+            group.getPlainAttrs().add(attrTO("title", "first"));
+            group.getResources().add(RESOURCE_NAME_LDAP);
+
+            ProvisioningResult<GroupTO> result = createGroup(group);
+            assertNotNull(result);
+            assertEquals(1, result.getPropagationStatuses().size());
+            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+            group = result.getAny();
+
+            // 2. update succeeds
+            GroupPatch patch = new GroupPatch();
+            patch.setKey(group.getKey());
+            patch.getPlainAttrs().add(new AttrPatch.Builder().
+                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "second")).build());
+
+            result = updateGroup(patch);
+            assertNotNull(result);
+            assertEquals(1, result.getPropagationStatuses().size());
+            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+            group = result.getAny();
+
+            // 3. set capability override with only search allowed, but not enable
+            ldap.getCapabilitiesOverride().add(ConnectorCapability.SEARCH);
+            resourceService.update(ldap);
+            ldap = resourceService.read(RESOURCE_NAME_LDAP);
+            assertNotNull(ldap);
+            assertFalse(ldap.isOverrideCapabilities());
+            assertEquals(1, ldap.getCapabilitiesOverride().size());
+            assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
+
+            // 4. update succeeds again
+            patch = new GroupPatch();
+            patch.setKey(group.getKey());
+            patch.getPlainAttrs().add(new AttrPatch.Builder().
+                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "third")).build());
+
+            result = updateGroup(patch);
+            assertNotNull(result);
+            assertEquals(1, result.getPropagationStatuses().size());
+            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+            group = result.getAny();
+
+            // 5. enable capability override
+            ldap.setOverrideCapabilities(true);
+            resourceService.update(ldap);
+            ldap = resourceService.read(RESOURCE_NAME_LDAP);
+            assertNotNull(ldap);
+            assertTrue(ldap.isOverrideCapabilities());
+            assertEquals(1, ldap.getCapabilitiesOverride().size());
+            assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
+
+            // 6. update now fails
+            patch = new GroupPatch();
+            patch.setKey(group.getKey());
+            patch.getPlainAttrs().add(new AttrPatch.Builder().
+                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "fourth")).build());
+
+            result = updateGroup(patch);
+            assertNotNull(result);
+            assertEquals(1, result.getPropagationStatuses().size());
+            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
+            assertEquals(PropagationTaskExecStatus.NOT_ATTEMPTED, result.getPropagationStatuses().get(0).getStatus());
+        } finally {
+            ldap.getCapabilitiesOverride().clear();
+            ldap.setOverrideCapabilities(false);
+            resourceService.update(ldap);
+        }
+    }
+
+    @Test
+    public void typeExtensions() {
+        TypeExtensionTO typeExtension = new TypeExtensionTO();
+        typeExtension.setAnyType(AnyTypeKind.USER.name());
+        typeExtension.getAuxClasses().add("csv");
+
+        GroupTO groupTO = getBasicSampleTO("typeExtensions");
+        groupTO.getTypeExtensions().add(typeExtension);
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+        assertEquals(1, groupTO.getTypeExtensions().size());
+        assertEquals(1, groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().size());
+        assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().contains("csv"));
+
+        typeExtension = new TypeExtensionTO();
+        typeExtension.setAnyType(AnyTypeKind.USER.name());
+        typeExtension.getAuxClasses().add("csv");
+        typeExtension.getAuxClasses().add("other");
+
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(groupTO.getKey());
+        groupPatch.getTypeExtensions().add(typeExtension);
+
+        groupTO = updateGroup(groupPatch).getAny();
+        assertNotNull(groupTO);
+        assertEquals(1, groupTO.getTypeExtensions().size());
+        assertEquals(2, groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().size());
+        assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().contains("csv"));
+        assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().contains("other"));
+    }
+
+    @Test
+    public void issue178() {
+        GroupTO groupTO = new GroupTO();
+        String groupName = "torename" + getUUIDString();
+        groupTO.setName(groupName);
+        groupTO.setRealm("/");
+
+        GroupTO actual = createGroup(groupTO).getAny();
+
+        assertNotNull(actual);
+        assertEquals(groupName, actual.getName());
+
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(actual.getKey());
+        String renamedGroup = "renamed" + getUUIDString();
+        groupPatch.setName(new StringReplacePatchItem.Builder().value(renamedGroup).build());
+
+        actual = updateGroup(groupPatch).getAny();
+        assertNotNull(actual);
+        assertEquals(renamedGroup, actual.getName());
+    }
+
+    @Test
+    public void issueSYNCOPE632() {
+        GroupTO groupTO = null;
+        try {
+            // 1. create new LDAP resource having ConnObjectKey mapped to a derived attribute
+            ResourceTO newLDAP = resourceService.read(RESOURCE_NAME_LDAP);
+            newLDAP.setKey("new-ldap");
+            newLDAP.setPropagationPriority(0);
+
+            for (ProvisionTO provision : newLDAP.getProvisions()) {
+                provision.getVirSchemas().clear();
+            }
+
+            MappingTO mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).getMapping();
+
+            MappingItemTO connObjectKey = mapping.getConnObjectKeyItem();
+            connObjectKey.setIntMappingType(IntMappingType.GroupDerivedSchema);
+            connObjectKey.setIntAttrName("displayProperty");
+            connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
+            mapping.setConnObjectKeyItem(connObjectKey);
+            mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
+
+            MappingItemTO description = new MappingItemTO();
+            description.setIntMappingType(IntMappingType.GroupKey);
+            description.setExtAttrName("description");
+            description.setPurpose(MappingPurpose.BOTH);
+            mapping.add(description);
+
+            newLDAP = createResource(newLDAP);
+            assertNotNull(newLDAP);
+
+            // 2. create a group and give the resource created above
+            groupTO = getSampleTO("lastGroup" + getUUIDString());
+            groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
+            groupTO.getPlainAttrs().add(attrTO("show", "true"));
+            groupTO.getDerAttrs().add(attrTO("displayProperty", null));
+            groupTO.getResources().clear();
+            groupTO.getResources().add("new-ldap");
+
+            groupTO = createGroup(groupTO).getAny();
+            assertNotNull(groupTO);
+
+            // 3. update the group
+            GroupPatch groupPatch = new GroupPatch();
+            groupPatch.setKey(groupTO.getKey());
+            groupPatch.getPlainAttrs().add(attrAddReplacePatch("icon", "anotherIcon"));
+
+            groupTO = updateGroup(groupPatch).getAny();
+            assertNotNull(groupTO);
+
+            // 4. check that a single group exists in LDAP for the group created and updated above
+            int entries = 0;
+            DirContext ctx = null;
+            try {
+                ctx = getLdapResourceDirContext(null, null);
+
+                SearchControls ctls = new SearchControls();
+                ctls.setReturningAttributes(new String[] { "*", "+" });
+                ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+                NamingEnumeration<SearchResult> result =
+                        ctx.search("ou=groups,o=isp", "(description=" + groupTO.getKey() + ")", ctls);
+                while (result.hasMore()) {
+                    result.next();
+                    entries++;
+                }
+            } catch (Exception e) {
+                // ignore
+            } finally {
+                if (ctx != null) {
+                    try {
+                        ctx.close();
+                    } catch (NamingException e) {
+                        // ignore
+                    }
+                }
+            }
+
+            assertEquals(1, entries);
+        } finally {
+            if (groupTO != null) {
+                groupService.delete(groupTO.getKey());
+            }
+            resourceService.delete("new-ldap");
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE717() {
+        String doubleSchemaName = "double" + getUUIDString();
+
+        // 1. create double schema without conversion pattern
+        PlainSchemaTO schema = new PlainSchemaTO();
+        schema.setKey(doubleSchemaName);
+        schema.setType(AttrSchemaType.Double);
+
+        schema = createSchema(SchemaType.PLAIN, schema);
+        assertNotNull(schema);
+        assertNull(schema.getConversionPattern());
+
+        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
+        assertNotNull(minimalGroup);
+        minimalGroup.getPlainSchemas().add(doubleSchemaName);
+        anyTypeClassService.update(minimalGroup);
+
+        // 2. create group, provide valid input value
+        GroupTO groupTO = getBasicSampleTO("syncope717");
+        groupTO.getPlainAttrs().add(attrTO(doubleSchemaName, "11.23"));
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+        assertEquals("11.23", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
+
+        // 3. update schema, set conversion pattern
+        schema.setConversionPattern("0.000");
+        schemaService.update(SchemaType.PLAIN, schema);
+
+        // 4. re-read group, verify that pattern was applied
+        groupTO = groupService.read(groupTO.getKey());
+        assertNotNull(groupTO);
+        assertEquals("11.230", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
+
+        // 5. modify group with new double value
+        GroupPatch patch = new GroupPatch();
+        patch.setKey(groupTO.getKey());
+        patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO(doubleSchemaName, "11.257")).build());
+
+        groupTO = updateGroup(patch).getAny();
+        assertNotNull(groupTO);
+        assertEquals("11.257", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
+
+        // 6. update schema, unset conversion pattern
+        schema.setConversionPattern(null);
+        schemaService.update(SchemaType.PLAIN, schema);
+
+        // 7. modify group with new double value, verify that no pattern is applied
+        patch = new GroupPatch();
+        patch.setKey(groupTO.getKey());
+        patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO(doubleSchemaName, "11.23")).build());
+
+        groupTO = updateGroup(patch).getAny();
+        assertNotNull(groupTO);
+        assertEquals("11.23", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
+    }
+
+}


[06/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
deleted file mode 100644
index dd8242b..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ /dev/null
@@ -1,2555 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.security.AccessControlException;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.naming.NamingException;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.common.util.Base64Utility;
-import org.apache.cxf.helpers.IOUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.patch.AssociationPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.DeassociationPatch;
-import org.apache.syncope.common.lib.patch.MembershipPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.StatusPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.policy.AccountPolicyTO;
-import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
-import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.BulkActionResult.Status;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.PropagationTaskTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.ResourceAssociationAction;
-import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
-import org.apache.syncope.common.lib.types.StatusPatchType;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.common.rest.api.service.UserService;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
-import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
-import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-import org.junit.Assume;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class UserITCase extends AbstractITCase {
-
-    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
-
-        @Override
-        protected SimpleDateFormat initialValue() {
-            SimpleDateFormat sdf = new SimpleDateFormat();
-            sdf.applyPattern("yyyy-MM-dd");
-            return sdf;
-        }
-    };
-
-    private boolean getBooleanAttribute(final ConnObjectTO connObjectTO, final String attrName) {
-        return Boolean.parseBoolean(connObjectTO.getPlainAttrMap().get(attrName).getValues().get(0));
-    }
-
-    public static UserTO getUniqueSampleTO(final String email) {
-        return getSampleTO(getUUIDString() + email);
-    }
-
-    public static UserTO getSampleTO(final String email) {
-        UserTO userTO = new UserTO();
-        userTO.setRealm(SyncopeConstants.ROOT_REALM);
-        userTO.setPassword("password123");
-        userTO.setUsername(email);
-
-        userTO.getPlainAttrs().add(attrTO("fullname", email));
-        userTO.getPlainAttrs().add(attrTO("firstname", email));
-        userTO.getPlainAttrs().add(attrTO("surname", "surname"));
-        userTO.getPlainAttrs().add(attrTO("type", "a type"));
-        userTO.getPlainAttrs().add(attrTO("userId", email));
-        userTO.getPlainAttrs().add(attrTO("email", email));
-        userTO.getPlainAttrs().add(attrTO("loginDate", DATE_FORMAT.get().format(new Date())));
-        userTO.getDerAttrs().add(attrTO("cn", null));
-        return userTO;
-    }
-
-    @Test
-    public void createUserWithNoPropagation() {
-        // get task list
-        PagedResult<PropagationTaskTO> tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-        assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
-
-        long maxKey = tasks.getResult().iterator().next().getKey();
-
-        // create a new user
-        UserTO userTO = getUniqueSampleTO("xxx@xxx.xxx");
-        userTO.setPassword("password123");
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
-
-        createUser(userTO);
-
-        // get the new task list
-        tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-        assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
-
-        long newMaxKey = tasks.getResult().iterator().next().getKey();
-
-        assertTrue(newMaxKey > maxKey);
-
-        // get last task
-        PropagationTaskTO taskTO = taskService.read(newMaxKey, true);
-        assertNotNull(taskTO);
-        assertFalse(taskTO.getExecutions().isEmpty());
-        assertEquals(PropagationTaskExecStatus.NOT_ATTEMPTED.name(), taskTO.getExecutions().get(0).getStatus());
-    }
-
-    @Test
-    public void issue186() {
-        // 1. create an user with strict mandatory attributes only
-        UserTO userTO = new UserTO();
-        userTO.setRealm(SyncopeConstants.ROOT_REALM);
-        String userId = getUUIDString() + "issue186@syncope.apache.org";
-        userTO.setUsername(userId);
-        userTO.setPassword("password123");
-
-        userTO.getPlainAttrs().add(attrTO("userId", userId));
-        userTO.getPlainAttrs().add(attrTO("fullname", userId));
-        userTO.getPlainAttrs().add(attrTO("surname", userId));
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertTrue(userTO.getResources().isEmpty());
-
-        // 2. update assigning a resource forcing mandatory constraints: must fail with RequiredValuesMissing
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build());
-
-        try {
-            userTO = updateUser(userPatch).getAny();
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-
-        // 3. update assigning a resource NOT forcing mandatory constraints
-        // AND priority: must fail with PropagationException
-        userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
-
-        ProvisioningResult<UserTO> result = updateUser(userPatch);
-        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
-        userTO = result.getAny();
-
-        // 4. update assigning a resource NOT forcing mandatory constraints
-        // BUT not priority: must succeed
-        userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123456").build());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_CSV).build());
-
-        updateUser(userPatch);
-    }
-
-    @Test
-    public void enforceMandatoryCondition() {
-        UserTO userTO = getUniqueSampleTO("enforce@apache.org");
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-        userTO.setPassword("newPassword12");
-
-        AttrTO type = null;
-        for (AttrTO attr : userTO.getPlainAttrs()) {
-            if ("type".equals(attr.getSchema())) {
-                type = attr;
-            }
-        }
-        assertNotNull(type);
-        userTO.getPlainAttrs().remove(type);
-
-        try {
-            userTO = createUser(userTO).getAny();
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-
-        userTO.getPlainAttrs().add(type);
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-    }
-
-    @Test
-    public void enforceMandatoryConditionOnDerived() {
-        ResourceTO resourceTO = resourceService.read(RESOURCE_NAME_CSV);
-        assertNotNull(resourceTO);
-        resourceTO.setKey("resource-csv-enforcing");
-        resourceTO.setEnforceMandatoryCondition(true);
-
-        Response response = resourceService.create(resourceTO);
-        resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-        assertNotNull(resourceTO);
-
-        try {
-            UserTO userTO = getUniqueSampleTO("syncope222@apache.org");
-            userTO.getResources().add(resourceTO.getKey());
-            userTO.setPassword("newPassword12");
-
-            try {
-                userTO = createUser(userTO).getAny();
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-            }
-
-            userTO.getAuxClasses().add("csv");
-            userTO.getDerAttrs().add(new AttrTO.Builder().schema("csvuserid").build());
-
-            userTO = createUser(userTO).getAny();
-            assertNotNull(userTO);
-            assertEquals(Collections.singleton(resourceTO.getKey()), userTO.getResources());
-        } finally {
-            resourceService.delete(resourceTO.getKey());
-        }
-    }
-
-    @Test
-    public void createUserWithDbPropagation() {
-        UserTO userTO = getUniqueSampleTO("yyy@yyy.yyy");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertNotNull(result);
-        assertEquals(1, result.getPropagationStatuses().size());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void createWithInvalidPassword() {
-        UserTO userTO = getSampleTO("invalidpasswd@syncope.apache.org");
-        userTO.setPassword("pass");
-        createUser(userTO);
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void createWithInvalidUsername() {
-        UserTO userTO = getSampleTO("invalidusername@syncope.apache.org");
-        userTO.setUsername("us");
-        userTO.setRealm("/odd");
-
-        createUser(userTO);
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void createWithInvalidPasswordByRes() {
-        UserTO userTO = getSampleTO("invalidPwdByRes@passwd.com");
-
-        // configured to be minLength=16
-        userTO.setPassword("password1");
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
-        createUser(userTO);
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void createWithInvalidPasswordByGroup() {
-        UserTO userTO = getSampleTO("invalidPwdByGroup@passwd.com");
-
-        // configured to be minLength=16
-        userTO.setPassword("password1");
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-
-        createUser(userTO);
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void createWithException() {
-        UserTO newUserTO = new UserTO();
-        newUserTO.getPlainAttrs().add(attrTO("userId", "userId@nowhere.org"));
-        createUser(newUserTO);
-    }
-
-    @Test
-    public void create() {
-        // get task list
-        PagedResult<PropagationTaskTO> tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-        assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
-
-        long maxKey = tasks.getResult().iterator().next().getKey();
-        PropagationTaskTO taskTO = taskService.read(maxKey, true);
-
-        assertNotNull(taskTO);
-        int maxTaskExecutions = taskTO.getExecutions().size();
-
-        UserTO userTO = getUniqueSampleTO("a.b@c.com");
-
-        // add a membership
-        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-
-        // add an attribute with a non-existing schema: must be ignored
-        AttrTO attrWithInvalidSchemaTO = attrTO("invalid schema", "a value");
-        userTO.getPlainAttrs().add(attrWithInvalidSchemaTO);
-
-        // add an attribute with null value: must be ignored
-        userTO.getPlainAttrs().add(attrTO("activationDate", null));
-
-        // 1. create user
-        UserTO newUserTO = createUser(userTO).getAny();
-
-        assertNotNull(newUserTO);
-
-        // issue SYNCOPE-15
-        assertNotNull(newUserTO.getCreationDate());
-        assertNotNull(newUserTO.getCreator());
-        assertNotNull(newUserTO.getLastChangeDate());
-        assertNotNull(newUserTO.getLastModifier());
-        assertEquals(newUserTO.getCreationDate(), newUserTO.getLastChangeDate());
-
-        assertFalse(newUserTO.getPlainAttrs().contains(attrWithInvalidSchemaTO));
-
-        // check for changePwdDate
-        assertNotNull(newUserTO.getCreationDate());
-
-        // get the new task list
-        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-        assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
-
-        long newMaxKey = tasks.getResult().iterator().next().getKey();
-
-        // default configuration for ws-target-resource2:
-        // only failed executions have to be registered
-        // --> no more tasks/executions should be added
-        assertEquals(newMaxKey, maxKey);
-
-        // get last task
-        taskTO = taskService.read(newMaxKey, true);
-
-        assertNotNull(taskTO);
-        assertEquals(maxTaskExecutions, taskTO.getExecutions().size());
-
-        // 3. verify password
-        try {
-            Pair<Map<String, Set<String>>, UserTO> self =
-                    clientFactory.create(newUserTO.getUsername(), "password123").self();
-            assertNotNull(self);
-        } catch (AccessControlException e) {
-            fail("Credentials should be valid and not cause AccessControlException");
-        }
-
-        UserSelfService userSelfService2 = clientFactory.create(
-                newUserTO.getUsername(), "passwordXX").getService(UserSelfService.class);
-        try {
-            userSelfService2.read();
-            fail("Credentials are invalid, thus request should raise AccessControlException");
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        // 4. try (and fail) to create another user with same (unique) values
-        userTO = getSampleTO(userTO.getUsername());
-        AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
-        userIdAttr.getValues().clear();
-        userIdAttr.getValues().add("a.b@c.com");
-
-        try {
-            createUser(userTO);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.GenericPersistence, e.getType());
-        }
-    }
-
-    @Test
-    public void createWithRequiredValueMissing() {
-        UserTO userTO = getUniqueSampleTO("a.b@c.it");
-
-        AttrTO type = userTO.getPlainAttrMap().get("type");
-        userTO.getPlainAttrs().remove(type);
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-
-        // 1. create user without type (mandatory by UserSchema)
-        try {
-            createUser(userTO);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-
-        userTO.getPlainAttrs().add(attrTO("type", "F"));
-
-        AttrTO surname = userTO.getPlainAttrMap().get("surname");
-        userTO.getPlainAttrs().remove(surname);
-
-        // 2. create user without surname (mandatory when type == 'F')
-        try {
-            createUser(userTO);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-    }
-
-    @Test
-    public void delete() {
-        try {
-            userService.delete(0L);
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-
-        UserTO userTO = getSampleTO("qqgf.z@nn.com");
-
-        // specify a propagation
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        userTO = createUser(userTO).getAny();
-
-        long key = userTO.getKey();
-
-        ProvisioningResult<UserTO> result = deleteUser(key);
-        assertNotNull(result);
-        userTO = result.getAny();
-        assertEquals(key, userTO.getKey(), 0);
-        assertTrue(userTO.getPlainAttrs().isEmpty());
-
-        // check for propagation result
-        assertFalse(result.getPropagationStatuses().isEmpty());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-
-        try {
-            userService.delete(userTO.getKey());
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void deleteByUsername() {
-        UserTO userTO = getSampleTO("delete.by.username@apache.org");
-
-        // specify a propagation
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        userTO = createUser(userTO).getAny();
-
-        long key = userTO.getKey();
-        userTO = userService.read(key);
-
-        ProvisioningResult<UserTO> result = deleteUser(userTO.getKey());
-        assertNotNull(result);
-        userTO = result.getAny();
-        assertEquals(key, userTO.getKey(), 0);
-        assertTrue(userTO.getPlainAttrs().isEmpty());
-
-        // check for propagation result
-        assertFalse(result.getPropagationStatuses().isEmpty());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-
-        try {
-            userService.read(userTO.getKey());
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void list() {
-        PagedResult<UserTO> users = userService.list(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
-        assertNotNull(users);
-        assertFalse(users.getResult().isEmpty());
-
-        for (UserTO user : users.getResult()) {
-            assertNotNull(user);
-        }
-    }
-
-    @Test
-    public void paginatedList() {
-        PagedResult<UserTO> users = userService.list(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).page(1).size(2).build());
-        assertNotNull(users);
-        assertFalse(users.getResult().isEmpty());
-        assertEquals(2, users.getResult().size());
-
-        for (UserTO user : users.getResult()) {
-            assertNotNull(user);
-        }
-
-        users = userService.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                page(2).size(2).build());
-        assertNotNull(users);
-        assertEquals(2, users.getPage());
-        assertEquals(2, users.getResult().size());
-
-        users = userService.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                page(100).size(2).build());
-        assertNotNull(users);
-        assertTrue(users.getResult().isEmpty());
-    }
-
-    @Test
-    public void read() {
-        UserTO userTO = userService.read(1L);
-
-        assertNotNull(userTO);
-        assertNull(userTO.getPassword());
-        assertNotNull(userTO.getPlainAttrs());
-        assertFalse(userTO.getPlainAttrs().isEmpty());
-    }
-
-    @Test
-    public void readWithMailAddressAsUserName() {
-        UserTO userTO = createUser(getUniqueSampleTO("mail@domain.org")).getAny();
-        userTO = userService.read(userTO.getKey());
-        assertNotNull(userTO);
-    }
-
-    @Test
-    public void updateWithoutPassword() {
-        UserTO userTO = getUniqueSampleTO("updatewithout@password.com");
-
-        userTO = createUser(userTO).getAny();
-
-        assertNotNull(userTO);
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getPlainAttrs().add(new AttrPatch.Builder().operation(PatchOperation.DELETE).
-                attrTO(new AttrTO.Builder().schema("type").build()).
-                build());
-
-        userTO = updateUser(userPatch).getAny();
-
-        assertNotNull(userTO);
-        assertNotNull(userTO.getDerAttrMap());
-        assertFalse(userTO.getPlainAttrMap().containsKey("type"));
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void updateInvalidPassword() {
-        UserTO userTO = getSampleTO("updateinvalid@password.com");
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("pass").build());
-
-        userService.update(userPatch);
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void updateSamePassword() {
-        UserTO userTO = getUniqueSampleTO("updatesame@password.com");
-        userTO.setRealm("/even/two");
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("password123").build());
-
-        userService.update(userPatch);
-    }
-
-    @Test
-    public void update() {
-        UserTO userTO = getUniqueSampleTO("g.h@t.com");
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-
-        userTO = createUser(userTO).getAny();
-
-        assertFalse(userTO.getDerAttrs().isEmpty());
-        assertEquals(1, userTO.getMemberships().size());
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("new2Password").build());
-
-        String newUserId = getUUIDString() + "t.w@spre.net";
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("userId", newUserId));
-
-        String newFullName = getUUIDString() + "g.h@t.com";
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("fullname", newFullName));
-
-        userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).
-                membershipTO(new MembershipTO.Builder().group(8L).build()).build());
-        userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).
-                membershipTO(userTO.getMemberships().get(0)).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-
-        // issue SYNCOPE-15
-        assertNotNull(userTO.getCreationDate());
-        assertNotNull(userTO.getCreator());
-        assertNotNull(userTO.getLastChangeDate());
-        assertNotNull(userTO.getLastModifier());
-        assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
-
-        assertEquals(1, userTO.getMemberships().size());
-        assertFalse(userTO.getDerAttrs().isEmpty());
-
-        AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
-        assertEquals(Collections.singletonList(newUserId), userIdAttr.getValues());
-
-        AttrTO fullNameAttr = userTO.getPlainAttrMap().get("fullname");
-        assertEquals(Collections.singletonList(newFullName), fullNameAttr.getValues());
-    }
-
-    @Test
-    public void updatePasswordOnly() {
-        int beforeTasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build()).getTotalCount();
-        assertFalse(beforeTasks <= 0);
-
-        UserTO userTO = getUniqueSampleTO("pwdonly@t.com");
-        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-
-        userTO = createUser(userTO).getAny();
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").resource(RESOURCE_NAME_WS2).build());
-
-        userTO = updateUser(userPatch).getAny();
-
-        // check for changePwdDate
-        assertNotNull(userTO.getChangePwdDate());
-
-        int afterTasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build()).getTotalCount();
-        assertFalse(beforeTasks <= 0);
-
-        assertTrue(beforeTasks < afterTasks);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyTaskRegistration() {
-        // get task list
-        PagedResult<PropagationTaskTO> tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-        assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
-
-        long maxKey = tasks.getResult().iterator().next().getKey();
-
-        // --------------------------------------
-        // Create operation
-        // --------------------------------------
-        UserTO userTO = getUniqueSampleTO("t@p.mode");
-
-        // add a membership
-        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-
-        // 1. create user
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        // get the new task list
-        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-        assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
-
-        long newMaxKey = tasks.getResult().iterator().next().getKey();
-
-        // default configuration for ws-target-resource2 during create:
-        // only failed executions have to be registered
-        // --> no more tasks/executions should be added
-        assertEquals(newMaxKey, maxKey);
-
-        // --------------------------------------
-        // Update operation
-        // --------------------------------------
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("surname", "surname2"));
-
-        userTO = updateUser(userPatch).getAny();
-
-        assertNotNull(userTO);
-
-        // get the new task list
-        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-
-        maxKey = newMaxKey;
-        newMaxKey = tasks.getResult().iterator().next().getKey();
-
-        // default configuration for ws-target-resource2 during update:
-        // all update executions have to be registered
-        assertTrue(newMaxKey > maxKey);
-
-        PropagationTaskTO taskTO = taskService.read(newMaxKey, true);
-
-        assertNotNull(taskTO);
-        assertEquals(1, taskTO.getExecutions().size());
-
-        // --------------------------------------
-        // Delete operation
-        // --------------------------------------
-        userService.delete(userTO.getKey());
-
-        // get the new task list
-        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
-
-        maxKey = newMaxKey;
-        newMaxKey = tasks.getResult().iterator().next().getKey();
-
-        // default configuration for ws-target-resource2: no delete executions have to be registered
-        // --> no more tasks/executions should be added
-        assertEquals(newMaxKey, maxKey);
-    }
-
-    @Test
-    public void createActivate() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-
-        UserTO userTO = getUniqueSampleTO("createActivate@syncope.apache.org");
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(11L).build());
-
-        userTO = createUser(userTO).getAny();
-
-        assertNotNull(userTO);
-        assertNotNull(userTO.getToken());
-        assertNotNull(userTO.getTokenExpireTime());
-
-        assertEquals("created", userTO.getStatus());
-
-        StatusPatch statusPatch = new StatusPatch();
-        statusPatch.setKey(userTO.getKey());
-        statusPatch.setType(StatusPatchType.ACTIVATE);
-        statusPatch.setToken(userTO.getToken());
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-
-        assertNotNull(userTO);
-        assertNull(userTO.getToken());
-        assertNull(userTO.getTokenExpireTime());
-        assertEquals("active", userTO.getStatus());
-    }
-
-    @Test
-    public void suspendReactivate() {
-        UserTO userTO = getUniqueSampleTO("suspendReactivate@syncope.apache.org");
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
-
-        userTO = createUser(userTO).getAny();
-
-        assertNotNull(userTO);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
-                ? "active"
-                : "created", userTO.getStatus());
-
-        StatusPatch statusPatch = new StatusPatch();
-        statusPatch.setKey(userTO.getKey());
-        statusPatch.setType(StatusPatchType.SUSPEND);
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-        assertEquals("suspended", userTO.getStatus());
-
-        statusPatch = new StatusPatch();
-        statusPatch.setKey(userTO.getKey());
-        statusPatch.setType(StatusPatchType.REACTIVATE);
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-        assertEquals("active", userTO.getStatus());
-    }
-
-    @Test
-    public void suspendReactivateOnResource() {
-        // Assert resources are present
-        ResourceTO dbTable = resourceService.read(RESOURCE_NAME_TESTDB);
-        assertNotNull(dbTable);
-        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
-        assertNotNull(ldap);
-
-        // Create user with reference to resources
-        UserTO userTO = getUniqueSampleTO("suspreactonresource@syncope.apache.org");
-        userTO.getMemberships().clear();
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-        userTO.getResources().add(RESOURCE_NAME_LDAP);
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
-                ? "active"
-                : "created", userTO.getStatus());
-        long userKey = userTO.getKey();
-
-        // Suspend with effect on syncope, ldap and db => user should be suspended in syncope and all resources
-        StatusPatch statusPatch = new StatusPatch();
-        statusPatch.setKey(userKey);
-        statusPatch.setType(StatusPatchType.SUSPEND);
-        statusPatch.setOnSyncope(true);
-        statusPatch.getResources().add(RESOURCE_NAME_TESTDB);
-        statusPatch.getResources().add(RESOURCE_NAME_LDAP);
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-        assertEquals("suspended", userTO.getStatus());
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
-        assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userKey);
-        assertNotNull(connObjectTO);
-
-        // Suspend and reactivate only on ldap => db and syncope should still show suspended
-        statusPatch = new StatusPatch();
-        statusPatch.setKey(userKey);
-        statusPatch.setType(StatusPatchType.SUSPEND);
-        statusPatch.setOnSyncope(false);
-        statusPatch.getResources().add(RESOURCE_NAME_LDAP);
-        userService.status(statusPatch);
-        statusPatch.setType(StatusPatchType.REACTIVATE);
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-        assertEquals("suspended", userTO.getStatus());
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
-        assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
-
-        // Reactivate on syncope and db => syncope and db should show the user as active
-        statusPatch = new StatusPatch();
-        statusPatch.setKey(userKey);
-        statusPatch.setType(StatusPatchType.REACTIVATE);
-        statusPatch.setOnSyncope(true);
-        statusPatch.getResources().add(RESOURCE_NAME_TESTDB);
-
-        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-        assertEquals("active", userTO.getStatus());
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
-        assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
-    }
-
-    @Test
-    public void updateMultivalueAttribute() {
-        UserTO userTO = getUniqueSampleTO("multivalue@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        AttrTO loginDate = userTO.getPlainAttrMap().get("loginDate");
-        assertNotNull(loginDate);
-        assertEquals(1, loginDate.getValues().size());
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-
-        loginDate.getValues().add("2000-01-01");
-        userPatch.getPlainAttrs().add(new AttrPatch.Builder().
-                operation(PatchOperation.ADD_REPLACE).attrTO(loginDate).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-
-        loginDate = userTO.getPlainAttrMap().get("loginDate");
-        assertNotNull(loginDate);
-        assertEquals(2, loginDate.getValues().size());
-    }
-
-    private void verifyAsyncResult(final List<PropagationStatus> statuses) {
-        assertEquals(3, statuses.size());
-
-        Map<String, PropagationStatus> byResource = new HashMap<>(3);
-        MapUtils.populateMap(byResource, statuses, new Transformer<PropagationStatus, String>() {
-
-            @Override
-            public String transform(final PropagationStatus status) {
-                return status.getResource();
-            }
-        });
-        assertEquals(PropagationTaskExecStatus.SUCCESS, byResource.get(RESOURCE_NAME_LDAP).getStatus());
-        assertTrue(byResource.get(RESOURCE_NAME_TESTDB).getStatus() == PropagationTaskExecStatus.CREATED
-                || byResource.get(RESOURCE_NAME_TESTDB).getStatus() == PropagationTaskExecStatus.SUCCESS);
-        assertTrue(byResource.get(RESOURCE_NAME_TESTDB2).getStatus() == PropagationTaskExecStatus.CREATED
-                || byResource.get(RESOURCE_NAME_TESTDB2).getStatus() == PropagationTaskExecStatus.SUCCESS);
-    }
-
-    @Test
-    public void async() {
-        UserService asyncService =
-                clientFactory.create(ADMIN_UNAME, ADMIN_PWD).nullPriorityAsync(UserService.class, true);
-
-        UserTO user = getUniqueSampleTO("async@syncope.apache.org");
-        user.getResources().add(RESOURCE_NAME_TESTDB);
-        user.getResources().add(RESOURCE_NAME_TESTDB2);
-        user.getResources().add(RESOURCE_NAME_LDAP);
-
-        ProvisioningResult<UserTO> result = asyncService.create(user).readEntity(
-                new GenericType<ProvisioningResult<UserTO>>() {
-        });
-        assertNotNull(result);
-        verifyAsyncResult(result.getPropagationStatuses());
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(result.getAny().getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().
-                onSyncope(true).resources(RESOURCE_NAME_LDAP, RESOURCE_NAME_TESTDB, RESOURCE_NAME_TESTDB2).
-                value("password321").build());
-
-        result = asyncService.update(userPatch).readEntity(
-                new GenericType<ProvisioningResult<UserTO>>() {
-        });
-        assertNotNull(result);
-        verifyAsyncResult(result.getPropagationStatuses());
-
-        result = asyncService.delete(result.getAny().getKey()).readEntity(
-                new GenericType<ProvisioningResult<UserTO>>() {
-        });
-        assertNotNull(result);
-        verifyAsyncResult(result.getPropagationStatuses());
-    }
-
-    @Test(expected = EmptyResultDataAccessException.class)
-    public void issue213() {
-        UserTO userTO = getUniqueSampleTO("issue213@syncope.apache.org");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals(1, userTO.getResources().size());
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-        String username = jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class,
-                userTO.getUsername());
-
-        assertEquals(userTO.getUsername(), username);
-
-        UserPatch userPatch = new UserPatch();
-
-        userPatch.setKey(userTO.getKey());
-        userPatch.getResources().add(
-                new StringPatchItem.Builder().operation(PatchOperation.DELETE).value(RESOURCE_NAME_TESTDB).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertTrue(userTO.getResources().isEmpty());
-
-        jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
-    }
-
-    @Test
-    public void issue234() {
-        UserTO inUserTO = getUniqueSampleTO("issue234@syncope.apache.org");
-        inUserTO.getResources().add(RESOURCE_NAME_LDAP);
-
-        UserTO userTO = createUser(inUserTO).getAny();
-        assertNotNull(userTO);
-
-        UserPatch userPatch = new UserPatch();
-
-        userPatch.setKey(userTO.getKey());
-        userPatch.setUsername(new StringReplacePatchItem.Builder().value("1" + userTO.getUsername()).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-        assertEquals("1" + inUserTO.getUsername(), userTO.getUsername());
-    }
-
-    @Test
-    public final void issue280() {
-        UserTO userTO = getUniqueSampleTO("issue280@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).
-                resource(RESOURCE_NAME_TESTDB).value("123password").build());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
-
-        ProvisioningResult<UserTO> result = updateUser(userPatch);
-        assertNotNull(result);
-
-        List<PropagationStatus> propagations = result.getPropagationStatuses();
-        assertNotNull(propagations);
-        assertEquals(1, propagations.size());
-
-        assertEquals(PropagationTaskExecStatus.SUCCESS, propagations.get(0).getStatus());
-
-        String resource = propagations.get(0).getResource();
-        assertEquals(RESOURCE_NAME_TESTDB, resource);
-    }
-
-    @Test
-    public void issue281() {
-        UserTO userTO = getUniqueSampleTO("issue281@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertNotNull(result);
-
-        List<PropagationStatus> propagations = result.getPropagationStatuses();
-        assertNotNull(propagations);
-        assertEquals(1, propagations.size());
-        assertNotEquals(PropagationTaskExecStatus.SUCCESS, propagations.get(0).getStatus());
-
-        String resource = propagations.get(0).getResource();
-        assertEquals(RESOURCE_NAME_CSV, resource);
-    }
-
-    @Test
-    public void issue288() {
-        UserTO userTO = getSampleTO("issue288@syncope.apache.org");
-        userTO.getPlainAttrs().add(attrTO("aLong", "STRING"));
-
-        try {
-            createUser(userTO);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidValues, e.getType());
-        }
-    }
-
-    @Test
-    public void groupAttrPropagation() {
-        UserTO userTO = getUniqueSampleTO("checkGroupAttrPropagation@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(1L).build());
-
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertNotNull(actual.getDerAttrMap().get("csvuserid"));
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-        assertNotNull(connObjectTO);
-        assertEquals("sx-dx", connObjectTO.getPlainAttrMap().get("THEIRGROUP").getValues().get(0));
-    }
-
-    @Test
-    public void customPolicyRules() {
-        // Using custom policy rules with application/xml requires to overwrite
-        // org.apache.syncope.common.lib.policy.AbstractAccountRuleConf's and / or
-        // org.apache.syncope.common.lib.policy.AbstractPasswordRuleConf's
-        // @XmlSeeAlso - the power of JAXB :-/
-        Assume.assumeTrue(MediaType.APPLICATION_JSON_TYPE.equals(clientFactory.getContentType().getMediaType()));
-
-        AccountPolicyTO accountPolicy = new AccountPolicyTO();
-        accountPolicy.setDescription("Account Policy with custom rules");
-        accountPolicy.getRuleConfs().add(new TestAccountRuleConf());
-        accountPolicy = createPolicy(accountPolicy);
-        assertNotNull(accountPolicy);
-
-        PasswordPolicyTO passwordPolicy = new PasswordPolicyTO();
-        passwordPolicy.setDescription("Password Policy with custom rules");
-        passwordPolicy.getRuleConfs().add(new TestPasswordRuleConf());
-        passwordPolicy = createPolicy(passwordPolicy);
-        assertNotNull(passwordPolicy);
-
-        RealmTO realm = realmService.list("/even/two").get(0);
-        Long oldAccountPolicy = realm.getAccountPolicy();
-        realm.setAccountPolicy(accountPolicy.getKey());
-        Long oldPasswordPolicy = realm.getPasswordPolicy();
-        realm.setPasswordPolicy(passwordPolicy.getKey());
-        realmService.update(realm);
-
-        try {
-            UserTO user = getUniqueSampleTO("custompolicyrules@syncope.apache.org");
-            user.setRealm(realm.getFullPath());
-            try {
-                createUser(user);
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.InvalidUser, e.getType());
-                assertTrue(e.getElements().iterator().next().startsWith("InvalidPassword"));
-            }
-
-            user.setPassword(user.getPassword() + "XXX");
-            try {
-                createUser(user);
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.InvalidUser, e.getType());
-                assertTrue(e.getElements().iterator().next().startsWith("InvalidUsername"));
-            }
-
-            user.setUsername("YYY" + user.getUsername());
-            user = createUser(user).getAny();
-            assertNotNull(user);
-        } finally {
-            realm.setAccountPolicy(oldAccountPolicy);
-            realm.setPasswordPolicy(oldPasswordPolicy);
-            realmService.update(realm);
-
-            policyService.delete(passwordPolicy.getKey());
-            policyService.delete(accountPolicy.getKey());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE108() {
-        UserTO userTO = getUniqueSampleTO("syncope108@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(12L).build());
-        userTO.getMemberships().add(new MembershipTO.Builder().group(13L).build());
-
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals(2, userTO.getMemberships().size());
-        assertEquals(1, userTO.getResources().size());
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
-        assertNotNull(connObjectTO);
-
-        // -----------------------------------
-        // Remove the first membership: de-provisioning shouldn't happen
-        // -----------------------------------
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-
-        userPatch.getMemberships().add(new MembershipPatch.Builder().
-                operation(PatchOperation.DELETE).membershipTO(userTO.getMemberships().get(0)).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-        assertEquals(1, userTO.getMemberships().size());
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
-        assertNotNull(connObjectTO);
-        // -----------------------------------
-
-        // -----------------------------------
-        // Remove the resource assigned directly: de-provisioning shouldn't happen
-        // -----------------------------------
-        userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-
-        userPatch.getResources().add(new StringPatchItem.Builder().operation(PatchOperation.DELETE).
-                value(userTO.getResources().iterator().next()).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-        assertEquals(1, userTO.getMemberships().size());
-        assertFalse(userTO.getResources().isEmpty());
-
-        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
-        assertNotNull(connObjectTO);
-        // -----------------------------------
-
-        // -----------------------------------
-        // Remove the first membership: de-provisioning should happen
-        // -----------------------------------
-        userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-
-        userPatch.getMemberships().add(new MembershipPatch.Builder().
-                operation(PatchOperation.DELETE).membershipTO(userTO.getMemberships().get(0)).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-        assertTrue(userTO.getMemberships().isEmpty());
-        assertTrue(userTO.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
-            fail("Read should not succeeed");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE185() {
-        // 1. create user with LDAP resource, succesfully propagated
-        UserTO userTO = getSampleTO("syncope185@syncope.apache.org");
-        userTO.getVirAttrs().clear();
-        userTO.getResources().add(RESOURCE_NAME_LDAP);
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertNotNull(result);
-        assertFalse(result.getPropagationStatuses().isEmpty());
-        assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        userTO = result.getAny();
-
-        // 2. delete this user
-        userService.delete(userTO.getKey());
-
-        // 3. try (and fail) to find this user on the external LDAP resource
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
-            fail("This entry should not be present on this resource");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test()
-    public void issueSYNCOPE51() {
-        AttrTO defaultCA = configurationService.get("password.cipher.algorithm");
-        final String originalCAValue = defaultCA.getValues().get(0);
-        defaultCA.getValues().set(0, "MD5");
-        configurationService.set(defaultCA);
-
-        AttrTO newCA = configurationService.get(defaultCA.getSchema());
-        assertEquals(defaultCA, newCA);
-
-        UserTO userTO = getSampleTO("syncope51@syncope.apache.org");
-        userTO.setPassword("password");
-
-        try {
-            createUser(userTO);
-            fail("Create user should not succeed");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-            assertTrue(e.getElements().iterator().next().contains("MD5"));
-        }
-
-        defaultCA.getValues().set(0, originalCAValue);
-        configurationService.set(defaultCA);
-
-        AttrTO oldCA = configurationService.get(defaultCA.getSchema());
-        assertEquals(defaultCA, oldCA);
-    }
-
-    @Test
-    public void issueSYNCOPE267() {
-        // ----------------------------------
-        // create user and check virtual attribute value propagation
-        // ----------------------------------
-        UserTO userTO = getUniqueSampleTO("syncope267@apache.org");
-        userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertNotNull(result);
-        assertFalse(result.getPropagationStatuses().isEmpty());
-        assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(0).getResource());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        userTO = result.getAny();
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey());
-        assertNotNull(connObjectTO);
-        assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("USERNAME").getValues().get(0));
-        // ----------------------------------
-
-        userTO = userService.read(userTO.getKey());
-
-        assertNotNull(userTO);
-        assertEquals(1, userTO.getVirAttrs().size());
-        assertEquals("virtualvalue", userTO.getVirAttrs().iterator().next().getValues().get(0));
-    }
-
-    @Test
-    public void issueSYNCOPE266() {
-        UserTO userTO = getUniqueSampleTO("syncope266@apache.org");
-        userTO.getResources().clear();
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-
-        // this resource has not a mapping for Password
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_UPDATE).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertNotNull(userTO);
-    }
-
-    @Test
-    public void issueSYNCOPE279() {
-        UserTO userTO = getUniqueSampleTO("syncope279@apache.org");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_TIMEOUT);
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        assertEquals(RESOURCE_NAME_TIMEOUT, result.getPropagationStatuses().get(0).getResource());
-        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
-        assertEquals(PropagationTaskExecStatus.FAILURE, result.getPropagationStatuses().get(0).getStatus());
-    }
-
-    @Test
-    public void issueSYNCOPE122() {
-        // 1. create user on testdb and testdb2
-        UserTO userTO = getUniqueSampleTO("syncope122@apache.org");
-        userTO.getResources().clear();
-
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-        userTO.getResources().add(RESOURCE_NAME_TESTDB2);
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
-        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB2));
-
-        final String pwdOnSyncope = userTO.getPassword();
-
-        ConnObjectTO userOnDb = resourceService.readConnObject(
-                RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
-        final AttrTO pwdOnTestDbAttr = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
-        assertNotNull(pwdOnTestDbAttr);
-        assertNotNull(pwdOnTestDbAttr.getValues());
-        assertFalse(pwdOnTestDbAttr.getValues().isEmpty());
-        final String pwdOnTestDb = pwdOnTestDbAttr.getValues().iterator().next();
-
-        ConnObjectTO userOnDb2 = resourceService.readConnObject(
-                RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
-        final AttrTO pwdOnTestDb2Attr = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
-        assertNotNull(pwdOnTestDb2Attr);
-        assertNotNull(pwdOnTestDb2Attr.getValues());
-        assertFalse(pwdOnTestDb2Attr.getValues().isEmpty());
-        final String pwdOnTestDb2 = pwdOnTestDb2Attr.getValues().iterator().next();
-
-        // 2. request to change password only on testdb (no Syncope, no testdb2)
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value(getUUIDString()).onSyncope(false).
-                resource(RESOURCE_NAME_TESTDB).build());
-
-        ProvisioningResult<UserTO> result = updateUser(userPatch);
-        userTO = result.getAny();
-
-        // 3a. Chech that only a single propagation took place
-        assertNotNull(result.getPropagationStatuses());
-        assertEquals(1, result.getPropagationStatuses().size());
-        assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().iterator().next().getResource());
-
-        // 3b. verify that password hasn't changed on Syncope
-        assertEquals(pwdOnSyncope, userTO.getPassword());
-
-        // 3c. verify that password *has* changed on testdb
-        userOnDb = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
-        final AttrTO pwdOnTestDbAttrAfter = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
-        assertNotNull(pwdOnTestDbAttrAfter);
-        assertNotNull(pwdOnTestDbAttrAfter.getValues());
-        assertFalse(pwdOnTestDbAttrAfter.getValues().isEmpty());
-        assertNotEquals(pwdOnTestDb, pwdOnTestDbAttrAfter.getValues().iterator().next());
-
-        // 3d. verify that password hasn't changed on testdb2
-        userOnDb2 = resourceService.readConnObject(RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
-        final AttrTO pwdOnTestDb2AttrAfter = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
-        assertNotNull(pwdOnTestDb2AttrAfter);
-        assertNotNull(pwdOnTestDb2AttrAfter.getValues());
-        assertFalse(pwdOnTestDb2AttrAfter.getValues().isEmpty());
-        assertEquals(pwdOnTestDb2, pwdOnTestDb2AttrAfter.getValues().iterator().next());
-    }
-
-    @Test
-    public void isseSYNCOPE136AES() {
-        // 1. read configured cipher algorithm in order to be able to restore it at the end of test
-        AttrTO pwdCipherAlgo = configurationService.get("password.cipher.algorithm");
-        final String origpwdCipherAlgo = pwdCipherAlgo.getValues().get(0);
-
-        // 2. set AES password cipher algorithm
-        pwdCipherAlgo.getValues().set(0, "AES");
-        configurationService.set(pwdCipherAlgo);
-
-        try {
-            // 3. create user with no resources
-            UserTO userTO = getUniqueSampleTO("syncope136_AES@apache.org");
-            userTO.getResources().clear();
-
-            userTO = createUser(userTO).getAny();
-            assertNotNull(userTO);
-
-            // 4. update user, assign a propagation priority resource but don't provide any password
-            UserPatch userPatch = new UserPatch();
-            userPatch.setKey(userTO.getKey());
-            userPatch.getResources().add(new StringPatchItem.Builder().
-                    operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
-            userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_WS1).build());
-
-            ProvisioningResult<UserTO> result = updateUser(userPatch);
-            assertNotNull(result);
-            userTO = result.getAny();
-            assertNotNull(userTO);
-
-            // 5. verify that propagation was successful
-            List<PropagationStatus> props = result.getPropagationStatuses();
-            assertNotNull(props);
-            assertEquals(1, props.size());
-            PropagationStatus prop = props.iterator().next();
-            assertNotNull(prop);
-            assertEquals(RESOURCE_NAME_WS1, prop.getResource());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
-        } finally {
-            // restore initial cipher algorithm
-            pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
-            configurationService.set(pwdCipherAlgo);
-        }
-    }
-
-    @Test
-    public void isseSYNCOPE136Random() {
-        // 1. create user with no resources
-        UserTO userTO = getUniqueSampleTO("syncope136_Random@apache.org");
-        userTO.getResources().clear();
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        // 2. update user, assign a propagation priority resource but don't provide any password
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
-        userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
-
-        ProvisioningResult<UserTO> result = updateUser(userPatch);
-        assertNotNull(result);
-
-        // 3. verify that propagation was successful
-        List<PropagationStatus> props = result.getPropagationStatuses();
-        assertNotNull(props);
-        assertEquals(1, props.size());
-        PropagationStatus prop = props.iterator().next();
-        assertNotNull(prop);
-        assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
-    }
-
-    @Test
-    public void mappingPurpose() {
-        UserTO userTO = getUniqueSampleTO("mpurpose@apache.org");
-        userTO.getAuxClasses().add("csv");
-
-        AttrTO csvuserid = new AttrTO();
-        csvuserid.setSchema("csvuserid");
-        userTO.getDerAttrs().add(csvuserid);
-
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
-        assertNull(connObjectTO.getPlainAttrMap().get("email"));
-    }
-
-    @Test
-    public void issueSYNCOPE265() {
-        for (long key = 1; key <= 5; key++) {
-            UserPatch userPatch = new UserPatch();
-            userPatch.setKey(key);
-
-            userPatch.getPlainAttrs().add(attrAddReplacePatch("type", "a type"));
-
-            UserTO userTO = updateUser(userPatch).getAny();
-
-            assertEquals("a type", userTO.getPlainAttrMap().get("type").getValues().get(0));
-        }
-    }
-
-    @Test
-    public void bulkActions() {
-        BulkAction bulkAction = new BulkAction();
-
-        for (int i = 0; i < 10; i++) {
-            UserTO userTO = getUniqueSampleTO("bulk_" + i + "@apache.org");
-            bulkAction.getTargets().add(String.valueOf(createUser(userTO).getAny().getKey()));
-        }
-
-        // check for a fail
-        bulkAction.getTargets().add(String.valueOf(Long.MAX_VALUE));
-
-        assertEquals(11, bulkAction.getTargets().size());
-
-        bulkAction.setType(BulkAction.Type.SUSPEND);
-        BulkActionResult res = userService.bulk(bulkAction);
-        assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
-        assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
-        assertEquals("suspended", userService.read(
-                Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
-
-        bulkAction.setType(BulkAction.Type.REACTIVATE);
-        res = userService.bulk(bulkAction);
-        assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
-        assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
-        assertEquals("active", userService.read(
-                Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
-
-        bulkAction.setType(BulkAction.Type.DELETE);
-        res = userService.bulk(bulkAction);
-        assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
-        assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
-    }
-
-    @Test
-    public void issueSYNCOPE354() {
-        // change resource-ldap group mapping for including uniqueMember (need for assertions below)
-        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
-        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
-            if ("description".equals(item.getExtAttrName())) {
-                item.setExtAttrName("uniqueMember");
-            }
-        }
-        resourceService.update(ldap);
-
-        // 1. create group with LDAP resource
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName("SYNCOPE354-" + getUUIDString());
-        groupTO.setRealm("/");
-        groupTO.getResources().add(RESOURCE_NAME_LDAP);
-
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-
-        // 2. create user with LDAP resource and membership of the above group
-        UserTO userTO = getUniqueSampleTO("syncope354@syncope.apache.org");
-        userTO.getResources().add(RESOURCE_NAME_LDAP);
-        userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
-
-        userTO = createUser(userTO).getAny();
-        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
-
-        // 3. read group on resource, check that user DN is included in uniqueMember
-        ConnObjectTO connObj = resourceService.readConnObject(
-                RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
-        assertNotNull(connObj);
-        assertTrue(connObj.getPlainAttrMap().get("uniqueMember").getValues().
-                contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
-
-        // 4. remove membership
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.DELETE).
-                membershipTO(userTO.getMemberships().get(0)).build());
-
-        userTO = updateUser(userPatch).getAny();
-        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
-
-        // 5. read group on resource, check that user DN was removed from uniqueMember
-        connObj = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
-        assertNotNull(connObj);
-        assertFalse(connObj.getPlainAttrMap().get("uniqueMember").getValues().
-                contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
-
-        // 6. restore original resource-ldap group mapping
-        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
-            if ("uniqueMember".equals(item.getExtAttrName())) {
-                item.setExtAttrName("description");
-            }
-        }
-        resourceService.update(ldap);
-    }
-
-    @Test
-    public void issueSYNCOPE357() throws IOException {
-        // 1. create group with LDAP resource
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName("SYNCOPE357-" + getUUIDString());
-        groupTO.setRealm("/");
-        groupTO.getResources().add(RESOURCE_NAME_LDAP);
-
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-
-        // 2. create user with membership of the above group
-        UserTO userTO = getUniqueSampleTO("syncope357@syncope.apache.org");
-        userTO.getPlainAttrs().add(attrTO("obscure", "valueToBeObscured"));
-        userTO.getPlainAttrs().add(attrTO("photo",
-                Base64Utility.encode(IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
-        userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
-
-        userTO = createUser(userTO).getAny();
-        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
-        assertNotNull(userTO.getPlainAttrMap().get("obscure"));
-        assertNotNull(userTO.getPlainAttrMap().get("photo"));
-
-        // 3. read user on resource
-        ConnObjectTO connObj = resourceService.readConnObject(
-                RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
-        assertNotNull(connObj);
-        AttrTO registeredAddress = connObj.getPlainAttrMap().get("registeredAddress");
-        assertNotNull(registeredAddress);
-        assertEquals(userTO.getPlainAttrMap().get("obscure").getValues(), registeredAddress.getValues());
-        AttrTO jpegPhoto = connObj.getPlainAttrMap().get("jpegPhoto");
-        assertNotNull(jpegPhoto);
-        assertEquals(userTO.getPlainAttrMap().get("photo").getValues(), jpegPhoto.getValues());
-
-        // 4. remove group
-        groupService.delete(groupTO.getKey());
-
-        // 5. try to read user on resource: fail
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE383() {
-        // 1. create user without resources
-        UserTO userTO = getUniqueSampleTO("syncope383@apache.org");
-        userTO.getResources().clear();
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        // 2. assign resource without specifying a new pwd and check propagation failure
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
-
-        ProvisioningResult<UserTO> result = updateUser(userPatch);
-        assertNotNull(result);
-        userTO = result.getAny();
-        assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
-        assertNotEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
-        userTO = result.getAny();
-
-        // 3. request to change password only on testdb
-        userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(
-                new PasswordPatch.Builder().value(getUUIDString() + "abbcbcbddd123").resource(RESOURCE_NAME_TESTDB).
-                build());
-
-        result = updateUser(userPatch);
-        assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
-        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-    }
-
-    @Test
-    public void issueSYNCOPE402() {
-        // 1. create an user with strict mandatory attributes only
-        UserTO userTO = new UserTO();
-        userTO.setRealm(SyncopeConstants.ROOT_REALM);
-        String userId = getUUIDString() + "syncope402@syncope.apache.org";
-        userTO.setUsername(userId);
-        userTO.setPassword("password123");
-
-        userTO.getPlainAttrs().add(attrTO("userId", userId));
-        userTO.getPlainAttrs().add(attrTO("fullname", userId));
-        userTO.getPlainAttrs().add(attrTO("surname", userId));
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertTrue(userTO.getResources().isEmpty());
-
-        // 2. update assigning a resource NOT forcing mandatory constraints
-        // AND priority: must fail with PropagationException
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
-        ProvisioningResult<UserTO> result = updateUser(userPatch);
-
-        List<PropagationStatus> propagationStatuses = result.getPropagationStatuses();
-        PropagationStatus ws1PropagationStatus = null;
-        if (propagationStatuses != null) {
-            for (PropagationStatus propStatus : propagationStatuses) {
-                if (RESOURCE_NAME_WS1.equals(propStatus.getResource())) {
-                    ws1PropagationStatus = propStatus;
-                    break;
-                }
-            }
-        }
-        assertNotNull(ws1PropagationStatus);
-        assertEquals(RESOURCE_NAME_WS1, ws1PropagationStatus.getResource());
-        assertNotNull(ws1PropagationStatus.getFailureReason());
-        assertEquals(PropagationTaskExecStatus.FAILURE, ws1PropagationStatus.getStatus());
-    }
-
-    @Test
-    public void unlink() {
-        UserTO userTO = getUniqueSampleTO("unlink@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
-    }
-
-    @Test
-    public void link() {
-        UserTO userTO = getUniqueSampleTO("link@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setAction(ResourceAssociationAction.LINK);
-        associationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertFalse(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void unassign() {
-        UserTO userTO = getUniqueSampleTO("unassign@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.UNASSIGN);
-        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void assign() {
-        UserTO userTO = getUniqueSampleTO("assign@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setValue("password");
-        associationPatch.setAction(ResourceAssociationAction.ASSIGN);
-        associationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertFalse(actual.getResources().isEmpty());
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
-    }
-
-    @Test
-    public void deprovision() {
-        UserTO userTO = getUniqueSampleTO("deprovision@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
-        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertFalse(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void provision() {
-        UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setValue("password");
-        associationPatch.setAction(ResourceAssociationAction.PROVISION);
-        associationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
-    }
-
-    @Test
-    public void deprovisionUnlinked() {
-        UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getAuxClasses().add("csv");
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        UserTO actual = createUser(userTO).getAny();
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setValue("password");
-        associationPatch.setAction(ResourceAssociationAction.PROVISION);
-        associationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
-        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
-
-        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = userService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE420() {
-        RealmTO realm = realmService.list("/even/two").iterator().next();
-        assertNotNull(realm);
-        realm.getActionsClassNames().add(DoubleValueLogicActions.class.getName());
-        realmService.update(realm);
-
-        UserTO userTO = getUniqueSampleTO("syncope420@syncope.apache.org");
-        userTO.setRealm(realm.getFullPath());
-        userTO.getPlainAttrs().add(attrTO("makeItDouble", "3"));
-
-        userTO = createUser(userTO).getAny();
-        assertEquals("6", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("makeItDouble", "7"));
-
-        userTO = updateUser(userPatch).getAny();
-        assertEquals("14", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
-    }
-
-    @Test
-    public void issueSYNCOPE426() {
-        UserTO userTO = getUniqueSampleTO("syncope426@syncope.apache.org");
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
-        userTO = userService.update(userPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-    }
-
-    @Test
-    public void issueSYNCOPE435() {
-        // 1. create user without password
-        UserTO userTO = getUniqueSampleTO("syncope435@syncope.apache.org");
-        userTO.setPassword(null);
-        userTO = createUser(userTO, false).getAny();
-        assertNotNull(userTO);
-
-        // 2. try to update user by subscribing a resource - works but propagation is not even attempted
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
-
-        ProvisioningResult<UserTO> result = updateUser(userPatch);
-        assertNotNull(result);
-        userTO = result.getAny();
-        assertEquals(Collections.singleton(RESOURCE_NAME_WS1), userTO.getResources());
-        assertNotEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-        assertTrue(result.getPropagationStatuses().get(0).getFailureReason().
-                startsWith("Not attempted because there are mandatory attributes without

<TRUNCATED>

[02/21] syncope git commit: Clean up: removing some not necessary methods from persistence-api and adjusting accordingly

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
index 7f87029..c5099f3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
@@ -37,6 +37,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
 import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
@@ -130,24 +131,13 @@ public class JPAAccountPolicy extends AbstractPolicy implements AccountPolicy {
     }
 
     @Override
-    public boolean remove(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        return resources.remove((JPAExternalResource) resource);
-    }
-
-    @Override
     public Set<? extends ExternalResource> getResources() {
         return resources;
     }
 
     @Override
     public Set<String> getResourceNames() {
-        return CollectionUtils.collect(getResources(), new Transformer<ExternalResource, String>() {
-
-            @Override
-            public String transform(final ExternalResource input) {
-                return input.getKey();
-            }
-        }, new HashSet<String>());
+        return CollectionUtils.collect(
+                getResources(), EntityUtils.<String, ExternalResource>keyTransformer(), new HashSet<String>());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
index 1f10447..12d5959 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
@@ -211,12 +211,6 @@ public class JPAExternalResource extends AbstractAnnotatedEntity<String> impleme
     }
 
     @Override
-    public boolean remove(final Provision provision) {
-        checkType(provision, JPAProvision.class);
-        return this.provisions.remove((JPAProvision) provision);
-    }
-
-    @Override
     public Provision getProvision(final ObjectClass objectClass) {
         return IterableUtils.find(provisions, new Predicate<Provision>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
index 752115c..63fb48d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
@@ -84,12 +84,6 @@ public class JPAMapping extends AbstractEntity<Long> implements Mapping {
     }
 
     @Override
-    public boolean remove(final MappingItem item) {
-        checkType(item, JPAMappingItem.class);
-        return items.remove((JPAMappingItem) item);
-    }
-
-    @Override
     public List<? extends MappingItem> getItems() {
         return items;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractTask.java
index 938502d..4d67941 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractTask.java
@@ -68,18 +68,12 @@ public abstract class AbstractTask extends AbstractEntity<Long> implements Task
     }
 
     @Override
-    public boolean addExec(final TaskExec exec) {
+    public boolean add(final TaskExec exec) {
         checkType(exec, JPATaskExec.class);
         return exec != null && !executions.contains((JPATaskExec) exec) && executions.add((JPATaskExec) exec);
     }
 
     @Override
-    public boolean removeExec(final TaskExec exec) {
-        checkType(exec, JPATaskExec.class);
-        return exec != null && executions.remove((JPATaskExec) exec);
-    }
-
-    @Override
     public List<? extends TaskExec> getExecs() {
         return executions;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
index a6f6d75..c6677e0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
@@ -73,12 +73,6 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
     }
 
     @Override
-    public boolean remove(final PushTaskAnyFilter filter) {
-        checkType(filter, JPAPushTaskAnyFilter.class);
-        return this.filters.remove((JPAPushTaskAnyFilter) filter);
-    }
-
-    @Override
     public PushTaskAnyFilter getFilter(final AnyType anyType) {
         return IterableUtils.find(filters, new Predicate<PushTaskAnyFilter>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
index b48a6e3..30b654e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
@@ -121,12 +121,6 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @Override
-    public boolean remove(final AnyTemplateSyncTask template) {
-        checkType(template, JPAAnyTemplateSyncTask.class);
-        return this.templates.remove((JPAAnyTemplateSyncTask) template);
-    }
-
-    @Override
     public AnyTemplateSyncTask getTemplate(final AnyType anyType) {
         return IterableUtils.find(templates, new Predicate<AnyTemplate>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
index 5dd0902..d4fe264 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
@@ -37,12 +37,6 @@ public abstract class AbstractUDynMembership extends AbstractDynMembership<User>
     }
 
     @Override
-    public boolean remove(final User user) {
-        checkType(user, JPAUser.class);
-        return internalGetUsers().remove((JPAUser) user);
-    }
-
-    @Override
     public List<? extends User> getMembers() {
         return internalGetUsers();
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
index 50ce967..38fa9a7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
@@ -91,12 +91,6 @@ public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr
     }
 
     @Override
-    public boolean remove(final PlainAttrValue attrValue) {
-        checkType(attrValue, JPAUPlainAttrValue.class);
-        return values.remove((JPAUPlainAttrValue) attrValue);
-    }
-
-    @Override
     public List<? extends UPlainAttrValue> getValues() {
         return values;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index e4a6711..c8e6672 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -217,12 +217,6 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User {
     }
 
     @Override
-    public boolean remove(final Role role) {
-        checkType(role, JPARole.class);
-        return roles.remove((JPARole) role);
-    }
-
-    @Override
     public List<? extends Role> getRoles() {
         return roles;
     }
@@ -285,12 +279,6 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User {
     }
 
     @Override
-    public boolean remove(final UPlainAttr attr) {
-        checkType(attr, JPAUPlainAttr.class);
-        return plainAttrs.remove((JPAUPlainAttr) attr);
-    }
-
-    @Override
     public List<? extends UPlainAttr> getPlainAttrs() {
         return plainAttrs;
     }
@@ -481,12 +469,6 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User {
     }
 
     @Override
-    public boolean remove(final AnyTypeClass auxClass) {
-        checkType(auxClass, JPAAnyTypeClass.class);
-        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
-    }
-
-    @Override
     public List<? extends AnyTypeClass> getAuxClasses() {
         return auxClasses;
     }
@@ -498,12 +480,6 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User {
     }
 
     @Override
-    public boolean remove(final URelationship relationship) {
-        checkType(relationship, JPAURelationship.class);
-        return this.relationships.remove((JPAURelationship) relationship);
-    }
-
-    @Override
     public URelationship getRelationship(final RelationshipType relationshipType, final Long anyObjectKey) {
         return IterableUtils.find(getRelationships(), new Predicate<URelationship>() {
 
@@ -550,12 +526,6 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User {
     }
 
     @Override
-    public boolean remove(final UMembership membership) {
-        checkType(membership, JPAUMembership.class);
-        return this.memberships.remove((JPAUMembership) membership);
-    }
-
-    @Override
     public UMembership getMembership(final Long groupKey) {
         return IterableUtils.find(getMemberships(), new Predicate<UMembership>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
index cdf4478..469816c 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
@@ -81,7 +81,7 @@ public class TaskExecTest extends AbstractTest {
         exec.setStatus(PropagationTaskExecStatus.SUCCESS.name());
         exec.setMessage(faultyMessage);
 
-        task.addExec(exec);
+        task.add(exec);
         exec.setTask(task);
 
         exec = taskExecDAO.save(exec);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index 7d40678..33980a2 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -30,8 +30,8 @@ import java.util.HashSet;
 import java.util.List;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
@@ -217,13 +217,9 @@ public class GroupTest extends AbstractTest {
         // 3. verify that expected users have the created group dynamically assigned
         assertEquals(2, actual.getUDynMembership().getMembers().size());
         assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
-                CollectionUtils.collect(actual.getUDynMembership().getMembers(), new Transformer<User, Long>() {
-
-                    @Override
-                    public Long transform(final User input) {
-                        return input.getKey();
-                    }
-                }, new HashSet<Long>()));
+                CollectionUtils.collect(actual.getUDynMembership().getMembers(),
+                        EntityUtils.<Long, User>keyTransformer(),
+                        new HashSet<Long>()));
 
         user = userDAO.find(4L);
         assertNotNull(user);
@@ -312,13 +308,8 @@ public class GroupTest extends AbstractTest {
         assertEquals(2, actual.getADynMembership(anyTypeDAO.find("PRINTER")).getMembers().size());
         assertEquals(new HashSet<>(Arrays.asList(1L, newAnyObjectKey)),
                 CollectionUtils.collect(actual.getADynMembership(anyTypeDAO.find("PRINTER")).getMembers(),
-                        new Transformer<AnyObject, Long>() {
-
-                    @Override
-                    public Long transform(final AnyObject input) {
-                        return input.getKey();
-                    }
-                }, new HashSet<Long>()));
+                        EntityUtils.<Long, AnyObject>keyTransformer(),
+                        new HashSet<Long>()));
 
         anyObject = anyObjectDAO.find(1L);
         assertNotNull(anyObject);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
index 2a8a090..6f7e8be 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
@@ -275,7 +275,7 @@ public class ResourceTest extends AbstractTest {
         }
 
         Provision groupProvision = ldap.getProvision(anyTypeDAO.findGroup());
-        ldap.remove(groupProvision);
+        ldap.getProvisions().remove(groupProvision);
         for (VirSchema schema : virSchemaDAO.findByProvision(groupProvision)) {
             virSchemaDAO.delete(schema.getKey());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
index a3a4ea6..f9d284f 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -28,9 +28,9 @@ import java.util.Collection;
 import java.util.HashSet;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
@@ -125,13 +125,9 @@ public class RoleTest extends AbstractTest {
         // 3. verify that expected users have the created role dynamically assigned
         assertEquals(2, actual.getDynMembership().getMembers().size());
         assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
-                CollectionUtils.collect(actual.getDynMembership().getMembers(), new Transformer<User, Long>() {
-
-                    @Override
-                    public Long transform(final User input) {
-                        return input.getKey();
-                    }
-                }, new HashSet<Long>()));
+                CollectionUtils.collect(actual.getDynMembership().getMembers(),
+                        EntityUtils.<Long, User>keyTransformer(),
+                        new HashSet<Long>()));
 
         user = userDAO.find(4L);
         assertNotNull(user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
index 4a62a6a..ae07439 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
@@ -127,7 +127,7 @@ public class TaskTest extends AbstractTest {
         execution.setTask(task);
         execution.setStatus(PropagationTaskExecStatus.CREATED.name());
         execution.setStart(new Date());
-        task.addExec(execution);
+        task.add(execution);
 
         taskDAO.save(task);
         taskDAO.flush();
@@ -150,7 +150,7 @@ public class TaskTest extends AbstractTest {
         execution.setTask(task);
         execution.setStart(new Date());
         execution.setMessage("A message");
-        task.addExec(execution);
+        task.add(execution);
 
         taskDAO.save(task);
         taskDAO.flush();
@@ -173,7 +173,7 @@ public class TaskTest extends AbstractTest {
         execution.setTask(task);
         execution.setStart(new Date());
         execution.setMessage("A message");
-        task.addExec(execution);
+        task.add(execution);
 
         taskDAO.save(task);
         taskDAO.flush();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
index 62bba9c..129b78c 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
@@ -95,7 +95,7 @@ public class UserTest extends AbstractTest {
         assertEquals(1, user.getMemberships().size());
         assertEquals(7L, user.getMemberships().get(0).getRightEnd().getKey(), 0);
 
-        user.remove(user.getMemberships().get(0));
+        user.getMemberships().remove(0);
 
         UMembership newM = entityFactory.newEntity(UMembership.class);
         newM.setLeftEnd(user);
@@ -112,7 +112,7 @@ public class UserTest extends AbstractTest {
         assertEquals(1, user.getRelationships().size());
         assertEquals(1L, user.getRelationships().get(0).getRightEnd().getKey(), 0);
 
-        user.remove(user.getRelationships().get(0));
+        user.getRelationships().remove(0);
 
         URelationship newR = entityFactory.newEntity(URelationship.class);
         newR.setType(relationshipTypeDAO.find("neighborhood"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ConnInstanceDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ConnInstanceDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ConnInstanceDataBinder.java
index 373d1af..a111cc4 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ConnInstanceDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ConnInstanceDataBinder.java
@@ -31,6 +31,6 @@ public interface ConnInstanceDataBinder {
 
     ConnInstanceTO getConnInstanceTO(ConnInstance connInstance);
 
-    ConnInstance update(long key, ConnInstanceTO connInstanceTO);
+    ConnInstance update(Long key, ConnInstanceTO connInstanceTO);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/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 686742a..3d96cfc 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
@@ -62,6 +62,7 @@ import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.misc.utils.ConnObjectUtils;
 import org.apache.syncope.core.misc.utils.MappingUtils;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
@@ -345,7 +346,7 @@ abstract class AbstractAnyDataBinder {
 
             case DELETE:
             default:
-                any.remove(attr);
+                any.getPlainAttrs().remove(attr);
                 plainAttrDAO.delete(attr.getKey(), anyUtils.plainAttrClass());
         }
 
@@ -382,7 +383,7 @@ abstract class AbstractAnyDataBinder {
 
                     case DELETE:
                     default:
-                        any.remove(auxClass);
+                        any.getAuxClasses().remove(auxClass);
                 }
             }
         }
@@ -402,7 +403,7 @@ abstract class AbstractAnyDataBinder {
                     case DELETE:
                     default:
                         propByRes.add(ResourceOperation.DELETE, resource.getKey());
-                        any.remove(resource);
+                        any.getResources().remove(resource);
                 }
             }
         }
@@ -513,13 +514,7 @@ abstract class AbstractAnyDataBinder {
 
         anyTO.setRealm(realmFullPath);
 
-        CollectionUtils.collect(auxClasses, new Transformer<AnyTypeClass, String>() {
-
-            @Override
-            public String transform(final AnyTypeClass role) {
-                return role.getKey();
-            }
-        }, anyTO.getAuxClasses());
+        CollectionUtils.collect(auxClasses, EntityUtils.<String, AnyTypeClass>keyTransformer(), anyTO.getAuxClasses());
 
         for (PlainAttr<?> plainAttr : plainAttrs) {
             AttrTO attrTO = new AttrTO();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/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 fbd090c..1c889f6 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
@@ -41,6 +41,7 @@ import org.apache.syncope.common.lib.types.PatchOperation;
 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.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
@@ -111,13 +112,9 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
             }, anyObjectTO.getMemberships());
 
             // dynamic memberships
-            CollectionUtils.collect(anyObjectDAO.findDynGroupMemberships(anyObject), new Transformer<Group, Long>() {
-
-                @Override
-                public Long transform(final Group group) {
-                    return group.getKey();
-                }
-            }, anyObjectTO.getDynGroups());
+            CollectionUtils.collect(anyObjectDAO.findDynGroupMemberships(anyObject),
+                    EntityUtils.<Long, Group>keyTransformer(),
+                    anyObjectTO.getDynGroups());
         }
 
         return anyObjectTO;
@@ -256,7 +253,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
                     ARelationship relationship =
                             anyObject.getRelationship(relationshipType, patch.getRelationshipTO().getRightKey());
                     if (relationship != null) {
-                        anyObject.remove(relationship);
+                        anyObject.getRelationships().remove(relationship);
                         toBeDeprovisioned.addAll(relationship.getRightEnd().getResourceNames());
                     }
 
@@ -305,7 +302,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
             if (patch.getMembershipTO() != null) {
                 AMembership membership = anyObject.getMembership(patch.getMembershipTO().getRightKey());
                 if (membership != null) {
-                    anyObject.remove(membership);
+                    anyObject.getMemberships().remove(membership);
                     toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
                 }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
index aa0549b..d4a6b08 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
@@ -44,7 +44,7 @@ import org.springframework.stereotype.Component;
 @Component
 public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
 
-    private static final String[] IGNORE_PROPERTIES = { "key", "poolConf" };
+    private static final String[] IGNORE_PROPERTIES = { "poolConf" };
 
     @Autowired
     private ConnIdBundleManager connIdBundleManager;
@@ -99,14 +99,14 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
     }
 
     @Override
-    public ConnInstance update(final long connInstanceId, final ConnInstanceTO connInstanceTO) {
+    public ConnInstance update(final Long key, final ConnInstanceTO connInstanceTO) {
         SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
 
-        if (connInstanceId == 0) {
-            sce.getElements().add("connector id");
+        if (key == 0) {
+            sce.getElements().add("connector key");
         }
 
-        ConnInstance connInstance = connInstanceDAO.find(connInstanceId);
+        ConnInstance connInstance = connInstanceDAO.find(key);
         connInstance.getCapabilities().clear();
         connInstance.getCapabilities().addAll(connInstanceTO.getCapabilities());
 
@@ -180,7 +180,6 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
     @Override
     public ConnInstanceTO getConnInstanceTO(final ConnInstance connInstance) {
         ConnInstanceTO connInstanceTO = new ConnInstanceTO();
-        connInstanceTO.setKey(connInstance.getKey() == null ? 0L : connInstance.getKey());
 
         BeanUtils.copyProperties(connInstance, connInstanceTO, IGNORE_PROPERTIES);
 
@@ -193,11 +192,11 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
             ConnConfProperty property = IterableUtils.find(connInstanceTO.getConf(),
                     new Predicate<ConnConfProperty>() {
 
-                        @Override
-                        public boolean evaluate(final ConnConfProperty candidate) {
-                            return propName.equals(candidate.getSchema().getName());
-                        }
-                    });
+                @Override
+                public boolean evaluate(final ConnConfProperty candidate) {
+                    return propName.equals(candidate.getSchema().getName());
+                }
+            });
             if (property == null) {
                 property = new ConnConfProperty();
                 connInstanceTO.getConf().add(property);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
index 20c52b3..a51729b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -164,7 +164,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
                 }
 
                 if (typeExt.getAuxClasses().isEmpty()) {
-                    group.remove(typeExt);
+                    group.getTypeExtensions().remove(typeExt);
                     typeExt.setGroup(null);
                 }
             }
@@ -280,7 +280,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
 
                 // only consider non-empty type extensions
                 if (typeExt.getAuxClasses().isEmpty()) {
-                    group.remove(typeExt);
+                    group.getTypeExtensions().remove(typeExt);
                     typeExt.setGroup(null);
                 }
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
index 002fbd9..dc8a957 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
@@ -100,7 +100,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
                 merged.setAnyTypeClass(anyTypeClass);
             }
         } else if (schemaTO.getAnyTypeClass() == null && merged.getAnyTypeClass() != null) {
-            merged.getAnyTypeClass().remove(merged);
+            merged.getAnyTypeClass().getPlainSchemas().remove(merged);
             merged.setAnyTypeClass(null);
         }
 
@@ -191,7 +191,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
                 merged.setAnyTypeClass(anyTypeClass);
             }
         } else if (schemaTO.getAnyTypeClass() == null && merged.getAnyTypeClass() != null) {
-            merged.getAnyTypeClass().remove(merged);
+            merged.getAnyTypeClass().getDerSchemas().remove(merged);
             merged.setAnyTypeClass(null);
         }
 
@@ -234,7 +234,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
                 schema.setAnyTypeClass(anyTypeClass);
             }
         } else if (schemaTO.getAnyTypeClass() == null && schema.getAnyTypeClass() != null) {
-            schema.getAnyTypeClass().remove(schema);
+            schema.getAnyTypeClass().getVirSchemas().remove(schema);
             schema.setAnyTypeClass(null);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index 1668fc4..36b3b77 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -56,6 +56,7 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.Encryptor;
 import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
@@ -121,11 +122,11 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         String authUsername = AuthContextUtils.getUsername();
         if (anonymousUser.equals(authUsername)) {
             authUserTO = new UserTO();
-            authUserTO.setKey(-2);
+            authUserTO.setKey(-2L);
             authUserTO.setUsername(anonymousUser);
         } else if (adminUser.equals(authUsername)) {
             authUserTO = new UserTO();
-            authUserTO.setKey(-1);
+            authUserTO.setKey(-1L);
             authUserTO.setUsername(adminUser);
         } else {
             User authUser = userDAO.find(authUsername);
@@ -364,7 +365,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
 
                     case DELETE:
                     default:
-                        user.remove(role);
+                        user.getRoles().remove(role);
                 }
             }
         }
@@ -388,7 +389,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                     URelationship relationship =
                             user.getRelationship(relationshipType, patch.getRelationshipTO().getRightKey());
                     if (relationship != null) {
-                        user.remove(relationship);
+                        user.getRelationships().remove(relationship);
                         toBeDeprovisioned.addAll(relationship.getRightEnd().getResourceNames());
                     }
 
@@ -426,7 +427,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             if (patch.getMembershipTO() != null) {
                 UMembership membership = user.getMembership(patch.getMembershipTO().getRightKey());
                 if (membership != null) {
-                    user.remove(membership);
+                    user.getMemberships().remove(membership);
                     toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
                 }
 
@@ -516,13 +517,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
 
         if (details) {
             // roles
-            CollectionUtils.collect(user.getRoles(), new Transformer<Role, String>() {
-
-                @Override
-                public String transform(final Role role) {
-                    return role.getKey();
-                }
-            }, userTO.getRoles());
+            CollectionUtils.collect(user.getRoles(),
+                    EntityUtils.<String, Role>keyTransformer(),
+                    userTO.getRoles());
 
             // relationships
             CollectionUtils.collect(user.getRelationships(), new Transformer<URelationship, RelationshipTO>() {
@@ -544,20 +541,12 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             }, userTO.getMemberships());
 
             // dynamic memberships
-            CollectionUtils.collect(userDAO.findDynRoleMemberships(user), new Transformer<Role, String>() {
-
-                @Override
-                public String transform(final Role role) {
-                    return role.getKey();
-                }
-            }, userTO.getDynRoles());
-            CollectionUtils.collect(userDAO.findDynGroupMemberships(user), new Transformer<Group, Long>() {
-
-                @Override
-                public Long transform(final Group group) {
-                    return group.getKey();
-                }
-            }, userTO.getDynGroups());
+            CollectionUtils.collect(userDAO.findDynRoleMemberships(user),
+                    EntityUtils.<String, Role>keyTransformer(),
+                    userTO.getDynRoles());
+            CollectionUtils.collect(userDAO.findDynGroupMemberships(user),
+                    EntityUtils.<Long, Group>keyTransformer(),
+                    userTO.getDynGroups());
         }
 
         return userTO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 82166dc..09594d4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
@@ -408,7 +408,7 @@ public class NotificationManagerImpl implements NotificationManager {
     @Override
     public TaskExec storeExec(final TaskExec execution) {
         NotificationTask task = taskDAO.find(execution.getTask().getKey());
-        task.addExec(execution);
+        task.add(execution);
         task.setExecuted(true);
         taskDAO.save(task);
         // this flush call is needed to generate a value for the execution key

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 00affa6..b74471c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -450,7 +450,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                 LOG.debug("Execution to be stored: {}", execution);
 
                 execution.setTask(task);
-                task.addExec(execution);
+                task.add(execution);
 
                 taskDAO.save(task);
                 // needed to generate a value for the execution key

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
index 770a7cb..82f6f02 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
@@ -303,7 +303,7 @@ public class ConnectorITCase extends AbstractITCase {
         resourceTO.setKey("newAbout103" + getUUIDString());
 
         // Make it new.
-        connInstanceTO.setKey(0);
+        connInstanceTO.setKey(0L);
         connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
         // ----------------------------------
 
@@ -695,7 +695,7 @@ public class ConnectorITCase extends AbstractITCase {
 
         ConnInstanceTO conn = connectorService.read(101L, Locale.ENGLISH.getLanguage());
 
-        conn.setKey(0);
+        conn.setKey(0L);
         conn.setDisplayName("forBulk1");
 
         bulkAction.getTargets().add(String.valueOf(getObject(

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
index d5c77e7..d2baebb 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
@@ -134,12 +134,12 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
         // check read
         PropagationTaskTO task = taskService.read(1L, false);
         assertNotNull(task);
-        assertEquals(1L, task.getKey());
+        assertEquals(1L, task.getKey(), 0);
         assertTrue(task.getExecutions().isEmpty());
 
         task = taskService.read(1L, true);
         assertNotNull(task);
-        assertEquals(1L, task.getKey());
+        assertEquals(1L, task.getKey(), 0);
         assertFalse(task.getExecutions().isEmpty());
 
         // check list executions

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
index 11892af..4b727cf 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
@@ -84,7 +84,7 @@ public class RealmITCase extends AbstractITCase {
         assertNotNull(actual.getKey());
         assertEquals("last", actual.getName());
         assertEquals("/even/two/last", actual.getFullPath());
-        assertEquals(actual.getParent(), getRealm("/even/two").getKey());
+        assertEquals(actual.getParent(), getRealm("/even/two").getKey(), 0);
         assertNull(realm.getAccountPolicy());
         assertNull(realm.getPasswordPolicy());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
index aea35a9..c30cb19 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
@@ -184,7 +184,7 @@ public class ReportITCase extends AbstractITCase {
     @Test
     public void executeAndExport() throws IOException {
         ReportTO reportTO = reportService.read(1L);
-        reportTO.setKey(0);
+        reportTO.setKey(0L);
         reportTO.setName("executeAndExport" + getUUIDString());
         reportTO.setActive(false);
         reportTO.getExecutions().clear();
@@ -220,7 +220,7 @@ public class ReportITCase extends AbstractITCase {
         }
 
         ReportTO reportTO = reportService.read(1L);
-        reportTO.setKey(0);
+        reportTO.setKey(0L);
         reportTO.setName("deleteExecutions" + getUUIDString());
         reportTO.getExecutions().clear();
         reportTO = createReport(reportTO);
@@ -274,7 +274,7 @@ public class ReportITCase extends AbstractITCase {
     public void issueSYNCOPE102() throws IOException {
         // Create
         ReportTO reportTO = reportService.read(1L);
-        reportTO.setKey(0);
+        reportTO.setKey(0L);
         reportTO.setName("issueSYNCOPE102" + getUUIDString());
         reportTO = createReport(reportTO);
         assertNotNull(reportTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
index 327abe8..8832540 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
@@ -75,7 +75,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         assertNotNull(task);
 
         SchedTaskTO taskMod = new SchedTaskTO();
-        taskMod.setKey(5);
+        taskMod.setKey(5L);
         taskMod.setCronExpression(null);
 
         taskService.update(taskMod);
@@ -189,7 +189,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         } while (list.size() < 1 && i < maxit);
 
         assertEquals(1, list.size());
-        assertEquals(task.getKey(), list.get(0).getTask());
+        assertEquals(task.getKey(), list.get(0).getTask(), 0);
 
         taskService.actionJob(task.getKey(), JobAction.STOP);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
index db9156a..d047347 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
@@ -84,7 +84,7 @@ public class SearchITCase extends AbstractITCase {
         assertNotNull(matchingUsers);
         assertEquals(1, matchingUsers.getResult().size());
         assertEquals("rossini", matchingUsers.getResult().iterator().next().getUsername());
-        assertEquals(1L, matchingUsers.getResult().iterator().next().getKey());
+        assertEquals(1L, matchingUsers.getResult().iterator().next().getKey(), 0);
     }
 
     @Test
@@ -96,7 +96,7 @@ public class SearchITCase extends AbstractITCase {
         assertNotNull(groups);
         assertEquals(1, groups.getResult().size());
         assertEquals("root", groups.getResult().iterator().next().getName());
-        assertEquals(1L, groups.getResult().iterator().next().getKey());
+        assertEquals(1L, groups.getResult().iterator().next().getKey(), 0);
     }
 
     @Test
@@ -240,7 +240,7 @@ public class SearchITCase extends AbstractITCase {
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query()).build());
         assertNotNull(groups);
         assertEquals(1, groups.getResult().size());
-        assertEquals(6L, groups.getResult().iterator().next().getKey());
+        assertEquals(6L, groups.getResult().iterator().next().getKey(), 0);
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 199fe0b..dd8242b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -488,7 +488,7 @@ public class UserITCase extends AbstractITCase {
         ProvisioningResult<UserTO> result = deleteUser(key);
         assertNotNull(result);
         userTO = result.getAny();
-        assertEquals(key, userTO.getKey());
+        assertEquals(key, userTO.getKey(), 0);
         assertTrue(userTO.getPlainAttrs().isEmpty());
 
         // check for propagation result
@@ -517,7 +517,7 @@ public class UserITCase extends AbstractITCase {
         ProvisioningResult<UserTO> result = deleteUser(userTO.getKey());
         assertNotNull(result);
         userTO = result.getAny();
-        assertEquals(key, userTO.getKey());
+        assertEquals(key, userTO.getKey(), 0);
         assertTrue(userTO.getPlainAttrs().isEmpty());
 
         // check for propagation result

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
index 150b0bc..02a2c7a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
@@ -72,7 +72,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
         assertNotNull(form);
         assertNotNull(form.getUserKey());
-        assertEquals(userTO.getKey(), form.getUserKey());
+        assertEquals(userTO.getKey(), form.getUserKey(), 0);
         assertNotNull(form.getTaskId());
         assertNull(form.getOwner());
 
@@ -230,7 +230,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         // 1. create user with group 9 (and verify that no propagation occurred)
         userTO = createUser(userTO).getAny();
         assertNotNull(userTO);
-        assertNotEquals(0L, userTO.getKey());
+        assertNotEquals(0L, userTO.getKey(), 0);
         assertNotNull(userTO.getCreationDate());
         assertNotNull(userTO.getCreator());
         assertNotNull(userTO.getLastChangeDate());

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
index 56d8186..a6a2444 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
@@ -65,7 +65,7 @@ public class VirSchemaITCase extends AbstractITCase {
 
         schema = createSchema(SchemaType.VIRTUAL, schema);
         assertNotNull(schema);
-        assertEquals(csv.getProvisions().get(0).getKey(), schema.getProvision());
+        assertEquals(csv.getProvisions().get(0).getKey(), schema.getProvision(), 0);
 
         csv = resourceService.read(RESOURCE_NAME_CSV);
         assertNotNull(csv);


[21/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
[SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/17d5d892
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/17d5d892
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/17d5d892

Branch: refs/heads/master
Commit: 17d5d892889226c88ed28e81d8e98c0a6bd8ff52
Parents: 6f35621
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jan 26 13:04:17 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jan 26 13:04:17 2016 +0100

----------------------------------------------------------------------
 .../panels/AnyTypeClassesPanel.properties       |    1 +
 .../panels/AnyTypeClassesPanel_it.properties    |    1 +
 .../panels/AnyTypeClassesPanel_pt_BR.properties |    1 +
 .../syncope/common/lib/to/AnyTypeClassTO.java   |   18 +-
 fit/console-reference/pom.xml                   |  121 +-
 .../fit/console/reference/AbstractITCase.java   |  108 -
 .../fit/console/reference/BaseITCase.java       |   94 -
 .../fit/console/reference/commons/TestPage.java |   88 -
 .../html/form/AjaxPalettePanelITCase.java       |   59 -
 .../markup/html/form/AjaxTextFieldITCase.java   |   88 -
 .../console/reference/pages/TypesITCase.java    |  152 --
 .../pages/types/AnyTypeClassesITCase.java       |  140 -
 .../reference/pages/types/AnyTypesITCase.java   |  140 -
 .../pages/types/RelationshipTypeITCase.java     |  125 -
 .../reference/pages/types/SchemasITCase.java    |  157 --
 fit/core-reference/pom.xml                      |   22 +-
 .../org/apache/syncope/fit/AbstractITCase.java  |  454 ++++
 .../apache/syncope/fit/ActivitiDetector.java    |   36 +
 .../org/apache/syncope/fit/CamelDetector.java   |   36 +
 .../org/apache/syncope/fit/cli/CLIITCase.java   |  278 ++
 .../fit/console/AbstractConsoleITCase.java      |  100 +
 .../fit/console/AbstractTypesITCase.java        |  151 ++
 .../fit/console/AjaxPalettePanelITCase.java     |   57 +
 .../fit/console/AjaxTextFieldITCase.java        |   86 +
 .../fit/console/AnyTypeClassesITCase.java       |  139 +
 .../syncope/fit/console/AnyTypesITCase.java     |  139 +
 .../apache/syncope/fit/console/BaseITCase.java  |   94 +
 .../fit/console/RelationshipTypeITCase.java     |  121 +
 .../syncope/fit/console/SchemasITCase.java      |  156 ++
 .../apache/syncope/fit/console/TestPage.java    |   88 +
 .../syncope/fit/core/AbstractTaskITCase.java    |  184 ++
 .../syncope/fit/core/AnyObjectITCase.java       |  210 ++
 .../syncope/fit/core/AnyTypeClassITCase.java    |  154 ++
 .../apache/syncope/fit/core/AnyTypeITCase.java  |  194 ++
 .../syncope/fit/core/AuthenticationITCase.java  |  567 ++++
 .../syncope/fit/core/CamelRouteITCase.java      |  178 ++
 .../syncope/fit/core/ConfigurationITCase.java   |  173 ++
 .../syncope/fit/core/ConnectorITCase.java       |  747 +++++
 .../syncope/fit/core/DerSchemaITCase.java       |  148 +
 .../apache/syncope/fit/core/DomainITCase.java   |  121 +
 .../syncope/fit/core/ExceptionMapperITCase.java |  154 ++
 .../apache/syncope/fit/core/GroupITCase.java    |  939 +++++++
 .../apache/syncope/fit/core/LoggerITCase.java   |  231 ++
 .../syncope/fit/core/MultitenancyITCase.java    |  223 ++
 .../syncope/fit/core/NotificationITCase.java    |  175 ++
 .../fit/core/NotificationTaskITCase.java        |  399 +++
 .../syncope/fit/core/PlainSchemaITCase.java     |  336 +++
 .../apache/syncope/fit/core/PolicyITCase.java   |  195 ++
 .../syncope/fit/core/PropagationTaskITCase.java |  150 +
 .../apache/syncope/fit/core/PushTaskITCase.java |  384 +++
 .../org/apache/syncope/fit/core/RESTITCase.java |  148 +
 .../apache/syncope/fit/core/RealmITCase.java    |  188 ++
 .../fit/core/RelationshipTypeITCase.java        |   94 +
 .../apache/syncope/fit/core/ReportITCase.java   |  303 +++
 .../apache/syncope/fit/core/ResourceITCase.java |  697 +++++
 .../org/apache/syncope/fit/core/RoleITCase.java |  143 +
 .../syncope/fit/core/SchedTaskITCase.java       |  214 ++
 .../apache/syncope/fit/core/SearchITCase.java   |  398 +++
 .../fit/core/SecurityQuestionITCase.java        |  100 +
 .../apache/syncope/fit/core/SyncTaskITCase.java |  854 ++++++
 .../org/apache/syncope/fit/core/UserITCase.java | 2561 ++++++++++++++++++
 .../apache/syncope/fit/core/UserSelfITCase.java |  386 +++
 .../syncope/fit/core/UserWorkflowITCase.java    |  309 +++
 .../apache/syncope/fit/core/VirAttrITCase.java  |  678 +++++
 .../syncope/fit/core/VirSchemaITCase.java       |  152 ++
 .../apache/syncope/fit/core/WorkflowITCase.java |   78 +
 .../fit/core/reference/AbstractITCase.java      |  454 ----
 .../fit/core/reference/AbstractTaskITCase.java  |  183 --
 .../fit/core/reference/ActivitiDetector.java    |   36 -
 .../fit/core/reference/AnyObjectITCase.java     |  209 --
 .../fit/core/reference/AnyTypeClassITCase.java  |  153 --
 .../fit/core/reference/AnyTypeITCase.java       |  193 --
 .../core/reference/AuthenticationITCase.java    |  564 ----
 .../syncope/fit/core/reference/CLIITCase.java   |  276 --
 .../fit/core/reference/CamelDetector.java       |   36 -
 .../fit/core/reference/CamelRouteITCase.java    |  175 --
 .../fit/core/reference/ConfigurationITCase.java |  172 --
 .../fit/core/reference/ConnectorITCase.java     |  746 -----
 .../fit/core/reference/DerSchemaITCase.java     |  147 -
 .../fit/core/reference/DomainITCase.java        |  120 -
 .../core/reference/ExceptionMapperITCase.java   |  153 --
 .../syncope/fit/core/reference/GroupITCase.java |  938 -------
 .../fit/core/reference/LoggerITCase.java        |  230 --
 .../fit/core/reference/MultitenancyITCase.java  |  222 --
 .../fit/core/reference/NotificationITCase.java  |  174 --
 .../core/reference/NotificationTaskITCase.java  |  398 ---
 .../fit/core/reference/PlainSchemaITCase.java   |  335 ---
 .../fit/core/reference/PolicyITCase.java        |  193 --
 .../core/reference/PropagationTaskITCase.java   |  150 -
 .../fit/core/reference/PushTaskITCase.java      |  384 ---
 .../syncope/fit/core/reference/RESTITCase.java  |  147 -
 .../syncope/fit/core/reference/RealmITCase.java |  187 --
 .../core/reference/RelationshipTypeITCase.java  |   93 -
 .../fit/core/reference/ReportITCase.java        |  302 ---
 .../fit/core/reference/ResourceITCase.java      |  696 -----
 .../syncope/fit/core/reference/RoleITCase.java  |  142 -
 .../fit/core/reference/SchedTaskITCase.java     |  213 --
 .../fit/core/reference/SearchITCase.java        |  397 ---
 .../core/reference/SecurityQuestionITCase.java  |   99 -
 .../fit/core/reference/SyncTaskITCase.java      |  848 ------
 .../syncope/fit/core/reference/UserITCase.java  | 2555 -----------------
 .../fit/core/reference/UserSelfITCase.java      |  383 ---
 .../fit/core/reference/UserWorkflowITCase.java  |  306 ---
 .../fit/core/reference/VirAttrITCase.java       |  677 -----
 .../fit/core/reference/VirSchemaITCase.java     |  151 --
 .../fit/core/reference/WorkflowITCase.java      |   75 -
 .../src/test/resources/console.properties       |   31 +
 .../src/test/resources/log4j2.xml               |   10 +-
 108 files changed, 15173 insertions(+), 15195 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties
index 2c503c4..5614a54 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties
@@ -20,3 +20,4 @@ anyTypeClasses=AnyTypeClasses
 plainSchemas=Plain Schemas
 derSchemas=Derived Schemas
 virSchemas=Virtual Schemas
+inUseByTypes=AnyTypes

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties
index 7622557..cc1c289 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties
@@ -20,3 +20,4 @@ anyTypeClasses=AnyTypeClasses
 plainSchemas=Plain Schemas
 derSchemas=Derived Schemas
 virSchemas=Virtual Schemas
+inUseByTypes=AnyTypes

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties
index c8a828c..fbe36fd 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties
@@ -20,3 +20,4 @@ anyTypeClasses=AnyTypeClasses
 plainSchemas=Plain Schemas
 derSchemas=Derived Schemas
 virSchemas=Virtual Schemas
+inUseByTypes=AnyTypes

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
index 7ed12bd..1845e06 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
@@ -36,14 +36,14 @@ public class AnyTypeClassTO extends AbstractBaseBean implements EntityTO<String>
 
     private String key;
 
-    private final List<String> inUseByTypes = new ArrayList<>();
-
     private final List<String> plainSchemas = new ArrayList<>();
 
     private final List<String> derSchemas = new ArrayList<>();
 
     private final List<String> virSchemas = new ArrayList<>();
 
+    private final List<String> inUseByTypes = new ArrayList<>();
+
     @Override
     public String getKey() {
         return key;
@@ -55,13 +55,6 @@ public class AnyTypeClassTO extends AbstractBaseBean implements EntityTO<String>
         this.key = key;
     }
 
-    @XmlElementWrapper(name = "inUseByTypes")
-    @XmlElement(name = "anyTypeClass")
-    @JsonProperty("inUseByTypes")
-    public List<String> getInUseByTypes() {
-        return inUseByTypes;
-    }
-
     @XmlElementWrapper(name = "plainSchemas")
     @XmlElement(name = "schema")
     @JsonProperty("plainSchemas")
@@ -83,4 +76,11 @@ public class AnyTypeClassTO extends AbstractBaseBean implements EntityTO<String>
         return virSchemas;
     }
 
+    @XmlElementWrapper(name = "inUseByTypes")
+    @XmlElement(name = "anyTypeClass")
+    @JsonProperty("inUseByTypes")
+    public List<String> getInUseByTypes() {
+        return inUseByTypes;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml
index e34107b..a713d6d 100644
--- a/fit/console-reference/pom.xml
+++ b/fit/console-reference/pom.xml
@@ -173,20 +173,6 @@ under the License.
       </plugin>
       
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <inherited>true</inherited>
-        <executions>
-          <execution>
-            <id>verify</id>
-            <goals>
-              <goal>verify</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      
-      <plugin>
         <groupId>org.codehaus.cargo</groupId>
         <artifactId>cargo-maven2-plugin</artifactId>
         <inherited>true</inherited>
@@ -241,27 +227,14 @@ under the License.
                 <context>syncope</context>
               </properties>
             </deployable>
+            <deployable>
+              <location>${project.build.directory}/${project.build.finalName}</location>
+              <properties>
+                <context>syncope-console</context>
+              </properties>
+            </deployable>
           </deployables>
         </configuration>
-        <executions>
-          <execution>
-            <id>start-container</id>
-            <phase>pre-integration-test</phase>
-            <goals>
-              <goal>start</goal>
-            </goals>
-            <configuration>
-              <wait>false</wait>
-            </configuration>
-          </execution>
-          <execution>
-            <id>stop-container</id>
-            <phase>post-integration-test</phase>
-            <goals>
-              <goal>stop</goal>
-            </goals>
-          </execution>
-        </executions>
       </plugin>
       
       <plugin>
@@ -313,38 +286,6 @@ under the License.
                     -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m -Xmx1024m -Xms512m</cargo.jvmargs>
                 </properties>
               </configuration>
-              <deployables>
-                <deployable>
-                  <groupId>net.tirasa.connid.bundles.soap</groupId>
-                  <artifactId>wssample</artifactId>
-                  <type>war</type>
-                  <properties>
-                    <context>wssample</context>
-                  </properties>
-                </deployable>
-                <deployable>
-                  <groupId>org.apache.syncope.fit</groupId>
-                  <artifactId>syncope-fit-build-tools</artifactId>
-                  <type>war</type>
-                  <properties>
-                    <context>syncope-fit-build-tools</context>
-                  </properties>
-                </deployable>
-                <deployable>
-                  <location>${basedir}/../core-reference/target/syncope-fit-core-reference-${project.version}</location>
-                  <pingURL>http://localhost:${cargo.servlet.port}/syncope/cacheStats.jsp</pingURL>
-                  <pingTimeout>60000</pingTimeout>
-                  <properties>
-                    <context>syncope</context>
-                  </properties>
-                </deployable>
-                <deployable>
-                  <location>${project.build.directory}/${project.build.finalName}</location>
-                  <properties>
-                    <context>syncope-console</context>
-                  </properties>
-                </deployable>
-              </deployables>
             </configuration>
             <executions>
               <execution>
@@ -374,15 +315,6 @@ under the License.
       <build>
         <plugins>
           <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <inherited>true</inherited>
-            <configuration>
-              <skipTests>${skipTests}</skipTests>
-            </configuration>
-          </plugin>
-          
-          <plugin>
             <groupId>org.codehaus.cargo</groupId>
             <artifactId>cargo-maven2-plugin</artifactId>
             <inherited>true</inherited>
@@ -423,15 +355,6 @@ under the License.
 
         <plugins>
           <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <inherited>true</inherited>
-            <configuration>
-              <skipTests>true</skipTests>
-            </configuration>
-          </plugin>
-          
-          <plugin>
             <groupId>org.zeroturnaround</groupId>
             <artifactId>jrebel-maven-plugin</artifactId>
             <inherited>true</inherited>
@@ -557,38 +480,6 @@ under the License.
                     -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m -Xmx1024m -Xms512m</cargo.jvmargs>
                 </properties>
               </configuration>
-              <deployables>
-                <deployable>
-                  <groupId>net.tirasa.connid.bundles.soap</groupId>
-                  <artifactId>wssample</artifactId>
-                  <type>war</type>
-                  <properties>
-                    <context>wssample</context>
-                  </properties>
-                </deployable>
-                <deployable>
-                  <groupId>org.apache.syncope.fit</groupId>
-                  <artifactId>syncope-fit-build-tools</artifactId>
-                  <type>war</type>
-                  <properties>
-                    <context>syncope-fit-build-tools</context>
-                  </properties>
-                </deployable>
-                <deployable>
-                  <location>${basedir}/../core-reference/target/syncope-fit-core-reference-${project.version}</location>
-                  <pingURL>http://localhost:${cargo.servlet.port}/syncope/cacheStats.jsp</pingURL>
-                  <pingTimeout>60000</pingTimeout>
-                  <properties>
-                    <context>syncope</context>
-                  </properties>
-                </deployable>
-                <deployable>
-                  <location>${project.build.directory}/${project.build.finalName}</location>
-                  <properties>
-                    <context>syncope-console</context>
-                  </properties>
-                </deployable>
-              </deployables>
             </configuration>
             <executions>
               <execution>

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/AbstractITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/AbstractITCase.java
deleted file mode 100644
index 834adac..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/AbstractITCase.java
+++ /dev/null
@@ -1,108 +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.fit.console.reference;
-
-import java.lang.reflect.InvocationTargetException;
-import javax.servlet.ServletContext;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
-import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.client.console.init.ConsoleInitializer;
-import org.apache.syncope.client.console.init.MIMETypesLoader;
-import org.apache.syncope.client.console.pages.Login;
-import org.apache.wicket.Component;
-import org.apache.wicket.core.util.lang.PropertyResolver;
-import org.apache.wicket.markup.repeater.OddEvenItem;
-import org.apache.wicket.util.tester.FormTester;
-import org.apache.wicket.util.tester.WicketTester;
-import org.apache.wicket.util.visit.IVisit;
-import org.apache.wicket.util.visit.IVisitor;
-import org.junit.Before;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractITCase {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractITCase.class);
-
-    public static final String ADMIN = "admin";
-
-    public static final String PASSWORD = "password";
-    
-    public static final String KEY = "key";
-
-    protected WicketTester wicketTester;
-
-    protected SyncopeConsoleApplication testApplicaton;
-
-    @Before
-    public void setUp() {
-
-        testApplicaton = new SyncopeConsoleApplication() {
-
-            @Override
-            protected void init() {
-                final ServletContext ctx = getServletContext();
-                final ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
-                lookup.load();
-                ctx.setAttribute(ConsoleInitializer.CLASSPATH_LOOKUP, lookup);
-
-                final MIMETypesLoader mimeTypes = new MIMETypesLoader();
-                mimeTypes.load();
-                ctx.setAttribute(ConsoleInitializer.MIMETYPES_LOADER, mimeTypes);
-
-                super.init();
-            }
-        };
-
-        wicketTester = new WicketTester(testApplicaton);
-    }
-
-    protected void doLogin(final String user, final String passwd) {
-        wicketTester.startPage(Login.class);
-        wicketTester.assertRenderedPage(Login.class);
-
-        FormTester formTester = wicketTester.newFormTester("login");
-        formTester.setValue("username", user);
-        formTester.setValue("password", passwd);
-        formTester.submit("submit");
-    }
-
-    protected Component findComponentByProp(final String property, final String searchPath, final String key) {
-        Component component =
-                wicketTester.getComponentFromLastRenderedPage(searchPath);
-
-        Component result = component.getPage().
-                visitChildren(OddEvenItem.class, new IVisitor<OddEvenItem<?>, Component>() {
-
-                    @Override
-                    public void component(final OddEvenItem<?> object, final IVisit<Component> visit) {
-                        
-                        try {
-                            if (PropertyResolver.getPropertyGetter(
-                                    property, object.getModelObject()).invoke(object.getModelObject()).equals(key)) {
-                                visit.stop(object);
-                            }
-                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
-                            LOG.error("Error invoke method", ex);
-                        }
-                    }
-                });
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/BaseITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/BaseITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/BaseITCase.java
deleted file mode 100644
index 59fed66..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/BaseITCase.java
+++ /dev/null
@@ -1,94 +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.fit.console.reference;
-
-import org.apache.syncope.client.console.pages.Dashboard;
-import org.apache.syncope.client.console.pages.Layouts;
-import org.apache.syncope.client.console.pages.Login;
-import org.apache.syncope.client.console.pages.Logs;
-import org.apache.syncope.client.console.pages.Notifications;
-import org.apache.syncope.client.console.pages.Policies;
-import org.apache.syncope.client.console.pages.Realms;
-import org.apache.syncope.client.console.pages.Reports;
-import org.apache.syncope.client.console.pages.Roles;
-import org.apache.syncope.client.console.pages.SecurityQuestions;
-import org.apache.syncope.client.console.pages.Types;
-import org.apache.syncope.client.console.pages.Workflow;
-import org.apache.syncope.client.console.topology.Topology;
-import org.junit.Test;
-
-public class BaseITCase extends AbstractITCase {
-
-    @Test
-    public void loginPage() {
-        wicketTester.startPage(Login.class);
-        wicketTester.assertRenderedPage(Login.class);
-    }
-
-    @Test
-    public void successfullyLogin() {
-        doLogin(ADMIN, PASSWORD);
-        wicketTester.assertRenderedPage(Dashboard.class);
-    }
-
-    @Test
-    public void unsuccessfullyLogin() {
-        doLogin(ADMIN, PASSWORD + 1);
-        wicketTester.assertRenderedPage(Login.class);
-    }
-
-    @Test
-    public void browsingBookmarkablePageLink() {
-        doLogin(ADMIN, PASSWORD);
-        wicketTester.assertRenderedPage(Dashboard.class);
-
-        wicketTester.clickLink("realmsLI:realms");
-        wicketTester.assertRenderedPage(Realms.class);
-
-        wicketTester.clickLink("topologyLI:topology");
-        wicketTester.assertRenderedPage(Topology.class);
-
-        wicketTester.clickLink("reportsLI:reports");
-        wicketTester.assertRenderedPage(Reports.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:workflowLI:workflow");
-        wicketTester.assertRenderedPage(Workflow.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:logsLI:logs");
-        wicketTester.assertRenderedPage(Logs.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:securityquestionsLI:securityquestions");
-        wicketTester.assertRenderedPage(SecurityQuestions.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
-        wicketTester.assertRenderedPage(Types.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:rolesLI:roles");
-        wicketTester.assertRenderedPage(Roles.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:policiesLI:policies");
-        wicketTester.assertRenderedPage(Policies.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:layoutsLI:layouts");
-        wicketTester.assertRenderedPage(Layouts.class);
-
-        wicketTester.clickLink("configurationLI:configurationUL:notificationsLI:notifications");
-        wicketTester.assertRenderedPage(Notifications.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/commons/TestPage.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/commons/TestPage.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/commons/TestPage.java
deleted file mode 100644
index cb1bba2..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/commons/TestPage.java
+++ /dev/null
@@ -1,88 +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.fit.console.reference.commons;
-
-import java.io.Serializable;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.markup.IMarkupResourceStreamProvider;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.util.resource.IResourceStream;
-import org.apache.wicket.util.resource.StringResourceStream;
-
-public class TestPage<T extends Serializable, S extends Panel> extends WebPage implements
-        IMarkupResourceStreamProvider {
-
-    private static final long serialVersionUID = 483736530078975170L;
-
-    public static String FIELD = "field";
-
-    private final Form<T> form;
-
-    private final S fieldPanel;
-
-    private TestPage(S field, final Builder<T, S> builder) {
-
-        this.form = builder.form;
-        this.fieldPanel = field;
-        
-        field.setOutputMarkupId(builder.outputMarkupId);
-        add(form);
-        form.add(field);
-    }
-
-    public Form<T> getForm() {
-        return form;
-    }
-
-    public S getFieldPanel() {
-        return fieldPanel;
-    }
-
-    public static class Builder<T extends Serializable, S extends Panel> implements Serializable {
-
-        private static final long serialVersionUID = 4882978420728876617L;
-
-        private final Form<T> form;
-
-        private boolean outputMarkupId;
-
-        public Builder() {
-            this.form = new Form<>("form");
-
-        }
-
-        public Builder<T, S> setOutputMarkupId(final boolean outputMarkupId) {
-            this.outputMarkupId = outputMarkupId;
-            return this;
-        }
-
-        public TestPage<T, S> build(final S field) {
-            return new TestPage<>(field, this);
-        }
-    }
-
-    @Override
-    public IResourceStream getMarkupResourceStream(final MarkupContainer container,
-            final Class<?> containerClass) {
-        return new StringResourceStream("<html><body>"
-                + "<form wicket:id=\"form\"><span wicket:id=\"field\"></span></form></body></html>");
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxPalettePanelITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxPalettePanelITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxPalettePanelITCase.java
deleted file mode 100644
index 56f7fd6..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxPalettePanelITCase.java
+++ /dev/null
@@ -1,59 +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.fit.console.reference.markup.html.form;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
-import org.apache.syncope.fit.console.reference.AbstractITCase;
-import org.apache.syncope.fit.console.reference.commons.TestPage;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.util.ListModel;
-import org.apache.wicket.util.tester.FormTester;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class AjaxPalettePanelITCase extends AbstractITCase {
-
-    private static final IModel<List<String>> SELECTED = new ListModel<>(new ArrayList<>(Arrays.asList("A", "D")));
-
-    private static final ListModel<String> ALL = new ListModel<>(new ArrayList<>(Arrays.asList("A", "B", "C", "D")));
-
-    @Test
-    public void isRendered() {
-        TestPage<String, AjaxPalettePanel<String>> testPage =
-                new TestPage.Builder<String, AjaxPalettePanel<String>>().build(
-                        new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build(
-                        TestPage.FIELD, SELECTED, ALL));
-        wicketTester.startPage(testPage);
-
-        FormTester formTester = wicketTester.newFormTester(testPage.getForm().getId());
-        formTester.submit();
-
-        Collection<String> list = testPage.getFieldPanel().getModelCollection();
-        assertEquals(2, list.size());
-        Iterator<String> iterator = list.iterator();
-        assertEquals("A", iterator.next());
-        assertEquals("D", iterator.next());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxTextFieldITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxTextFieldITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxTextFieldITCase.java
deleted file mode 100644
index db7ee8d..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/markup/html/form/AjaxTextFieldITCase.java
+++ /dev/null
@@ -1,88 +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.fit.console.reference.markup.html.form;
-
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.fit.console.reference.AbstractITCase;
-import org.apache.wicket.util.string.Strings;
-import org.apache.wicket.util.tester.FormTester;
-import org.apache.wicket.validation.validator.StringValidator;
-import org.junit.Test;
-import org.apache.syncope.fit.console.reference.commons.TestPage;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public class AjaxTextFieldITCase extends AbstractITCase {
-
-    private final IModel<String> textModel = Model.of((String) null);
-
-    @Test
-    public void emptyInputConvertedToNull() {
-        TestPage<String, AjaxTextFieldPanel> testPage =
-                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
-                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
-        wicketTester.startPage(testPage);
-        FormTester formTester = wicketTester.newFormTester(testPage.getForm().getId());
-        formTester.setValue("field:textField", "");
-        formTester.submit();
-        assertEquals(null, testPage.getFieldPanel().getField().getDefaultModelObject());
-    }
-
-    @Test
-    public void valueAttribute() {
-        TestPage<String, AjaxTextFieldPanel> testPage =
-                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
-                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
-        String text = "sometext";
-        textModel.setObject(text);
-        wicketTester.startPage(testPage);
-        assertTrue(wicketTester.getLastResponseAsString().contains(Strings.escapeMarkup(text)));
-    }
-
-    @Test
-    public void nullIsNotValidated() {
-        TestPage<String, AjaxTextFieldPanel> testPage =
-                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
-                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
-        testPage.getFieldPanel().getField().setRequired(false);
-        testPage.getFieldPanel().getField().add(StringValidator.minimumLength(2));
-        wicketTester.startPage(testPage);
-        FormTester formTester = wicketTester.newFormTester(testPage.getForm().getId());
-        formTester.setValue("field:textField", "");
-        formTester.submit();
-        assertEquals(null, testPage.getFieldPanel().getDefaultModelObject());
-        assertTrue(testPage.getFieldPanel().getField().isValid());
-    }
-
-    @Test
-    public void requiredAttribute() {
-        TestPage<String, AjaxTextFieldPanel> testPage =
-                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
-                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
-        testPage.getFieldPanel().setOutputMarkupId(true);
-        testPage.getFieldPanel().getField().setRequired(true);
-        wicketTester.startPage(testPage);
-        wicketTester.assertLabel("form:field:field-label", "field");
-        wicketTester.assertVisible("form:field:required");
-        wicketTester.assertVisible("form:field:externalAction");
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/TypesITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/TypesITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/TypesITCase.java
deleted file mode 100644
index 7a5c63d..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/TypesITCase.java
+++ /dev/null
@@ -1,152 +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.fit.console.reference.pages;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import org.apache.syncope.client.console.pages.Types;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
-import org.apache.syncope.fit.console.reference.AbstractITCase;
-import org.apache.wicket.util.tester.FormTester;
-import org.junit.Before;
-
-public class TypesITCase extends AbstractITCase {
-
-    protected static final String PLAIN_DATATABLE_PATH = "content:tabbedPanel:panel:"
-            + "collapsePanel:tabs:0:body:content:searchContainer:resultTable";
-
-    protected static final String DATATABLE_PATH =
-            "content:tabbedPanel:panel:searchContainer:resultTable";
-
-    @Before
-    public void login() {
-        doLogin(ADMIN, PASSWORD);
-    }
-
-    protected void browsingToRelationshipType() {
-
-        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
-        wicketTester.assertRenderedPage(Types.class);
-
-        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:0:link");
-        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
-                AjaxFallbackDataTable.class);
-    }
-
-    protected void browsingToAnyTypes() {
-
-        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
-        wicketTester.assertRenderedPage(Types.class);
-
-        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:1:link");
-        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
-                AjaxFallbackDataTable.class);
-    }
-
-    protected void browsingToAnyTypeClasses() {
-
-        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
-        wicketTester.assertRenderedPage(Types.class);
-
-        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:2:link");
-        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
-                AjaxFallbackDataTable.class);
-    }
-
-    protected void browsingToPlainSchemas() {
-
-        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
-        wicketTester.assertRenderedPage(Types.class);
-
-        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:3:link");
-        wicketTester.assertComponent(PLAIN_DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
-                AjaxFallbackDataTable.class);
-    }
-
-    protected void createPlainSchema(final String key) {
-        browsingToPlainSchemas();
-        wicketTester.clickLink("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:container:content:add");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:"
-                + "collapsePanel:tabs:0:body:content:modal:form");
-        formTester.setValue("content:details:form:key:textField", key);
-        formTester.setValue("content:details:form:type:dropDownChoiceField", "3");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:"
-                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit");
-
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.cleanupFeedbackMessages();
-    }
-
-    protected void createAnyTypeClassWithoutSchema(final String name) {
-        browsingToAnyTypeClasses();
-
-        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue("content:anyTypeClassDetailsPanel:form:key:textField", name);
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.clearFeedbackMessages();
-    }
-
-    protected void createAnyType(final String name) {
-        browsingToAnyTypes();
-
-        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue("content:anyTypeDetailsPanel:container:form:key:textField", name);
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.clearFeedbackMessages();
-    }
-
-    protected void createRelationshipType(final String name) {
-        browsingToRelationshipType();
-
-        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue("content:relationshipTypeDetails:container:form:key:textField", name);
-        formTester.setValue(
-                "content:relationshipTypeDetails:container:form:description:textField", "test relationshipType");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.clearFeedbackMessages();
-        wicketTester.assertRenderedPage(Types.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypeClassesITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypeClassesITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypeClassesITCase.java
deleted file mode 100644
index 3f6b391..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypeClassesITCase.java
+++ /dev/null
@@ -1,140 +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.fit.console.reference.pages.types;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import org.apache.syncope.client.console.pages.Types;
-import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
-import org.apache.syncope.fit.console.reference.pages.TypesITCase;
-import org.apache.wicket.Component;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.util.tester.FormTester;
-import org.junit.Test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-public class AnyTypeClassesITCase extends TypesITCase {
-
-    @Test
-    public void read() {
-        browsingToAnyTypeClasses();
-        
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, "csv");
-        wicketTester.assertLabel(
-                result.getPageRelativePath() + ":cells:1:cell", "csv");
-
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:6:cell:panelEdit:editLink", IndicatingAjaxLink.class);
-
-        wicketTester.clickLink(
-                result.getPageRelativePath() + ":cells:6:cell:panelEdit:editLink");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", BaseModal.class);
-    }
-
-    @Test
-    public void create() {
-        browsingToAnyTypeClasses();
-        final String anyTypeClassTest = "anyTypeClassTest";
-
-        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue("content:anyTypeClassDetailsPanel:form:key:textField", anyTypeClassTest);
-        formTester.setValue(
-                "content:anyTypeClassDetailsPanel:form:container:derSchemas:paletteField:recorder", "mderiveddata");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.clearFeedbackMessages();
-        wicketTester.assertRenderedPage(Types.class);
-
-        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:2:link");
-        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
-                AjaxFallbackDataTable.class);
-
-        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
-
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassTest);
-
-        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:4:cell", "[mderiveddata]");
-    }
-
-    @Test
-    public void update() {
-        final String plainSchema = "anyPlainSchema";
-        createPlainSchema(plainSchema);
-        browsingToAnyTypeClasses();
-
-        wicketTester.assertComponent(
-                DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:"
-                + "body:rows:1:cells:6:cell:panelEdit:editLink", IndicatingAjaxLink.class);
-
-        wicketTester.clickLink(
-                DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:body:rows:1:cells:6:cell:panelEdit:editLink");
-
-        final FormTester formTester =
-                wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue(
-                "content:anyTypeClassDetailsPanel:form:container:plainSchemas:paletteField:recorder", plainSchema);
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-    }
-
-    @Test
-    public void delete() {
-        final String anyTypeClassName = "zStringDelete";
-        createAnyTypeClassWithoutSchema(anyTypeClassName);
-        browsingToAnyTypeClasses();
-        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
-        
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassName);
-
-        assertNotNull(result);
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:6:cell:panelDelete:deleteLink",
-                IndicatingOnConfirmAjaxLink.class);
-
-        wicketTester.getRequest().addParameter("confirm", "true");
-        wicketTester.clickLink(
-                wicketTester.getComponentFromLastRenderedPage(
-                        result.getPageRelativePath() + ":cells:6:cell:panelDelete:deleteLink"));
-
-        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
-                result.getPageRelativePath() + ":cells:6:cell:panelDelete:deleteLink"), "click");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.cleanupFeedbackMessages();
-        result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassName);
-
-        assertNull(result);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypesITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypesITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypesITCase.java
deleted file mode 100644
index cf77fd6..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/AnyTypesITCase.java
+++ /dev/null
@@ -1,140 +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.fit.console.reference.pages.types;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import org.apache.syncope.client.console.pages.Types;
-import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
-import org.apache.syncope.fit.console.reference.pages.TypesITCase;
-import org.apache.wicket.Component;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.util.tester.FormTester;
-import org.junit.Test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-public class AnyTypesITCase extends TypesITCase {
-
-    @Test
-    public void read() {
-        browsingToAnyTypes();
-        wicketTester.assertComponent(
-                DATATABLE_PATH
-                + ":tablePanel:groupForm:"
-                + "checkgroup:dataTable:body:rows:1:cells:1:cell", Label.class);
-
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, "GROUP");
-
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:4:cell:panelEdit:editLink", IndicatingAjaxLink.class);
-
-        wicketTester.clickLink(
-                result.getPageRelativePath() + ":cells:4:cell:panelEdit:editLink");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", BaseModal.class);
-    }
-
-    @Test
-    public void create() {
-        browsingToAnyTypes();
-        final String anyTypeTest = "anyTypeTest2";
-
-        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue("content:anyTypeDetailsPanel:container:form:key:textField", anyTypeTest);
-        formTester.setValue(
-                "content:anyTypeDetailsPanel:container:form:classes:paletteField:recorder", "csv");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.clearFeedbackMessages();
-        wicketTester.assertRenderedPage(Types.class);
-
-        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:1:link");
-        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
-
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeTest);
-
-        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:1:cell", anyTypeTest);
-        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:3:cell", "[csv]");
-    }
-
-    @Test
-    public void update() {
-        final String name = "anyTypeClassUpdate";
-        createAnyTypeClassWithoutSchema(name);
-        browsingToAnyTypes();
-
-        wicketTester.assertComponent(
-                DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:"
-                + "body:rows:1:cells:4:cell:panelEdit:editLink", IndicatingAjaxLink.class);
-
-        wicketTester.clickLink(
-                DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:body:rows:1:cells:4:cell:panelEdit:editLink");
-
-        final FormTester formTester =
-                wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue(
-                "content:anyTypeDetailsPanel:container:form:classes:paletteField:recorder", name);
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-    }
-
-    @Test
-    public void delete() {
-        final String name = "anyTypeDelete";
-        createAnyType(name);
-        browsingToAnyTypes();
-        
-        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, name);
-
-        assertNotNull(result);
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:4:cell:panelDelete:deleteLink",
-                IndicatingOnConfirmAjaxLink.class);
-
-        wicketTester.getRequest().addParameter("confirm", "true");
-        wicketTester.clickLink(
-                wicketTester.getComponentFromLastRenderedPage(
-                        result.getPageRelativePath() + ":cells:4:cell:panelDelete:deleteLink"));
-
-        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
-                result.getPageRelativePath() + ":cells:4:cell:panelDelete:deleteLink"), "onclick");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.cleanupFeedbackMessages();
-        result = findComponentByProp(KEY, DATATABLE_PATH, name);
-
-        assertNull(result);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/RelationshipTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/RelationshipTypeITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/RelationshipTypeITCase.java
deleted file mode 100644
index b7f63ad..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/RelationshipTypeITCase.java
+++ /dev/null
@@ -1,125 +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.fit.console.reference.pages.types;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
-import org.apache.syncope.fit.console.reference.pages.TypesITCase;
-import org.apache.wicket.Component;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.util.tester.FormTester;
-import org.junit.Test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-public class RelationshipTypeITCase extends TypesITCase {
-
-    @Test
-    public void read() {
-        browsingToRelationshipType();
-
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, "inclusion");
-
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:1:cell", Label.class);
-
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:3:cell:panelEdit:editLink", IndicatingAjaxLink.class);
-
-        wicketTester.clickLink(
-                result.getPageRelativePath() + ":cells:3:cell:panelEdit:editLink");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:modal", BaseModal.class);
-    }
-
-    @Test
-    public void create() {
-        final String name = "relationshipTypeTest";
-        createRelationshipType(name);
-        browsingToRelationshipType();
-
-        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
-
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, name);
-
-        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:1:cell", name);
-        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:2:cell", "test relationshipType");
-    }
-
-    @Test
-    public void update() {
-        final String name = "relationshipTypeUpdate";
-        createRelationshipType(name);
-        browsingToRelationshipType();
-
-        wicketTester.assertComponent(
-                DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:"
-                + "body:rows:1:cells:3:cell:panelEdit:editLink", IndicatingAjaxLink.class);
-
-        wicketTester.clickLink(
-                DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:body:rows:1:cells:3:cell:panelEdit:editLink");
-
-        final FormTester formTester =
-                wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
-        formTester.setValue(
-                "content:relationshipTypeDetails:container:form:description:textField", "new description");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-    }
-
-    @Test
-    public void delete() {
-        final String name = "relationshipTypeDelete";
-        createRelationshipType(name);
-        browsingToRelationshipType();
-
-        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
-
-        Component result = findComponentByProp(KEY, DATATABLE_PATH, name);
-
-        assertNotNull(result);
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink",
-                IndicatingOnConfirmAjaxLink.class);
-
-        wicketTester.getRequest().addParameter("confirm", "true");
-        wicketTester.clickLink(
-                wicketTester.getComponentFromLastRenderedPage(
-                        result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"));
-
-        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
-                result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"), "onclick");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.cleanupFeedbackMessages();
-        result = findComponentByProp(KEY, DATATABLE_PATH, name);
-
-        assertNull(result);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/SchemasITCase.java
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/SchemasITCase.java b/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/SchemasITCase.java
deleted file mode 100644
index fd041eb..0000000
--- a/fit/console-reference/src/test/java/org/apache/syncope/fit/console/reference/pages/types/SchemasITCase.java
+++ /dev/null
@@ -1,157 +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.fit.console.reference.pages.types;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import org.apache.syncope.client.console.pages.Types;
-import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
-import org.apache.syncope.fit.console.reference.pages.TypesITCase;
-import org.apache.wicket.Component;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.markup.html.form.DropDownChoice;
-import org.apache.wicket.util.tester.FormTester;
-import org.junit.Test;
-
-import static org.junit.Assert.assertNull;
-
-public class SchemasITCase extends TypesITCase {
-
-    @Test
-    public void readPlainSchema() {
-        browsingToPlainSchemas();
-        wicketTester.assertLabel(
-                PLAIN_DATATABLE_PATH
-                + ":tablePanel:groupForm:"
-                + "checkgroup:dataTable:body:rows:1:cells:1:cell", "aLong");
-
-        wicketTester.assertComponent(
-                PLAIN_DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:"
-                + "body:rows:1:cells:7:cell:panelEdit:editLink", IndicatingAjaxLink.class);
-
-        wicketTester.clickLink(
-                PLAIN_DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:dataTable:"
-                + "body:rows:1:cells:7:cell:panelEdit:editLink");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:"
-                + "panel:collapsePanel:tabs:0:body:content:modal:"
-                + "form:content:kindForm:kind:dropDownChoiceField", DropDownChoice.class);
-    }
-
-    @Test
-    public void createPlainSchema() {
-        browsingToPlainSchemas();
-        wicketTester.clickLink("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:container:content:add");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:"
-                + "collapsePanel:tabs:0:body:content:modal:form");
-        formTester.setValue("content:details:form:key:textField", "zBoolean");
-        formTester.setValue("content:details:form:type:dropDownChoiceField", "3");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:"
-                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit");
-
-        wicketTester.assertInfoMessages("Operation executed successfully");
-
-        wicketTester.cleanupFeedbackMessages();
-        wicketTester.assertRenderedPage(Types.class);
-    }
-
-    @Test
-    public void updatePlainSchema() {
-        browsingToPlainSchemas();
-        
-        Component result = findComponentByProp(KEY, PLAIN_DATATABLE_PATH, "firstname");
-        
-        wicketTester.assertLabel(
-                result.getPageRelativePath() + ":cells:1:cell", "firstname");
-
-        wicketTester.clickLink(
-                result.getPageRelativePath() + ":cells:7:cell:panelEdit:editLink");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:"
-                + "panel:collapsePanel:tabs:0:body:content:modal:"
-                + "form:content:kindForm:kind:dropDownChoiceField", DropDownChoice.class);
-
-        final FormTester formTester =
-                wicketTester.newFormTester("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal:form");
-        formTester.setValue("content:details:form:multivalue:checkboxField", "true");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:"
-                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit", true);
-
-        wicketTester.assertInfoMessages("Operation executed successfully");
-    }
-
-    @Test
-    public void deletePlainSchema() {
-        browsingToPlainSchemas();
-        //create new Plain Schema
-        final String schemaName = "zStringDelete";
-        wicketTester.clickLink("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:container:content:add");
-
-        wicketTester.assertComponent(
-                "content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal", Modal.class);
-
-        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:"
-                + "collapsePanel:tabs:0:body:content:modal:form");
-        formTester.setValue("content:details:form:key:textField", schemaName);
-        formTester.setValue("content:details:form:type:dropDownChoiceField", "0");
-
-        wicketTester.clickLink("content:tabbedPanel:panel:"
-                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit");
-
-        wicketTester.assertInfoMessages("Operation executed successfully");;
-
-        wicketTester.cleanupFeedbackMessages();
-
-        //delete plain schema
-        wicketTester.clickLink(
-                PLAIN_DATATABLE_PATH
-                + ":tablePanel:groupForm:checkgroup:"
-                + "dataTable:topToolbars:toolbars:1:span:navigator:last");
-
-        wicketTester.assertComponent(PLAIN_DATATABLE_PATH, AjaxDataTablePanel.class);
-
-        Component result = findComponentByProp(KEY, PLAIN_DATATABLE_PATH, schemaName);
-
-        wicketTester.assertComponent(
-                result.getPageRelativePath() + ":cells:7:cell:panelDelete:deleteLink",
-                IndicatingOnConfirmAjaxLink.class);
-
-        wicketTester.getRequest().addParameter("confirm", "true");
-        wicketTester.clickLink(
-                wicketTester.getComponentFromLastRenderedPage(
-                        result.getPageRelativePath() + ":cells:7:cell:panelDelete:deleteLink"));
-
-        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
-                result.getPageRelativePath() + ":cells:7:cell:panelDelete:deleteLink"), "onclick");
-        wicketTester.assertInfoMessages("Operation executed successfully");
-        wicketTester.cleanupFeedbackMessages();
-
-        assertNull(findComponentByProp(KEY, PLAIN_DATATABLE_PATH, schemaName));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 1a09486..e438a78 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -126,24 +126,36 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.camel</groupId>
-      <artifactId>syncope-ext-camel-rest-cxf</artifactId>
+      <groupId>org.apache.syncope.client</groupId>
+      <artifactId>syncope-client-lib</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>          
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.syncope.client</groupId>
-      <artifactId>syncope-client-lib</artifactId>
+      <artifactId>syncope-client-cli</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.syncope.client</groupId>
-      <artifactId>syncope-client-cli</artifactId>
+      <artifactId>syncope-client-console</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.syncope.ext.camel</groupId>
+      <artifactId>syncope-ext-camel-rest-cxf</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>          
+    </dependency>
+    <dependency>
+      <groupId>org.apache.syncope.ext.camel</groupId>
+      <artifactId>syncope-ext-camel-client-console</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>    
+    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
       <scope>test</scope>


[15/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
new file mode 100644
index 0000000..b23866f
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
@@ -0,0 +1,214 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.time.DateUtils;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.types.JobAction;
+import org.apache.syncope.common.lib.types.JobStatusType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.TaskExecQuery;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.fit.core.reference.TestSampleJobDelegate;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SchedTaskITCase extends AbstractTaskITCase {
+
+    @Test
+    public void getJobClasses() {
+        Set<String> jobClasses = syncopeService.info().getTaskJobs();
+        assertNotNull(jobClasses);
+        assertFalse(jobClasses.isEmpty());
+    }
+
+    @Test
+    public void list() {
+        PagedResult<SchedTaskTO> tasks =
+                taskService.list(new TaskQuery.Builder().type(TaskType.SCHEDULED).build());
+        assertFalse(tasks.getResult().isEmpty());
+        for (AbstractTaskTO task : tasks.getResult()) {
+            if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO || task instanceof PushTaskTO) {
+                fail();
+            }
+        }
+    }
+
+    @Test
+    public void update() {
+        SchedTaskTO task = taskService.read(SCHED_TASK_ID, true);
+        assertNotNull(task);
+
+        SchedTaskTO taskMod = new SchedTaskTO();
+        taskMod.setKey(5L);
+        taskMod.setCronExpression(null);
+
+        taskService.update(taskMod);
+        SchedTaskTO actual = taskService.read(taskMod.getKey(), true);
+        assertNotNull(actual);
+        assertEquals(task.getKey(), actual.getKey());
+        assertNull(actual.getCronExpression());
+    }
+
+    @Test
+    public void deferred() {
+        SchedTaskTO task = new SchedTaskTO();
+        task.setActive(true);
+        task.setName("deferred");
+        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
+
+        Response response = taskService.create(task);
+        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+        assertNotNull(task);
+
+        Date initial = new Date();
+        Date later = DateUtils.addSeconds(initial, 2);
+
+        taskService.execute(new ExecuteQuery.Builder().key(task.getKey()).startAt(later).build());
+
+        int i = 0;
+        int maxit = 50;
+
+        // wait for completion (executions incremented)
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            task = taskService.read(task.getKey(), true);
+
+            assertNotNull(task);
+            assertNotNull(task.getExecutions());
+
+            i++;
+        } while (task.getExecutions().isEmpty() && i < maxit);
+
+        PagedResult<TaskExecTO> execs =
+                taskService.listExecutions(new TaskExecQuery.Builder().key(task.getKey()).build());
+        assertEquals(1, execs.getTotalCount());
+        assertTrue(execs.getResult().get(0).getStart().after(initial));
+        // round 1 sec for safety
+        assertTrue(DateUtils.addSeconds(execs.getResult().get(0).getStart(), 1).after(later));
+    }
+
+    @Test
+    public void issueSYNCOPE144() {
+        SchedTaskTO task = new SchedTaskTO();
+        task.setName("issueSYNCOPE144");
+        task.setDescription("issueSYNCOPE144 Description");
+        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
+
+        Response response = taskService.create(task);
+        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+        assertNotNull(task);
+        assertEquals("issueSYNCOPE144", task.getName());
+        assertEquals("issueSYNCOPE144 Description", task.getDescription());
+
+        task = taskService.read(task.getKey(), true);
+        assertNotNull(task);
+        assertEquals("issueSYNCOPE144", task.getName());
+        assertEquals("issueSYNCOPE144 Description", task.getDescription());
+
+        task.setName("issueSYNCOPE144_2");
+        task.setDescription("issueSYNCOPE144 Description_2");
+
+        response = taskService.create(task);
+        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+        assertNotNull(task);
+        assertEquals("issueSYNCOPE144_2", task.getName());
+        assertEquals("issueSYNCOPE144 Description_2", task.getDescription());
+    }
+
+    @Test
+    public void issueSYNCOPE660() {
+        List<TaskExecTO> list = taskService.listJobs(JobStatusType.ALL);
+        int old_size = list.size();
+
+        SchedTaskTO task = new SchedTaskTO();
+        task.setName("issueSYNCOPE660");
+        task.setDescription("issueSYNCOPE660 Description");
+        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
+
+        Response response = taskService.create(task);
+        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+
+        list = taskService.listJobs(JobStatusType.ALL);
+        assertEquals(old_size + 1, list.size());
+
+        taskService.actionJob(task.getKey(), JobAction.START);
+
+        int i = 0, maxit = 50;
+
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                // ignore
+            }
+
+            list = taskService.listJobs(JobStatusType.RUNNING);
+
+            assertNotNull(list);
+            i++;
+        } while (list.size() < 1 && i < maxit);
+
+        assertEquals(1, list.size());
+        assertEquals(task.getKey(), list.get(0).getTask(), 0);
+
+        taskService.actionJob(task.getKey(), JobAction.STOP);
+
+        i = 0;
+
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                // ignore
+            }
+
+            list = taskService.listJobs(JobStatusType.RUNNING);
+
+            assertNotNull(list);
+            i++;
+        } while (list.size() >= 1 && i < maxit);
+
+        assertTrue(list.isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
new file mode 100644
index 0000000..5626612
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -0,0 +1,398 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SearchITCase extends AbstractITCase {
+
+    @Test
+    public void searchUser() {
+        // LIKE
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
+
+        for (UserTO user : matchingUsers.getResult()) {
+            assertNotNull(user);
+        }
+
+        // ISNULL
+        matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).build());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
+
+        Collection<UserTO> found = CollectionUtils.select(matchingUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 2L || user.getKey() == 3L;
+            }
+        });
+        assertEquals(2, found.size());
+    }
+
+    @Test
+    public void searchByUsernameAndKey() {
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        is("username").equalTo("rossini").and("key").lessThan(2).query()).build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+        assertEquals("rossini", matchingUsers.getResult().iterator().next().getUsername());
+        assertEquals(1L, matchingUsers.getResult().iterator().next().getKey(), 0);
+    }
+
+    @Test
+    public void searchByGroupNameAndKey() {
+        PagedResult<GroupTO> groups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().
+                        is("name").equalTo("root").and("key").lessThan(2).query()).build());
+        assertNotNull(groups);
+        assertEquals(1, groups.getResult().size());
+        assertEquals("root", groups.getResult().iterator().next().getName());
+        assertEquals(1L, groups.getResult().iterator().next().getKey(), 0);
+    }
+
+    @Test
+    public void searchByGroup() {
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(1L).query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
+
+        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 1;
+            }
+        }));
+    }
+
+    @Test
+    public void searchByDynGroup() {
+        GroupTO group = GroupITCase.getBasicSampleTO("dynMembership");
+        group.setUDynMembershipCond("cool==true");
+        group = createGroup(group).getAny();
+        assertNotNull(group);
+
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(group.getKey()).query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
+
+        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 4;
+            }
+        }));
+    }
+
+    @Test
+    public void searchByRole() {
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles("Other").query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
+
+        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 1;
+            }
+        }));
+    }
+
+    @Test
+    public void searchByDynRole() {
+        RoleTO role = RoleITCase.getSampleRoleTO("dynMembership");
+        role.setDynMembershipCond("cool==true");
+        Response response = roleService.create(role);
+        role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
+        assertNotNull(role);
+
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(role.getKey()).query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
+
+        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 4;
+            }
+        }));
+    }
+
+    @Test
+    public void searchUserByResourceName() {
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
+
+        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 2;
+            }
+        }));
+    }
+
+    @Test
+    public void paginatedSearch() {
+        // LIKE
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).page(1).size(2).build());
+        assertNotNull(matchingUsers);
+
+        assertFalse(matchingUsers.getResult().isEmpty());
+        for (UserTO user : matchingUsers.getResult()) {
+            assertNotNull(user);
+        }
+
+        // ISNULL
+        matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).page(2).size(2).
+                build());
+        assertNotNull(matchingUsers);
+        assertEquals(2, matchingUsers.getPage());
+        assertEquals(2, matchingUsers.getResult().size());
+    }
+
+    @Test
+    public void searchByBooleanAnyCond() {
+        PagedResult<GroupTO> groups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("show").equalTo("true").query()).build());
+        assertNotNull(groups);
+        assertFalse(groups.getResult().isEmpty());
+    }
+
+    @Test
+    public void searchByRelationshipAnyCond() {
+        PagedResult<GroupTO> groups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query()).build());
+        assertNotNull(groups);
+        assertEquals(1, groups.getResult().size());
+        assertEquals(6L, groups.getResult().iterator().next().getKey(), 0);
+    }
+
+    @Test
+    public void nested() {
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
+        assertNotNull(matchingUsers);
+
+        assertFalse(matchingUsers.getResult().isEmpty());
+        for (UserTO user : matchingUsers.getResult()) {
+            assertNotNull(user);
+        }
+    }
+
+    @Test
+    public void searchByType() {
+        PagedResult<AnyObjectTO> matching = anyObjectService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").query()).build());
+        assertNotNull(matching);
+
+        assertFalse(matching.getResult().isEmpty());
+        for (AnyObjectTO printer : matching.getResult()) {
+            assertNotNull(printer);
+        }
+
+        matching = anyObjectService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("UNEXISTING").query()).build());
+        assertNotNull(matching);
+
+        assertTrue(matching.getResult().isEmpty());
+    }
+
+    @Test
+    public void searchByRelationship() {
+        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                        inRelationships(2L).query()).
+                build());
+        assertNotNull(anyObjects);
+        assertTrue(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 1L;
+            }
+        }));
+
+        PagedResult<UserTO> users = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationships(1L).query()).
+                build());
+        assertNotNull(users);
+        assertTrue(IterableUtils.matchesAny(users.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 4L;
+            }
+        }));
+    }
+
+    @Test
+    public void searchByRelationshipType() {
+        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                        inRelationshipTypes("neighborhood").query()).
+                build());
+        assertNotNull(anyObjects);
+        assertTrue(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 1L;
+            }
+        }));
+        assertTrue(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 2L;
+            }
+        }));
+
+        PagedResult<UserTO> users = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationshipTypes("neighborhood").query()).
+                build());
+        assertNotNull(users);
+        assertTrue(IterableUtils.matchesAny(users.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 4L;
+            }
+        }));
+    }
+
+    @Test
+    public void assignable() {
+        PagedResult<GroupTO> groups = groupService.search(
+                new AnySearchQuery.Builder().realm("/even/two").page(1).size(1000).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().isAssignable().
+                        and("name").equalTo("*").query()).
+                build());
+        assertNotNull(groups);
+        assertTrue(IterableUtils.matchesAny(groups.getResult(), new Predicate<GroupTO>() {
+
+            @Override
+            public boolean evaluate(final GroupTO group) {
+                return group.getKey() == 15L;
+            }
+        }));
+        assertFalse(IterableUtils.matchesAny(groups.getResult(), new Predicate<GroupTO>() {
+
+            @Override
+            public boolean evaluate(final GroupTO group) {
+                return group.getKey() == 16L;
+            }
+        }));
+
+        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+                new AnySearchQuery.Builder().realm("/odd").
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").isAssignable().
+                        and("name").equalTo("*").query()).
+                build());
+        assertNotNull(anyObjects);
+        assertFalse(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 3L;
+            }
+        }));
+    }
+
+    @Test
+    public void orderBy() {
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
+                orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
+        assertNotNull(matchingUsers);
+
+        assertFalse(matchingUsers.getResult().isEmpty());
+        for (UserTO user : matchingUsers.getResult()) {
+            assertNotNull(user);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SecurityQuestionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SecurityQuestionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SecurityQuestionITCase.java
new file mode 100644
index 0000000..40d4b54
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SecurityQuestionITCase.java
@@ -0,0 +1,100 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.SecurityQuestionTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SecurityQuestionITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
+        assertNotNull(securityQuestionTO);
+    }
+
+    @Test
+    public void list() {
+        List<SecurityQuestionTO> securityQuestionTOs = securityQuestionService.list();
+        assertNotNull(securityQuestionTOs);
+        assertFalse(securityQuestionTOs.isEmpty());
+        for (SecurityQuestionTO instance : securityQuestionTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void create() {
+        SecurityQuestionTO securityQuestionTO = new SecurityQuestionTO();
+        securityQuestionTO.setContent("What is your favorite pet's name?");
+
+        Response response = securityQuestionService.create(securityQuestionTO);
+        SecurityQuestionTO actual = getObject(response.getLocation(), SecurityQuestionService.class,
+                SecurityQuestionTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        securityQuestionTO.setKey(actual.getKey());
+        assertEquals(actual, securityQuestionTO);
+    }
+
+    @Test
+    public void update() {
+        SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
+        securityQuestionTO.setContent("What is your favorite color?");
+
+        securityQuestionService.update(securityQuestionTO);
+        SecurityQuestionTO actual = securityQuestionService.read(securityQuestionTO.getKey());
+        assertNotNull(actual);
+        assertEquals(actual, securityQuestionTO);
+    }
+
+    @Test
+    public void delete() {
+        SecurityQuestionTO securityQuestion = new SecurityQuestionTO();
+        securityQuestion.setContent("What is your first pet's name?");
+
+        Response response = securityQuestionService.create(securityQuestion);
+        securityQuestion = getObject(response.getLocation(), SecurityQuestionService.class, SecurityQuestionTO.class);
+
+        securityQuestionService.delete(securityQuestion.getKey());
+
+        try {
+            securityQuestionService.read(securityQuestion.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
new file mode 100644
index 0000000..234887d
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
@@ -0,0 +1,854 @@
+/*
+ * 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.fit.core;
+
+import org.apache.syncope.fit.ActivitiDetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.patch.DeassociationPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.policy.SyncPolicyTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
+import org.apache.syncope.common.lib.types.SyncMode;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.provisioning.java.sync.DBPasswordSyncActions;
+import org.apache.syncope.core.provisioning.java.sync.LDAPPasswordSyncActions;
+import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
+import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
+import org.apache.syncope.fit.core.reference.TestSyncActions;
+import org.apache.syncope.fit.core.reference.TestSyncRule;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SyncTaskITCase extends AbstractTaskITCase {
+
+    @BeforeClass
+    public static void testSyncActionsSetup() {
+        SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID, true);
+        syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
+        taskService.update(syncTask);
+    }
+
+    @Test
+    public void getSyncActionsClasses() {
+        Set<String> actions = syncopeService.info().getSyncActions();
+        assertNotNull(actions);
+        assertFalse(actions.isEmpty());
+    }
+
+    @Test
+    public void list() {
+        PagedResult<SyncTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.SYNCHRONIZATION).build());
+        assertFalse(tasks.getResult().isEmpty());
+        for (AbstractTaskTO task : tasks.getResult()) {
+            if (!(task instanceof SyncTaskTO)) {
+                fail();
+            }
+        }
+    }
+
+    @Test
+    public void create() {
+        SyncTaskTO task = new SyncTaskTO();
+        task.setName("Test create Sync");
+        task.setDestinationRealm("/");
+        task.setResource(RESOURCE_NAME_WS2);
+        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
+
+        UserTO userTemplate = new UserTO();
+        userTemplate.getResources().add(RESOURCE_NAME_WS2);
+
+        userTemplate.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+        task.getTemplates().put(AnyTypeKind.USER.name(), userTemplate);
+
+        GroupTO groupTemplate = new GroupTO();
+        groupTemplate.getResources().add(RESOURCE_NAME_LDAP);
+        task.getTemplates().put(AnyTypeKind.GROUP.name(), groupTemplate);
+
+        Response response = taskService.create(task);
+        SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
+        assertNotNull(actual);
+
+        task = taskService.read(actual.getKey(), true);
+        assertNotNull(task);
+        assertEquals(actual.getKey(), task.getKey());
+        assertEquals(actual.getJobDelegateClassName(), task.getJobDelegateClassName());
+        assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
+        assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name()));
+    }
+
+    @Test
+    public void sync() throws Exception {
+        removeTestUsers();
+
+        // -----------------------------
+        // Create a new user ... it should be updated applying sync policy
+        // -----------------------------
+        UserTO inUserTO = new UserTO();
+        inUserTO.setRealm(SyncopeConstants.ROOT_REALM);
+        inUserTO.setPassword("password123");
+        String userName = "test9";
+        inUserTO.setUsername(userName);
+        inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
+        inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
+        inUserTO.getPlainAttrs().add(attrTO("type", "a type"));
+        inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
+        inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
+        inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
+        inUserTO.getAuxClasses().add("csv");
+        inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        inUserTO = createUser(inUserTO).getAny();
+        assertNotNull(inUserTO);
+        assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
+
+        // -----------------------------
+        try {
+            int usersPre = userService.list(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
+            assertNotNull(usersPre);
+
+            execProvisioningTask(taskService, SYNC_TASK_ID, 50, false);
+
+            // after execution of the sync task the user data should have been synced from CSV
+            // and processed by user template
+            UserTO userTO = userService.read(inUserTO.getKey());
+            assertNotNull(userTO);
+            assertEquals(userName, userTO.getUsername());
+            assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                    ? "active" : "created", userTO.getStatus());
+            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
+            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+
+            // Matching --> Update (no link)
+            assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
+            // check for user template
+            userTO = readUser("test7");
+            assertNotNull(userTO);
+            assertEquals("TYPE_OTHER", userTO.getPlainAttrMap().get("type").getValues().get(0));
+            assertEquals(3, userTO.getResources().size());
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+            assertEquals(1, userTO.getMemberships().size());
+            assertEquals(8, userTO.getMemberships().get(0).getRightKey());
+
+            // Unmatching --> Assign (link) - SYNCOPE-658
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
+            assertEquals(1, IterableUtils.countMatches(userTO.getDerAttrs(), new Predicate<AttrTO>() {
+
+                @Override
+                public boolean evaluate(final AttrTO attributeTO) {
+                    return "csvuserid".equals(attributeTO.getSchema());
+                }
+            }));
+
+            userTO = readUser("test8");
+            assertNotNull(userTO);
+            assertEquals("TYPE_8", userTO.getPlainAttrMap().get("type").getValues().get(0));
+
+            // Check for ignored user - SYNCOPE-663
+            try {
+                readUser("test2");
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+            }
+
+            // check for sync results
+            int usersPost = userService.list(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
+            assertNotNull(usersPost);
+            assertEquals(usersPre + 8, usersPost);
+
+            // Check for issue 215:
+            // * expected disabled user test1
+            // * expected enabled user test2
+            userTO = readUser("test1");
+            assertNotNull(userTO);
+            assertEquals("suspended", userTO.getStatus());
+
+            userTO = readUser("test3");
+            assertNotNull(userTO);
+            assertEquals("active", userTO.getStatus());
+
+            Set<Long> otherSyncTaskKeys = new HashSet<>();
+            otherSyncTaskKeys.add(25L);
+            otherSyncTaskKeys.add(26L);
+            execProvisioningTasks(taskService, otherSyncTaskKeys, 50, false);
+
+            // Matching --> UNLINK
+            assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
+            assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
+        } finally {
+            removeTestUsers();
+        }
+    }
+
+    @Test
+    public void dryRun() {
+        TaskExecTO execution = execProvisioningTask(taskService, SYNC_TASK_ID, 50, true);
+        assertEquals(
+                "Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(),
+                "SUCCESS", execution.getStatus());
+    }
+
+    @Test
+    public void reconcileFromDB() {
+        UserTO userTO = null;
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        try {
+            TaskExecTO execution = execProvisioningTask(taskService, 7L, 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser1");
+            assertNotNull(userTO);
+            assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertEquals("suspended", userTO.getStatus());
+
+            // enable user on external resource
+            jdbcTemplate.execute("UPDATE TEST SET status=TRUE WHERE id='testuser1'");
+
+            // re-execute the same SyncTask: now user must be active
+            execution = execProvisioningTask(taskService, 7L, 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser1");
+            assertNotNull(userTO);
+            assertEquals("active", userTO.getStatus());
+        } finally {
+            jdbcTemplate.execute("UPDATE TEST SET status=FALSE WHERE id='testUser1'");
+            if (userTO != null) {
+                userService.delete(userTO.getKey());
+            }
+        }
+    }
+
+    /**
+     * Clean Syncope and LDAP resource status.
+     */
+    private void ldapCleanup() {
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
+        if (matchingGroups.getSize() > 0) {
+            for (GroupTO group : matchingGroups.getResult()) {
+                DeassociationPatch deassociationPatch = new DeassociationPatch();
+                deassociationPatch.setKey(group.getKey());
+                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+                groupService.deassociate(deassociationPatch);
+                groupService.delete(group.getKey());
+            }
+        }
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
+                build());
+        if (matchingUsers.getSize() > 0) {
+            for (UserTO user : matchingUsers.getResult()) {
+                DeassociationPatch deassociationPatch = new DeassociationPatch();
+                deassociationPatch.setKey(user.getKey());
+                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+                userService.deassociate(deassociationPatch);
+                userService.delete(user.getKey());
+            }
+        }
+    }
+
+    @Test
+    public void reconcileFromLDAP() {
+        // First of all, clear any potential conflict with existing user / group
+        ldapCleanup();
+
+        // 0. synchronize
+        TaskExecTO execution = execProvisioningTask(taskService, 11L, 50, false);
+
+        // 1. verify execution status
+        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 2. verify that synchronized group is found
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
+        assertNotNull(matchingGroups);
+        assertEquals(1, matchingGroups.getResult().size());
+
+        // 3. verify that synchronized user is found
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+
+        // Check for SYNCOPE-436
+        assertEquals("syncFromLDAP",
+                matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
+        // Check for SYNCOPE-270
+        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
+        // Check for SYNCOPE-123
+        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
+
+        GroupTO groupTO = matchingGroups.getResult().iterator().next();
+        assertNotNull(groupTO);
+        assertEquals("testLDAPGroup", groupTO.getName());
+        assertEquals("true", groupTO.getPlainAttrMap().get("show").getValues().get(0));
+        assertEquals(matchingUsers.getResult().iterator().next().getKey(), groupTO.getUserOwner(), 0);
+        assertNull(groupTO.getGroupOwner());
+
+        // SYNCOPE-317
+        execProvisioningTask(taskService, 11L, 50, false);
+    }
+
+    @Test
+    public void reconcileFromScriptedSQL() {
+        // 0. reset sync token and set MappingItemTransformer
+        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
+        ResourceTO originalResource = SerializationUtils.clone(resource);
+        ProvisionTO provision = resource.getProvision("PRINTER");
+        assertNotNull(provision);
+
+        try {
+            provision.setSyncToken(null);
+
+            MappingItemTO mappingItem = IterableUtils.find(
+                    provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+
+                @Override
+                public boolean evaluate(final MappingItemTO object) {
+                    return "location".equals(object.getIntAttrName());
+                }
+            });
+            assertNotNull(mappingItem);
+            mappingItem.getMappingItemTransformerClassNames().clear();
+            mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
+
+            resourceService.update(resource);
+
+            // 1. create printer on external resource
+            AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync");
+            String originalLocation = anyObjectTO.getPlainAttrMap().get("location").getValues().get(0);
+            assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
+
+            anyObjectTO = createAnyObject(anyObjectTO).getAny();
+            assertNotNull(anyObjectTO);
+
+            // 2. verify that PrefixMappingItemTransformer was applied during propagation
+            // (location starts with given prefix on external resource)
+            ConnObjectTO connObjectTO = resourceService.
+                    readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
+            assertFalse(anyObjectTO.getPlainAttrMap().get("location").getValues().get(0).
+                    startsWith(PrefixMappingItemTransformer.PREFIX));
+            assertTrue(connObjectTO.getPlainAttrMap().get("location").getValues().get(0).
+                    startsWith(PrefixMappingItemTransformer.PREFIX));
+
+            // 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
+            PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                            is("location").equalTo("sync*").query()).build());
+            assertTrue(matchingPrinters.getSize() > 0);
+            for (AnyObjectTO printer : matchingPrinters.getResult()) {
+                DeassociationPatch deassociationPatch = new DeassociationPatch();
+                deassociationPatch.setKey(printer.getKey());
+                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_DBSCRIPTED);
+                anyObjectService.deassociate(deassociationPatch);
+                anyObjectService.delete(printer.getKey());
+            }
+
+            // 4. synchronize
+            execProvisioningTask(taskService, 28L, 50, false);
+
+            // 5. verify that printer was re-created in Syncope (implies that location does not start with given prefix,
+            // hence PrefixMappingItemTransformer was applied during sync)
+            matchingPrinters = anyObjectService.search(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                            is("location").equalTo("sync*").query()).build());
+            assertTrue(matchingPrinters.getSize() > 0);
+
+            // 6. verify that synctoken was updated
+            assertNotNull(
+                    resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
+        } finally {
+            resourceService.update(originalResource);
+        }
+    }
+
+    @Test
+    public void filteredReconciliation() {
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        SyncTaskTO task = null;
+        UserTO userTO = null;
+        try {
+            // 1. create 2 users on testsync
+            jdbcTemplate.execute("INSERT INTO testsync VALUES (1001, 'user1', 'Doe', 'mail1@apache.org')");
+            jdbcTemplate.execute("INSERT INTO testsync VALUES (1002, 'user2', 'Rossi', 'mail2@apache.org')");
+
+            // 2. create new sync task for test-db, with reconciliation filter (surname 'Rossi') 
+            task = taskService.read(10L, true);
+            task.setSyncMode(SyncMode.FILTERED_RECONCILIATION);
+            task.setReconciliationFilterBuilderClassName(TestReconciliationFilterBuilder.class.getName());
+            Response response = taskService.create(task);
+            task = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
+            assertNotNull(task);
+            assertEquals(
+                    TestReconciliationFilterBuilder.class.getName(),
+                    task.getReconciliationFilterBuilderClassName());
+
+            // 3. exec task
+            TaskExecTO execution = execProvisioningTask(taskService, task.getKey(), 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            // 4. verify that only enabled user was synchronized
+            userTO = readUser("user2");
+            assertNotNull(userTO);
+
+            try {
+                readUser("user1");
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.NotFound, e.getType());
+            }
+        } finally {
+            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1001");
+            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1002");
+            if (task != null && task.getKey() != 7L) {
+                taskService.delete(task.getKey());
+            }
+            if (userTO != null) {
+                userService.delete(userTO.getKey());
+            }
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE68() {
+        //-----------------------------
+        // Create a new user ... it should be updated applying sync policy
+        //-----------------------------
+        UserTO userTO = new UserTO();
+        userTO.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO.setPassword("password123");
+        userTO.setUsername("testuser2");
+
+        userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
+        userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
+        userTO.getPlainAttrs().add(attrTO("type", "a type"));
+        userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
+        userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org"));
+        userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org"));
+
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals("testuser2", userTO.getUsername());
+        assertEquals(1, userTO.getMemberships().size());
+        assertEquals(3, userTO.getResources().size());
+        //-----------------------------
+
+        try {
+            //-----------------------------
+            //  add user template
+            //-----------------------------
+            UserTO template = new UserTO();
+
+            template.getMemberships().add(new MembershipTO.Builder().group(10L).build());
+
+            template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+            //-----------------------------
+
+            // Update sync task
+            SyncTaskTO task = taskService.read(9L, true);
+            assertNotNull(task);
+
+            task.getTemplates().put(AnyTypeKind.USER.name(), template);
+
+            taskService.update(task);
+            SyncTaskTO actual = taskService.read(task.getKey(), true);
+            assertNotNull(actual);
+            assertEquals(task.getKey(), actual.getKey());
+            assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
+            assertFalse(((UserTO) actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
+
+            TaskExecTO execution = execProvisioningTask(taskService, actual.getKey(), 50, false);
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser2");
+            assertNotNull(userTO);
+            assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertEquals(2, userTO.getMemberships().size());
+            assertEquals(4, userTO.getResources().size());
+        } finally {
+            UserTO dUserTO = deleteUser(userTO.getKey()).getAny();
+            assertNotNull(dUserTO);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE230() {
+        // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
+        execProvisioningTask(taskService, 10L, 50, false);
+
+        // 3. read e-mail address for user created by the SyncTask first execution
+        UserTO userTO = readUser("issuesyncope230");
+        assertNotNull(userTO);
+        String email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+        assertNotNull(email);
+
+        // 4. update TESTSYNC on external H2 by changing e-mail address
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
+
+        // 5. re-execute the SyncTask
+        execProvisioningTask(taskService, 10L, 50, false);
+
+        // 6. verify that the e-mail was updated
+        userTO = readUser("issuesyncope230");
+        assertNotNull(userTO);
+        email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+        assertNotNull(email);
+        assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
+    }
+
+    @Test
+    public void issueSYNCOPE258() {
+        // -----------------------------
+        // Add a custom correlation rule
+        // -----------------------------
+        SyncPolicyTO policyTO = policyService.read(9L);
+        policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
+        policyService.update(policyTO);
+        // -----------------------------
+
+        SyncTaskTO task = new SyncTaskTO();
+        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        task.setName("Test Sync Rule");
+        task.setActive(true);
+        task.setResource(RESOURCE_NAME_WS2);
+        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
+        task.setPerformCreate(true);
+        task.setPerformDelete(true);
+        task.setPerformUpdate(true);
+
+        Response response = taskService.create(task);
+        task = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        createUser(userTO);
+
+        userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        userTO = createUser(userTO).getAny();
+
+        // change email in order to unmatch the second user
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("email", "s258@apache.org"));
+
+        userService.update(userPatch);
+
+        execProvisioningTask(taskService, task.getKey(), 50, false);
+
+        SyncTaskTO executed = taskService.read(task.getKey(), true);
+        assertEquals(1, executed.getExecutions().size());
+
+        // asser for just one match
+        assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
+                executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
+    }
+
+    @Test
+    public void issueSYNCOPE272() {
+        removeTestUsers();
+
+        // create user with testdb resource
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        userTO = result.getAny();
+        try {
+            assertNotNull(userTO);
+            assertEquals(1, result.getPropagationStatuses().size());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+
+            TaskExecTO taskExecTO = execProvisioningTask(taskService, 24L, 50, false);
+
+            assertNotNull(taskExecTO.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()));
+
+            userTO = userService.read(userTO.getKey());
+            assertNotNull(userTO);
+            assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
+        } finally {
+            removeTestUsers();
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE307() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
+        userTO.setUsername("test0");
+        userTO.getPlainAttrMap().get("firstname").getValues().clear();
+        userTO.getPlainAttrMap().get("firstname").getValues().add("nome0");
+        userTO.getAuxClasses().add("csv");
+
+        AttrTO csvuserid = new AttrTO();
+        csvuserid.setSchema("csvuserid");
+        userTO.getDerAttrs().add(csvuserid);
+
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        userTO = userService.read(userTO.getKey());
+        assertTrue(userTO.getVirAttrMap().isEmpty());
+
+        // Update sync task
+        SyncTaskTO task = taskService.read(12L, true);
+        assertNotNull(task);
+
+        UserTO template = new UserTO();
+        template.setPassword("'password123'");
+        template.getResources().add(RESOURCE_NAME_DBVIRATTR);
+        template.getVirAttrs().add(attrTO("virtualdata", "'virtualvalue'"));
+
+        task.getTemplates().put(AnyTypeKind.USER.name(), template);
+
+        taskService.update(task);
+
+        // exec task: one user from CSV will match the user created above and template will be applied
+        execProvisioningTask(taskService, task.getKey(), 50, false);
+
+        // check that template was successfully applied...
+        userTO = userService.read(userTO.getKey());
+        assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // ...and that propagation to db succeeded
+        try {
+            JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+            String value = jdbcTemplate.queryForObject(
+                    "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
+            assertEquals("virtualvalue", value);
+        } catch (EmptyResultDataAccessException e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE313DB() throws Exception {
+        // 1. create user in DB
+        UserTO user = UserITCase.getUniqueSampleTO("syncope313-db@syncope.apache.org");
+        user.setPassword("security123");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        user = createUser(user).getAny();
+        assertNotNull(user);
+        assertFalse(user.getResources().isEmpty());
+
+        // 2. Check that the DB resource has the correct password
+        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        String value = jdbcTemplate.queryForObject(
+                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+        assertEquals(Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1), value.toUpperCase());
+
+        // 3. Update the password in the DB
+        String newCleanPassword = "new-security";
+        String newPassword = Encryptor.getInstance().encode(newCleanPassword, CipherAlgorithm.SHA1);
+        jdbcTemplate.execute("UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'");
+
+        // 4. Sync the user from the resource
+        SyncTaskTO syncTask = new SyncTaskTO();
+        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        syncTask.setName("DB Sync Task");
+        syncTask.setActive(true);
+        syncTask.setPerformCreate(true);
+        syncTask.setPerformUpdate(true);
+        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
+        syncTask.setResource(RESOURCE_NAME_TESTDB);
+        syncTask.getActionsClassNames().add(DBPasswordSyncActions.class.getName());
+        Response taskResponse = taskService.create(syncTask);
+
+        SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
+        assertNotNull(actual);
+
+        syncTask = taskService.read(actual.getKey(), true);
+        assertNotNull(syncTask);
+        assertEquals(actual.getKey(), syncTask.getKey());
+        assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
+
+        TaskExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
+        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 5. Test the sync'd user
+        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
+        assertNotNull(self);
+
+        // 6. Delete SyncTask + user
+        taskService.delete(syncTask.getKey());
+        deleteUser(user.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE313LDAP() throws Exception {
+        // First of all, clear any potential conflict with existing user / group
+        ldapCleanup();
+
+        // 1. create user in LDAP
+        String oldCleanPassword = "security123";
+        UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org");
+        user.setPassword(oldCleanPassword);
+        user.getResources().add(RESOURCE_NAME_LDAP);
+        user = createUser(user).getAny();
+        assertNotNull(user);
+        assertFalse(user.getResources().isEmpty());
+
+        // 2. request to change password only on Syncope and not on LDAP
+        String newCleanPassword = "new-security123";
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(user.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value(newCleanPassword).build());
+        user = updateUser(userPatch).getAny();
+
+        // 3. Check that the Syncope user now has the changed password
+        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
+        assertNotNull(self);
+
+        // 4. Check that the LDAP resource has the old password
+        ConnObjectTO connObject =
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
+        assertNotNull(getLdapRemoteObject(
+                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
+                oldCleanPassword,
+                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+        // 5. Update the LDAP Connector to retrieve passwords
+        ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
+        ConnInstanceTO resourceConnector = connectorService.read(
+                ldapResource.getConnector(), Locale.ENGLISH.getLanguage());
+        ConnConfProperty property = resourceConnector.getConfMap().get("retrievePasswordsWithSearch");
+        property.getValues().clear();
+        property.getValues().add(Boolean.TRUE);
+        connectorService.update(resourceConnector);
+
+        // 6. Sync the user from the resource
+        SyncTaskTO syncTask = new SyncTaskTO();
+        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        syncTask.setName("LDAP Sync Task");
+        syncTask.setActive(true);
+        syncTask.setPerformCreate(true);
+        syncTask.setPerformUpdate(true);
+        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
+        syncTask.setResource(RESOURCE_NAME_LDAP);
+        syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName());
+        Response taskResponse = taskService.create(syncTask);
+
+        syncTask = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
+        assertNotNull(syncTask);
+
+        TaskExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
+        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 7. Test the sync'd user
+        self = clientFactory.create(user.getUsername(), oldCleanPassword).self();
+        assertNotNull(self);
+
+        // 8. Delete SyncTask + user + reset the connector
+        taskService.delete(syncTask.getKey());
+        property.getValues().clear();
+        property.getValues().add(Boolean.FALSE);
+        connectorService.update(resourceConnector);
+        deleteUser(user.getKey());
+    }
+}


[09/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java
deleted file mode 100644
index edd32ec..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java
+++ /dev/null
@@ -1,335 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.rest.api.beans.SchemaQuery;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class PlainSchemaITCase extends AbstractITCase {
-
-    private PlainSchemaTO buildPlainSchemaTO(final String name, final AttrSchemaType type) {
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey(name + getUUIDString());
-        schemaTO.setType(type);
-        return schemaTO;
-    }
-
-    @Test
-    public void create() {
-        PlainSchemaTO schemaTO = buildPlainSchemaTO("testAttribute", AttrSchemaType.String);
-        schemaTO.setMandatoryCondition("false");
-
-        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertEquals(schemaTO, newPlainSchemaTO);
-
-        try {
-            createSchema(SchemaType.PLAIN, schemaTO);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.EntityExists, e.getType());
-        }
-    }
-
-    @Test
-    public void createWithNotPermittedName() {
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey("failedLogins");
-        schemaTO.setType(AttrSchemaType.String);
-
-        try {
-            createSchema(SchemaType.PLAIN, schemaTO);
-            fail("This should not be reacheable");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
-        }
-    }
-
-    @Test
-    public void createREnumWithoutEnumeration() {
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey("enumcheck");
-        schemaTO.setType(AttrSchemaType.Enum);
-
-        try {
-            createSchema(SchemaType.PLAIN, schemaTO);
-            fail("This should not be reacheable");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidSchemaEnum.name()));
-        }
-    }
-
-    @Test
-    public void createUEnumWithoutEnumeration() {
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey("enumcheck");
-        schemaTO.setType(AttrSchemaType.Enum);
-
-        try {
-            createSchema(SchemaType.PLAIN, schemaTO);
-            fail("This should not be reacheable");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidSchemaEnum.name()));
-        }
-    }
-
-    @Test
-    public void createEncrypted() {
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey("encrypted");
-        schemaTO.setType(AttrSchemaType.Encrypted);
-        schemaTO.setCipherAlgorithm(CipherAlgorithm.AES);
-        schemaTO.setSecretKey("huhadfhsjfsfsdkj!####");
-
-        createSchema(SchemaType.PLAIN, schemaTO);
-    }
-
-    @Test
-    public void createBinary() {
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey("x509certificate");
-        schemaTO.setType(AttrSchemaType.Binary);
-        schemaTO.setMimeType("application/x-x509-ca-cert");
-
-        createSchema(SchemaType.PLAIN, schemaTO);
-    }
-
-    @Test
-    public void delete() {
-        PlainSchemaTO schemaTO = buildPlainSchemaTO("todelete", AttrSchemaType.String);
-        schemaTO.setMandatoryCondition("false");
-        createSchema(SchemaType.PLAIN, schemaTO);
-
-        schemaService.delete(SchemaType.PLAIN, schemaTO.getKey());
-        PlainSchemaTO firstname = null;
-        try {
-            firstname = schemaService.read(SchemaType.PLAIN, schemaTO.getKey());
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-        assertNull(firstname);
-    }
-
-    @Test
-    public void list() {
-        List<PlainSchemaTO> schemas = schemaService.list(new SchemaQuery.Builder().type(SchemaType.PLAIN).build());
-        assertFalse(schemas.isEmpty());
-        for (PlainSchemaTO schemaTO : schemas) {
-            assertNotNull(schemaTO);
-        }
-    }
-
-    @Test
-    public void listByAnyTypeClass() {
-        final String clazz = anyTypeService.read(AnyTypeKind.USER.name()).getClasses().get(0);
-
-        List<PlainSchemaTO> userSchemas = schemaService.list(
-                new SchemaQuery.Builder().type(SchemaType.PLAIN).anyTypeClass(clazz).build());
-
-        assertTrue(IterableUtils.matchesAny(userSchemas, new Predicate<PlainSchemaTO>() {
-
-            @Override
-            public boolean evaluate(final PlainSchemaTO object) {
-                return "fullname".equals(object.getKey());
-            }
-        }));
-
-        assertFalse(IterableUtils.matchesAny(userSchemas, new Predicate<PlainSchemaTO>() {
-
-            @Override
-            public boolean evaluate(final PlainSchemaTO object) {
-                return "password.cipher.algorithm".equals(object.getKey())
-                        || "rderived_dx".equals(object.getKey())
-                        || "icon".equals(object.getKey())
-                        || "mderived_sx".equals(object.getKey())
-                        || "self.membership.layout".equals(object.getKey());
-            }
-        }));
-    }
-
-    @Test
-    public void update() {
-        PlainSchemaTO schemaTO = schemaService.read(SchemaType.PLAIN, "icon");
-        assertNotNull(schemaTO);
-
-        schemaService.update(SchemaType.PLAIN, schemaTO);
-        PlainSchemaTO updatedTO = schemaService.read(SchemaType.PLAIN, "icon");
-        assertEquals(schemaTO, updatedTO);
-
-        updatedTO.setType(AttrSchemaType.Date);
-        try {
-            schemaService.update(SchemaType.PLAIN, updatedTO);
-            fail("This should not be reacheable");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-        }
-    }
-
-    @Test
-    public void issue258() {
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey("schema_issue258");
-        schemaTO.setType(AttrSchemaType.Double);
-
-        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertNotNull(schemaTO);
-
-        AnyTypeClassTO typeClass = new AnyTypeClassTO();
-        typeClass.setKey("issue258");
-        typeClass.getPlainSchemas().add(schemaTO.getKey());
-        anyTypeClassService.create(typeClass);
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("issue258@syncope.apache.org");
-        userTO.getAuxClasses().add(typeClass.getKey());
-        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        schemaTO.setType(AttrSchemaType.Long);
-        try {
-            schemaService.update(SchemaType.PLAIN, schemaTO);
-            fail("This should not be reacheable");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-        }
-    }
-
-    @Test
-    public void issue259() {
-        PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue259", AttrSchemaType.Double);
-        schemaTO.setUniqueConstraint(true);
-
-        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertNotNull(schemaTO);
-
-        AnyTypeClassTO typeClass = new AnyTypeClassTO();
-        typeClass.setKey("issue259");
-        typeClass.getPlainSchemas().add(schemaTO.getKey());
-        anyTypeClassService.create(typeClass);
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("issue259@syncope.apache.org");
-        userTO.getAuxClasses().add(typeClass.getKey());
-        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1"));
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        UserTO newUserTO = SerializationUtils.clone(userTO);
-        newUserTO.getMemberships().add(new MembershipTO.Builder().group(2L).build());
-
-        userTO = userService.update(newUserTO).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(userTO);
-    }
-
-    @Test
-    public void issue260() {
-        PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue260", AttrSchemaType.Double);
-        schemaTO.setUniqueConstraint(true);
-
-        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertNotNull(schemaTO);
-
-        AnyTypeClassTO typeClass = new AnyTypeClassTO();
-        typeClass.setKey("issue260");
-        typeClass.getPlainSchemas().add(schemaTO.getKey());
-        anyTypeClassService.create(typeClass);
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("issue260@syncope.apache.org");
-        userTO.getAuxClasses().add(typeClass.getKey());
-        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        schemaTO.setUniqueConstraint(false);
-        try {
-            schemaService.update(SchemaType.PLAIN, schemaTO);
-            fail("This should not be reacheable");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE323() {
-        PlainSchemaTO actual = schemaService.read(SchemaType.PLAIN, "icon");
-        assertNotNull(actual);
-
-        try {
-            createSchema(SchemaType.PLAIN, actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.EntityExists, e.getType());
-        }
-
-        actual.setKey(null);
-        try {
-            createSchema(SchemaType.PLAIN, actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        PlainSchemaTO schema = buildPlainSchemaTO("http://schemas.examples.org/security/authorization/organizationUnit",
-                AttrSchemaType.Double);
-
-        try {
-            createSchema(SchemaType.PLAIN, schema);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
deleted file mode 100644
index a08b881..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
+++ /dev/null
@@ -1,193 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Arrays;
-import java.util.List;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.policy.AccountPolicyTO;
-import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
-import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
-import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class PolicyITCase extends AbstractITCase {
-
-    private SyncPolicyTO buildSyncPolicyTO() {
-        SyncPolicyTO policy = new SyncPolicyTO();
-
-        SyncPolicySpec spec = new SyncPolicySpec();
-        spec.getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
-
-        policy.setSpecification(spec);
-        policy.setDescription("Sync policy");
-
-        return policy;
-    }
-
-    @Test
-    public void listByType() {
-        List<SyncPolicyTO> policyTOs = policyService.list(PolicyType.SYNC);
-
-        assertNotNull(policyTOs);
-        assertFalse(policyTOs.isEmpty());
-    }
-
-    @Test
-    public void getAccountPolicy() {
-        AccountPolicyTO policyTO = policyService.read(6L);
-
-        assertNotNull(policyTO);
-        assertTrue(policyTO.getUsedByResources().isEmpty());
-        assertTrue(policyTO.getUsedByRealms().contains("/odd"));
-    }
-
-    @Test
-    public void getPasswordPolicy() {
-        PasswordPolicyTO policyTO = policyService.read(4L);
-
-        assertNotNull(policyTO);
-        assertTrue(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
-        assertTrue(policyTO.getUsedByRealms().containsAll(Arrays.asList("/", "/odd", "/even")));
-    }
-
-    @Test
-    public void getSyncPolicy() {
-        SyncPolicyTO policyTO = policyService.read(1L);
-
-        assertNotNull(policyTO);
-        assertTrue(policyTO.getUsedByRealms().isEmpty());
-    }
-
-    @Test
-    public void createMissingDescription() {
-        SyncPolicyTO policy = new SyncPolicyTO();
-        policy.setSpecification(new SyncPolicySpec());
-
-        try {
-            createPolicy(policy);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
-        }
-    }
-
-    @Test
-    public void create() {
-        SyncPolicyTO policy = buildSyncPolicyTO();
-
-        SyncPolicyTO policyTO = createPolicy(policy);
-
-        assertNotNull(policyTO);
-        assertEquals(PolicyType.SYNC, policyTO.getType());
-        assertEquals(TestSyncRule.class.getName(),
-                policyTO.getSpecification().getCorrelationRules().get(AnyTypeKind.USER.name()));
-    }
-
-    @Test
-    public void update() {
-        PasswordPolicyTO globalPolicy = policyService.read(2L);
-
-        PasswordPolicyTO policy = SerializationUtils.clone(globalPolicy);
-        policy.setDescription("A simple password policy");
-
-        // create a new password policy using the former as a template
-        policy = createPolicy(policy);
-        assertNotNull(policy);
-        assertNotEquals(2L, policy.getKey());
-
-        ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).setMaxLength(22);
-
-        // update new password policy
-        policyService.update(policy);
-        policy = policyService.read(policy.getKey());
-
-        assertNotNull(policy);
-        assertEquals(PolicyType.PASSWORD, policy.getType());
-        assertEquals(22, ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).getMaxLength());
-        assertEquals(8, ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).getMinLength());
-    }
-
-    @Test
-    public void delete() {
-        SyncPolicyTO policy = buildSyncPolicyTO();
-
-        SyncPolicyTO policyTO = createPolicy(policy);
-        assertNotNull(policyTO);
-
-        policyService.delete(policyTO.getKey());
-
-        try {
-            policyService.read(policyTO.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void getCorrelationRules() {
-        assertEquals(2, syncopeService.info().getSyncCorrelationRules().size());
-    }
-
-    @Test
-    public void issueSYNCOPE553() {
-        AccountPolicyTO policy = new AccountPolicyTO();
-        policy.setDescription("SYNCOPE553");
-
-        DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
-        ruleConf.setMinLength(3);
-        ruleConf.setMaxLength(8);
-        policy.getRuleConfs().add(ruleConf);
-
-        policy = createPolicy(policy);
-        assertNotNull(policy);
-    }
-
-    @Test
-    public void issueSYNCOPE682() {
-        AccountPolicyTO policy = new AccountPolicyTO();
-        policy.setDescription("SYNCOPE682");
-        policy.getResources().add(RESOURCE_NAME_LDAP);
-
-        DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
-        ruleConf.setMinLength(3);
-        ruleConf.setMaxLength(8);
-        policy.getRuleConfs().add(ruleConf);
-
-        policy = createPolicy(policy);
-        assertNotNull(policy);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
deleted file mode 100644
index d2baebb..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
+++ /dev/null
@@ -1,150 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PropagationTaskTO;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
-import org.apache.syncope.common.rest.api.beans.TaskExecQuery;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class PropagationTaskITCase extends AbstractTaskITCase {
-
-    @Test
-    public void paginatedList() {
-        PagedResult<PropagationTaskTO> tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(2).build());
-        assertNotNull(tasks);
-        assertEquals(2, tasks.getResult().size());
-
-        for (AbstractTaskTO task : tasks.getResult()) {
-            assertNotNull(task);
-        }
-
-        tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(2).size(2).build());
-        assertNotNull(tasks);
-        assertEquals(2, tasks.getPage());
-        assertEquals(2, tasks.getResult().size());
-
-        for (AbstractTaskTO task : tasks.getResult()) {
-            assertNotNull(task);
-        }
-
-        tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1000).size(2).build());
-        assertNotNull(tasks);
-        assertTrue(tasks.getResult().isEmpty());
-    }
-
-    @Test
-    public void read() {
-        final PropagationTaskTO taskTO = taskService.read(3L, true);
-        assertNotNull(taskTO);
-        assertNotNull(taskTO.getExecutions());
-        assertTrue(taskTO.getExecutions().isEmpty());
-    }
-
-    @Test
-    public void bulkAction() {
-        PagedResult<PropagationTaskTO> before = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).build());
-
-        // create user with testdb resource
-        UserTO userTO = UserITCase.getUniqueSampleTO("taskBulk@apache.org");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-        createUser(userTO);
-
-        List<PropagationTaskTO> after = new ArrayList<>(
-                taskService.<PropagationTaskTO>list(new TaskQuery.Builder().type(TaskType.PROPAGATION).build()).
-                getResult());
-        after.removeAll(before.getResult());
-        assertFalse(after.isEmpty());
-
-        BulkAction bulkAction = new BulkAction();
-        bulkAction.setType(BulkAction.Type.DELETE);
-
-        for (PropagationTaskTO taskTO : after) {
-            bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));
-        }
-
-        taskService.bulk(bulkAction);
-
-        assertFalse(taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).build()).getResult().
-                containsAll(after));
-    }
-
-    @Test
-    public void issueSYNCOPE741() {
-        for (int i = 0; i < 3; i++) {
-            taskService.execute(new ExecuteQuery.Builder().key(1L).build());
-            taskService.execute(new ExecuteQuery.Builder().key(2L).build());
-        }
-        try {
-            Thread.sleep(3000);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-
-        // check list
-        PagedResult<AbstractTaskTO> tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(2).details(false).build());
-        for (AbstractTaskTO item : tasks.getResult()) {
-            assertTrue(item.getExecutions().isEmpty());
-        }
-
-        tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(2).details(true).build());
-        for (AbstractTaskTO item : tasks.getResult()) {
-            assertFalse(item.getExecutions().isEmpty());
-        }
-
-        // check read
-        PropagationTaskTO task = taskService.read(1L, false);
-        assertNotNull(task);
-        assertEquals(1L, task.getKey(), 0);
-        assertTrue(task.getExecutions().isEmpty());
-
-        task = taskService.read(1L, true);
-        assertNotNull(task);
-        assertEquals(1L, task.getKey(), 0);
-        assertFalse(task.getExecutions().isEmpty());
-
-        // check list executions
-        PagedResult<TaskExecTO> execs = taskService.listExecutions(
-                new TaskExecQuery.Builder().key(1L).page(1).size(2).build());
-        assertTrue(execs.getTotalCount() >= execs.getResult().size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
deleted file mode 100644
index 93f0139..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ /dev/null
@@ -1,384 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.NotificationTO;
-import org.apache.syncope.common.lib.to.NotificationTaskTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.PushTaskTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.apache.syncope.common.rest.api.service.NotificationService;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class PushTaskITCase extends AbstractTaskITCase {
-
-    @Test
-    public void getPushActionsClasses() {
-        Set<String> actions = syncopeService.info().getPushActions();
-        assertNotNull(actions);
-    }
-
-    @Test
-    public void read() {
-        PushTaskTO pushTaskTO = taskService.<PushTaskTO>read(17L, true);
-        assertEquals(UnmatchingRule.ASSIGN, pushTaskTO.getUnmatchingRule());
-        assertEquals(MatchingRule.UPDATE, pushTaskTO.getMatchingRule());
-    }
-
-    @Test
-    public void list() {
-        PagedResult<PushTaskTO> tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PUSH).build());
-        assertFalse(tasks.getResult().isEmpty());
-        for (AbstractTaskTO task : tasks.getResult()) {
-            if (!(task instanceof PushTaskTO)) {
-                fail();
-            }
-        }
-    }
-
-    @Test
-    public void createPushTask() {
-        PushTaskTO task = new PushTaskTO();
-        task.setName("Test create Push");
-        task.setResource(RESOURCE_NAME_WS2);
-        task.getFilters().put(AnyTypeKind.USER.name(),
-                SyncopeClient.getUserSearchConditionBuilder().hasNotResources(RESOURCE_NAME_TESTDB2).query());
-        task.getFilters().put(AnyTypeKind.GROUP.name(),
-                SyncopeClient.getGroupSearchConditionBuilder().isNotNull("cool").query());
-        task.setMatchingRule(MatchingRule.LINK);
-
-        final Response response = taskService.create(task);
-        final PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
-        assertNotNull(actual);
-
-        task = taskService.read(actual.getKey(), true);
-        assertNotNull(task);
-        assertEquals(task.getKey(), actual.getKey());
-        assertEquals(task.getJobDelegateClassName(), actual.getJobDelegateClassName());
-        assertEquals(task.getFilters().get(AnyTypeKind.USER.name()),
-                actual.getFilters().get(AnyTypeKind.USER.name()));
-        assertEquals(task.getFilters().get(AnyTypeKind.GROUP.name()),
-                actual.getFilters().get(AnyTypeKind.GROUP.name()));
-        assertEquals(UnmatchingRule.ASSIGN, actual.getUnmatchingRule());
-        assertEquals(MatchingRule.LINK, actual.getMatchingRule());
-    }
-
-    @Test
-    public void pushMatchingUnmatchingGroups() {
-        assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
-
-        execProvisioningTask(taskService, 23L, 50, false);
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
-        assertTrue(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
-
-        execProvisioningTask(taskService, 23L, 50, false);
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
-        assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
-    }
-
-    @Test
-    public void pushUnmatchingUsers() throws Exception {
-        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        assertTrue(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
-
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
-
-        // ------------------------------------------
-        // Unmatching --> Assign --> dryRuyn
-        // ------------------------------------------
-        execProvisioningTask(taskService, 13L, 50, true);
-        assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
-        assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        // ------------------------------------------
-
-        Set<Long> pushTaskIds = new HashSet<>();
-        pushTaskIds.add(13L);
-        pushTaskIds.add(14L);
-        pushTaskIds.add(15L);
-        pushTaskIds.add(16L);
-        execProvisioningTasks(taskService, pushTaskIds, 50, false);
-
-        // ------------------------------------------
-        // Unatching --> Ignore
-        // ------------------------------------------
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
-        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        // ------------------------------------------
-
-        // ------------------------------------------
-        // Unmatching --> Assign
-        // ------------------------------------------
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
-        assertTrue(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        jdbcTemplate.execute("DELETE FROM test2 WHERE ID='vivaldi'");
-        // ------------------------------------------
-
-        // ------------------------------------------
-        // Unmatching --> Provision
-        // ------------------------------------------
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='bellini'").size());
-        assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        jdbcTemplate.execute("DELETE FROM test2 WHERE ID='bellini'");
-        // ------------------------------------------
-
-        // ------------------------------------------
-        // Unmatching --> Unlink
-        // ------------------------------------------
-        assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
-        assertFalse(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        // ------------------------------------------
-    }
-
-    @Test
-    public void pushMatchingUser() throws Exception {
-        assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
-
-        // ------------------------------------------
-        // Matching --> Deprovision --> dryRuyn
-        // ------------------------------------------
-        execProvisioningTask(taskService, 19L, 50, true);
-        assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
-        // ------------------------------------------
-
-        Set<Long> pushTaskKeys = new HashSet<>();
-        pushTaskKeys.add(18L);
-        pushTaskKeys.add(19L);
-        pushTaskKeys.add(16L);
-
-        execProvisioningTasks(taskService, pushTaskKeys, 50, false);
-
-        // ------------------------------------------
-        // Matching --> Deprovision && Ignore
-        // ------------------------------------------
-        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        // DELETE Capability not available ....
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
-        // ------------------------------------------
-
-        // ------------------------------------------
-        // Matching --> Unassign
-        // ------------------------------------------
-        assertFalse(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        // DELETE Capability not available ....
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
-        // ------------------------------------------
-
-        // ------------------------------------------
-        // Matching --> Link
-        // ------------------------------------------
-        execProvisioningTask(taskService, 20L, 50, false);
-        assertTrue(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
-        // ------------------------------------------
-
-        pushTaskKeys.clear();
-        pushTaskKeys.add(21L);
-        pushTaskKeys.add(22L);
-
-        execProvisioningTasks(taskService, pushTaskKeys, 50, false);
-
-        // ------------------------------------------
-        // Matching --> Unlink && Update
-        // ------------------------------------------
-        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
-        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
-        // ------------------------------------------
-    }
-
-    @Test
-    public void issueSYNCOPE598() {
-        // create a new group schema
-        PlainSchemaTO schemaTO = new PlainSchemaTO();
-        schemaTO.setKey("LDAPGroupName" + getUUIDString());
-        schemaTO.setType(AttrSchemaType.String);
-        schemaTO.setMandatoryCondition("true");
-
-        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertNotNull(schemaTO);
-
-        AnyTypeClassTO typeClass = new AnyTypeClassTO();
-        typeClass.setKey("SYNCOPE-598");
-        typeClass.getPlainSchemas().add(schemaTO.getKey());
-        anyTypeClassService.create(typeClass);
-
-        // create a new sample group
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName("all" + getUUIDString());
-        groupTO.setRealm("/even");
-        groupTO.getAuxClasses().add(typeClass.getKey());
-
-        groupTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "all"));
-
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-
-        String resourceName = "resource-ldap-grouponly";
-        ResourceTO newResourceTO = null;
-
-        try {
-            // Create resource ad-hoc
-            ResourceTO resourceTO = new ResourceTO();
-            resourceTO.setKey(resourceName);
-            resourceTO.setConnector(105L);
-
-            ProvisionTO provisionTO = new ProvisionTO();
-            provisionTO.setAnyType(AnyTypeKind.GROUP.name());
-            provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
-            resourceTO.getProvisions().add(provisionTO);
-
-            MappingTO mapping = new MappingTO();
-            provisionTO.setMapping(mapping);
-
-            MappingItemTO item = new MappingItemTO();
-            item.setIntMappingType(IntMappingType.GroupPlainSchema);
-            item.setExtAttrName("cn");
-            item.setIntAttrName(schemaTO.getKey());
-            item.setConnObjectKey(true);
-            item.setPurpose(MappingPurpose.BOTH);
-            mapping.setConnObjectKeyItem(item);
-
-            mapping.setConnObjectLink("'cn=' + " + schemaTO.getKey() + " + ',ou=groups,o=isp'");
-
-            Response response = resourceService.create(resourceTO);
-            newResourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-            assertNotNull(newResourceTO);
-            assertNull(newResourceTO.getProvision(AnyTypeKind.USER.name()));
-            assertNotNull(newResourceTO.getProvision(AnyTypeKind.GROUP.name()).getMapping());
-
-            // create push task ad-hoc
-            PushTaskTO task = new PushTaskTO();
-            task.setName("issueSYNCOPE598");
-            task.setActive(true);
-            task.setResource(resourceName);
-            task.setPerformCreate(true);
-            task.setPerformDelete(true);
-            task.setPerformUpdate(true);
-            task.setUnmatchingRule(UnmatchingRule.ASSIGN);
-            task.setMatchingRule(MatchingRule.UPDATE);
-            task.getFilters().put(AnyTypeKind.GROUP.name(),
-                    SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo(groupTO.getName()).query());
-
-            response = taskService.create(task);
-            PushTaskTO push = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
-            assertNotNull(push);
-
-            // execute the new task
-            TaskExecTO pushExec = execProvisioningTask(taskService, push.getKey(), 50, false);
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(pushExec.getStatus()));
-        } finally {
-            groupService.delete(groupTO.getKey());
-            if (newResourceTO != null) {
-                resourceService.delete(resourceName);
-            }
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE648() {
-        // 1. Create Push Task
-        PushTaskTO task = new PushTaskTO();
-        task.setName("Test create Push");
-        task.setActive(true);
-        task.setResource(RESOURCE_NAME_LDAP);
-        task.getFilters().put(AnyTypeKind.USER.name(),
-                SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("_NO_ONE_").query());
-        task.getFilters().put(AnyTypeKind.GROUP.name(),
-                SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("citizen").query());
-        task.setMatchingRule(MatchingRule.IGNORE);
-        task.setUnmatchingRule(UnmatchingRule.IGNORE);
-
-        Response response = taskService.create(task);
-        PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
-        assertNotNull(actual);
-
-        // 2. Create notification
-        NotificationTO notification = new NotificationTO();
-        notification.setTraceLevel(TraceLevel.FAILURES);
-        notification.getEvents().add("[PushTask]:[group]:[resource-ldap]:[matchingrule_ignore]:[SUCCESS]");
-        notification.getEvents().add("[PushTask]:[group]:[resource-ldap]:[unmatchingrule_ignore]:[SUCCESS]");
-
-        notification.getStaticRecipients().add("issueyncope648@syncope.apache.org");
-        notification.setSelfAsRecipient(false);
-        notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
-
-        notification.setSender("syncope648@syncope.apache.org");
-        String subject = "Test notification";
-        notification.setSubject(subject);
-        notification.setTemplate("optin");
-        notification.setActive(true);
-
-        Response responseNotification = notificationService.create(notification);
-        notification = getObject(responseNotification.getLocation(), NotificationService.class, NotificationTO.class);
-        assertNotNull(notification);
-
-        execProvisioningTask(taskService, actual.getKey(), 50, false);
-
-        NotificationTaskTO taskTO = findNotificationTaskBySender("syncope648@syncope.apache.org");
-        assertNotNull(taskTO);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RESTITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RESTITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RESTITCase.java
deleted file mode 100644
index a3bc1c7..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RESTITCase.java
+++ /dev/null
@@ -1,147 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.io.InputStream;
-import javax.ws.rs.core.EntityTag;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.rest.api.Preference;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
-import org.apache.syncope.common.rest.api.service.GroupService;
-import org.apache.syncope.common.rest.api.service.UserService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class RESTITCase extends AbstractITCase {
-
-    @Test
-    public void noContent() throws IOException {
-        SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
-        GroupService noContentService = noContentclient.prefer(GroupService.class, Preference.RETURN_NO_CONTENT);
-
-        GroupTO group = GroupITCase.getSampleTO("noContent");
-
-        Response response = noContentService.create(group);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
-        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
-        assertEquals(StringUtils.EMPTY, org.apache.commons.io.IOUtils.toString((InputStream) response.getEntity()));
-
-        group = getObject(response.getLocation(), GroupService.class, GroupTO.class);
-        assertNotNull(group);
-
-        GroupPatch groupPatch = new GroupPatch();
-        groupPatch.setKey(group.getKey());
-        groupPatch.getPlainAttrs().add(attrAddReplacePatch("badge", "xxxxxxxxxx"));
-
-        response = noContentService.update(groupPatch);
-        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
-        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
-        assertEquals(StringUtils.EMPTY, org.apache.commons.io.IOUtils.toString((InputStream) response.getEntity()));
-
-        response = noContentService.delete(group.getKey());
-        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
-        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
-        assertEquals(StringUtils.EMPTY, org.apache.commons.io.IOUtils.toString((InputStream) response.getEntity()));
-    }
-
-    @Test
-    public void ifMatch() {
-        UserTO userTO = userService.create(UserITCase.getUniqueSampleTO("ifmatch@syncope.apache.org"), true).
-                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-                }).getAny();
-        assertNotNull(userTO);
-        assertNotNull(userTO.getKey());
-
-        EntityTag etag = adminClient.getLatestEntityTag(userService);
-        assertNotNull(etag);
-        assertTrue(StringUtils.isNotBlank(etag.getValue()));
-
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.setUsername(new StringReplacePatchItem.Builder().value(userTO.getUsername() + "XX").build());
-        userTO = userService.update(userPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertTrue(userTO.getUsername().endsWith("XX"));
-        EntityTag etag1 = adminClient.getLatestEntityTag(userService);
-        assertFalse(etag.getValue().equals(etag1.getValue()));
-
-        UserService ifMatchService = adminClient.ifMatch(UserService.class, etag);
-        userPatch.setUsername(new StringReplacePatchItem.Builder().value(userTO.getUsername() + "YY").build());
-        try {
-            ifMatchService.update(userPatch);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.ConcurrentModification, e.getType());
-        }
-
-        userTO = userService.read(userTO.getKey());
-        assertTrue(userTO.getUsername().endsWith("XX"));
-    }
-
-    @Test
-    public void defaultContentType() {
-        // manualy instantiate SyncopeClient so that media type can be set to */*
-        SyncopeClientFactoryBean factory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
-        SyncopeClient client = new SyncopeClient(
-                MediaType.WILDCARD_TYPE,
-                factory.getRestClientFactoryBean(),
-                factory.getExceptionMapper(),
-                ADMIN_UNAME,
-                ADMIN_PWD,
-                false);
-
-        // perform operation
-        AnyTypeClassService service = client.getService(AnyTypeClassService.class);
-        service.list();
-
-        // check that */* was actually sent
-        MultivaluedMap<String, String> requestHeaders = WebClient.client(service).getHeaders();
-        assertEquals(MediaType.WILDCARD, requestHeaders.getFirst(HttpHeaders.ACCEPT));
-
-        // check that application/json was received
-        String contentType = WebClient.client(service).getResponse().getHeaderString(HttpHeaders.CONTENT_TYPE);
-        assertTrue(contentType.startsWith(MediaType.APPLICATION_JSON));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
deleted file mode 100644
index 4b727cf..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
+++ /dev/null
@@ -1,187 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.policy.AccountPolicyTO;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.rest.api.service.RealmService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class RealmITCase extends AbstractITCase {
-
-    private RealmTO getRealm(final String fullPath) {
-        return IterableUtils.find(realmService.list(fullPath), new Predicate<RealmTO>() {
-
-            @Override
-            public boolean evaluate(final RealmTO object) {
-                return fullPath.equals(object.getFullPath());
-            }
-        });
-    }
-
-    @Test
-    public void list() {
-        List<RealmTO> realms = realmService.list();
-        assertNotNull(realms);
-        assertFalse(realms.isEmpty());
-        for (RealmTO realm : realms) {
-            assertNotNull(realm);
-        }
-
-        try {
-            realmService.list("a name");
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPath, e.getType());
-        }
-    }
-
-    @Test
-    public void createUpdate() {
-        final RealmTO realm = new RealmTO();
-        realm.setName("last");
-
-        // 1. create
-        Response response = realmService.create("/even/two", realm);
-        RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
-        assertNotNull(actuals);
-        assertTrue(actuals.length > 0);
-        RealmTO actual = actuals[0];
-        assertNotNull(actual.getKey());
-        assertEquals("last", actual.getName());
-        assertEquals("/even/two/last", actual.getFullPath());
-        assertEquals(actual.getParent(), getRealm("/even/two").getKey(), 0);
-        assertNull(realm.getAccountPolicy());
-        assertNull(realm.getPasswordPolicy());
-
-        // 2. update setting policies
-        actual.setAccountPolicy(6L);
-        actual.setPasswordPolicy(4L);
-        realmService.update(actual);
-
-        actual = getRealm(actual.getFullPath());
-        assertNotNull(actual.getAccountPolicy());
-        assertNotNull(actual.getPasswordPolicy());
-
-        // 3. update changing parent
-        actual.setParent(getRealm("/odd").getKey());
-        realmService.update(actual);
-
-        actual = getRealm("/odd/last");
-        assertNotNull(actual);
-        assertEquals("/odd/last", actual.getFullPath());
-
-        assertEquals(1, IterableUtils.countMatches(realmService.list(), new Predicate<RealmTO>() {
-
-            @Override
-            public boolean evaluate(final RealmTO object) {
-                return realm.getName().equals(object.getName());
-            }
-        }));
-
-        // 4. create under invalid path
-        try {
-            realmService.create("a name", realm);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPath, e.getType());
-        }
-
-        // 5. attempt to create duplicate
-        try {
-            realmService.create("/odd", realm);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.DataIntegrityViolation, e.getType());
-        }
-    }
-
-    @Test
-    public void deletingAccountPolicy() {
-        // 1. create account policy
-        AccountPolicyTO policy = new AccountPolicyTO();
-        policy.setDescription("deletingAccountPolicy");
-
-        DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
-        ruleConf.setMinLength(3);
-        ruleConf.setMaxLength(8);
-        policy.getRuleConfs().add(ruleConf);
-
-        policy = createPolicy(policy);
-        assertNotNull(policy);
-
-        // 2. create realm with policy assigned
-        RealmTO realm = new RealmTO();
-        realm.setName("withppolicy");
-        realm.setAccountPolicy(policy.getKey());
-
-        Response response = realmService.create(SyncopeConstants.ROOT_REALM, realm);
-        RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
-        assertNotNull(actuals);
-        assertTrue(actuals.length > 0);
-        RealmTO actual = actuals[0];
-        assertEquals(policy.getKey(), actual.getAccountPolicy(), 0);
-
-        // 3. remove policy
-        policyService.delete(policy.getKey());
-
-        // 4. verify
-        actual = getRealm(actual.getFullPath());
-        assertNull(actual.getAccountPolicy());
-    }
-
-    @Test
-    public void delete() {
-        RealmTO realm = new RealmTO();
-        realm.setName("deletable");
-
-        Response response = realmService.create("/even/two", realm);
-        RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
-        assertNotNull(actuals);
-        assertTrue(actuals.length > 0);
-        RealmTO actual = actuals[0];
-
-        realmService.delete(actual.getFullPath());
-
-        try {
-            realmService.list(actual.getFullPath());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java
deleted file mode 100644
index 3d8d82f..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java
+++ /dev/null
@@ -1,93 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.RelationshipTypeTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class RelationshipTypeITCase extends AbstractITCase {
-
-    @Test
-    public void read() {
-        RelationshipTypeTO otherType = relationshipTypeService.read("inclusion");
-        assertNotNull(otherType);
-        assertEquals("inclusion", otherType.getKey());
-    }
-
-    @Test
-    public void list() {
-        List<RelationshipTypeTO> list = relationshipTypeService.list();
-        assertFalse(list.isEmpty());
-    }
-
-    @Test
-    public void crud() {
-        RelationshipTypeTO newType = new RelationshipTypeTO();
-        newType.setKey("new type");
-        newType.setDescription("description");
-
-        Response response = relationshipTypeService.create(newType);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-
-        newType = getObject(response.getLocation(), RelationshipTypeService.class, RelationshipTypeTO.class);
-        assertNotNull(newType);
-        assertEquals("description", newType.getDescription());
-
-        newType.setDescription("new description");
-        relationshipTypeService.update(newType);
-
-        newType = relationshipTypeService.read(newType.getKey());
-        assertNotNull(newType);
-        assertEquals("new description", newType.getDescription());
-
-        relationshipTypeService.delete(newType.getKey());
-
-        try {
-            relationshipTypeService.read(newType.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void createInvalidName() {
-        RelationshipTypeTO newType = new RelationshipTypeTO();
-        newType.setKey("membership");
-        try {
-            relationshipTypeService.create(newType);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidRelationshipType, e.getType());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
deleted file mode 100644
index c30cb19..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
+++ /dev/null
@@ -1,302 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Response;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.report.UserReportletConf;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.ReportExecTO;
-import org.apache.syncope.common.lib.to.ReportTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.ReportExecExportFormat;
-import org.apache.syncope.common.lib.types.ReportExecStatus;
-import org.apache.syncope.common.rest.api.beans.BulkExecDeleteQuery;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
-import org.apache.syncope.common.rest.api.service.ReportService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class ReportITCase extends AbstractITCase {
-
-    private ReportTO createReport(final ReportTO report) {
-        Response response = reportService.create(report);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
-        return getObject(response.getLocation(), ReportService.class, ReportTO.class);
-    }
-
-    @Test
-    public void getReportletClasses() {
-        Set<String> reportlets = syncopeService.info().getReportlets();
-        assertNotNull(reportlets);
-        assertFalse(reportlets.isEmpty());
-    }
-
-    @Test
-    public void list() {
-        List<ReportTO> reports = reportService.list();
-        assertNotNull(reports);
-        assertFalse(reports.isEmpty());
-        for (ReportTO report : reports) {
-            assertNotNull(report);
-        }
-    }
-
-    @Test
-    public void read() {
-        ReportTO reportTO = reportService.read(1L);
-
-        assertNotNull(reportTO);
-        assertNotNull(reportTO.getExecutions());
-        assertFalse(reportTO.getExecutions().isEmpty());
-    }
-
-    @Test
-    public void create() {
-        ReportTO report = new ReportTO();
-        report.setName("testReportForCreate" + getUUIDString());
-        report.getReportletConfs().add(new UserReportletConf("first"));
-        report.getReportletConfs().add(new UserReportletConf("second"));
-
-        report = createReport(report);
-        assertNotNull(report);
-
-        ReportTO actual = reportService.read(report.getKey());
-        assertNotNull(actual);
-
-        assertEquals(actual, report);
-    }
-
-    @Test
-    public void update() {
-        ReportTO report = new ReportTO();
-        report.setName("testReportForUpdate" + getUUIDString());
-
-        report.getReportletConfs().add(new UserReportletConf("first"));
-        report.getReportletConfs().add(new UserReportletConf("second"));
-
-        report = createReport(report);
-        assertNotNull(report);
-        assertEquals(2, report.getReportletConfs().size());
-
-        report.getReportletConfs().add(new UserReportletConf("last"));
-
-        reportService.update(report);
-        ReportTO updated = reportService.read(report.getKey());
-        assertNotNull(updated);
-        assertEquals(3, updated.getReportletConfs().size());
-    }
-
-    @Test
-    public void delete() {
-        ReportTO report = new ReportTO();
-        report.setName("testReportForDelete" + getUUIDString());
-        report.getReportletConfs().add(new UserReportletConf("first"));
-        report.getReportletConfs().add(new UserReportletConf("second"));
-
-        report = createReport(report);
-        assertNotNull(report);
-
-        reportService.delete(report.getKey());
-
-        try {
-            reportService.read(report.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    private Long execute(final Long reportKey) {
-        ReportExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportKey).build());
-        assertNotNull(execution);
-
-        int i = 0;
-        int maxit = 50;
-
-        ReportTO reportTO;
-
-        // wait for report execution completion (executions incremented)
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-            }
-
-            reportTO = reportService.read(reportKey);
-
-            assertNotNull(reportTO);
-            assertNotNull(reportTO.getExecutions());
-
-            i++;
-        } while (reportTO.getExecutions().isEmpty()
-                || (!ReportExecStatus.SUCCESS.name().equals(reportTO.getExecutions().get(0).getStatus()) && i < maxit));
-        assertEquals(ReportExecStatus.SUCCESS.name(), reportTO.getExecutions().get(0).getStatus());
-
-        return reportTO.getExecutions().get(0).getKey();
-    }
-
-    private void checkExport(final Long execId, final ReportExecExportFormat fmt) throws IOException {
-        Response response = reportService.exportExecutionResult(execId, fmt);
-        assertNotNull(response);
-        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
-        assertNotNull(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION));
-        assertTrue(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION).
-                endsWith("." + fmt.name().toLowerCase()));
-
-        Object entity = response.getEntity();
-        assertTrue(entity instanceof InputStream);
-        assertFalse(IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING).isEmpty());
-    }
-
-    @Test
-    public void executeAndExport() throws IOException {
-        ReportTO reportTO = reportService.read(1L);
-        reportTO.setKey(0L);
-        reportTO.setName("executeAndExport" + getUUIDString());
-        reportTO.setActive(false);
-        reportTO.getExecutions().clear();
-        reportTO = createReport(reportTO);
-        assertNotNull(reportTO);
-
-        try {
-            execute(reportTO.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.Scheduling, e.getType());
-            assertTrue(e.getElements().iterator().next().contains("active"));
-        }
-
-        reportTO.setActive(true);
-        reportService.update(reportTO);
-
-        long execId = execute(reportTO.getKey());
-
-        checkExport(execId, ReportExecExportFormat.XML);
-        checkExport(execId, ReportExecExportFormat.HTML);
-        checkExport(execId, ReportExecExportFormat.PDF);
-        checkExport(execId, ReportExecExportFormat.RTF);
-        checkExport(execId, ReportExecExportFormat.CSV);
-    }
-
-    @Test
-    public void deleteExecutions() {
-        Date start = new Date();
-        try {
-            Thread.sleep(1000);
-        } catch (InterruptedException e) {
-        }
-
-        ReportTO reportTO = reportService.read(1L);
-        reportTO.setKey(0L);
-        reportTO.setName("deleteExecutions" + getUUIDString());
-        reportTO.getExecutions().clear();
-        reportTO = createReport(reportTO);
-        assertNotNull(reportTO);
-
-        Long execId = execute(reportTO.getKey());
-        assertNotNull(execId);
-
-        try {
-            Thread.sleep(1000);
-        } catch (InterruptedException e) {
-        }
-        Date end = new Date();
-
-        BulkActionResult result = reportService.deleteExecutions(
-                new BulkExecDeleteQuery.Builder().key(reportTO.getKey()).startedAfter(start).endedBefore(end).build());
-        assertNotNull(result);
-
-        assertEquals(1, result.getResults().size());
-        assertEquals(execId.toString(), result.getResults().keySet().iterator().next());
-        assertEquals(BulkActionResult.Status.SUCCESS, result.getResults().entrySet().iterator().next().getValue());
-    }
-
-    @Test
-    public void issueSYNCOPE43() {
-        ReportTO reportTO = new ReportTO();
-        reportTO.setName("issueSYNCOPE43" + getUUIDString());
-        reportTO.setActive(true);
-        reportTO = createReport(reportTO);
-        assertNotNull(reportTO);
-
-        ReportExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportTO.getKey()).build());
-        assertNotNull(execution);
-
-        int maxit = 50;
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-            }
-
-            reportTO = reportService.read(reportTO.getKey());
-
-            maxit--;
-        } while (reportTO.getExecutions().isEmpty() && maxit > 0);
-
-        assertEquals(1, reportTO.getExecutions().size());
-    }
-
-    @Test
-    public void issueSYNCOPE102() throws IOException {
-        // Create
-        ReportTO reportTO = reportService.read(1L);
-        reportTO.setKey(0L);
-        reportTO.setName("issueSYNCOPE102" + getUUIDString());
-        reportTO = createReport(reportTO);
-        assertNotNull(reportTO);
-
-        // Execute (multiple requests)
-        for (int i = 0; i < 10; i++) {
-            ReportExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportTO.getKey()).build());
-            assertNotNull(execution);
-        }
-
-        // Wait for one execution
-        int maxit = 50;
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-            }
-
-            reportTO = reportService.read(reportTO.getKey());
-
-            maxit--;
-        } while (reportTO.getExecutions().isEmpty() && maxit > 0);
-        assertFalse(reportTO.getExecutions().isEmpty());
-    }
-}


[16/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
new file mode 100644
index 0000000..c766d0b
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
@@ -0,0 +1,384 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PushTaskITCase extends AbstractTaskITCase {
+
+    @Test
+    public void getPushActionsClasses() {
+        Set<String> actions = syncopeService.info().getPushActions();
+        assertNotNull(actions);
+    }
+
+    @Test
+    public void read() {
+        PushTaskTO pushTaskTO = taskService.<PushTaskTO>read(17L, true);
+        assertEquals(UnmatchingRule.ASSIGN, pushTaskTO.getUnmatchingRule());
+        assertEquals(MatchingRule.UPDATE, pushTaskTO.getMatchingRule());
+    }
+
+    @Test
+    public void list() {
+        PagedResult<PushTaskTO> tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PUSH).build());
+        assertFalse(tasks.getResult().isEmpty());
+        for (AbstractTaskTO task : tasks.getResult()) {
+            if (!(task instanceof PushTaskTO)) {
+                fail();
+            }
+        }
+    }
+
+    @Test
+    public void createPushTask() {
+        PushTaskTO task = new PushTaskTO();
+        task.setName("Test create Push");
+        task.setResource(RESOURCE_NAME_WS2);
+        task.getFilters().put(AnyTypeKind.USER.name(),
+                SyncopeClient.getUserSearchConditionBuilder().hasNotResources(RESOURCE_NAME_TESTDB2).query());
+        task.getFilters().put(AnyTypeKind.GROUP.name(),
+                SyncopeClient.getGroupSearchConditionBuilder().isNotNull("cool").query());
+        task.setMatchingRule(MatchingRule.LINK);
+
+        final Response response = taskService.create(task);
+        final PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+        assertNotNull(actual);
+
+        task = taskService.read(actual.getKey(), true);
+        assertNotNull(task);
+        assertEquals(task.getKey(), actual.getKey());
+        assertEquals(task.getJobDelegateClassName(), actual.getJobDelegateClassName());
+        assertEquals(task.getFilters().get(AnyTypeKind.USER.name()),
+                actual.getFilters().get(AnyTypeKind.USER.name()));
+        assertEquals(task.getFilters().get(AnyTypeKind.GROUP.name()),
+                actual.getFilters().get(AnyTypeKind.GROUP.name()));
+        assertEquals(UnmatchingRule.ASSIGN, actual.getUnmatchingRule());
+        assertEquals(MatchingRule.LINK, actual.getMatchingRule());
+    }
+
+    @Test
+    public void pushMatchingUnmatchingGroups() {
+        assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+
+        execProvisioningTask(taskService, 23L, 50, false);
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
+        assertTrue(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+
+        execProvisioningTask(taskService, 23L, 50, false);
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
+        assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+    }
+
+    @Test
+    public void pushUnmatchingUsers() throws Exception {
+        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        assertTrue(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
+
+        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
+
+        // ------------------------------------------
+        // Unmatching --> Assign --> dryRuyn
+        // ------------------------------------------
+        execProvisioningTask(taskService, 13L, 50, true);
+        assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
+        assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        // ------------------------------------------
+
+        Set<Long> pushTaskIds = new HashSet<>();
+        pushTaskIds.add(13L);
+        pushTaskIds.add(14L);
+        pushTaskIds.add(15L);
+        pushTaskIds.add(16L);
+        execProvisioningTasks(taskService, pushTaskIds, 50, false);
+
+        // ------------------------------------------
+        // Unatching --> Ignore
+        // ------------------------------------------
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        // ------------------------------------------
+
+        // ------------------------------------------
+        // Unmatching --> Assign
+        // ------------------------------------------
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
+        assertTrue(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        jdbcTemplate.execute("DELETE FROM test2 WHERE ID='vivaldi'");
+        // ------------------------------------------
+
+        // ------------------------------------------
+        // Unmatching --> Provision
+        // ------------------------------------------
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='bellini'").size());
+        assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        jdbcTemplate.execute("DELETE FROM test2 WHERE ID='bellini'");
+        // ------------------------------------------
+
+        // ------------------------------------------
+        // Unmatching --> Unlink
+        // ------------------------------------------
+        assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
+        assertFalse(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        // ------------------------------------------
+    }
+
+    @Test
+    public void pushMatchingUser() throws Exception {
+        assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+
+        // ------------------------------------------
+        // Matching --> Deprovision --> dryRuyn
+        // ------------------------------------------
+        execProvisioningTask(taskService, 19L, 50, true);
+        assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+        // ------------------------------------------
+
+        Set<Long> pushTaskKeys = new HashSet<>();
+        pushTaskKeys.add(18L);
+        pushTaskKeys.add(19L);
+        pushTaskKeys.add(16L);
+
+        execProvisioningTasks(taskService, pushTaskKeys, 50, false);
+
+        // ------------------------------------------
+        // Matching --> Deprovision && Ignore
+        // ------------------------------------------
+        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        // DELETE Capability not available ....
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+        // ------------------------------------------
+
+        // ------------------------------------------
+        // Matching --> Unassign
+        // ------------------------------------------
+        assertFalse(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        // DELETE Capability not available ....
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+        // ------------------------------------------
+
+        // ------------------------------------------
+        // Matching --> Link
+        // ------------------------------------------
+        execProvisioningTask(taskService, 20L, 50, false);
+        assertTrue(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+        // ------------------------------------------
+
+        pushTaskKeys.clear();
+        pushTaskKeys.add(21L);
+        pushTaskKeys.add(22L);
+
+        execProvisioningTasks(taskService, pushTaskKeys, 50, false);
+
+        // ------------------------------------------
+        // Matching --> Unlink && Update
+        // ------------------------------------------
+        assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+        assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+        // ------------------------------------------
+    }
+
+    @Test
+    public void issueSYNCOPE598() {
+        // create a new group schema
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("LDAPGroupName" + getUUIDString());
+        schemaTO.setType(AttrSchemaType.String);
+        schemaTO.setMandatoryCondition("true");
+
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("SYNCOPE-598");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
+        // create a new sample group
+        GroupTO groupTO = new GroupTO();
+        groupTO.setName("all" + getUUIDString());
+        groupTO.setRealm("/even");
+        groupTO.getAuxClasses().add(typeClass.getKey());
+
+        groupTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "all"));
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+
+        String resourceName = "resource-ldap-grouponly";
+        ResourceTO newResourceTO = null;
+
+        try {
+            // Create resource ad-hoc
+            ResourceTO resourceTO = new ResourceTO();
+            resourceTO.setKey(resourceName);
+            resourceTO.setConnector(105L);
+
+            ProvisionTO provisionTO = new ProvisionTO();
+            provisionTO.setAnyType(AnyTypeKind.GROUP.name());
+            provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
+            resourceTO.getProvisions().add(provisionTO);
+
+            MappingTO mapping = new MappingTO();
+            provisionTO.setMapping(mapping);
+
+            MappingItemTO item = new MappingItemTO();
+            item.setIntMappingType(IntMappingType.GroupPlainSchema);
+            item.setExtAttrName("cn");
+            item.setIntAttrName(schemaTO.getKey());
+            item.setConnObjectKey(true);
+            item.setPurpose(MappingPurpose.BOTH);
+            mapping.setConnObjectKeyItem(item);
+
+            mapping.setConnObjectLink("'cn=' + " + schemaTO.getKey() + " + ',ou=groups,o=isp'");
+
+            Response response = resourceService.create(resourceTO);
+            newResourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+            assertNotNull(newResourceTO);
+            assertNull(newResourceTO.getProvision(AnyTypeKind.USER.name()));
+            assertNotNull(newResourceTO.getProvision(AnyTypeKind.GROUP.name()).getMapping());
+
+            // create push task ad-hoc
+            PushTaskTO task = new PushTaskTO();
+            task.setName("issueSYNCOPE598");
+            task.setActive(true);
+            task.setResource(resourceName);
+            task.setPerformCreate(true);
+            task.setPerformDelete(true);
+            task.setPerformUpdate(true);
+            task.setUnmatchingRule(UnmatchingRule.ASSIGN);
+            task.setMatchingRule(MatchingRule.UPDATE);
+            task.getFilters().put(AnyTypeKind.GROUP.name(),
+                    SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo(groupTO.getName()).query());
+
+            response = taskService.create(task);
+            PushTaskTO push = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+            assertNotNull(push);
+
+            // execute the new task
+            TaskExecTO pushExec = execProvisioningTask(taskService, push.getKey(), 50, false);
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(pushExec.getStatus()));
+        } finally {
+            groupService.delete(groupTO.getKey());
+            if (newResourceTO != null) {
+                resourceService.delete(resourceName);
+            }
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE648() {
+        // 1. Create Push Task
+        PushTaskTO task = new PushTaskTO();
+        task.setName("Test create Push");
+        task.setActive(true);
+        task.setResource(RESOURCE_NAME_LDAP);
+        task.getFilters().put(AnyTypeKind.USER.name(),
+                SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("_NO_ONE_").query());
+        task.getFilters().put(AnyTypeKind.GROUP.name(),
+                SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("citizen").query());
+        task.setMatchingRule(MatchingRule.IGNORE);
+        task.setUnmatchingRule(UnmatchingRule.IGNORE);
+
+        Response response = taskService.create(task);
+        PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+        assertNotNull(actual);
+
+        // 2. Create notification
+        NotificationTO notification = new NotificationTO();
+        notification.setTraceLevel(TraceLevel.FAILURES);
+        notification.getEvents().add("[PushTask]:[group]:[resource-ldap]:[matchingrule_ignore]:[SUCCESS]");
+        notification.getEvents().add("[PushTask]:[group]:[resource-ldap]:[unmatchingrule_ignore]:[SUCCESS]");
+
+        notification.getStaticRecipients().add("issueyncope648@syncope.apache.org");
+        notification.setSelfAsRecipient(false);
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+        notification.setSender("syncope648@syncope.apache.org");
+        String subject = "Test notification";
+        notification.setSubject(subject);
+        notification.setTemplate("optin");
+        notification.setActive(true);
+
+        Response responseNotification = notificationService.create(notification);
+        notification = getObject(responseNotification.getLocation(), NotificationService.class, NotificationTO.class);
+        assertNotNull(notification);
+
+        execProvisioningTask(taskService, actual.getKey(), 50, false);
+
+        NotificationTaskTO taskTO = findNotificationTaskBySender("syncope648@syncope.apache.org");
+        assertNotNull(taskTO);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RESTITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RESTITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RESTITCase.java
new file mode 100644
index 0000000..30183fd
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RESTITCase.java
@@ -0,0 +1,148 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.GroupService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class RESTITCase extends AbstractITCase {
+
+    @Test
+    public void noContent() throws IOException {
+        SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
+        GroupService noContentService = noContentclient.prefer(GroupService.class, Preference.RETURN_NO_CONTENT);
+
+        GroupTO group = GroupITCase.getSampleTO("noContent");
+
+        Response response = noContentService.create(group);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+        assertEquals(StringUtils.EMPTY, org.apache.commons.io.IOUtils.toString((InputStream) response.getEntity()));
+
+        group = getObject(response.getLocation(), GroupService.class, GroupTO.class);
+        assertNotNull(group);
+
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(group.getKey());
+        groupPatch.getPlainAttrs().add(attrAddReplacePatch("badge", "xxxxxxxxxx"));
+
+        response = noContentService.update(groupPatch);
+        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+        assertEquals(StringUtils.EMPTY, org.apache.commons.io.IOUtils.toString((InputStream) response.getEntity()));
+
+        response = noContentService.delete(group.getKey());
+        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+        assertEquals(StringUtils.EMPTY, org.apache.commons.io.IOUtils.toString((InputStream) response.getEntity()));
+    }
+
+    @Test
+    public void ifMatch() {
+        UserTO userTO = userService.create(UserITCase.getUniqueSampleTO("ifmatch@syncope.apache.org"), true).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                }).getAny();
+        assertNotNull(userTO);
+        assertNotNull(userTO.getKey());
+
+        EntityTag etag = adminClient.getLatestEntityTag(userService);
+        assertNotNull(etag);
+        assertTrue(StringUtils.isNotBlank(etag.getValue()));
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setUsername(new StringReplacePatchItem.Builder().value(userTO.getUsername() + "XX").build());
+        userTO = userService.update(userPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertTrue(userTO.getUsername().endsWith("XX"));
+        EntityTag etag1 = adminClient.getLatestEntityTag(userService);
+        assertFalse(etag.getValue().equals(etag1.getValue()));
+
+        UserService ifMatchService = adminClient.ifMatch(UserService.class, etag);
+        userPatch.setUsername(new StringReplacePatchItem.Builder().value(userTO.getUsername() + "YY").build());
+        try {
+            ifMatchService.update(userPatch);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.ConcurrentModification, e.getType());
+        }
+
+        userTO = userService.read(userTO.getKey());
+        assertTrue(userTO.getUsername().endsWith("XX"));
+    }
+
+    @Test
+    public void defaultContentType() {
+        // manualy instantiate SyncopeClient so that media type can be set to */*
+        SyncopeClientFactoryBean factory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
+        SyncopeClient client = new SyncopeClient(
+                MediaType.WILDCARD_TYPE,
+                factory.getRestClientFactoryBean(),
+                factory.getExceptionMapper(),
+                ADMIN_UNAME,
+                ADMIN_PWD,
+                false);
+
+        // perform operation
+        AnyTypeClassService service = client.getService(AnyTypeClassService.class);
+        service.list();
+
+        // check that */* was actually sent
+        MultivaluedMap<String, String> requestHeaders = WebClient.client(service).getHeaders();
+        assertEquals(MediaType.WILDCARD, requestHeaders.getFirst(HttpHeaders.ACCEPT));
+
+        // check that application/json was received
+        String contentType = WebClient.client(service).getResponse().getHeaderString(HttpHeaders.CONTENT_TYPE);
+        assertTrue(contentType.startsWith(MediaType.APPLICATION_JSON));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
new file mode 100644
index 0000000..c2b27df
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
@@ -0,0 +1,188 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.policy.AccountPolicyTO;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.RealmService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class RealmITCase extends AbstractITCase {
+
+    private RealmTO getRealm(final String fullPath) {
+        return IterableUtils.find(realmService.list(fullPath), new Predicate<RealmTO>() {
+
+            @Override
+            public boolean evaluate(final RealmTO object) {
+                return fullPath.equals(object.getFullPath());
+            }
+        });
+    }
+
+    @Test
+    public void list() {
+        List<RealmTO> realms = realmService.list();
+        assertNotNull(realms);
+        assertFalse(realms.isEmpty());
+        for (RealmTO realm : realms) {
+            assertNotNull(realm);
+        }
+
+        try {
+            realmService.list("a name");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPath, e.getType());
+        }
+    }
+
+    @Test
+    public void createUpdate() {
+        final RealmTO realm = new RealmTO();
+        realm.setName("last");
+
+        // 1. create
+        Response response = realmService.create("/even/two", realm);
+        RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
+        assertNotNull(actuals);
+        assertTrue(actuals.length > 0);
+        RealmTO actual = actuals[0];
+        assertNotNull(actual.getKey());
+        assertEquals("last", actual.getName());
+        assertEquals("/even/two/last", actual.getFullPath());
+        assertEquals(actual.getParent(), getRealm("/even/two").getKey(), 0);
+        assertNull(realm.getAccountPolicy());
+        assertNull(realm.getPasswordPolicy());
+
+        // 2. update setting policies
+        actual.setAccountPolicy(6L);
+        actual.setPasswordPolicy(4L);
+        realmService.update(actual);
+
+        actual = getRealm(actual.getFullPath());
+        assertNotNull(actual.getAccountPolicy());
+        assertNotNull(actual.getPasswordPolicy());
+
+        // 3. update changing parent
+        actual.setParent(getRealm("/odd").getKey());
+        realmService.update(actual);
+
+        actual = getRealm("/odd/last");
+        assertNotNull(actual);
+        assertEquals("/odd/last", actual.getFullPath());
+
+        assertEquals(1, IterableUtils.countMatches(realmService.list(), new Predicate<RealmTO>() {
+
+            @Override
+            public boolean evaluate(final RealmTO object) {
+                return realm.getName().equals(object.getName());
+            }
+        }));
+
+        // 4. create under invalid path
+        try {
+            realmService.create("a name", realm);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPath, e.getType());
+        }
+
+        // 5. attempt to create duplicate
+        try {
+            realmService.create("/odd", realm);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.DataIntegrityViolation, e.getType());
+        }
+    }
+
+    @Test
+    public void deletingAccountPolicy() {
+        // 1. create account policy
+        AccountPolicyTO policy = new AccountPolicyTO();
+        policy.setDescription("deletingAccountPolicy");
+
+        DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
+        ruleConf.setMinLength(3);
+        ruleConf.setMaxLength(8);
+        policy.getRuleConfs().add(ruleConf);
+
+        policy = createPolicy(policy);
+        assertNotNull(policy);
+
+        // 2. create realm with policy assigned
+        RealmTO realm = new RealmTO();
+        realm.setName("withppolicy");
+        realm.setAccountPolicy(policy.getKey());
+
+        Response response = realmService.create(SyncopeConstants.ROOT_REALM, realm);
+        RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
+        assertNotNull(actuals);
+        assertTrue(actuals.length > 0);
+        RealmTO actual = actuals[0];
+        assertEquals(policy.getKey(), actual.getAccountPolicy(), 0);
+
+        // 3. remove policy
+        policyService.delete(policy.getKey());
+
+        // 4. verify
+        actual = getRealm(actual.getFullPath());
+        assertNull(actual.getAccountPolicy());
+    }
+
+    @Test
+    public void delete() {
+        RealmTO realm = new RealmTO();
+        realm.setName("deletable");
+
+        Response response = realmService.create("/even/two", realm);
+        RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
+        assertNotNull(actuals);
+        assertTrue(actuals.length > 0);
+        RealmTO actual = actuals[0];
+
+        realmService.delete(actual.getFullPath());
+
+        try {
+            realmService.list(actual.getFullPath());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RelationshipTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RelationshipTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RelationshipTypeITCase.java
new file mode 100644
index 0000000..bcf0b23
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RelationshipTypeITCase.java
@@ -0,0 +1,94 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.RelationshipTypeTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class RelationshipTypeITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        RelationshipTypeTO otherType = relationshipTypeService.read("inclusion");
+        assertNotNull(otherType);
+        assertEquals("inclusion", otherType.getKey());
+    }
+
+    @Test
+    public void list() {
+        List<RelationshipTypeTO> list = relationshipTypeService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        RelationshipTypeTO newType = new RelationshipTypeTO();
+        newType.setKey("new type");
+        newType.setDescription("description");
+
+        Response response = relationshipTypeService.create(newType);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newType = getObject(response.getLocation(), RelationshipTypeService.class, RelationshipTypeTO.class);
+        assertNotNull(newType);
+        assertEquals("description", newType.getDescription());
+
+        newType.setDescription("new description");
+        relationshipTypeService.update(newType);
+
+        newType = relationshipTypeService.read(newType.getKey());
+        assertNotNull(newType);
+        assertEquals("new description", newType.getDescription());
+
+        relationshipTypeService.delete(newType.getKey());
+
+        try {
+            relationshipTypeService.read(newType.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidName() {
+        RelationshipTypeTO newType = new RelationshipTypeTO();
+        newType.setKey("membership");
+        try {
+            relationshipTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidRelationshipType, e.getType());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
new file mode 100644
index 0000000..98ab976
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
@@ -0,0 +1,303 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.report.UserReportletConf;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.common.rest.api.beans.BulkExecDeleteQuery;
+import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ReportITCase extends AbstractITCase {
+
+    private ReportTO createReport(final ReportTO report) {
+        Response response = reportService.create(report);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+        return getObject(response.getLocation(), ReportService.class, ReportTO.class);
+    }
+
+    @Test
+    public void getReportletClasses() {
+        Set<String> reportlets = syncopeService.info().getReportlets();
+        assertNotNull(reportlets);
+        assertFalse(reportlets.isEmpty());
+    }
+
+    @Test
+    public void list() {
+        List<ReportTO> reports = reportService.list();
+        assertNotNull(reports);
+        assertFalse(reports.isEmpty());
+        for (ReportTO report : reports) {
+            assertNotNull(report);
+        }
+    }
+
+    @Test
+    public void read() {
+        ReportTO reportTO = reportService.read(1L);
+
+        assertNotNull(reportTO);
+        assertNotNull(reportTO.getExecutions());
+        assertFalse(reportTO.getExecutions().isEmpty());
+    }
+
+    @Test
+    public void create() {
+        ReportTO report = new ReportTO();
+        report.setName("testReportForCreate" + getUUIDString());
+        report.getReportletConfs().add(new UserReportletConf("first"));
+        report.getReportletConfs().add(new UserReportletConf("second"));
+
+        report = createReport(report);
+        assertNotNull(report);
+
+        ReportTO actual = reportService.read(report.getKey());
+        assertNotNull(actual);
+
+        assertEquals(actual, report);
+    }
+
+    @Test
+    public void update() {
+        ReportTO report = new ReportTO();
+        report.setName("testReportForUpdate" + getUUIDString());
+
+        report.getReportletConfs().add(new UserReportletConf("first"));
+        report.getReportletConfs().add(new UserReportletConf("second"));
+
+        report = createReport(report);
+        assertNotNull(report);
+        assertEquals(2, report.getReportletConfs().size());
+
+        report.getReportletConfs().add(new UserReportletConf("last"));
+
+        reportService.update(report);
+        ReportTO updated = reportService.read(report.getKey());
+        assertNotNull(updated);
+        assertEquals(3, updated.getReportletConfs().size());
+    }
+
+    @Test
+    public void delete() {
+        ReportTO report = new ReportTO();
+        report.setName("testReportForDelete" + getUUIDString());
+        report.getReportletConfs().add(new UserReportletConf("first"));
+        report.getReportletConfs().add(new UserReportletConf("second"));
+
+        report = createReport(report);
+        assertNotNull(report);
+
+        reportService.delete(report.getKey());
+
+        try {
+            reportService.read(report.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    private Long execute(final Long reportKey) {
+        ReportExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportKey).build());
+        assertNotNull(execution);
+
+        int i = 0;
+        int maxit = 50;
+
+        ReportTO reportTO;
+
+        // wait for report execution completion (executions incremented)
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            reportTO = reportService.read(reportKey);
+
+            assertNotNull(reportTO);
+            assertNotNull(reportTO.getExecutions());
+
+            i++;
+        } while (reportTO.getExecutions().isEmpty()
+                || (!ReportExecStatus.SUCCESS.name().equals(reportTO.getExecutions().get(0).getStatus()) && i < maxit));
+        assertEquals(ReportExecStatus.SUCCESS.name(), reportTO.getExecutions().get(0).getStatus());
+
+        return reportTO.getExecutions().get(0).getKey();
+    }
+
+    private void checkExport(final Long execId, final ReportExecExportFormat fmt) throws IOException {
+        Response response = reportService.exportExecutionResult(execId, fmt);
+        assertNotNull(response);
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+        assertNotNull(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION));
+        assertTrue(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION).
+                endsWith("." + fmt.name().toLowerCase()));
+
+        Object entity = response.getEntity();
+        assertTrue(entity instanceof InputStream);
+        assertFalse(IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING).isEmpty());
+    }
+
+    @Test
+    public void executeAndExport() throws IOException {
+        ReportTO reportTO = reportService.read(1L);
+        reportTO.setKey(0L);
+        reportTO.setName("executeAndExport" + getUUIDString());
+        reportTO.setActive(false);
+        reportTO.getExecutions().clear();
+        reportTO = createReport(reportTO);
+        assertNotNull(reportTO);
+
+        try {
+            execute(reportTO.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.Scheduling, e.getType());
+            assertTrue(e.getElements().iterator().next().contains("active"));
+        }
+
+        reportTO.setActive(true);
+        reportService.update(reportTO);
+
+        long execId = execute(reportTO.getKey());
+
+        checkExport(execId, ReportExecExportFormat.XML);
+        checkExport(execId, ReportExecExportFormat.HTML);
+        checkExport(execId, ReportExecExportFormat.PDF);
+        checkExport(execId, ReportExecExportFormat.RTF);
+        checkExport(execId, ReportExecExportFormat.CSV);
+    }
+
+    @Test
+    public void deleteExecutions() {
+        Date start = new Date();
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+        }
+
+        ReportTO reportTO = reportService.read(1L);
+        reportTO.setKey(0L);
+        reportTO.setName("deleteExecutions" + getUUIDString());
+        reportTO.getExecutions().clear();
+        reportTO = createReport(reportTO);
+        assertNotNull(reportTO);
+
+        Long execId = execute(reportTO.getKey());
+        assertNotNull(execId);
+
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+        }
+        Date end = new Date();
+
+        BulkActionResult result = reportService.deleteExecutions(
+                new BulkExecDeleteQuery.Builder().key(reportTO.getKey()).startedAfter(start).endedBefore(end).build());
+        assertNotNull(result);
+
+        assertEquals(1, result.getResults().size());
+        assertEquals(execId.toString(), result.getResults().keySet().iterator().next());
+        assertEquals(BulkActionResult.Status.SUCCESS, result.getResults().entrySet().iterator().next().getValue());
+    }
+
+    @Test
+    public void issueSYNCOPE43() {
+        ReportTO reportTO = new ReportTO();
+        reportTO.setName("issueSYNCOPE43" + getUUIDString());
+        reportTO.setActive(true);
+        reportTO = createReport(reportTO);
+        assertNotNull(reportTO);
+
+        ReportExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportTO.getKey()).build());
+        assertNotNull(execution);
+
+        int maxit = 50;
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            reportTO = reportService.read(reportTO.getKey());
+
+            maxit--;
+        } while (reportTO.getExecutions().isEmpty() && maxit > 0);
+
+        assertEquals(1, reportTO.getExecutions().size());
+    }
+
+    @Test
+    public void issueSYNCOPE102() throws IOException {
+        // Create
+        ReportTO reportTO = reportService.read(1L);
+        reportTO.setKey(0L);
+        reportTO.setName("issueSYNCOPE102" + getUUIDString());
+        reportTO = createReport(reportTO);
+        assertNotNull(reportTO);
+
+        // Execute (multiple requests)
+        for (int i = 0; i < 10; i++) {
+            ReportExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportTO.getKey()).build());
+            assertNotNull(execution);
+        }
+
+        // Wait for one execution
+        int maxit = 50;
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            reportTO = reportService.read(reportTO.getKey());
+
+            maxit--;
+        } while (reportTO.getExecutions().isEmpty() && maxit > 0);
+        assertFalse(reportTO.getExecutions().isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
new file mode 100644
index 0000000..e9e50ce
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -0,0 +1,697 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.rest.api.beans.ConnObjectTOListQuery;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ResourceITCase extends AbstractITCase {
+
+    private ResourceTO buildResourceTO(final String resourceName) {
+        ResourceTO resourceTO = new ResourceTO();
+
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(102L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setExtAttrName("userId");
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("username");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("fullname");
+        item.setIntAttrName("cn");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setConnObjectKey(false);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        return resourceTO;
+    }
+
+    @Test
+    public void getPropagationActionsClasses() {
+        Set<String> actions = syncopeService.info().getPropagationActions();
+        assertNotNull(actions);
+        assertFalse(actions.isEmpty());
+    }
+
+    @Test
+    public void create() {
+        String resourceName = RESOURCE_NAME_CREATE;
+        ResourceTO resourceTO = buildResourceTO(resourceName);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        // check for existence
+        actual = resourceService.read(resourceName);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void createOverridingProps() {
+        String resourceName = "overriding-conn-conf-target-resource-create";
+        ResourceTO resourceTO = new ResourceTO();
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setExtAttrName("uid");
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("username");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setConnObjectKey(true);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("fullname");
+        item.setIntAttrName("cn");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setConnObjectKey(false);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(102L);
+
+        ConnConfProperty prop = new ConnConfProperty();
+        ConnConfPropSchema schema = new ConnConfPropSchema();
+        schema.setType("java.lang.String");
+        schema.setName("endpoint");
+        schema.setRequired(true);
+        prop.setSchema(schema);
+        prop.getValues().add("http://invalidurl/");
+
+        Set<ConnConfProperty> connectorConfigurationProperties = new HashSet<>(Arrays.asList(prop));
+        resourceTO.getConfOverride().addAll(connectorConfigurationProperties);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        // check the existence
+        actual = resourceService.read(resourceName);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void createWithSingleMappingItem() {
+        String resourceName = RESOURCE_NAME_CREATE_SINGLE;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(102L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setExtAttrName("userId");
+        item.setConnObjectKey(true);
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.setConnObjectKeyItem(item);
+
+        provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.GROUP.name());
+        provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.GroupKey);
+        item.setExtAttrName("groupId");
+        item.setConnObjectKey(true);
+        item.setPurpose(MappingPurpose.SYNCHRONIZATION);
+        mapping.setConnObjectKeyItem(item);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping());
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
+        assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping());
+        assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems());
+        assertEquals(MappingPurpose.SYNCHRONIZATION,
+                actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getConnObjectKeyItem().getPurpose());
+        assertEquals(MappingPurpose.PROPAGATION,
+                actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
+    }
+
+    @Test
+    public void createWithInvalidMapping() {
+        String resourceName = RESOURCE_NAME_CREATE_WRONG;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(102L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setExtAttrName("userId");
+        item.setConnObjectKey(true);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setExtAttrName("email");
+        // missing intAttrName ...
+        mapping.add(item);
+
+        try {
+            createResource(resourceTO);
+            fail("Create should not have worked");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+            assertEquals("intAttrName", e.getElements().iterator().next());
+        }
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithoutExtAttr() {
+        String resourceName = RESOURCE_NAME_CREATE_WRONG;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(102L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setExtAttrName("userId");
+        item.setConnObjectKey(true);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setIntAttrName("usernane");
+        // missing extAttrName ...
+        mapping.add(item);
+
+        createResource(resourceTO);
+    }
+
+    @Test
+    public void createWithPasswordPolicy() {
+        String resourceName = "res-with-password-policy";
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(102L);
+        resourceTO.setPasswordPolicy(4L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setExtAttrName("userId");
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setConnObjectKey(true);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        // check the existence
+        actual = resourceService.read(resourceName);
+        assertNotNull(actual);
+        assertNotNull(actual.getPasswordPolicy());
+        assertEquals(4L, (long) actual.getPasswordPolicy());
+    }
+
+    @Test
+    public void updateWithException() {
+        try {
+            ResourceTO resourceTO = new ResourceTO();
+            resourceTO.setKey("resourcenotfound");
+            resourceService.update(resourceTO);
+
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void update() {
+        String resourceName = RESOURCE_NAME_UPDATE;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(101L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        // Update with an existing and already assigned mapping
+        MappingItemTO item = new MappingItemTO();
+        item.setKey(112L);
+        item.setExtAttrName("test3");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        // Update defining new mappings
+        for (int i = 4; i < 6; i++) {
+            item = new MappingItemTO();
+            item.setExtAttrName("test" + i);
+            item.setIntAttrName("fullname");
+            item.setIntMappingType(IntMappingType.UserPlainSchema);
+            item.setPurpose(MappingPurpose.BOTH);
+            mapping.add(item);
+        }
+        item = new MappingItemTO();
+        item.setExtAttrName("username");
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setConnObjectKey(true);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        resourceService.update(resourceTO);
+        ResourceTO actual = resourceService.read(resourceTO.getKey());
+        assertNotNull(actual);
+
+        // check for existence
+        Collection<MappingItemTO> mapItems = actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
+        assertNotNull(mapItems);
+        assertEquals(4, mapItems.size());
+    }
+
+    @Test
+    public void deleteWithException() {
+        try {
+            resourceService.delete("resourcenotfound");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void updateResetSyncToken() {
+        // create resource with sync token
+        String resourceName = RESOURCE_NAME_RESETSYNCTOKEN + getUUIDString();
+        ResourceTO pre = buildResourceTO(resourceName);
+
+        pre.getProvision(AnyTypeKind.USER.name()).setSyncToken("test");
+        resourceService.create(pre);
+
+        pre.getProvision(AnyTypeKind.USER.name()).setSyncToken(null);
+        resourceService.update(pre);
+        ResourceTO actual = resourceService.read(pre.getKey());
+        // check that the synctoken has been reset
+        assertNull(actual.getProvision(AnyTypeKind.USER.name()).getSyncToken());
+    }
+
+    @Test
+    public void delete() {
+        String resourceName = "tobedeleted";
+
+        ResourceTO resource = buildResourceTO(resourceName);
+        Response response = resourceService.create(resource);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(actual);
+
+        resourceService.delete(resourceName);
+
+        try {
+            resourceService.read(resourceName);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        List<ResourceTO> actuals = resourceService.list();
+        assertNotNull(actuals);
+        assertFalse(actuals.isEmpty());
+        for (ResourceTO resourceTO : actuals) {
+            assertNotNull(resourceTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBVIRATTR);
+        assertNotNull(resource);
+
+        ProvisionTO provision = resource.getProvision(AnyTypeKind.USER.name());
+        assertNotNull(provision);
+        assertFalse(provision.getMapping().getItems().isEmpty());
+        assertFalse(provision.getMapping().getLinkingItems().isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
+        assertNotNull(actual);
+
+        try {
+            createResource(actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createResource(actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void bulkAction() {
+        resourceService.create(buildResourceTO("forBulk1"));
+        resourceService.create(buildResourceTO("forBulk2"));
+
+        assertNotNull(resourceService.read("forBulk1"));
+        assertNotNull(resourceService.read("forBulk2"));
+
+        final BulkAction bulkAction = new BulkAction();
+        bulkAction.setType(BulkAction.Type.DELETE);
+
+        bulkAction.getTargets().add(String.valueOf("forBulk1"));
+        bulkAction.getTargets().add(String.valueOf("forBulk2"));
+
+        resourceService.bulk(bulkAction);
+
+        try {
+            resourceService.read("forBulk1");
+            fail();
+        } catch (SyncopeClientException e) {
+        }
+
+        try {
+            resourceService.read("forBulk2");
+            fail();
+        } catch (SyncopeClientException e) {
+        }
+    }
+
+    @Test
+    public void anonymous() {
+        ResourceService unauthenticated = clientFactory.create().getService(ResourceService.class);
+        try {
+            unauthenticated.list();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        ResourceService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).
+                getService(ResourceService.class);
+        assertFalse(anonymous.list().isEmpty());
+    }
+
+    @Test
+    public void listConnObjects() {
+        List<Long> groupKeys = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            GroupTO group = GroupITCase.getSampleTO("group");
+            group.getResources().add(RESOURCE_NAME_LDAP);
+            group = createGroup(group).getAny();
+            groupKeys.add(group.getKey());
+        }
+
+        int totalRead = 0;
+        Set<String> read = new HashSet<>();
+        try {
+            ConnObjectTOListQuery.Builder builder = new ConnObjectTOListQuery.Builder().size(10);
+            PagedConnObjectTOResult list;
+            do {
+                list = null;
+
+                boolean succeeded = false;
+                // needed because ApacheDS seems to randomly fail when searching with cookie
+                for (int i = 0; i < 5 && !succeeded; i++) {
+                    try {
+                        list = resourceService.listConnObjects(
+                                RESOURCE_NAME_LDAP,
+                                AnyTypeKind.GROUP.name(),
+                                builder.build());
+                        succeeded = true;
+                    } catch (SyncopeClientException e) {
+                        assertEquals(ClientExceptionType.ConnectorException, e.getType());
+                    }
+                }
+                assertNotNull(list);
+
+                totalRead += list.getResult().size();
+                CollectionUtils.collect(list.getResult(), new Transformer<ConnObjectTO, String>() {
+
+                    @Override
+                    public String transform(final ConnObjectTO input) {
+                        return input.getPlainAttrMap().get("__NAME__").getValues().get(0);
+                    }
+                }, read);
+
+                if (list.getPagedResultsCookie() != null) {
+                    builder.pagedResultsCookie(list.getPagedResultsCookie());
+                }
+            } while (list.getPagedResultsCookie() != null);
+
+            assertEquals(totalRead, read.size());
+            assertTrue(totalRead >= 10);
+        } finally {
+            for (Long key : groupKeys) {
+                groupService.delete(key);
+            }
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE360() {
+        final String name = "SYNCOPE360-" + getUUIDString();
+        resourceService.create(buildResourceTO(name));
+
+        ResourceTO resource = resourceService.read(name);
+        assertNotNull(resource);
+        assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
+
+        resource.getProvision(AnyTypeKind.USER.name()).setMapping(null);
+        resourceService.update(resource);
+
+        resource = resourceService.read(name);
+        assertNotNull(resource);
+        assertNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
+    }
+
+    @Test
+    public void issueSYNCOPE368() {
+        final String name = "SYNCOPE368-" + getUUIDString();
+
+        ResourceTO resourceTO = new ResourceTO();
+
+        resourceTO.setKey(name);
+        resourceTO.setConnector(105L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.GROUP.name());
+        provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.GroupName);
+        item.setExtAttrName("cn");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.GroupOwnerSchema);
+        item.setExtAttrName("owner");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        resourceTO = createResource(resourceTO);
+        assertNotNull(resourceTO);
+        assertEquals(2, resourceTO.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems().size());
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        try {
+            resourceService.create(
+                    buildResourceTO("http://schemas.examples.org/security/authorization/organizationUnit"));
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidExternalResource, e.getType());
+
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE493() {
+        // create resource with attribute mapping set to NONE and check its propagation
+        String resourceName = RESOURCE_NAME_CREATE_NONE;
+        ResourceTO resourceTO = new ResourceTO();
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(102L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setExtAttrName("userId");
+        item.setConnObjectKey(true);
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.setConnObjectKeyItem(item);
+
+        MappingItemTO item2 = new MappingItemTO();
+        item2.setIntMappingType(IntMappingType.UserPlainSchema);
+        item2.setConnObjectKey(false);
+        item2.setIntAttrName("gender");
+        item2.setExtAttrName("gender");
+        item2.setPurpose(MappingPurpose.NONE);
+        mapping.add(item2);
+
+        Response response = resourceService.create(resourceTO);
+        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping());
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
+        assertEquals(MappingPurpose.PROPAGATION,
+                actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
+        for (MappingItemTO itemTO : actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems()) {
+            if ("gender".equals(itemTO.getIntAttrName())) {
+                assertEquals(MappingPurpose.NONE, itemTO.getPurpose());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RoleITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RoleITCase.java
new file mode 100644
index 0000000..19adfd3
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RoleITCase.java
@@ -0,0 +1,143 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class RoleITCase extends AbstractITCase {
+
+    public static RoleTO getSampleRoleTO(final String name) {
+        RoleTO role = new RoleTO();
+        role.setKey(name + getUUIDString());
+        role.getRealms().add("/even");
+        role.getEntitlements().add(StandardEntitlement.LOG_SET_LEVEL);
+
+        return role;
+    }
+
+    @Test
+    public void list() {
+        List<RoleTO> roleTOs = roleService.list();
+        assertNotNull(roleTOs);
+        assertFalse(roleTOs.isEmpty());
+        for (RoleTO instance : roleTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void read() {
+        RoleTO roleTO = roleService.read("Search for realm evenTwo");
+        assertNotNull(roleTO);
+        assertTrue(roleTO.getEntitlements().contains(StandardEntitlement.USER_READ));
+    }
+
+    @Test
+    public void create() {
+        RoleTO role = new RoleTO();
+        role.getRealms().add(SyncopeConstants.ROOT_REALM);
+        role.getRealms().add("/even/two");
+        role.getEntitlements().add(StandardEntitlement.LOG_LIST);
+        role.getEntitlements().add(StandardEntitlement.LOG_SET_LEVEL);
+
+        try {
+            createRole(role);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidRole, e.getType());
+        }
+
+        role.setKey("new" + getUUIDString());
+        role = createRole(role);
+        assertNotNull(role);
+    }
+
+    @Test
+    public void update() {
+        RoleTO role = getSampleRoleTO("update");
+        role = createRole(role);
+        assertNotNull(role);
+
+        assertFalse(role.getEntitlements().contains(StandardEntitlement.WORKFLOW_TASK_LIST));
+        assertFalse(role.getRealms().contains("/even/two"));
+
+        role.getEntitlements().add(StandardEntitlement.WORKFLOW_TASK_LIST);
+        role.getRealms().add("/even/two");
+
+        roleService.update(role);
+
+        role = roleService.read(role.getKey());
+        assertTrue(role.getEntitlements().contains(StandardEntitlement.WORKFLOW_TASK_LIST));
+        assertTrue(role.getRealms().contains("/even/two"));
+    }
+
+    @Test
+    public void delete() {
+        RoleTO role = getSampleRoleTO("delete");
+        Response response = roleService.create(role);
+
+        RoleTO actual = getObject(response.getLocation(), RoleService.class, RoleTO.class);
+        assertNotNull(actual);
+
+        roleService.delete(actual.getKey());
+
+        try {
+            roleService.read(actual.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void dynMembership() {
+        assertTrue(userService.read(4L).getDynRoles().isEmpty());
+
+        RoleTO role = getSampleRoleTO("dynMembership");
+        role.setDynMembershipCond("cool==true");
+        Response response = roleService.create(role);
+        role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
+        assertNotNull(role);
+
+        assertTrue(userService.read(4L).getDynRoles().contains(role.getKey()));
+
+        role.setDynMembershipCond("cool==false");
+        roleService.update(role);
+
+        assertTrue(userService.read(4L).getDynGroups().isEmpty());
+    }
+}


[07/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
deleted file mode 100644
index 2385ebe..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ /dev/null
@@ -1,848 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.patch.DeassociationPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
-import org.apache.syncope.common.lib.types.SyncMode;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.provisioning.java.sync.DBPasswordSyncActions;
-import org.apache.syncope.core.provisioning.java.sync.LDAPPasswordSyncActions;
-import org.identityconnectors.framework.common.objects.Name;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class SyncTaskITCase extends AbstractTaskITCase {
-
-    @BeforeClass
-    public static void testSyncActionsSetup() {
-        SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID, true);
-        syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
-        taskService.update(syncTask);
-    }
-
-    @Test
-    public void getSyncActionsClasses() {
-        Set<String> actions = syncopeService.info().getSyncActions();
-        assertNotNull(actions);
-        assertFalse(actions.isEmpty());
-    }
-
-    @Test
-    public void list() {
-        PagedResult<SyncTaskTO> tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.SYNCHRONIZATION).build());
-        assertFalse(tasks.getResult().isEmpty());
-        for (AbstractTaskTO task : tasks.getResult()) {
-            if (!(task instanceof SyncTaskTO)) {
-                fail();
-            }
-        }
-    }
-
-    @Test
-    public void create() {
-        SyncTaskTO task = new SyncTaskTO();
-        task.setName("Test create Sync");
-        task.setDestinationRealm("/");
-        task.setResource(RESOURCE_NAME_WS2);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-
-        UserTO userTemplate = new UserTO();
-        userTemplate.getResources().add(RESOURCE_NAME_WS2);
-
-        userTemplate.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-        task.getTemplates().put(AnyTypeKind.USER.name(), userTemplate);
-
-        GroupTO groupTemplate = new GroupTO();
-        groupTemplate.getResources().add(RESOURCE_NAME_LDAP);
-        task.getTemplates().put(AnyTypeKind.GROUP.name(), groupTemplate);
-
-        Response response = taskService.create(task);
-        SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
-        assertNotNull(actual);
-
-        task = taskService.read(actual.getKey(), true);
-        assertNotNull(task);
-        assertEquals(actual.getKey(), task.getKey());
-        assertEquals(actual.getJobDelegateClassName(), task.getJobDelegateClassName());
-        assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
-        assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name()));
-    }
-
-    @Test
-    public void sync() throws Exception {
-        removeTestUsers();
-
-        // -----------------------------
-        // Create a new user ... it should be updated applying sync policy
-        // -----------------------------
-        UserTO inUserTO = new UserTO();
-        inUserTO.setRealm(SyncopeConstants.ROOT_REALM);
-        inUserTO.setPassword("password123");
-        String userName = "test9";
-        inUserTO.setUsername(userName);
-        inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
-        inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
-        inUserTO.getPlainAttrs().add(attrTO("type", "a type"));
-        inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
-        inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
-        inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
-        inUserTO.getAuxClasses().add("csv");
-        inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        inUserTO = createUser(inUserTO).getAny();
-        assertNotNull(inUserTO);
-        assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
-
-        // -----------------------------
-        try {
-            int usersPre = userService.list(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    page(1).size(1).build()).getTotalCount();
-            assertNotNull(usersPre);
-
-            execProvisioningTask(taskService, SYNC_TASK_ID, 50, false);
-
-            // after execution of the sync task the user data should have been synced from CSV
-            // and processed by user template
-            UserTO userTO = userService.read(inUserTO.getKey());
-            assertNotNull(userTO);
-            assertEquals(userName, userTO.getUsername());
-            assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
-                    ? "active" : "created", userTO.getStatus());
-            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
-            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
-
-            // Matching --> Update (no link)
-            assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
-
-            // check for user template
-            userTO = readUser("test7");
-            assertNotNull(userTO);
-            assertEquals("TYPE_OTHER", userTO.getPlainAttrMap().get("type").getValues().get(0));
-            assertEquals(3, userTO.getResources().size());
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
-            assertEquals(1, userTO.getMemberships().size());
-            assertEquals(8, userTO.getMemberships().get(0).getRightKey());
-
-            // Unmatching --> Assign (link) - SYNCOPE-658
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
-            assertEquals(1, IterableUtils.countMatches(userTO.getDerAttrs(), new Predicate<AttrTO>() {
-
-                @Override
-                public boolean evaluate(final AttrTO attributeTO) {
-                    return "csvuserid".equals(attributeTO.getSchema());
-                }
-            }));
-
-            userTO = readUser("test8");
-            assertNotNull(userTO);
-            assertEquals("TYPE_8", userTO.getPlainAttrMap().get("type").getValues().get(0));
-
-            // Check for ignored user - SYNCOPE-663
-            try {
-                readUser("test2");
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-            }
-
-            // check for sync results
-            int usersPost = userService.list(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    page(1).size(1).build()).getTotalCount();
-            assertNotNull(usersPost);
-            assertEquals(usersPre + 8, usersPost);
-
-            // Check for issue 215:
-            // * expected disabled user test1
-            // * expected enabled user test2
-            userTO = readUser("test1");
-            assertNotNull(userTO);
-            assertEquals("suspended", userTO.getStatus());
-
-            userTO = readUser("test3");
-            assertNotNull(userTO);
-            assertEquals("active", userTO.getStatus());
-
-            Set<Long> otherSyncTaskKeys = new HashSet<>();
-            otherSyncTaskKeys.add(25L);
-            otherSyncTaskKeys.add(26L);
-            execProvisioningTasks(taskService, otherSyncTaskKeys, 50, false);
-
-            // Matching --> UNLINK
-            assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
-            assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
-        } finally {
-            removeTestUsers();
-        }
-    }
-
-    @Test
-    public void dryRun() {
-        TaskExecTO execution = execProvisioningTask(taskService, SYNC_TASK_ID, 50, true);
-        assertEquals(
-                "Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(),
-                "SUCCESS", execution.getStatus());
-    }
-
-    @Test
-    public void reconcileFromDB() {
-        UserTO userTO = null;
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        try {
-            TaskExecTO execution = execProvisioningTask(taskService, 7L, 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser1");
-            assertNotNull(userTO);
-            assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertEquals("suspended", userTO.getStatus());
-
-            // enable user on external resource
-            jdbcTemplate.execute("UPDATE TEST SET status=TRUE WHERE id='testuser1'");
-
-            // re-execute the same SyncTask: now user must be active
-            execution = execProvisioningTask(taskService, 7L, 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser1");
-            assertNotNull(userTO);
-            assertEquals("active", userTO.getStatus());
-        } finally {
-            jdbcTemplate.execute("UPDATE TEST SET status=FALSE WHERE id='testUser1'");
-            if (userTO != null) {
-                userService.delete(userTO.getKey());
-            }
-        }
-    }
-
-    /**
-     * Clean Syncope and LDAP resource status.
-     */
-    private void ldapCleanup() {
-        PagedResult<GroupTO> matchingGroups = groupService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
-                build());
-        if (matchingGroups.getSize() > 0) {
-            for (GroupTO group : matchingGroups.getResult()) {
-                DeassociationPatch deassociationPatch = new DeassociationPatch();
-                deassociationPatch.setKey(group.getKey());
-                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-                groupService.deassociate(deassociationPatch);
-                groupService.delete(group.getKey());
-            }
-        }
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
-                build());
-        if (matchingUsers.getSize() > 0) {
-            for (UserTO user : matchingUsers.getResult()) {
-                DeassociationPatch deassociationPatch = new DeassociationPatch();
-                deassociationPatch.setKey(user.getKey());
-                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-                userService.deassociate(deassociationPatch);
-                userService.delete(user.getKey());
-            }
-        }
-    }
-
-    @Test
-    public void reconcileFromLDAP() {
-        // First of all, clear any potential conflict with existing user / group
-        ldapCleanup();
-
-        // 0. synchronize
-        TaskExecTO execution = execProvisioningTask(taskService, 11L, 50, false);
-
-        // 1. verify execution status
-        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 2. verify that synchronized group is found
-        PagedResult<GroupTO> matchingGroups = groupService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
-                build());
-        assertNotNull(matchingGroups);
-        assertEquals(1, matchingGroups.getResult().size());
-
-        // 3. verify that synchronized user is found
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertEquals(1, matchingUsers.getResult().size());
-
-        // Check for SYNCOPE-436
-        assertEquals("syncFromLDAP",
-                matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
-        // Check for SYNCOPE-270
-        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
-        // Check for SYNCOPE-123
-        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
-
-        GroupTO groupTO = matchingGroups.getResult().iterator().next();
-        assertNotNull(groupTO);
-        assertEquals("testLDAPGroup", groupTO.getName());
-        assertEquals("true", groupTO.getPlainAttrMap().get("show").getValues().get(0));
-        assertEquals(matchingUsers.getResult().iterator().next().getKey(), groupTO.getUserOwner(), 0);
-        assertNull(groupTO.getGroupOwner());
-
-        // SYNCOPE-317
-        execProvisioningTask(taskService, 11L, 50, false);
-    }
-
-    @Test
-    public void reconcileFromScriptedSQL() {
-        // 0. reset sync token and set MappingItemTransformer
-        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
-        ResourceTO originalResource = SerializationUtils.clone(resource);
-        ProvisionTO provision = resource.getProvision("PRINTER");
-        assertNotNull(provision);
-
-        try {
-            provision.setSyncToken(null);
-
-            MappingItemTO mappingItem = IterableUtils.find(
-                    provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
-
-                @Override
-                public boolean evaluate(final MappingItemTO object) {
-                    return "location".equals(object.getIntAttrName());
-                }
-            });
-            assertNotNull(mappingItem);
-            mappingItem.getMappingItemTransformerClassNames().clear();
-            mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
-
-            resourceService.update(resource);
-
-            // 1. create printer on external resource
-            AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync");
-            String originalLocation = anyObjectTO.getPlainAttrMap().get("location").getValues().get(0);
-            assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
-
-            anyObjectTO = createAnyObject(anyObjectTO).getAny();
-            assertNotNull(anyObjectTO);
-
-            // 2. verify that PrefixMappingItemTransformer was applied during propagation
-            // (location starts with given prefix on external resource)
-            ConnObjectTO connObjectTO = resourceService.
-                    readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
-            assertFalse(anyObjectTO.getPlainAttrMap().get("location").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
-            assertTrue(connObjectTO.getPlainAttrMap().get("location").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
-
-            // 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
-            PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                            is("location").equalTo("sync*").query()).build());
-            assertTrue(matchingPrinters.getSize() > 0);
-            for (AnyObjectTO printer : matchingPrinters.getResult()) {
-                DeassociationPatch deassociationPatch = new DeassociationPatch();
-                deassociationPatch.setKey(printer.getKey());
-                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_DBSCRIPTED);
-                anyObjectService.deassociate(deassociationPatch);
-                anyObjectService.delete(printer.getKey());
-            }
-
-            // 4. synchronize
-            execProvisioningTask(taskService, 28L, 50, false);
-
-            // 5. verify that printer was re-created in Syncope (implies that location does not start with given prefix,
-            // hence PrefixMappingItemTransformer was applied during sync)
-            matchingPrinters = anyObjectService.search(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                            is("location").equalTo("sync*").query()).build());
-            assertTrue(matchingPrinters.getSize() > 0);
-
-            // 6. verify that synctoken was updated
-            assertNotNull(
-                    resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
-        } finally {
-            resourceService.update(originalResource);
-        }
-    }
-
-    @Test
-    public void filteredReconciliation() {
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        SyncTaskTO task = null;
-        UserTO userTO = null;
-        try {
-            // 1. create 2 users on testsync
-            jdbcTemplate.execute("INSERT INTO testsync VALUES (1001, 'user1', 'Doe', 'mail1@apache.org')");
-            jdbcTemplate.execute("INSERT INTO testsync VALUES (1002, 'user2', 'Rossi', 'mail2@apache.org')");
-
-            // 2. create new sync task for test-db, with reconciliation filter (surname 'Rossi') 
-            task = taskService.read(10L, true);
-            task.setSyncMode(SyncMode.FILTERED_RECONCILIATION);
-            task.setReconciliationFilterBuilderClassName(TestReconciliationFilterBuilder.class.getName());
-            Response response = taskService.create(task);
-            task = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
-            assertNotNull(task);
-            assertEquals(
-                    TestReconciliationFilterBuilder.class.getName(),
-                    task.getReconciliationFilterBuilderClassName());
-
-            // 3. exec task
-            TaskExecTO execution = execProvisioningTask(taskService, task.getKey(), 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            // 4. verify that only enabled user was synchronized
-            userTO = readUser("user2");
-            assertNotNull(userTO);
-
-            try {
-                readUser("user1");
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.NotFound, e.getType());
-            }
-        } finally {
-            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1001");
-            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1002");
-            if (task != null && task.getKey() != 7L) {
-                taskService.delete(task.getKey());
-            }
-            if (userTO != null) {
-                userService.delete(userTO.getKey());
-            }
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE68() {
-        //-----------------------------
-        // Create a new user ... it should be updated applying sync policy
-        //-----------------------------
-        UserTO userTO = new UserTO();
-        userTO.setRealm(SyncopeConstants.ROOT_REALM);
-        userTO.setPassword("password123");
-        userTO.setUsername("testuser2");
-
-        userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
-        userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
-        userTO.getPlainAttrs().add(attrTO("type", "a type"));
-        userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
-        userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org"));
-        userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org"));
-
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals("testuser2", userTO.getUsername());
-        assertEquals(1, userTO.getMemberships().size());
-        assertEquals(3, userTO.getResources().size());
-        //-----------------------------
-
-        try {
-            //-----------------------------
-            //  add user template
-            //-----------------------------
-            UserTO template = new UserTO();
-
-            template.getMemberships().add(new MembershipTO.Builder().group(10L).build());
-
-            template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
-            //-----------------------------
-
-            // Update sync task
-            SyncTaskTO task = taskService.read(9L, true);
-            assertNotNull(task);
-
-            task.getTemplates().put(AnyTypeKind.USER.name(), template);
-
-            taskService.update(task);
-            SyncTaskTO actual = taskService.read(task.getKey(), true);
-            assertNotNull(actual);
-            assertEquals(task.getKey(), actual.getKey());
-            assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
-            assertFalse(((UserTO) actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
-
-            TaskExecTO execution = execProvisioningTask(taskService, actual.getKey(), 50, false);
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser2");
-            assertNotNull(userTO);
-            assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertEquals(2, userTO.getMemberships().size());
-            assertEquals(4, userTO.getResources().size());
-        } finally {
-            UserTO dUserTO = deleteUser(userTO.getKey()).getAny();
-            assertNotNull(dUserTO);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE230() {
-        // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
-        execProvisioningTask(taskService, 10L, 50, false);
-
-        // 3. read e-mail address for user created by the SyncTask first execution
-        UserTO userTO = readUser("issuesyncope230");
-        assertNotNull(userTO);
-        String email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
-        assertNotNull(email);
-
-        // 4. update TESTSYNC on external H2 by changing e-mail address
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
-
-        // 5. re-execute the SyncTask
-        execProvisioningTask(taskService, 10L, 50, false);
-
-        // 6. verify that the e-mail was updated
-        userTO = readUser("issuesyncope230");
-        assertNotNull(userTO);
-        email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
-        assertNotNull(email);
-        assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
-    }
-
-    @Test
-    public void issueSYNCOPE258() {
-        // -----------------------------
-        // Add a custom correlation rule
-        // -----------------------------
-        SyncPolicyTO policyTO = policyService.read(9L);
-        policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
-        policyService.update(policyTO);
-        // -----------------------------
-
-        SyncTaskTO task = new SyncTaskTO();
-        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        task.setName("Test Sync Rule");
-        task.setActive(true);
-        task.setResource(RESOURCE_NAME_WS2);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        task.setPerformCreate(true);
-        task.setPerformDelete(true);
-        task.setPerformUpdate(true);
-
-        Response response = taskService.create(task);
-        task = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        createUser(userTO);
-
-        userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        userTO = createUser(userTO).getAny();
-
-        // change email in order to unmatch the second user
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("email", "s258@apache.org"));
-
-        userService.update(userPatch);
-
-        execProvisioningTask(taskService, task.getKey(), 50, false);
-
-        SyncTaskTO executed = taskService.read(task.getKey(), true);
-        assertEquals(1, executed.getExecutions().size());
-
-        // asser for just one match
-        assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
-                executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
-    }
-
-    @Test
-    public void issueSYNCOPE272() {
-        removeTestUsers();
-
-        // create user with testdb resource
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        userTO = result.getAny();
-        try {
-            assertNotNull(userTO);
-            assertEquals(1, result.getPropagationStatuses().size());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-
-            TaskExecTO taskExecTO = execProvisioningTask(taskService, 24L, 50, false);
-
-            assertNotNull(taskExecTO.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()));
-
-            userTO = userService.read(userTO.getKey());
-            assertNotNull(userTO);
-            assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
-        } finally {
-            removeTestUsers();
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE307() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
-        userTO.setUsername("test0");
-        userTO.getPlainAttrMap().get("firstname").getValues().clear();
-        userTO.getPlainAttrMap().get("firstname").getValues().add("nome0");
-        userTO.getAuxClasses().add("csv");
-
-        AttrTO csvuserid = new AttrTO();
-        csvuserid.setSchema("csvuserid");
-        userTO.getDerAttrs().add(csvuserid);
-
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        userTO = userService.read(userTO.getKey());
-        assertTrue(userTO.getVirAttrMap().isEmpty());
-
-        // Update sync task
-        SyncTaskTO task = taskService.read(12L, true);
-        assertNotNull(task);
-
-        UserTO template = new UserTO();
-        template.setPassword("'password123'");
-        template.getResources().add(RESOURCE_NAME_DBVIRATTR);
-        template.getVirAttrs().add(attrTO("virtualdata", "'virtualvalue'"));
-
-        task.getTemplates().put(AnyTypeKind.USER.name(), template);
-
-        taskService.update(task);
-
-        // exec task: one user from CSV will match the user created above and template will be applied
-        execProvisioningTask(taskService, task.getKey(), 50, false);
-
-        // check that template was successfully applied...
-        userTO = userService.read(userTO.getKey());
-        assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // ...and that propagation to db succeeded
-        try {
-            JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-            String value = jdbcTemplate.queryForObject(
-                    "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
-            assertEquals("virtualvalue", value);
-        } catch (EmptyResultDataAccessException e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE313DB() throws Exception {
-        // 1. create user in DB
-        UserTO user = UserITCase.getUniqueSampleTO("syncope313-db@syncope.apache.org");
-        user.setPassword("security123");
-        user.getResources().add(RESOURCE_NAME_TESTDB);
-        user = createUser(user).getAny();
-        assertNotNull(user);
-        assertFalse(user.getResources().isEmpty());
-
-        // 2. Check that the DB resource has the correct password
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        String value = jdbcTemplate.queryForObject(
-                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
-        assertEquals(Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1), value.toUpperCase());
-
-        // 3. Update the password in the DB
-        String newCleanPassword = "new-security";
-        String newPassword = Encryptor.getInstance().encode(newCleanPassword, CipherAlgorithm.SHA1);
-        jdbcTemplate.execute("UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'");
-
-        // 4. Sync the user from the resource
-        SyncTaskTO syncTask = new SyncTaskTO();
-        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        syncTask.setName("DB Sync Task");
-        syncTask.setActive(true);
-        syncTask.setPerformCreate(true);
-        syncTask.setPerformUpdate(true);
-        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        syncTask.setResource(RESOURCE_NAME_TESTDB);
-        syncTask.getActionsClassNames().add(DBPasswordSyncActions.class.getName());
-        Response taskResponse = taskService.create(syncTask);
-
-        SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
-        assertNotNull(actual);
-
-        syncTask = taskService.read(actual.getKey(), true);
-        assertNotNull(syncTask);
-        assertEquals(actual.getKey(), syncTask.getKey());
-        assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
-
-        TaskExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
-        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 5. Test the sync'd user
-        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
-        assertNotNull(self);
-
-        // 6. Delete SyncTask + user
-        taskService.delete(syncTask.getKey());
-        deleteUser(user.getKey());
-    }
-
-    @Test
-    public void issueSYNCOPE313LDAP() throws Exception {
-        // First of all, clear any potential conflict with existing user / group
-        ldapCleanup();
-
-        // 1. create user in LDAP
-        String oldCleanPassword = "security123";
-        UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org");
-        user.setPassword(oldCleanPassword);
-        user.getResources().add(RESOURCE_NAME_LDAP);
-        user = createUser(user).getAny();
-        assertNotNull(user);
-        assertFalse(user.getResources().isEmpty());
-
-        // 2. request to change password only on Syncope and not on LDAP
-        String newCleanPassword = "new-security123";
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(user.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value(newCleanPassword).build());
-        user = updateUser(userPatch).getAny();
-
-        // 3. Check that the Syncope user now has the changed password
-        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
-        assertNotNull(self);
-
-        // 4. Check that the LDAP resource has the old password
-        ConnObjectTO connObject =
-                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
-        assertNotNull(getLdapRemoteObject(
-                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
-                oldCleanPassword,
-                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
-
-        // 5. Update the LDAP Connector to retrieve passwords
-        ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
-        ConnInstanceTO resourceConnector = connectorService.read(
-                ldapResource.getConnector(), Locale.ENGLISH.getLanguage());
-        ConnConfProperty property = resourceConnector.getConfMap().get("retrievePasswordsWithSearch");
-        property.getValues().clear();
-        property.getValues().add(Boolean.TRUE);
-        connectorService.update(resourceConnector);
-
-        // 6. Sync the user from the resource
-        SyncTaskTO syncTask = new SyncTaskTO();
-        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        syncTask.setName("LDAP Sync Task");
-        syncTask.setActive(true);
-        syncTask.setPerformCreate(true);
-        syncTask.setPerformUpdate(true);
-        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        syncTask.setResource(RESOURCE_NAME_LDAP);
-        syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName());
-        Response taskResponse = taskService.create(syncTask);
-
-        syncTask = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
-        assertNotNull(syncTask);
-
-        TaskExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
-        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 7. Test the sync'd user
-        self = clientFactory.create(user.getUsername(), oldCleanPassword).self();
-        assertNotNull(self);
-
-        // 8. Delete SyncTask + user + reset the connector
-        taskService.delete(syncTask.getKey());
-        property.getValues().clear();
-        property.getValues().add(Boolean.FALSE);
-        connectorService.update(resourceConnector);
-        deleteUser(user.getKey());
-    }
-}


[03/21] syncope git commit: Clean up: removing some not necessary methods from persistence-api and adjusting accordingly

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java
index d1d72f7..f790255 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java
@@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "relationshipType")
 @XmlType
-public class RelationshipTypeTO extends AbstractBaseBean {
+public class RelationshipTypeTO extends AbstractBaseBean implements EntityTO<String> {
 
     private static final long serialVersionUID = -1884088415277925817L;
 
@@ -33,11 +33,13 @@ public class RelationshipTypeTO extends AbstractBaseBean {
 
     private String description;
 
+    @Override
     public String getKey() {
         return key;
     }
 
     @Path("{key}")
+    @Override
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
index 73297fc..82f48a4 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
@@ -31,11 +31,11 @@ import org.apache.syncope.common.lib.report.AbstractReportletConf;
 
 @XmlRootElement(name = "report")
 @XmlType
-public class ReportTO extends AbstractStartEndBean {
+public class ReportTO extends AbstractStartEndBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = 5274568072084814410L;
 
-    private long key;
+    private Long key;
 
     private String name;
 
@@ -53,12 +53,14 @@ public class ReportTO extends AbstractStartEndBean {
 
     private boolean active;
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
     @PathParam("key")
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
index a4f56ab..5f75794 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
@@ -38,7 +38,7 @@ import org.apache.syncope.common.lib.types.TraceLevel;
 
 @XmlRootElement(name = "resource")
 @XmlType
-public class ResourceTO extends AbstractAnnotatedBean {
+public class ResourceTO extends AbstractAnnotatedBean implements EntityTO<String> {
 
     private static final long serialVersionUID = -9193551354041698963L;
 
@@ -84,11 +84,13 @@ public class ResourceTO extends AbstractAnnotatedBean {
 
     private final List<String> propagationActionsClassNames = new ArrayList<>();
 
+    @Override
     public String getKey() {
         return key;
     }
 
     @PathParam("key")
+    @Override
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
index 7160fdc..bf59bb5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
@@ -32,7 +32,7 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "role")
 @XmlType
-public class RoleTO extends AbstractBaseBean {
+public class RoleTO extends AbstractBaseBean implements EntityTO<String> {
 
     private static final long serialVersionUID = 4560822655754800031L;
 
@@ -44,11 +44,13 @@ public class RoleTO extends AbstractBaseBean {
 
     private String dynMembershipCond;
 
+    @Override
     public String getKey() {
         return key;
     }
 
     @PathParam("key")
+    @Override
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
index 83a8c55..aa7e2ce 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
@@ -25,20 +25,22 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "securityQuestion")
 @XmlType
-public class SecurityQuestionTO extends AbstractBaseBean {
+public class SecurityQuestionTO extends AbstractBaseBean implements EntityTO<Long> {
 
     private static final long serialVersionUID = 5969810939993556530L;
 
-    private long key;
+    private Long key;
 
     private String content;
 
-    public long getKey() {
+    @Override
+    public Long getKey() {
         return key;
     }
 
     @PathParam("key")
-    public void setKey(final long key) {
+    @Override
+    public void setKey(final Long key) {
         this.key = key;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
index 4ad7959..e754798 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
@@ -38,7 +38,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 @XmlRootElement(name = "user")
 @XmlType
-public class UserTO extends AnyTO {
+public class UserTO extends AnyTO implements RelatableTO, GroupableTO {
 
     private static final long serialVersionUID = 7791304495192615740L;
 
@@ -183,29 +183,31 @@ public class UserTO extends AnyTO {
     @XmlElementWrapper(name = "relationships")
     @XmlElement(name = "relationship")
     @JsonProperty("relationships")
+    @Override
     public List<RelationshipTO> getRelationships() {
         return relationships;
     }
 
     @JsonIgnore
+    @Override
     public Map<Pair<String, Long>, RelationshipTO> getRelationshipMap() {
         Map<Pair<String, Long>, RelationshipTO> result = new HashMap<>(getRelationships().size());
         for (RelationshipTO relationship : getRelationships()) {
             result.put(Pair.of(relationship.getType(), relationship.getRightKey()), relationship);
         }
-        result = Collections.unmodifiableMap(result);
-
-        return result;
+        return Collections.unmodifiableMap(result);
     }
 
     @XmlElementWrapper(name = "memberships")
     @XmlElement(name = "membership")
     @JsonProperty("memberships")
+    @Override
     public List<MembershipTO> getMemberships() {
         return memberships;
     }
 
     @JsonIgnore
+    @Override
     public Map<Long, MembershipTO> getMembershipMap() {
         Map<Long, MembershipTO> result = new HashMap<>(getMemberships().size());
         for (MembershipTO membership : getMemberships()) {
@@ -219,6 +221,7 @@ public class UserTO extends AnyTO {
     @XmlElementWrapper(name = "dynGroups")
     @XmlElement(name = "role")
     @JsonProperty("dynGroups")
+    @Override
     public List<Long> getDynGroups() {
         return dynGroups;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
new file mode 100644
index 0000000..e47efc8
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
@@ -0,0 +1,41 @@
+/*
+ * 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.misc.utils;
+
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public final class EntityUtils {
+
+    public static <KEY, E extends Entity<KEY>> Transformer<E, KEY> keyTransformer() {
+        return new Transformer<E, KEY>() {
+
+            @Override
+            public KEY transform(final E input) {
+                return input.getKey();
+            }
+        };
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private EntityUtils() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
index 432913d..e09e0e2 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
@@ -109,7 +109,7 @@ public class TemplateUtils {
             final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
 
         for (RelationshipTO memb : templateRels) {
-            if (!anyRelMap.containsKey(memb.getRightKey())) {
+            if (!anyRelMap.containsKey(Pair.of(memb.getRightType(), memb.getRightKey()))) {
                 anyRels.add(memb);
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
index d14d3b0..c5d4af7 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
@@ -41,23 +41,17 @@ public interface Any<P extends PlainAttr<?>> extends AnnotatedEntity<Long> {
 
     boolean add(P attr);
 
-    boolean remove(P attr);
-
     P getPlainAttr(String plainSchemaName);
 
     List<? extends P> getPlainAttrs();
 
     boolean add(ExternalResource resource);
 
-    boolean remove(ExternalResource resource);
-
     List<String> getResourceNames();
 
     List<? extends ExternalResource> getResources();
 
     boolean add(AnyTypeClass auxClass);
 
-    boolean remove(AnyTypeClass auxClass);
-
     List<? extends AnyTypeClass> getAuxClasses();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java
index c23897c..0a807fb 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java
@@ -31,7 +31,5 @@ public interface AnyType extends Entity<String> {
 
     boolean add(AnyTypeClass anyTypeClass);
 
-    boolean remove(AnyTypeClass anyTypeClass);
-
     List<? extends AnyTypeClass> getClasses();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
index e1e5411..f6682b5 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
@@ -28,19 +28,13 @@ public interface AnyTypeClass extends Entity<String> {
 
     boolean add(PlainSchema schema);
 
-    boolean remove(PlainSchema schema);
-
     List<? extends PlainSchema> getPlainSchemas();
 
     boolean add(DerSchema schema);
 
-    boolean remove(DerSchema schema);
-
     List<? extends DerSchema> getDerSchemas();
 
     boolean add(VirSchema schema);
 
-    boolean remove(VirSchema schema);
-
     List<? extends VirSchema> getVirSchemas();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
index 2019e8e..43af15b 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
@@ -54,8 +54,6 @@ public interface ConnInstance extends Entity<Long> {
 
     boolean add(ExternalResource resource);
 
-    boolean remove(ExternalResource resource);
-
     List<? extends ExternalResource> getResources();
 
     void setConf(Set<ConnConfProperty> conf);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
index 2ad2425..9062bd9 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
@@ -28,7 +28,5 @@ public interface DynMembership<A extends Any<?>> extends Entity<Long> {
 
     boolean add(A any);
 
-    boolean remove(A any);
-
     List<? extends A> getMembers();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
index bb395fa..dcda3d6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
@@ -50,8 +50,6 @@ public interface Notification extends Entity<Long> {
 
     boolean add(AnyAbout about);
 
-    boolean remove(AnyAbout about);
-
     AnyAbout getAbout(AnyType anyType);
 
     List<? extends AnyAbout> getAbouts();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
index 5107f54..b7bdc0c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
@@ -34,8 +34,6 @@ public interface PlainAttr<A extends Any<?>> extends Entity<Long> {
 
     void add(String value, PlainAttrValue attrValue);
 
-    boolean remove(PlainAttrValue attrValue);
-
     PlainAttrUniqueValue getUniqueValue();
 
     void setUniqueValue(PlainAttrUniqueValue uniqueValue);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
index f973138..71b7a22 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
@@ -47,8 +47,6 @@ public interface Realm extends Entity<Long> {
 
     boolean add(AnyTemplateRealm template);
 
-    boolean remove(AnyTemplateRealm template);
-
     AnyTemplateRealm getTemplate(AnyType anyType);
 
     List<? extends AnyTemplateRealm> getTemplates();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Report.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Report.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Report.java
index 5b31063..48c8f68 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Report.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Report.java
@@ -29,8 +29,6 @@ public interface Report extends Entity<Long> {
 
     boolean add(ReportExec exec);
 
-    boolean remove(ReportExec exec);
-
     List<? extends ReportExec> getExecs();
 
     boolean add(ReportletConf reportletConf);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
index c26c15b..3987e96 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
@@ -30,8 +30,6 @@ public interface Role extends Entity<String> {
 
     boolean add(Realm realm);
 
-    boolean remove(Realm realm);
-
     List<? extends Realm> getRealms();
 
     DynRoleMembership getDynMembership();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
index 666b82c..c40c643 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
@@ -27,8 +27,6 @@ public interface AnyObject extends Any<APlainAttr> {
 
     boolean add(ARelationship relationship);
 
-    boolean remove(ARelationship relationship);
-
     ARelationship getRelationship(RelationshipType relationshipType, Long anyObjectKey);
 
     Collection<? extends ARelationship> getRelationships(Long anyObjectKey);
@@ -39,8 +37,6 @@ public interface AnyObject extends Any<APlainAttr> {
 
     boolean add(AMembership membership);
 
-    boolean remove(AMembership membership);
-
     AMembership getMembership(Long membershipKey);
 
     List<? extends AMembership> getMemberships();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
index f31b21a..64c60d0 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
@@ -29,9 +29,6 @@ public interface Conf extends Any<CPlainAttr> {
     boolean add(CPlainAttr attr);
 
     @Override
-    boolean remove(CPlainAttr attr);
-
-    @Override
     List<? extends CPlainAttr> getPlainAttrs();
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
index 74a32f3..b696eee 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
@@ -43,9 +43,6 @@ public interface Group extends Any<GPlainAttr> {
     boolean add(GPlainAttr attr);
 
     @Override
-    boolean remove(GPlainAttr attr);
-
-    @Override
     GPlainAttr getPlainAttr(String plainSchemaName);
 
     @Override
@@ -57,16 +54,12 @@ public interface Group extends Any<GPlainAttr> {
 
     boolean add(ADynGroupMembership dynGroupMembership);
 
-    boolean remove(ADynGroupMembership dynGroupMembership);
-
     ADynGroupMembership getADynMembership(AnyType anyType);
 
     List<? extends ADynGroupMembership> getADynMemberships();
 
     boolean add(TypeExtension typeExtension);
 
-    boolean remove(TypeExtension typeExtension);
-
     TypeExtension getTypeExtension(AnyType anyType);
 
     List<? extends TypeExtension> getTypeExtensions();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java
index a426146..450112f 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java
@@ -35,7 +35,5 @@ public interface TypeExtension extends Entity<Long> {
 
     boolean add(AnyTypeClass anyTypeClass);
 
-    boolean remove(AnyTypeClass anyTypeClass);
-
     List<? extends AnyTypeClass> getAuxClasses();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java
index 066efdf..6aed282 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java
@@ -42,8 +42,6 @@ public interface AccountPolicy extends Policy {
 
     boolean add(ExternalResource resource);
 
-    boolean remove(ExternalResource resource);
-
     Set<String> getResourceNames();
 
     Set<? extends ExternalResource> getResources();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
index 968b779..32759cd 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
@@ -93,8 +93,6 @@ public interface ExternalResource extends AnnotatedEntity<String> {
 
     boolean add(Provision provision);
 
-    boolean remove(Provision provision);
-
     Provision getProvision(AnyType anyType);
 
     Provision getProvision(ObjectClass objectClass);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
index ea9f165..02ac485 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
@@ -29,8 +29,6 @@ public interface Mapping extends Entity<Long> {
 
     boolean add(MappingItem item);
 
-    boolean remove(MappingItem item);
-
     MappingItem getConnObjectKeyItem();
 
     void setConnObjectKeyItem(MappingItem item);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
index 0052cd5..93e112d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
@@ -25,8 +25,6 @@ public interface PushTask extends ProvisioningTask {
 
     boolean add(PushTaskAnyFilter filter);
 
-    boolean remove(PushTaskAnyFilter filter);
-
     PushTaskAnyFilter getFilter(AnyType anyType);
 
     List<? extends PushTaskAnyFilter> getFilters();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
index ca07988..127b1cf 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
@@ -39,8 +39,6 @@ public interface SyncTask extends ProvisioningTask {
 
     boolean add(AnyTemplateSyncTask template);
 
-    boolean remove(AnyTemplateSyncTask template);
-
     AnyTemplateSyncTask getTemplate(AnyType anyType);
 
     List<? extends AnyTemplateSyncTask> getTemplates();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/Task.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/Task.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/Task.java
index b356356..7d2c9f6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/Task.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/Task.java
@@ -26,9 +26,7 @@ public interface Task extends Entity<Long> {
 
     TaskType getType();
 
-    boolean addExec(TaskExec exec);
-
-    boolean removeExec(TaskExec exec);
+    boolean add(TaskExec exec);
 
     List<? extends TaskExec> getExecs();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
index cbec1c9..d1b94e7 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
@@ -96,9 +96,6 @@ public interface User extends Any<UPlainAttr> {
     boolean add(UPlainAttr attr);
 
     @Override
-    boolean remove(UPlainAttr attr);
-
-    @Override
     UPlainAttr getPlainAttr(String plainSchemaName);
 
     @Override
@@ -106,14 +103,10 @@ public interface User extends Any<UPlainAttr> {
 
     boolean add(Role role);
 
-    boolean remove(Role role);
-
     List<? extends Role> getRoles();
 
     boolean add(URelationship relationship);
 
-    boolean remove(URelationship relationship);
-
     URelationship getRelationship(RelationshipType relationshipType, Long anyObjectKey);
 
     Collection<? extends URelationship> getRelationships(Long anyObjectKey);
@@ -124,8 +117,6 @@ public interface User extends Any<UPlainAttr> {
 
     boolean add(UMembership membership);
 
-    boolean remove(UMembership membership);
-
     UMembership getMembership(Long groupKey);
 
     List<? extends UMembership> getMemberships();

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 659952b..e27c1c9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -33,6 +33,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.misc.EntitlementsHolder;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
@@ -110,7 +111,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     @Override
     public void delete(final AnyObject any) {
         for (Group group : findDynGroupMemberships(any)) {
-            group.getADynMembership(any.getType()).remove(any);
+            group.getADynMembership(any.getType()).getMembers().remove(any);
         }
 
         entityManager().remove(any);
@@ -144,13 +145,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public Collection<Long> findAllGroupKeys(final AnyObject anyObject) {
-        return CollectionUtils.collect(findAllGroups(anyObject), new Transformer<Group, Long>() {
-
-            @Override
-            public Long transform(final Group input) {
-                return input.getKey();
-            }
-        });
+        return CollectionUtils.collect(findAllGroups(anyObject), EntityUtils.<Long, Group>keyTransformer());
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
@@ -168,13 +163,8 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public Collection<String> findAllResourceNames(final AnyObject anyObject) {
-        return CollectionUtils.collect(findAllResources(anyObject), new Transformer<ExternalResource, String>() {
-
-            @Override
-            public String transform(final ExternalResource input) {
-                return input.getKey();
-            }
-        });
+        return CollectionUtils.collect(
+                findAllResources(anyObject), EntityUtils.<String, ExternalResource>keyTransformer());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index 942b950..d414456 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -34,13 +34,13 @@ import javax.validation.ValidationException;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.misc.utils.RealmUtils;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
@@ -101,13 +101,8 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
             if (realm == null) {
                 LOG.warn("Ignoring invalid realm {}", realmPath);
             } else {
-                CollectionUtils.collect(realmDAO.findDescendants(realm), new Transformer<Realm, Long>() {
-
-                    @Override
-                    public Long transform(final Realm descendant) {
-                        return descendant.getKey();
-                    }
-                }, realmKeys);
+                CollectionUtils.collect(
+                        realmDAO.findDescendants(realm), EntityUtils.<Long, Realm>keyTransformer(), realmKeys);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
index 7a32a18..8efb01f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -102,14 +102,14 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
         }
 
         for (AnyType type : anyTypeDAO.findByTypeClass(anyTypeClass)) {
-            type.remove(anyTypeClass);
+            type.getClasses().remove(anyTypeClass);
         }
 
         for (TypeExtension typeExt : groupDAO.findTypeExtensionByAnyTypeClass(anyTypeClass)) {
-            typeExt.remove(anyTypeClass);
+            typeExt.getAuxClasses().remove(anyTypeClass);
 
             if (typeExt.getAuxClasses().isEmpty()) {
-                typeExt.getGroup().remove(typeExt);
+                typeExt.getGroup().getTypeExtensions().remove(typeExt);
                 typeExt.setGroup(null);
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
index 985c7aa..2797847 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
@@ -94,7 +94,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         if (old != null && (!attr.getSchema().isUniqueConstraint()
                 || (!attr.getUniqueValue().getStringValue().equals(old.getUniqueValue().getStringValue())))) {
 
-            instance.remove(old);
+            instance.getPlainAttrs().remove(old);
             attrDAO.delete(old.getKey(), CPlainAttr.class);
         }
 
@@ -109,7 +109,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         Conf instance = get();
         CPlainAttr attr = instance.getPlainAttr(key);
         if (attr != null) {
-            instance.remove(attr);
+            instance.getPlainAttrs().remove(attr);
             instance = entityManager().merge(instance);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
index d09ae25..a0e5479 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -83,7 +83,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
         }
 
         if (schema.getAnyTypeClass() != null) {
-            schema.getAnyTypeClass().remove(schema);
+            schema.getAnyTypeClass().getDerSchemas().remove(schema);
         }
 
         entityManager().remove(schema);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index facea51..b270d8b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -170,7 +170,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
         for (Long itemKey : itemKeys) {
             MappingItem item = entityManager().find(JPAMappingItem.class, itemKey);
             if (item != null) {
-                item.getMapping().remove(item);
+                item.getMapping().getItems().remove(item);
                 item.setMapping(null);
 
                 entityManager().remove(item);
@@ -194,16 +194,16 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
         taskDAO.deleteAll(resource, TaskType.PUSH);
 
         for (AnyObject anyObject : anyObjectDAO.findByResource(resource)) {
-            anyObject.remove(resource);
+            anyObject.getResources().remove(resource);
         }
         for (User user : userDAO.findByResource(resource)) {
-            user.remove(resource);
+            user.getResources().remove(resource);
         }
         for (Group group : groupDAO.findByResource(resource)) {
-            group.remove(resource);
+            group.getResources().remove(resource);
         }
         for (AccountPolicy policy : policyDAO.findByResource(resource)) {
-            policy.remove(resource);
+            policy.getResources().remove(resource);
         }
 
         for (Provision provision : resource.getProvisions()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index 9fae1d5..6c4815c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -202,13 +202,13 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
     @Override
     public void delete(final Group group) {
         for (AMembership membership : findAMemberships(group)) {
-            membership.getLeftEnd().remove(membership);
+            membership.getLeftEnd().getMemberships().remove(membership);
             anyObjectDAO.save(membership.getLeftEnd());
 
             entityManager().remove(membership);
         }
         for (UMembership membership : findUMemberships(group)) {
-            membership.getLeftEnd().remove(membership);
+            membership.getLeftEnd().getMemberships().remove(membership);
             userDAO.save(membership.getLeftEnd());
 
             entityManager().remove(membership);
@@ -282,7 +282,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
                     memb.add(anyObject);
                 } else {
-                    memb.remove(anyObject);
+                    memb.getMembers().remove(anyObject);
                 }
             }
         }
@@ -300,7 +300,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
                     group.getUDynMembership().add(user);
                 } else {
-                    group.getUDynMembership().remove(user);
+                    group.getUDynMembership().getMembers().remove(user);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
index 975b6e9..2afbe15 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
@@ -41,12 +41,12 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements
         return CPlainAttr.class.isAssignableFrom(reference)
                 ? JPACPlainAttr.class
                 : GPlainAttr.class.isAssignableFrom(reference)
-                        ? JPAGPlainAttr.class
-                        : APlainAttr.class.isAssignableFrom(reference)
-                                ? JPAAPlainAttr.class
-                                : UPlainAttr.class.isAssignableFrom(reference)
-                                        ? JPAUPlainAttr.class
-                                        : null;
+                ? JPAGPlainAttr.class
+                : APlainAttr.class.isAssignableFrom(reference)
+                ? JPAAPlainAttr.class
+                : UPlainAttr.class.isAssignableFrom(reference)
+                ? JPAUPlainAttr.class
+                : null;
     }
 
     @Override
@@ -68,7 +68,7 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements
     @SuppressWarnings("unchecked")
     public <T extends PlainAttr<?>> void delete(final T plainAttr) {
         if (plainAttr.getOwner() != null) {
-            ((Any<T>) plainAttr.getOwner()).remove(plainAttr);
+            ((Any<T>) plainAttr.getOwner()).getPlainAttrs().remove(plainAttr);
         }
 
         entityManager().remove(plainAttr);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
index 60f3786..4b414be 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
@@ -52,22 +52,22 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
         return AbstractPlainAttrValue.class.isAssignableFrom(reference)
                 ? (Class<? extends AbstractPlainAttrValue>) reference
                 : reference.equals(CPlainAttrValue.class)
-                        ? JPACPlainAttrValue.class
-                        : reference.equals(CPlainAttrUniqueValue.class)
-                                ? JPACPlainAttrUniqueValue.class
-                                : reference.equals(GPlainAttrValue.class)
-                                        ? JPAGPlainAttrValue.class
-                                        : reference.equals(GPlainAttrUniqueValue.class)
-                                                ? JPAGPlainAttrUniqueValue.class
-                                                : reference.equals(APlainAttrValue.class)
-                                                        ? JPAAPlainAttrValue.class
-                                                        : reference.equals(APlainAttrUniqueValue.class)
-                                                                ? JPAAPlainAttrUniqueValue.class
-                                                                : reference.equals(UPlainAttrValue.class)
-                                                                        ? JPAUPlainAttrValue.class
-                                                                        : reference.equals(UPlainAttrUniqueValue.class)
-                                                                                ? JPAUPlainAttrUniqueValue.class
-                                                                                : null;
+                ? JPACPlainAttrValue.class
+                : reference.equals(CPlainAttrUniqueValue.class)
+                ? JPACPlainAttrUniqueValue.class
+                : reference.equals(GPlainAttrValue.class)
+                ? JPAGPlainAttrValue.class
+                : reference.equals(GPlainAttrUniqueValue.class)
+                ? JPAGPlainAttrUniqueValue.class
+                : reference.equals(APlainAttrValue.class)
+                ? JPAAPlainAttrValue.class
+                : reference.equals(APlainAttrUniqueValue.class)
+                ? JPAAPlainAttrUniqueValue.class
+                : reference.equals(UPlainAttrValue.class)
+                ? JPAUPlainAttrValue.class
+                : reference.equals(UPlainAttrUniqueValue.class)
+                ? JPAUPlainAttrUniqueValue.class
+                : null;
     }
 
     @Override
@@ -103,7 +103,7 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
             if (attrValue instanceof PlainAttrUniqueValue) {
                 attrValue.getAttr().setUniqueValue(null);
             } else {
-                attrValue.getAttr().remove(attrValue);
+                attrValue.getAttr().getValues().remove(attrValue);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
index fe9e573..61b3dbd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -73,11 +73,9 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
     @Override
     public <T extends PlainAttr<?>> List<T> findAttrs(final PlainSchema schema, final Class<T> reference) {
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
-                append(((JPAPlainAttrDAO) plainAttrDAO).getJPAEntityReference(reference).getSimpleName()).
-                append(" e WHERE e.schema=:schema");
-
-        TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
+        TypedQuery<T> query = entityManager().createQuery(
+                "SELECT e FROM " + ((JPAPlainAttrDAO) plainAttrDAO).getJPAEntityReference(reference).getSimpleName()
+                + " e WHERE e.schema=:schema", reference);
         query.setParameter("schema", schema);
 
         return query.getResultList();
@@ -107,7 +105,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
         }
 
         if (schema.getAnyTypeClass() != null) {
-            schema.getAnyTypeClass().remove(schema);
+            schema.getAnyTypeClass().getPlainSchemas().remove(schema);
         }
 
         entityManager().remove(schema);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
index 5eb3951..d662cd0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
@@ -76,13 +76,13 @@ public class JPARelationshipTypeDAO extends AbstractDAO<RelationshipType, String
 
         for (Relationship<?, ?> relationship : findRelationshipsByType(type)) {
             if (relationship instanceof URelationship) {
-                ((URelationship) relationship).getLeftEnd().remove((URelationship) relationship);
+                ((URelationship) relationship).getLeftEnd().getRelationships().remove((URelationship) relationship);
             } else if (relationship instanceof UMembership) {
-                ((UMembership) relationship).getLeftEnd().remove((UMembership) relationship);
+                ((UMembership) relationship).getLeftEnd().getMemberships().remove((UMembership) relationship);
             } else if (relationship instanceof ARelationship) {
-                ((ARelationship) relationship).getLeftEnd().remove((ARelationship) relationship);
+                ((ARelationship) relationship).getLeftEnd().getRelationships().remove((ARelationship) relationship);
             } else if (relationship instanceof AMembership) {
-                ((AMembership) relationship).getLeftEnd().remove((AMembership) relationship);
+                ((AMembership) relationship).getLeftEnd().getMemberships().remove((AMembership) relationship);
             }
 
             relationship.setLeftEnd(null);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
index dc72759..400f8a2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
@@ -117,7 +117,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
     @Override
     public void delete(final ReportExec execution) {
         if (execution.getReport() != null) {
-            execution.getReport().remove(execution);
+            execution.getReport().getExecs().remove(execution);
         }
 
         entityManager().remove(execution);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index ea47cf8..19ee6d1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -82,7 +82,7 @@ public class JPARoleDAO extends AbstractDAO<Role, String> implements RoleDAO {
         query.setParameter("role", role);
 
         for (User user : query.getResultList()) {
-            user.remove(role);
+            user.getRoles().remove(role);
         }
 
         entityManager().remove(role);
@@ -108,7 +108,7 @@ public class JPARoleDAO extends AbstractDAO<Role, String> implements RoleDAO {
 
                     role.getDynMembership().add(user);
                 } else {
-                    role.getDynMembership().remove(user);
+                    role.getDynMembership().getMembers().remove(user);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
index d88a2cb..b44d4c7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
@@ -164,7 +164,7 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
     @Transactional(rollbackFor = { Throwable.class })
     public void saveAndAdd(final Long taskId, final TaskExec execution) {
         Task task = taskDAO.find(taskId);
-        task.addExec(execution);
+        task.add(execution);
         taskDAO.save(task);
     }
 
@@ -181,7 +181,7 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
     @Override
     public void delete(final TaskExec execution) {
         if (execution.getTask() != null) {
-            execution.getTask().removeExec(execution);
+            execution.getTask().getExecs().remove(execution);
         }
 
         entityManager().remove(execution);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index a669e24..0bbe763 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -364,10 +364,10 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     @Override
     public void delete(final User user) {
         for (Role role : findDynRoleMemberships(user)) {
-            role.getDynMembership().remove(user);
+            role.getDynMembership().getMembers().remove(user);
         }
         for (Group group : findDynGroupMemberships(user)) {
-            group.getUDynMembership().remove(user);
+            group.getUDynMembership().getMembers().remove(user);
         }
 
         entityManager().remove(user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
index dd77060..d9f5604 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
@@ -62,11 +62,9 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
 
     @Override
     public List<VirSchema> findByProvision(final Provision provision) {
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
-                append(JPAVirSchema.class.getSimpleName()).
-                append(" e WHERE e.provision=:provision");
-
-        TypedQuery<VirSchema> query = entityManager().createQuery(queryString.toString(), VirSchema.class);
+        TypedQuery<VirSchema> query = entityManager().createQuery(
+                "SELECT e FROM " + JPAVirSchema.class.getSimpleName()
+                + " e WHERE e.provision=:provision", VirSchema.class);
         query.setParameter("provision", provision);
 
         return query.getResultList();
@@ -99,7 +97,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
         }
 
         if (schema.getAnyTypeClass() != null) {
-            schema.getAnyTypeClass().remove(schema);
+            schema.getAnyTypeClass().getVirSchemas().remove(schema);
         }
 
         entityManager().remove(schema);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
index bb2b855..e6ead6f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
@@ -19,25 +19,18 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
-import java.util.Set;
 import javax.persistence.Column;
 import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
-import javax.persistence.Transient;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.core.misc.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.AnyCheck;
@@ -58,15 +51,6 @@ public abstract class AbstractAny<P extends PlainAttr<?>>
     @Column(nullable = true)
     private String status;
 
-    @Transient
-    private Set<PlainSchema> allowedPlainSchemas;
-
-    @Transient
-    private Set<DerSchema> allowedDerSchemas;
-
-    @Transient
-    private Set<VirSchema> allowedVirSchemas;
-
     @Override
     public Realm getRealm() {
         return realm;
@@ -119,32 +103,13 @@ public abstract class AbstractAny<P extends PlainAttr<?>>
     }
 
     @Override
-    public boolean remove(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        return internalGetResources().remove((JPAExternalResource) resource);
-    }
-
-    @Override
     public List<String> getResourceNames() {
-        return CollectionUtils.collect(getResources(), new Transformer<ExternalResource, String>() {
-
-            @Override
-            public String transform(final ExternalResource input) {
-                return input.getKey();
-            }
-        }, new ArrayList<String>());
+        return CollectionUtils.collect(
+                getResources(), EntityUtils.<String, ExternalResource>keyTransformer(), new ArrayList<String>());
     }
 
     @Override
     public List<? extends ExternalResource> getResources() {
         return internalGetResources();
     }
-
-    private void populateAllowedSchemas(final Collection<? extends AnyTypeClass> anyTypeClasses) {
-        for (AnyTypeClass anyTypeClass : anyTypeClasses) {
-            allowedPlainSchemas.addAll(anyTypeClass.getPlainSchemas());
-            allowedDerSchemas.addAll(anyTypeClass.getDerSchemas());
-            allowedVirSchemas.addAll(anyTypeClass.getVirSchemas());
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
index 8f99efc..64cd644 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
@@ -87,12 +87,6 @@ public class JPAAnyType extends AbstractEntity<String> implements AnyType {
     }
 
     @Override
-    public boolean remove(final AnyTypeClass anyTypeClass) {
-        checkType(anyTypeClass, JPAAnyTypeClass.class);
-        return this.classes.remove((JPAAnyTypeClass) anyTypeClass);
-    }
-
-    @Override
     public List<? extends AnyTypeClass> getClasses() {
         return classes;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
index 6a5e03e..b823f49 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
@@ -79,12 +79,6 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     }
 
     @Override
-    public boolean remove(final PlainSchema schema) {
-        checkType(schema, JPAPlainSchema.class);
-        return this.plainSchemas.remove((JPAPlainSchema) schema);
-    }
-
-    @Override
     public List<? extends PlainSchema> getPlainSchemas() {
         return plainSchemas;
     }
@@ -96,12 +90,6 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     }
 
     @Override
-    public boolean remove(final DerSchema schema) {
-        checkType(schema, JPADerSchema.class);
-        return this.derSchemas.remove((JPADerSchema) schema);
-    }
-
-    @Override
     public List<? extends DerSchema> getDerSchemas() {
         return derSchemas;
     }
@@ -113,12 +101,6 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     }
 
     @Override
-    public boolean remove(final VirSchema schema) {
-        checkType(schema, JPAVirSchema.class);
-        return this.virSchemas.remove((JPAVirSchema) schema);
-    }
-
-    @Override
     public List<? extends VirSchema> getVirSchemas() {
         return virSchemas;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index e31aaaa..d59982e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -46,6 +45,7 @@ import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
 import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 
 @Entity
 @Table(name = JPAConnInstance.TABLE)
@@ -211,12 +211,6 @@ public class JPAConnInstance extends AbstractEntity<Long> implements ConnInstanc
     }
 
     @Override
-    public boolean remove(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        return this.resources.remove((JPAExternalResource) resource);
-    }
-
-    @Override
     public Set<ConnectorCapability> getCapabilities() {
         return capabilities;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
index 12555ea..8afba79 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
@@ -20,7 +20,6 @@ package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.ArrayList;
 import java.util.List;
-
 import javax.persistence.Basic;
 import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
@@ -177,12 +176,6 @@ public class JPANotification extends AbstractEntity<Long> implements Notificatio
     }
 
     @Override
-    public boolean remove(final AnyAbout about) {
-        checkType(about, JPAAnyAbout.class);
-        return this.abouts.remove((JPAAnyAbout) about);
-    }
-
-    @Override
     public AnyAbout getAbout(final AnyType anyType) {
         return IterableUtils.find(abouts, new Predicate<AnyAbout>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
index a784c68..5455168 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
@@ -153,12 +153,6 @@ public class JPARealm extends AbstractEntity<Long> implements Realm {
     }
 
     @Override
-    public boolean remove(final AnyTemplateRealm template) {
-        checkType(template, JPAAnyTemplateRealm.class);
-        return this.templates.remove((JPAAnyTemplateRealm) template);
-    }
-
-    @Override
     public AnyTemplateRealm getTemplate(final AnyType anyType) {
         return IterableUtils.find(templates, new Predicate<AnyTemplate>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReport.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReport.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReport.java
index 8cf3d57..835e108 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReport.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReport.java
@@ -89,12 +89,6 @@ public class JPAReport extends AbstractEntity<Long> implements Report {
     }
 
     @Override
-    public boolean remove(final ReportExec exec) {
-        checkType(exec, JPAReportExec.class);
-        return exec != null && executions.remove((JPAReportExec) exec);
-    }
-
-    @Override
     public List<? extends ReportExec> getExecs() {
         return executions;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
index 78d7380..d2c6dc0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
@@ -96,12 +96,6 @@ public class JPARole extends AbstractEntity<String> implements Role {
     }
 
     @Override
-    public boolean remove(final Realm realm) {
-        checkType(realm, JPARealm.class);
-        return realms.remove((JPARealm) realm);
-    }
-
-    @Override
     public List<? extends Realm> getRealms() {
         return realms;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java
index 1d3d69e..b6ad613 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java
@@ -94,12 +94,6 @@ public class JPAADynGroupMembership extends AbstractDynMembership<AnyObject> imp
     }
 
     @Override
-    public boolean remove(final AnyObject anyObject) {
-        checkType(anyObject, JPAAnyObject.class);
-        return anyObjects.remove((JPAAnyObject) anyObject);
-    }
-
-    @Override
     public List<? extends AnyObject> getMembers() {
         return anyObjects;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
index 46c1680..d0abc91 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
@@ -82,12 +82,6 @@ public class JPAAPlainAttr extends AbstractPlainAttr<AnyObject> implements APlai
     }
 
     @Override
-    public boolean remove(final PlainAttrValue attrValue) {
-        checkType(attrValue, JPAAPlainAttrValue.class);
-        return values.remove((JPAAPlainAttrValue) attrValue);
-    }
-
-    @Override
     public List<? extends APlainAttrValue> getValues() {
         return values;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
index 955d168..304956e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
@@ -114,12 +114,6 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject {
     }
 
     @Override
-    public boolean remove(final APlainAttr attr) {
-        checkType(attr, JPAAPlainAttr.class);
-        return plainAttrs.remove((JPAAPlainAttr) attr);
-    }
-
-    @Override
     public List<? extends APlainAttr> getPlainAttrs() {
         return plainAttrs;
     }
@@ -136,12 +130,6 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject {
     }
 
     @Override
-    public boolean remove(final AnyTypeClass auxClass) {
-        checkType(auxClass, JPAAnyTypeClass.class);
-        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
-    }
-
-    @Override
     public List<? extends AnyTypeClass> getAuxClasses() {
         return auxClasses;
     }
@@ -153,12 +141,6 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject {
     }
 
     @Override
-    public boolean remove(final ARelationship relationship) {
-        checkType(relationship, JPAARelationship.class);
-        return this.relationships.remove((JPAARelationship) relationship);
-    }
-
-    @Override
     public ARelationship getRelationship(final RelationshipType relationshipType, final Long anyObjectKey) {
         return IterableUtils.find(getRelationships(), new Predicate<ARelationship>() {
 
@@ -205,12 +187,6 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject {
     }
 
     @Override
-    public boolean remove(final AMembership membership) {
-        checkType(membership, JPAAMembership.class);
-        return this.memberships.remove((JPAAMembership) membership);
-    }
-
-    @Override
     public AMembership getMembership(final Long groupKey) {
         return IterableUtils.find(getMemberships(), new Predicate<AMembership>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
index b6b683b..270fa8b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
@@ -111,12 +111,6 @@ public class JPACPlainAttr extends AbstractPlainAttr<Conf> implements CPlainAttr
     }
 
     @Override
-    public boolean remove(final PlainAttrValue attrValue) {
-        checkType(attrValue, JPACPlainAttrValue.class);
-        return values.remove((JPACPlainAttrValue) attrValue);
-    }
-
-    @Override
     public List<? extends CPlainAttrValue> getValues() {
         return values;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
index 48453ca..7347fbb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
@@ -71,12 +71,6 @@ public class JPAConf extends AbstractAnnotatedEntity<Long> implements Conf {
     }
 
     @Override
-    public boolean remove(final CPlainAttr attr) {
-        checkType(attr, JPACPlainAttr.class);
-        return plainAttrs.remove((JPACPlainAttr) attr);
-    }
-
-    @Override
     public CPlainAttr getPlainAttr(final String plainSchemaName) {
         return IterableUtils.find(plainAttrs, new Predicate<CPlainAttr>() {
 
@@ -99,11 +93,6 @@ public class JPAConf extends AbstractAnnotatedEntity<Long> implements Conf {
     }
 
     @Override
-    public boolean remove(final ExternalResource resource) {
-        return false;
-    }
-
-    @Override
     public List<String> getResourceNames() {
         return Collections.emptyList();
     }
@@ -119,11 +108,6 @@ public class JPAConf extends AbstractAnnotatedEntity<Long> implements Conf {
     }
 
     @Override
-    public boolean remove(final AnyTypeClass auxClass) {
-        return false;
-    }
-
-    @Override
     public List<? extends AnyTypeClass> getAuxClasses() {
         return Collections.emptyList();
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
index daafd08..1090351 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
@@ -82,12 +82,6 @@ public class JPAGPlainAttr extends AbstractPlainAttr<Group> implements GPlainAtt
     }
 
     @Override
-    public boolean remove(final PlainAttrValue attrValue) {
-        checkType(attrValue, JPAGPlainAttrValue.class);
-        return values.remove((JPAGPlainAttrValue) attrValue);
-    }
-
-    @Override
     public List<? extends GPlainAttrValue> getValues() {
         return values;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
index bd3cbce..7444bd3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
@@ -166,12 +166,6 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group {
     }
 
     @Override
-    public boolean remove(final GPlainAttr attr) {
-        checkType(attr, JPAGPlainAttr.class);
-        return plainAttrs.remove((JPAGPlainAttr) attr);
-    }
-
-    @Override
     public List<? extends GPlainAttr> getPlainAttrs() {
         return plainAttrs;
     }
@@ -194,12 +188,6 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group {
     }
 
     @Override
-    public boolean remove(final AnyTypeClass auxClass) {
-        checkType(auxClass, JPAAnyTypeClass.class);
-        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
-    }
-
-    @Override
     public List<? extends AnyTypeClass> getAuxClasses() {
         return auxClasses;
     }
@@ -211,12 +199,6 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group {
     }
 
     @Override
-    public boolean remove(final ADynGroupMembership dynGroupMembership) {
-        checkType(dynGroupMembership, JPAADynGroupMembership.class);
-        return this.aDynMemberships.remove((JPAADynGroupMembership) dynGroupMembership);
-    }
-
-    @Override
     public ADynGroupMembership getADynMembership(final AnyType anyType) {
         return IterableUtils.find(aDynMemberships, new Predicate<ADynGroupMembership>() {
 
@@ -239,12 +221,6 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group {
     }
 
     @Override
-    public boolean remove(final TypeExtension typeExtension) {
-        checkType(typeExtension, JPATypeExtension.class);
-        return this.typeExtensions.remove((JPATypeExtension) typeExtension);
-    }
-
-    @Override
     public TypeExtension getTypeExtension(final AnyType anyType) {
         return IterableUtils.find(typeExtensions, new Predicate<TypeExtension>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6d56c7ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
index 7d244da..9510c23 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
@@ -96,12 +96,6 @@ public class JPATypeExtension extends AbstractEntity<Long> implements TypeExtens
     }
 
     @Override
-    public boolean remove(final AnyTypeClass auxClass) {
-        checkType(auxClass, JPAAnyTypeClass.class);
-        return auxClasses.remove((JPAAnyTypeClass) auxClass);
-    }
-
-    @Override
     public List<? extends AnyTypeClass> getAuxClasses() {
         return auxClasses;
     }


[17/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
new file mode 100644
index 0000000..8e825ea
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
@@ -0,0 +1,231 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.text.ParseException;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import javax.xml.ws.WebServiceException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.rest.api.LoggerWrapper;
+import org.apache.syncope.core.logic.ReportLogic;
+import org.apache.syncope.core.logic.ResourceLogic;
+import org.apache.syncope.core.logic.GroupLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class LoggerITCase extends AbstractITCase {
+
+    @Test
+    public void listLogs() {
+        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertFalse(loggers.isEmpty());
+        for (LoggerTO logger : loggers) {
+            assertNotNull(logger);
+        }
+    }
+
+    @Test
+    public void listAudits() throws ParseException {
+        List<LoggerTO> audits = loggerService.list(LoggerType.AUDIT);
+
+        assertNotNull(audits);
+        assertFalse(audits.isEmpty());
+        for (LoggerTO audit : audits) {
+            assertNotNull(AuditLoggerName.fromLoggerName(audit.getKey()));
+        }
+    }
+
+    @Test
+    public void setLevel() {
+        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        int startSize = loggers.size();
+
+        LoggerTO logger = new LoggerTO();
+        logger.setKey("TEST");
+        logger.setLevel(LoggerLevel.INFO);
+        loggerService.update(LoggerType.LOG, logger);
+        logger = loggerService.read(LoggerType.LOG, logger.getKey());
+        assertNotNull(logger);
+        assertEquals(LoggerLevel.INFO, logger.getLevel());
+
+        loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertEquals(startSize + 1, loggers.size());
+
+        // TEST Delete
+        loggerService.delete(LoggerType.LOG, "TEST");
+        loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertEquals(startSize, loggers.size());
+    }
+
+    @Test
+    public void enableDisableAudit() {
+        AuditLoggerName auditLoggerName = new AuditLoggerName(
+                EventCategoryType.REST,
+                ReportLogic.class.getSimpleName(),
+                null,
+                "deleteExecution",
+                AuditElements.Result.FAILURE);
+
+        List<AuditLoggerName> audits = LoggerWrapper.wrap(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertFalse(audits.contains(auditLoggerName));
+
+        LoggerTO loggerTO = new LoggerTO();
+        loggerTO.setKey(auditLoggerName.toLoggerName());
+        loggerTO.setLevel(LoggerLevel.DEBUG);
+        loggerService.update(LoggerType.AUDIT, loggerTO);
+
+        audits = LoggerWrapper.wrap(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertTrue(audits.contains(auditLoggerName));
+
+        loggerService.delete(LoggerType.AUDIT, auditLoggerName.toLoggerName());
+
+        audits = LoggerWrapper.wrap(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertFalse(audits.contains(auditLoggerName));
+    }
+
+    @Test
+    public void listAuditEvents() {
+        final List<EventCategoryTO> events = loggerService.events();
+
+        boolean found = false;
+
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (UserLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("list"));
+                assertFalse(eventCategoryTO.getEvents().contains("doCreate"));
+                assertFalse(eventCategoryTO.getEvents().contains("setStatusOnWfAdapter"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (GroupLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("list"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (ResourceLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("read"));
+                assertTrue(eventCategoryTO.getEvents().contains("delete"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (AnyTypeKind.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+                if (RESOURCE_NAME_LDAP.equals(eventCategoryTO.getSubcategory())
+                        && EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()) {
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+                    found = true;
+                }
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (AnyTypeKind.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+                if (RESOURCE_NAME_CSV.equals(eventCategoryTO.getSubcategory())
+                        && EventCategoryType.PROPAGATION == eventCategoryTO.getType()) {
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+                    found = true;
+                }
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (EventCategoryType.TASK == eventCategoryTO.getType()
+                    && "TestSampleJobDelegate".equals(eventCategoryTO.getCategory())) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (EventCategoryType.TASK == eventCategoryTO.getType()
+                    && "SyncJobDelegate".equals(eventCategoryTO.getCategory())) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+    }
+
+    @Test
+    public void issueSYNCOPE708() {
+        try {
+            loggerService.read(LoggerType.LOG, "notExists");
+            fail("Reading non-existing logger, it should go in exception");
+        } catch (final WebServiceException ex) {
+            fail("Exception is WebServiceException but it should be SyncopeClientException");
+        } catch (final SyncopeClientException ex) {
+            assertEquals(Response.Status.NOT_FOUND, ex.getType().getResponseStatus());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
new file mode 100644
index 0000000..c70029a
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
@@ -0,0 +1,223 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.List;
+import java.util.Locale;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.SyncMode;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.beans.SchemaQuery;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.DomainService;
+import org.apache.syncope.common.rest.api.service.LoggerService;
+import org.apache.syncope.common.rest.api.service.RealmService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class MultitenancyITCase extends AbstractITCase {
+
+    @BeforeClass
+    public static void restSetup() {
+        clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("Two");
+
+        String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
+        if (StringUtils.isNotBlank(envContentType)) {
+            clientFactory.setContentType(envContentType);
+        }
+        LOG.info("Performing IT with content type {}", clientFactory.getContentType().getMediaType());
+
+        adminClient = clientFactory.create(ADMIN_UNAME, "password2");
+    }
+
+    @Test
+    public void masterOnly() {
+        try {
+            adminClient.getService(DomainService.class).read("Two");
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        try {
+            adminClient.getService(LoggerService.class).list(LoggerType.LOG);
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        adminClient.getService(LoggerService.class).list(LoggerType.AUDIT);
+    }
+
+    @Test
+    public void readPlainSchemas() {
+        assertEquals(17, adminClient.getService(SchemaService.class).
+                list(new SchemaQuery.Builder().type(SchemaType.PLAIN).build()).size());
+    }
+
+    @Test
+    public void readRealm() {
+        List<RealmTO> realms = adminClient.getService(RealmService.class).list();
+        assertEquals(1, realms.size());
+        assertEquals(SyncopeConstants.ROOT_REALM, realms.get(0).getName());
+    }
+
+    @Test
+    public void createUser() {
+        assertNull(adminClient.getService(RealmService.class).list().get(0).getPasswordPolicy());
+
+        UserTO user = new UserTO();
+        user.setRealm(SyncopeConstants.ROOT_REALM);
+        user.setUsername(getUUIDString());
+        user.setPassword("password");
+
+        Response response = adminClient.getService(UserService.class).create(user);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+
+        user = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(user);
+    }
+
+    @Test
+    public void createResourceAndSync() {
+        // read connector
+        ConnInstanceTO conn = adminClient.getService(ConnectorService.class).read(100L, Locale.ENGLISH.getLanguage());
+        assertNotNull(conn);
+        assertEquals("LDAP", conn.getDisplayName());
+
+        // prepare resource
+        ResourceTO resource = new ResourceTO();
+        resource.setKey("new-ldap-resource");
+        resource.setConnector(conn.getKey());
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resource.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        mapping.setConnObjectLink("'uid=' + username + ',ou=people,o=isp'");
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntAttrName("username");
+        item.setIntMappingType(IntMappingType.Username);
+        item.setExtAttrName("cn");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setPassword(true);
+        item.setIntMappingType(IntMappingType.Password);
+        item.setExtAttrName("userPassword");
+        item.setPurpose(MappingPurpose.BOTH);
+        item.setMandatoryCondition("true");
+        mapping.add(item);
+
+        item = new MappingItemTO();
+        item.setIntMappingType(IntMappingType.UserKey);
+        item.setPurpose(MappingPurpose.BOTH);
+        item.setExtAttrName("sn");
+        item.setMandatoryCondition("true");
+        mapping.add(item);
+
+        item = new MappingItemTO();
+        item.setIntAttrName("email");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        item.setExtAttrName("mail");
+        mapping.add(item);
+
+        // create resource
+        Response response = adminClient.getService(ResourceService.class).create(resource);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+        resource = adminClient.getService(ResourceService.class).read(resource.getKey());
+        assertNotNull(resource);
+
+        // create sync task
+        SyncTaskTO task = new SyncTaskTO();
+        task.setName("LDAP Sync Task");
+        task.setActive(true);
+        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        task.setResource(resource.getKey());
+        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
+        task.setPerformCreate(true);
+
+        response = adminClient.getService(TaskService.class).create(task);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+        task = adminClient.getService(TaskService.class).read(
+                Long.valueOf(StringUtils.substringAfterLast(response.getLocation().toASCIIString(), "/")), true);
+        assertNotNull(resource);
+
+        // synchronize
+        TaskExecTO execution = AbstractTaskITCase.execProvisioningTask(
+                adminClient.getService(TaskService.class), task.getKey(), 50, false);
+
+        // verify execution status
+        String status = execution.getStatus();
+        assertNotNull(status);
+        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(status));
+
+        // verify that synchronized user is found
+        PagedResult<UserTO> matchingUsers = adminClient.getService(UserService.class).search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationITCase.java
new file mode 100644
index 0000000..b1c125d
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationITCase.java
@@ -0,0 +1,175 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class NotificationITCase extends AbstractITCase {
+
+    private NotificationTO buildNotificationTO() {
+        NotificationTO notificationTO = new NotificationTO();
+        notificationTO.setTraceLevel(TraceLevel.SUMMARY);
+        notificationTO.getEvents().add("create");
+
+        notificationTO.getAbouts().put(AnyTypeKind.USER.name(),
+                SyncopeClient.getUserSearchConditionBuilder().
+                is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
+
+        notificationTO.setRecipientAttrName("email");
+        notificationTO.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+        notificationTO.setSender("syncope@syncope.apache.org");
+        notificationTO.setSubject("Test notification");
+        notificationTO.setTemplate("test");
+        return notificationTO;
+    }
+
+    @Test
+    public void read() {
+        NotificationTO notificationTO = notificationService.read(10L);
+        assertNotNull(notificationTO);
+    }
+
+    @Test
+    public void list() {
+        List<NotificationTO> notificationTOs = notificationService.list();
+        assertNotNull(notificationTOs);
+        assertFalse(notificationTOs.isEmpty());
+        for (NotificationTO instance : notificationTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void create() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
+
+        Response response = notificationService.create(notificationTO);
+        NotificationTO actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void update() {
+        NotificationTO notificationTO = notificationService.read(10L);
+        notificationTO.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
+
+        notificationService.update(notificationTO);
+        NotificationTO actual = notificationService.read(notificationTO.getKey());
+        assertNotNull(actual);
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void delete() {
+        NotificationTO notification = buildNotificationTO();
+        notification.setSelfAsRecipient(true);
+        Response response = notificationService.create(notification);
+        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+
+        notificationService.delete(notification.getKey());
+
+        try {
+            notificationService.read(notification.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE83() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.setSelfAsRecipient(true);
+
+        NotificationTO actual = null;
+        try {
+            Response response = notificationService.create(notificationTO);
+            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void issueSYNCOPE445() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.getStaticRecipients().add("syncope445@syncope.apache.org");
+
+        NotificationTO actual = null;
+        try {
+            Response response = notificationService.create(notificationTO);
+            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+
+    @Test
+    public void issueSYNCOPE446() {
+        NotificationTO notificationTO = buildNotificationTO();
+        notificationTO.getStaticRecipients().add("syncope446@syncope.apache.org");
+        notificationTO.getAbouts().put(AnyTypeKind.GROUP.name(),
+                SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("citizen").query());
+
+        NotificationTO actual = null;
+        try {
+            Response response = notificationService.create(notificationTO);
+            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        notificationTO.setKey(actual.getKey());
+        assertEquals(actual, notificationTO);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
new file mode 100644
index 0000000..605663f
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
@@ -0,0 +1,399 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.icegreen.greenmail.util.GreenMail;
+import com.icegreen.greenmail.util.ServerSetup;
+import java.io.InputStream;
+import java.util.Properties;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.core.logic.notification.NotificationJob;
+import org.apache.syncope.fit.core.reference.TestNotificationRecipientsProvider;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class NotificationTaskITCase extends AbstractTaskITCase {
+
+    private static final String MAIL_ADDRESS = "notificationtest@syncope.apache.org";
+
+    private static final String POP3_HOST = "localhost";
+
+    private static final int POP3_PORT = 1110;
+
+    private static String SMTP_HOST;
+
+    private static int SMTP_PORT;
+
+    private static GreenMail greenMail;
+
+    @BeforeClass
+    public static void startGreenMail() {
+        Properties props = new Properties();
+        InputStream propStream = null;
+        try {
+            propStream = ExceptionMapperITCase.class.getResourceAsStream("/mail.properties");
+            props.load(propStream);
+        } catch (Exception e) {
+            LOG.error("Could not load /mail.properties", e);
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+
+        SMTP_HOST = props.getProperty("smtpHost");
+        assertNotNull(SMTP_HOST);
+        SMTP_PORT = Integer.parseInt(props.getProperty("smtpPort"));
+        assertNotNull(SMTP_PORT);
+
+        ServerSetup[] config = new ServerSetup[2];
+        config[0] = new ServerSetup(SMTP_PORT, SMTP_HOST, ServerSetup.PROTOCOL_SMTP);
+        config[1] = new ServerSetup(POP3_PORT, POP3_HOST, ServerSetup.PROTOCOL_POP3);
+        greenMail = new GreenMail(config);
+        greenMail.start();
+    }
+
+    @AfterClass
+    public static void stopGreenMail() {
+        if (greenMail != null) {
+            greenMail.stop();
+        }
+    }
+
+    private boolean verifyMail(final String sender, final String subject, final String mailAddress) throws Exception {
+        LOG.info("Waiting for notification to be sent...");
+        greenMail.waitForIncomingEmail(1);
+
+        boolean found = false;
+        Session session = Session.getDefaultInstance(System.getProperties());
+        session.setDebug(true);
+        Store store = session.getStore("pop3");
+        store.connect(POP3_HOST, POP3_PORT, mailAddress, mailAddress);
+
+        Folder inbox = store.getFolder("INBOX");
+        assertNotNull(inbox);
+        inbox.open(Folder.READ_WRITE);
+
+        Message[] messages = inbox.getMessages();
+        for (Message message : messages) {
+            if (sender.equals(message.getFrom()[0].toString()) && subject.equals(message.getSubject())) {
+                found = true;
+                message.setFlag(Flags.Flag.DELETED, true);
+            }
+        }
+
+        inbox.close(true);
+        store.close();
+        return found;
+    }
+
+    @Test
+    public void notifyByMail() throws Exception {
+        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
+        String subject = "Test notification " + getUUIDString();
+        String recipient = createNotificationTask(true, true, TraceLevel.ALL, sender, subject);
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        execNotificationTask(taskService, taskTO.getKey(), 50);
+
+        assertTrue(verifyMail(sender, subject, recipient));
+
+        // verify message body
+        taskTO = taskService.read(taskTO.getKey(), true);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.isExecuted());
+        assertNotNull(taskTO.getTextBody());
+        assertTrue("Notification mail text doesn't contain expected content.",
+                taskTO.getTextBody().contains("Your email address is " + recipient + "."));
+        assertTrue("Notification mail text doesn't contain expected content.",
+                taskTO.getTextBody().contains("Your email address inside a link: "
+                        + "http://localhost/?email=" + recipient.replaceAll("@", "%40") + " ."));
+    }
+
+    @Test
+    public void notifyByMailEmptyAbout() throws Exception {
+        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
+        String subject = "Test notification " + getUUIDString();
+        String recipient = createNotificationTask(true, false, TraceLevel.ALL, sender, subject);
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        execNotificationTask(taskService, taskTO.getKey(), 50);
+
+        assertTrue(verifyMail(sender, subject, recipient));
+    }
+
+    @Test
+    public void notifyByMailWithRetry() throws Exception {
+        // 1. Set higher number of retries
+        AttrTO origMaxRetries = configurationService.get("notification.maxRetries");
+
+        configurationService.set(attrTO(origMaxRetries.getSchema(), "10"));
+
+        // 2. Stop mail server to force errors while sending out e-mails
+        stopGreenMail();
+
+        try {
+            // 3. create notification and user
+            String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
+            String subject = "Test notification " + getUUIDString();
+            createNotificationTask(true, true, TraceLevel.ALL, sender, subject);
+            NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+            assertNotNull(taskTO);
+            assertTrue(taskTO.getExecutions().isEmpty());
+
+            // 4. verify notification could not be delivered
+            execTask(taskService, taskTO.getKey(), NotificationJob.Status.NOT_SENT.name(), 5, false);
+
+            taskTO = taskService.read(taskTO.getKey(), true);
+            assertNotNull(taskTO);
+            assertFalse(taskTO.isExecuted());
+            assertFalse(taskTO.getExecutions().isEmpty());
+            for (TaskExecTO exec : taskTO.getExecutions()) {
+                assertEquals(NotificationJob.Status.NOT_SENT.name(), exec.getStatus());
+            }
+        } finally {
+            // start mail server again
+            startGreenMail();
+            // reset number of retries
+            configurationService.set(origMaxRetries);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE81() {
+        String sender = "syncope81@syncope.apache.org";
+        createNotificationTask(true, true, TraceLevel.ALL, sender, "Test notification");
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        // generate an execution in order to verify the deletion of a notification task with one or more executions
+        execNotificationTask(taskService, taskTO.getKey(), 50);
+
+        taskTO = taskService.read(taskTO.getKey(), true);
+        assertTrue(taskTO.isExecuted());
+        assertFalse(taskTO.getExecutions().isEmpty());
+
+        taskService.delete(taskTO.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE86() {
+        // 1. create notification task
+        String sender = "syncope86@syncope.apache.org";
+        createNotificationTask(true, true, TraceLevel.ALL, sender, "Test notification");
+
+        // 2. get NotificationTaskTO for user just created
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        try {
+            // 3. execute the generated NotificationTask
+            execNotificationTask(taskService, taskTO.getKey(), 50);
+
+            // 4. verify
+            taskTO = taskService.read(taskTO.getKey(), true);
+            assertNotNull(taskTO);
+            assertTrue(taskTO.isExecuted());
+            assertEquals(1, taskTO.getExecutions().size());
+        } finally {
+            // Remove execution to make test re-runnable
+            taskService.deleteExecution(taskTO.getExecutions().get(0).getKey());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE192() throws Exception {
+        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
+        String subject = "Test notification " + getUUIDString();
+        String recipient = createNotificationTask(true, true, TraceLevel.NONE, sender, subject);
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        taskService.execute(new ExecuteQuery.Builder().key(taskTO.getKey()).build());
+
+        try {
+            Thread.sleep(5);
+        } catch (InterruptedException e) {
+        }
+
+        assertTrue(verifyMail(sender, subject, recipient));
+
+        // verify that last exec status was updated
+        taskTO = taskService.read(taskTO.getKey(), true);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.isExecuted());
+        assertTrue(taskTO.getExecutions().isEmpty());
+        assertTrue(StringUtils.isNotBlank(taskTO.getLatestExecStatus()));
+    }
+
+    @Test
+    public void issueSYNCOPE445() throws Exception {
+        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
+        String subject = "Test notification " + getUUIDString();
+        String recipient = createNotificationTask(
+                true, true, TraceLevel.ALL, sender, subject, "syncope445@syncope.apache.org");
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getExecutions().isEmpty());
+
+        execNotificationTask(taskService, taskTO.getKey(), 50);
+
+        assertTrue(verifyMail(sender, subject, recipient));
+
+        // verify task
+        taskTO = taskService.read(taskTO.getKey(), true);
+        assertTrue(taskTO.isExecuted());
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getRecipients().contains("syncope445@syncope.apache.org"));
+    }
+
+    @Test
+    public void issueSYNCOPE446() throws Exception {
+        // 1. Create notification
+        NotificationTO notification = new NotificationTO();
+        notification.setTraceLevel(TraceLevel.ALL);
+        notification.getEvents().add("[REST]:[GroupLogic]:[]:[create]:[SUCCESS]");
+
+        String groupName = "group" + getUUIDString();
+        notification.getAbouts().put(AnyTypeKind.GROUP.name(),
+                SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo(groupName).query());
+
+        notification.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(8L).query());
+        notification.setSelfAsRecipient(false);
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+        notification.getStaticRecipients().add(MAIL_ADDRESS);
+        notification.setRecipientsProviderClassName(TestNotificationRecipientsProvider.class.getName());
+
+        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
+        notification.setSender(sender);
+        String subject = "Test notification " + getUUIDString();
+        notification.setSubject(subject);
+        notification.setTemplate("optin");
+        notification.setActive(true);
+
+        Response response = notificationService.create(notification);
+        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        assertNotNull(notification);
+        assertEquals(TestNotificationRecipientsProvider.class.getName(), notification.getRecipientsProviderClassName());
+
+        // 2. create group
+        GroupTO groupTO = new GroupTO();
+        groupTO.setName(groupName);
+        groupTO.setRealm("/even/two");
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+
+        // 3. verify
+        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+        assertNotNull(taskTO);
+        assertTrue(taskTO.getRecipients().containsAll(
+                new TestNotificationRecipientsProvider().provideRecipients(null)));
+
+        execNotificationTask(taskService, taskTO.getKey(), 50);
+
+        assertTrue(verifyMail(sender, subject, MAIL_ADDRESS));
+    }
+
+    @Test
+    public void issueSYNCOPE492() throws Exception {
+        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
+        String subject = "Test notification " + getUUIDString();
+        createNotificationTask(false, true, TraceLevel.NONE, sender, subject, "syncope445@syncope.apache.org");
+
+        // verify that no task was created for disabled notification
+        assertNull(findNotificationTaskBySender(sender));
+    }
+
+    private String createNotificationTask(final boolean active, final boolean includeAbout, final TraceLevel traceLevel,
+            final String sender, final String subject, final String... staticRecipients) {
+
+        // 1. Create notification
+        NotificationTO notification = new NotificationTO();
+        notification.setTraceLevel(traceLevel);
+        notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
+
+        if (includeAbout) {
+            notification.getAbouts().put(AnyTypeKind.USER.name(),
+                    SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
+        }
+
+        notification.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(8L).query());
+        notification.setSelfAsRecipient(true);
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+        if (staticRecipients != null) {
+            CollectionUtils.addAll(notification.getStaticRecipients(), staticRecipients);
+        }
+
+        notification.setSender(sender);
+        notification.setSubject(subject);
+        notification.setTemplate("optin");
+        notification.setActive(active);
+
+        Response response = notificationService.create(notification);
+        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+        assertNotNull(notification);
+
+        // 2. create user
+        UserTO userTO = UserITCase.getUniqueSampleTO(MAIL_ADDRESS);
+        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        return userTO.getUsername();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java
new file mode 100644
index 0000000..973b09e
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java
@@ -0,0 +1,336 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.beans.SchemaQuery;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PlainSchemaITCase extends AbstractITCase {
+
+    private PlainSchemaTO buildPlainSchemaTO(final String name, final AttrSchemaType type) {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey(name + getUUIDString());
+        schemaTO.setType(type);
+        return schemaTO;
+    }
+
+    @Test
+    public void create() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("testAttribute", AttrSchemaType.String);
+        schemaTO.setMandatoryCondition("false");
+
+        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
+        assertEquals(schemaTO, newPlainSchemaTO);
+
+        try {
+            createSchema(SchemaType.PLAIN, schemaTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+    }
+
+    @Test
+    public void createWithNotPermittedName() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("failedLogins");
+        schemaTO.setType(AttrSchemaType.String);
+
+        try {
+            createSchema(SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+
+    @Test
+    public void createREnumWithoutEnumeration() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("enumcheck");
+        schemaTO.setType(AttrSchemaType.Enum);
+
+        try {
+            createSchema(SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidSchemaEnum.name()));
+        }
+    }
+
+    @Test
+    public void createUEnumWithoutEnumeration() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("enumcheck");
+        schemaTO.setType(AttrSchemaType.Enum);
+
+        try {
+            createSchema(SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidSchemaEnum.name()));
+        }
+    }
+
+    @Test
+    public void createEncrypted() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("encrypted");
+        schemaTO.setType(AttrSchemaType.Encrypted);
+        schemaTO.setCipherAlgorithm(CipherAlgorithm.AES);
+        schemaTO.setSecretKey("huhadfhsjfsfsdkj!####");
+
+        createSchema(SchemaType.PLAIN, schemaTO);
+    }
+
+    @Test
+    public void createBinary() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("x509certificate");
+        schemaTO.setType(AttrSchemaType.Binary);
+        schemaTO.setMimeType("application/x-x509-ca-cert");
+
+        createSchema(SchemaType.PLAIN, schemaTO);
+    }
+
+    @Test
+    public void delete() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("todelete", AttrSchemaType.String);
+        schemaTO.setMandatoryCondition("false");
+        createSchema(SchemaType.PLAIN, schemaTO);
+
+        schemaService.delete(SchemaType.PLAIN, schemaTO.getKey());
+        PlainSchemaTO firstname = null;
+        try {
+            firstname = schemaService.read(SchemaType.PLAIN, schemaTO.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+        assertNull(firstname);
+    }
+
+    @Test
+    public void list() {
+        List<PlainSchemaTO> schemas = schemaService.list(new SchemaQuery.Builder().type(SchemaType.PLAIN).build());
+        assertFalse(schemas.isEmpty());
+        for (PlainSchemaTO schemaTO : schemas) {
+            assertNotNull(schemaTO);
+        }
+    }
+
+    @Test
+    public void listByAnyTypeClass() {
+        final String clazz = anyTypeService.read(AnyTypeKind.USER.name()).getClasses().get(0);
+
+        List<PlainSchemaTO> userSchemas = schemaService.list(
+                new SchemaQuery.Builder().type(SchemaType.PLAIN).anyTypeClass(clazz).build());
+
+        assertTrue(IterableUtils.matchesAny(userSchemas, new Predicate<PlainSchemaTO>() {
+
+            @Override
+            public boolean evaluate(final PlainSchemaTO object) {
+                return "fullname".equals(object.getKey());
+            }
+        }));
+
+        assertFalse(IterableUtils.matchesAny(userSchemas, new Predicate<PlainSchemaTO>() {
+
+            @Override
+            public boolean evaluate(final PlainSchemaTO object) {
+                return "password.cipher.algorithm".equals(object.getKey())
+                        || "rderived_dx".equals(object.getKey())
+                        || "icon".equals(object.getKey())
+                        || "mderived_sx".equals(object.getKey())
+                        || "self.membership.layout".equals(object.getKey());
+            }
+        }));
+    }
+
+    @Test
+    public void update() {
+        PlainSchemaTO schemaTO = schemaService.read(SchemaType.PLAIN, "icon");
+        assertNotNull(schemaTO);
+
+        schemaService.update(SchemaType.PLAIN, schemaTO);
+        PlainSchemaTO updatedTO = schemaService.read(SchemaType.PLAIN, "icon");
+        assertEquals(schemaTO, updatedTO);
+
+        updatedTO.setType(AttrSchemaType.Date);
+        try {
+            schemaService.update(SchemaType.PLAIN, updatedTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+        }
+    }
+
+    @Test
+    public void issue258() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("schema_issue258");
+        schemaTO.setType(AttrSchemaType.Double);
+
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("issue258");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("issue258@syncope.apache.org");
+        userTO.getAuxClasses().add(typeClass.getKey());
+        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        schemaTO.setType(AttrSchemaType.Long);
+        try {
+            schemaService.update(SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+        }
+    }
+
+    @Test
+    public void issue259() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue259", AttrSchemaType.Double);
+        schemaTO.setUniqueConstraint(true);
+
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("issue259");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("issue259@syncope.apache.org");
+        userTO.getAuxClasses().add(typeClass.getKey());
+        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1"));
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        UserTO newUserTO = SerializationUtils.clone(userTO);
+        newUserTO.getMemberships().add(new MembershipTO.Builder().group(2L).build());
+
+        userTO = userService.update(newUserTO).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+    }
+
+    @Test
+    public void issue260() {
+        PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue260", AttrSchemaType.Double);
+        schemaTO.setUniqueConstraint(true);
+
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("issue260");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("issue260@syncope.apache.org");
+        userTO.getAuxClasses().add(typeClass.getKey());
+        userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        schemaTO.setUniqueConstraint(false);
+        try {
+            schemaService.update(SchemaType.PLAIN, schemaTO);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        PlainSchemaTO actual = schemaService.read(SchemaType.PLAIN, "icon");
+        assertNotNull(actual);
+
+        try {
+            createSchema(SchemaType.PLAIN, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createSchema(SchemaType.PLAIN, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        PlainSchemaTO schema = buildPlainSchemaTO("http://schemas.examples.org/security/authorization/organizationUnit",
+                AttrSchemaType.Double);
+
+        try {
+            createSchema(SchemaType.PLAIN, schema);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
new file mode 100644
index 0000000..1930579
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
@@ -0,0 +1,195 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.policy.AccountPolicyTO;
+import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
+import org.apache.syncope.common.lib.policy.SyncPolicyTO;
+import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.policy.SyncPolicySpec;
+import org.apache.syncope.fit.AbstractITCase;
+import org.apache.syncope.fit.core.reference.TestSyncRule;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PolicyITCase extends AbstractITCase {
+
+    private SyncPolicyTO buildSyncPolicyTO() {
+        SyncPolicyTO policy = new SyncPolicyTO();
+
+        SyncPolicySpec spec = new SyncPolicySpec();
+        spec.getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
+
+        policy.setSpecification(spec);
+        policy.setDescription("Sync policy");
+
+        return policy;
+    }
+
+    @Test
+    public void listByType() {
+        List<SyncPolicyTO> policyTOs = policyService.list(PolicyType.SYNC);
+
+        assertNotNull(policyTOs);
+        assertFalse(policyTOs.isEmpty());
+    }
+
+    @Test
+    public void getAccountPolicy() {
+        AccountPolicyTO policyTO = policyService.read(6L);
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByResources().isEmpty());
+        assertTrue(policyTO.getUsedByRealms().contains("/odd"));
+    }
+
+    @Test
+    public void getPasswordPolicy() {
+        PasswordPolicyTO policyTO = policyService.read(4L);
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
+        assertTrue(policyTO.getUsedByRealms().containsAll(Arrays.asList("/", "/odd", "/even")));
+    }
+
+    @Test
+    public void getSyncPolicy() {
+        SyncPolicyTO policyTO = policyService.read(1L);
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByRealms().isEmpty());
+    }
+
+    @Test
+    public void createMissingDescription() {
+        SyncPolicyTO policy = new SyncPolicyTO();
+        policy.setSpecification(new SyncPolicySpec());
+
+        try {
+            createPolicy(policy);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
+        }
+    }
+
+    @Test
+    public void create() {
+        SyncPolicyTO policy = buildSyncPolicyTO();
+
+        SyncPolicyTO policyTO = createPolicy(policy);
+
+        assertNotNull(policyTO);
+        assertEquals(PolicyType.SYNC, policyTO.getType());
+        assertEquals(TestSyncRule.class.getName(),
+                policyTO.getSpecification().getCorrelationRules().get(AnyTypeKind.USER.name()));
+    }
+
+    @Test
+    public void update() {
+        PasswordPolicyTO globalPolicy = policyService.read(2L);
+
+        PasswordPolicyTO policy = SerializationUtils.clone(globalPolicy);
+        policy.setDescription("A simple password policy");
+
+        // create a new password policy using the former as a template
+        policy = createPolicy(policy);
+        assertNotNull(policy);
+        assertNotEquals(2L, policy.getKey());
+
+        ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).setMaxLength(22);
+
+        // update new password policy
+        policyService.update(policy);
+        policy = policyService.read(policy.getKey());
+
+        assertNotNull(policy);
+        assertEquals(PolicyType.PASSWORD, policy.getType());
+        assertEquals(22, ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).getMaxLength());
+        assertEquals(8, ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).getMinLength());
+    }
+
+    @Test
+    public void delete() {
+        SyncPolicyTO policy = buildSyncPolicyTO();
+
+        SyncPolicyTO policyTO = createPolicy(policy);
+        assertNotNull(policyTO);
+
+        policyService.delete(policyTO.getKey());
+
+        try {
+            policyService.read(policyTO.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void getCorrelationRules() {
+        assertEquals(2, syncopeService.info().getSyncCorrelationRules().size());
+    }
+
+    @Test
+    public void issueSYNCOPE553() {
+        AccountPolicyTO policy = new AccountPolicyTO();
+        policy.setDescription("SYNCOPE553");
+
+        DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
+        ruleConf.setMinLength(3);
+        ruleConf.setMaxLength(8);
+        policy.getRuleConfs().add(ruleConf);
+
+        policy = createPolicy(policy);
+        assertNotNull(policy);
+    }
+
+    @Test
+    public void issueSYNCOPE682() {
+        AccountPolicyTO policy = new AccountPolicyTO();
+        policy.setDescription("SYNCOPE682");
+        policy.getResources().add(RESOURCE_NAME_LDAP);
+
+        DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
+        ruleConf.setMinLength(3);
+        ruleConf.setMaxLength(8);
+        policy.getRuleConfs().add(ruleConf);
+
+        policy = createPolicy(policy);
+        assertNotNull(policy);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
new file mode 100644
index 0000000..9686e20
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
@@ -0,0 +1,150 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
+import org.apache.syncope.common.rest.api.beans.TaskExecQuery;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PropagationTaskITCase extends AbstractTaskITCase {
+
+    @Test
+    public void paginatedList() {
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(2).build());
+        assertNotNull(tasks);
+        assertEquals(2, tasks.getResult().size());
+
+        for (AbstractTaskTO task : tasks.getResult()) {
+            assertNotNull(task);
+        }
+
+        tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(2).size(2).build());
+        assertNotNull(tasks);
+        assertEquals(2, tasks.getPage());
+        assertEquals(2, tasks.getResult().size());
+
+        for (AbstractTaskTO task : tasks.getResult()) {
+            assertNotNull(task);
+        }
+
+        tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1000).size(2).build());
+        assertNotNull(tasks);
+        assertTrue(tasks.getResult().isEmpty());
+    }
+
+    @Test
+    public void read() {
+        final PropagationTaskTO taskTO = taskService.read(3L, true);
+        assertNotNull(taskTO);
+        assertNotNull(taskTO.getExecutions());
+        assertTrue(taskTO.getExecutions().isEmpty());
+    }
+
+    @Test
+    public void bulkAction() {
+        PagedResult<PropagationTaskTO> before = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).build());
+
+        // create user with testdb resource
+        UserTO userTO = UserITCase.getUniqueSampleTO("taskBulk@apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+        createUser(userTO);
+
+        List<PropagationTaskTO> after = new ArrayList<>(
+                taskService.<PropagationTaskTO>list(new TaskQuery.Builder().type(TaskType.PROPAGATION).build()).
+                getResult());
+        after.removeAll(before.getResult());
+        assertFalse(after.isEmpty());
+
+        BulkAction bulkAction = new BulkAction();
+        bulkAction.setType(BulkAction.Type.DELETE);
+
+        for (PropagationTaskTO taskTO : after) {
+            bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));
+        }
+
+        taskService.bulk(bulkAction);
+
+        assertFalse(taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).build()).getResult().
+                containsAll(after));
+    }
+
+    @Test
+    public void issueSYNCOPE741() {
+        for (int i = 0; i < 3; i++) {
+            taskService.execute(new ExecuteQuery.Builder().key(1L).build());
+            taskService.execute(new ExecuteQuery.Builder().key(2L).build());
+        }
+        try {
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+
+        // check list
+        PagedResult<AbstractTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(2).details(false).build());
+        for (AbstractTaskTO item : tasks.getResult()) {
+            assertTrue(item.getExecutions().isEmpty());
+        }
+
+        tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(2).details(true).build());
+        for (AbstractTaskTO item : tasks.getResult()) {
+            assertFalse(item.getExecutions().isEmpty());
+        }
+
+        // check read
+        PropagationTaskTO task = taskService.read(1L, false);
+        assertNotNull(task);
+        assertEquals(1L, task.getKey(), 0);
+        assertTrue(task.getExecutions().isEmpty());
+
+        task = taskService.read(1L, true);
+        assertNotNull(task);
+        assertEquals(1L, task.getKey(), 0);
+        assertFalse(task.getExecutions().isEmpty());
+
+        // check list executions
+        PagedResult<TaskExecTO> execs = taskService.listExecutions(
+                new TaskExecQuery.Builder().key(1L).page(1).size(2).build());
+        assertTrue(execs.getTotalCount() >= execs.getResult().size());
+    }
+}


[08/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
deleted file mode 100644
index f2c940c..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
+++ /dev/null
@@ -1,696 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.security.AccessControlException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.ConnConfPropSchema;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.rest.api.beans.ConnObjectTOListQuery;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class ResourceITCase extends AbstractITCase {
-
-    private ResourceTO buildResourceTO(final String resourceName) {
-        ResourceTO resourceTO = new ResourceTO();
-
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(102L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setExtAttrName("userId");
-        item.setIntAttrName("userId");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        item = new MappingItemTO();
-        item.setExtAttrName("username");
-        item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        item = new MappingItemTO();
-        item.setExtAttrName("fullname");
-        item.setIntAttrName("cn");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setConnObjectKey(false);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        return resourceTO;
-    }
-
-    @Test
-    public void getPropagationActionsClasses() {
-        Set<String> actions = syncopeService.info().getPropagationActions();
-        assertNotNull(actions);
-        assertFalse(actions.isEmpty());
-    }
-
-    @Test
-    public void create() {
-        String resourceName = RESOURCE_NAME_CREATE;
-        ResourceTO resourceTO = buildResourceTO(resourceName);
-
-        Response response = resourceService.create(resourceTO);
-        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-        assertNotNull(actual);
-
-        // check for existence
-        actual = resourceService.read(resourceName);
-        assertNotNull(actual);
-    }
-
-    @Test
-    public void createOverridingProps() {
-        String resourceName = "overriding-conn-conf-target-resource-create";
-        ResourceTO resourceTO = new ResourceTO();
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setExtAttrName("uid");
-        item.setIntAttrName("userId");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        item = new MappingItemTO();
-        item.setExtAttrName("username");
-        item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        item = new MappingItemTO();
-        item.setExtAttrName("fullname");
-        item.setIntAttrName("cn");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setConnObjectKey(false);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(102L);
-
-        ConnConfProperty prop = new ConnConfProperty();
-        ConnConfPropSchema schema = new ConnConfPropSchema();
-        schema.setType("java.lang.String");
-        schema.setName("endpoint");
-        schema.setRequired(true);
-        prop.setSchema(schema);
-        prop.getValues().add("http://invalidurl/");
-
-        Set<ConnConfProperty> connectorConfigurationProperties = new HashSet<>(Arrays.asList(prop));
-        resourceTO.getConfOverride().addAll(connectorConfigurationProperties);
-
-        Response response = resourceService.create(resourceTO);
-        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-        assertNotNull(actual);
-
-        // check the existence
-        actual = resourceService.read(resourceName);
-        assertNotNull(actual);
-    }
-
-    @Test
-    public void createWithSingleMappingItem() {
-        String resourceName = RESOURCE_NAME_CREATE_SINGLE;
-        ResourceTO resourceTO = new ResourceTO();
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(102L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setExtAttrName("userId");
-        item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.setConnObjectKeyItem(item);
-
-        provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.GROUP.name());
-        provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-        item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.GroupKey);
-        item.setExtAttrName("groupId");
-        item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.SYNCHRONIZATION);
-        mapping.setConnObjectKeyItem(item);
-
-        Response response = resourceService.create(resourceTO);
-        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-
-        assertNotNull(actual);
-        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping());
-        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
-        assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping());
-        assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems());
-        assertEquals(MappingPurpose.SYNCHRONIZATION,
-                actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getConnObjectKeyItem().getPurpose());
-        assertEquals(MappingPurpose.PROPAGATION,
-                actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
-    }
-
-    @Test
-    public void createWithInvalidMapping() {
-        String resourceName = RESOURCE_NAME_CREATE_WRONG;
-        ResourceTO resourceTO = new ResourceTO();
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(102L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setExtAttrName("userId");
-        item.setConnObjectKey(true);
-        mapping.setConnObjectKeyItem(item);
-
-        item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setExtAttrName("email");
-        // missing intAttrName ...
-        mapping.add(item);
-
-        try {
-            createResource(resourceTO);
-            fail("Create should not have worked");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-            assertEquals("intAttrName", e.getElements().iterator().next());
-        }
-    }
-
-    @Test(expected = SyncopeClientException.class)
-    public void createWithoutExtAttr() {
-        String resourceName = RESOURCE_NAME_CREATE_WRONG;
-        ResourceTO resourceTO = new ResourceTO();
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(102L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setExtAttrName("userId");
-        item.setConnObjectKey(true);
-        mapping.setConnObjectKeyItem(item);
-
-        item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setIntAttrName("usernane");
-        // missing extAttrName ...
-        mapping.add(item);
-
-        createResource(resourceTO);
-    }
-
-    @Test
-    public void createWithPasswordPolicy() {
-        String resourceName = "res-with-password-policy";
-        ResourceTO resourceTO = new ResourceTO();
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(102L);
-        resourceTO.setPasswordPolicy(4L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setExtAttrName("userId");
-        item.setIntAttrName("userId");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        Response response = resourceService.create(resourceTO);
-        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-        assertNotNull(actual);
-
-        // check the existence
-        actual = resourceService.read(resourceName);
-        assertNotNull(actual);
-        assertNotNull(actual.getPasswordPolicy());
-        assertEquals(4L, (long) actual.getPasswordPolicy());
-    }
-
-    @Test
-    public void updateWithException() {
-        try {
-            ResourceTO resourceTO = new ResourceTO();
-            resourceTO.setKey("resourcenotfound");
-            resourceService.update(resourceTO);
-
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void update() {
-        String resourceName = RESOURCE_NAME_UPDATE;
-        ResourceTO resourceTO = new ResourceTO();
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(101L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        // Update with an existing and already assigned mapping
-        MappingItemTO item = new MappingItemTO();
-        item.setKey(112L);
-        item.setExtAttrName("test3");
-        item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        // Update defining new mappings
-        for (int i = 4; i < 6; i++) {
-            item = new MappingItemTO();
-            item.setExtAttrName("test" + i);
-            item.setIntAttrName("fullname");
-            item.setIntMappingType(IntMappingType.UserPlainSchema);
-            item.setPurpose(MappingPurpose.BOTH);
-            mapping.add(item);
-        }
-        item = new MappingItemTO();
-        item.setExtAttrName("username");
-        item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        resourceService.update(resourceTO);
-        ResourceTO actual = resourceService.read(resourceTO.getKey());
-        assertNotNull(actual);
-
-        // check for existence
-        Collection<MappingItemTO> mapItems = actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
-        assertNotNull(mapItems);
-        assertEquals(4, mapItems.size());
-    }
-
-    @Test
-    public void deleteWithException() {
-        try {
-            resourceService.delete("resourcenotfound");
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void updateResetSyncToken() {
-        // create resource with sync token
-        String resourceName = RESOURCE_NAME_RESETSYNCTOKEN + getUUIDString();
-        ResourceTO pre = buildResourceTO(resourceName);
-
-        pre.getProvision(AnyTypeKind.USER.name()).setSyncToken("test");
-        resourceService.create(pre);
-
-        pre.getProvision(AnyTypeKind.USER.name()).setSyncToken(null);
-        resourceService.update(pre);
-        ResourceTO actual = resourceService.read(pre.getKey());
-        // check that the synctoken has been reset
-        assertNull(actual.getProvision(AnyTypeKind.USER.name()).getSyncToken());
-    }
-
-    @Test
-    public void delete() {
-        String resourceName = "tobedeleted";
-
-        ResourceTO resource = buildResourceTO(resourceName);
-        Response response = resourceService.create(resource);
-        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-        assertNotNull(actual);
-
-        resourceService.delete(resourceName);
-
-        try {
-            resourceService.read(resourceName);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void list() {
-        List<ResourceTO> actuals = resourceService.list();
-        assertNotNull(actuals);
-        assertFalse(actuals.isEmpty());
-        for (ResourceTO resourceTO : actuals) {
-            assertNotNull(resourceTO);
-        }
-    }
-
-    @Test
-    public void read() {
-        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBVIRATTR);
-        assertNotNull(resource);
-
-        ProvisionTO provision = resource.getProvision(AnyTypeKind.USER.name());
-        assertNotNull(provision);
-        assertFalse(provision.getMapping().getItems().isEmpty());
-        assertFalse(provision.getMapping().getLinkingItems().isEmpty());
-    }
-
-    @Test
-    public void issueSYNCOPE323() {
-        ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
-        assertNotNull(actual);
-
-        try {
-            createResource(actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.EntityExists, e.getType());
-        }
-
-        actual.setKey(null);
-        try {
-            createResource(actual);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
-    }
-
-    @Test
-    public void bulkAction() {
-        resourceService.create(buildResourceTO("forBulk1"));
-        resourceService.create(buildResourceTO("forBulk2"));
-
-        assertNotNull(resourceService.read("forBulk1"));
-        assertNotNull(resourceService.read("forBulk2"));
-
-        final BulkAction bulkAction = new BulkAction();
-        bulkAction.setType(BulkAction.Type.DELETE);
-
-        bulkAction.getTargets().add(String.valueOf("forBulk1"));
-        bulkAction.getTargets().add(String.valueOf("forBulk2"));
-
-        resourceService.bulk(bulkAction);
-
-        try {
-            resourceService.read("forBulk1");
-            fail();
-        } catch (SyncopeClientException e) {
-        }
-
-        try {
-            resourceService.read("forBulk2");
-            fail();
-        } catch (SyncopeClientException e) {
-        }
-    }
-
-    @Test
-    public void anonymous() {
-        ResourceService unauthenticated = clientFactory.create().getService(ResourceService.class);
-        try {
-            unauthenticated.list();
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        ResourceService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).
-                getService(ResourceService.class);
-        assertFalse(anonymous.list().isEmpty());
-    }
-
-    @Test
-    public void listConnObjects() {
-        List<Long> groupKeys = new ArrayList<>();
-        for (int i = 0; i < 10; i++) {
-            GroupTO group = GroupITCase.getSampleTO("group");
-            group.getResources().add(RESOURCE_NAME_LDAP);
-            group = createGroup(group).getAny();
-            groupKeys.add(group.getKey());
-        }
-
-        int totalRead = 0;
-        Set<String> read = new HashSet<>();
-        try {
-            ConnObjectTOListQuery.Builder builder = new ConnObjectTOListQuery.Builder().size(10);
-            PagedConnObjectTOResult list;
-            do {
-                list = null;
-
-                boolean succeeded = false;
-                // needed because ApacheDS seems to randomly fail when searching with cookie
-                for (int i = 0; i < 5 && !succeeded; i++) {
-                    try {
-                        list = resourceService.listConnObjects(
-                                RESOURCE_NAME_LDAP,
-                                AnyTypeKind.GROUP.name(),
-                                builder.build());
-                        succeeded = true;
-                    } catch (SyncopeClientException e) {
-                        assertEquals(ClientExceptionType.ConnectorException, e.getType());
-                    }
-                }
-                assertNotNull(list);
-
-                totalRead += list.getResult().size();
-                CollectionUtils.collect(list.getResult(), new Transformer<ConnObjectTO, String>() {
-
-                    @Override
-                    public String transform(final ConnObjectTO input) {
-                        return input.getPlainAttrMap().get("__NAME__").getValues().get(0);
-                    }
-                }, read);
-
-                if (list.getPagedResultsCookie() != null) {
-                    builder.pagedResultsCookie(list.getPagedResultsCookie());
-                }
-            } while (list.getPagedResultsCookie() != null);
-
-            assertEquals(totalRead, read.size());
-            assertTrue(totalRead >= 10);
-        } finally {
-            for (Long key : groupKeys) {
-                groupService.delete(key);
-            }
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE360() {
-        final String name = "SYNCOPE360-" + getUUIDString();
-        resourceService.create(buildResourceTO(name));
-
-        ResourceTO resource = resourceService.read(name);
-        assertNotNull(resource);
-        assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
-
-        resource.getProvision(AnyTypeKind.USER.name()).setMapping(null);
-        resourceService.update(resource);
-
-        resource = resourceService.read(name);
-        assertNotNull(resource);
-        assertNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
-    }
-
-    @Test
-    public void issueSYNCOPE368() {
-        final String name = "SYNCOPE368-" + getUUIDString();
-
-        ResourceTO resourceTO = new ResourceTO();
-
-        resourceTO.setKey(name);
-        resourceTO.setConnector(105L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.GROUP.name());
-        provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.GroupName);
-        item.setExtAttrName("cn");
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.GroupOwnerSchema);
-        item.setExtAttrName("owner");
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        resourceTO = createResource(resourceTO);
-        assertNotNull(resourceTO);
-        assertEquals(2, resourceTO.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems().size());
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        try {
-            resourceService.create(
-                    buildResourceTO("http://schemas.examples.org/security/authorization/organizationUnit"));
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidExternalResource, e.getType());
-
-            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE493() {
-        // create resource with attribute mapping set to NONE and check its propagation
-        String resourceName = RESOURCE_NAME_CREATE_NONE;
-        ResourceTO resourceTO = new ResourceTO();
-        resourceTO.setKey(resourceName);
-        resourceTO.setConnector(102L);
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resourceTO.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setExtAttrName("userId");
-        item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.setConnObjectKeyItem(item);
-
-        MappingItemTO item2 = new MappingItemTO();
-        item2.setIntMappingType(IntMappingType.UserPlainSchema);
-        item2.setConnObjectKey(false);
-        item2.setIntAttrName("gender");
-        item2.setExtAttrName("gender");
-        item2.setPurpose(MappingPurpose.NONE);
-        mapping.add(item2);
-
-        Response response = resourceService.create(resourceTO);
-        ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-
-        assertNotNull(actual);
-        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping());
-        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
-        assertEquals(MappingPurpose.PROPAGATION,
-                actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
-        for (MappingItemTO itemTO : actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems()) {
-            if ("gender".equals(itemTO.getIntAttrName())) {
-                assertEquals(MappingPurpose.NONE, itemTO.getPurpose());
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java
deleted file mode 100644
index e7787e0..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java
+++ /dev/null
@@ -1,142 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.common.rest.api.service.RoleService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class RoleITCase extends AbstractITCase {
-
-    public static RoleTO getSampleRoleTO(final String name) {
-        RoleTO role = new RoleTO();
-        role.setKey(name + getUUIDString());
-        role.getRealms().add("/even");
-        role.getEntitlements().add(StandardEntitlement.LOG_SET_LEVEL);
-
-        return role;
-    }
-
-    @Test
-    public void list() {
-        List<RoleTO> roleTOs = roleService.list();
-        assertNotNull(roleTOs);
-        assertFalse(roleTOs.isEmpty());
-        for (RoleTO instance : roleTOs) {
-            assertNotNull(instance);
-        }
-    }
-
-    @Test
-    public void read() {
-        RoleTO roleTO = roleService.read("Search for realm evenTwo");
-        assertNotNull(roleTO);
-        assertTrue(roleTO.getEntitlements().contains(StandardEntitlement.USER_READ));
-    }
-
-    @Test
-    public void create() {
-        RoleTO role = new RoleTO();
-        role.getRealms().add(SyncopeConstants.ROOT_REALM);
-        role.getRealms().add("/even/two");
-        role.getEntitlements().add(StandardEntitlement.LOG_LIST);
-        role.getEntitlements().add(StandardEntitlement.LOG_SET_LEVEL);
-
-        try {
-            createRole(role);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidRole, e.getType());
-        }
-
-        role.setKey("new" + getUUIDString());
-        role = createRole(role);
-        assertNotNull(role);
-    }
-
-    @Test
-    public void update() {
-        RoleTO role = getSampleRoleTO("update");
-        role = createRole(role);
-        assertNotNull(role);
-
-        assertFalse(role.getEntitlements().contains(StandardEntitlement.WORKFLOW_TASK_LIST));
-        assertFalse(role.getRealms().contains("/even/two"));
-
-        role.getEntitlements().add(StandardEntitlement.WORKFLOW_TASK_LIST);
-        role.getRealms().add("/even/two");
-
-        roleService.update(role);
-
-        role = roleService.read(role.getKey());
-        assertTrue(role.getEntitlements().contains(StandardEntitlement.WORKFLOW_TASK_LIST));
-        assertTrue(role.getRealms().contains("/even/two"));
-    }
-
-    @Test
-    public void delete() {
-        RoleTO role = getSampleRoleTO("delete");
-        Response response = roleService.create(role);
-
-        RoleTO actual = getObject(response.getLocation(), RoleService.class, RoleTO.class);
-        assertNotNull(actual);
-
-        roleService.delete(actual.getKey());
-
-        try {
-            roleService.read(actual.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void dynMembership() {
-        assertTrue(userService.read(4L).getDynRoles().isEmpty());
-
-        RoleTO role = getSampleRoleTO("dynMembership");
-        role.setDynMembershipCond("cool==true");
-        Response response = roleService.create(role);
-        role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
-        assertNotNull(role);
-
-        assertTrue(userService.read(4L).getDynRoles().contains(role.getKey()));
-
-        role.setDynMembershipCond("cool==false");
-        roleService.update(role);
-
-        assertTrue(userService.read(4L).getDynGroups().isEmpty());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
deleted file mode 100644
index 8832540..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
+++ /dev/null
@@ -1,213 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.time.DateUtils;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PushTaskTO;
-import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.types.JobAction;
-import org.apache.syncope.common.lib.types.JobStatusType;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
-import org.apache.syncope.common.rest.api.beans.TaskExecQuery;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class SchedTaskITCase extends AbstractTaskITCase {
-
-    @Test
-    public void getJobClasses() {
-        Set<String> jobClasses = syncopeService.info().getTaskJobs();
-        assertNotNull(jobClasses);
-        assertFalse(jobClasses.isEmpty());
-    }
-
-    @Test
-    public void list() {
-        PagedResult<SchedTaskTO> tasks =
-                taskService.list(new TaskQuery.Builder().type(TaskType.SCHEDULED).build());
-        assertFalse(tasks.getResult().isEmpty());
-        for (AbstractTaskTO task : tasks.getResult()) {
-            if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO || task instanceof PushTaskTO) {
-                fail();
-            }
-        }
-    }
-
-    @Test
-    public void update() {
-        SchedTaskTO task = taskService.read(SCHED_TASK_ID, true);
-        assertNotNull(task);
-
-        SchedTaskTO taskMod = new SchedTaskTO();
-        taskMod.setKey(5L);
-        taskMod.setCronExpression(null);
-
-        taskService.update(taskMod);
-        SchedTaskTO actual = taskService.read(taskMod.getKey(), true);
-        assertNotNull(actual);
-        assertEquals(task.getKey(), actual.getKey());
-        assertNull(actual.getCronExpression());
-    }
-
-    @Test
-    public void deferred() {
-        SchedTaskTO task = new SchedTaskTO();
-        task.setActive(true);
-        task.setName("deferred");
-        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
-
-        Response response = taskService.create(task);
-        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
-        assertNotNull(task);
-
-        Date initial = new Date();
-        Date later = DateUtils.addSeconds(initial, 2);
-
-        taskService.execute(new ExecuteQuery.Builder().key(task.getKey()).startAt(later).build());
-
-        int i = 0;
-        int maxit = 50;
-
-        // wait for completion (executions incremented)
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-            }
-
-            task = taskService.read(task.getKey(), true);
-
-            assertNotNull(task);
-            assertNotNull(task.getExecutions());
-
-            i++;
-        } while (task.getExecutions().isEmpty() && i < maxit);
-
-        PagedResult<TaskExecTO> execs =
-                taskService.listExecutions(new TaskExecQuery.Builder().key(task.getKey()).build());
-        assertEquals(1, execs.getTotalCount());
-        assertTrue(execs.getResult().get(0).getStart().after(initial));
-        // round 1 sec for safety
-        assertTrue(DateUtils.addSeconds(execs.getResult().get(0).getStart(), 1).after(later));
-    }
-
-    @Test
-    public void issueSYNCOPE144() {
-        SchedTaskTO task = new SchedTaskTO();
-        task.setName("issueSYNCOPE144");
-        task.setDescription("issueSYNCOPE144 Description");
-        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
-
-        Response response = taskService.create(task);
-        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
-        assertNotNull(task);
-        assertEquals("issueSYNCOPE144", task.getName());
-        assertEquals("issueSYNCOPE144 Description", task.getDescription());
-
-        task = taskService.read(task.getKey(), true);
-        assertNotNull(task);
-        assertEquals("issueSYNCOPE144", task.getName());
-        assertEquals("issueSYNCOPE144 Description", task.getDescription());
-
-        task.setName("issueSYNCOPE144_2");
-        task.setDescription("issueSYNCOPE144 Description_2");
-
-        response = taskService.create(task);
-        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
-        assertNotNull(task);
-        assertEquals("issueSYNCOPE144_2", task.getName());
-        assertEquals("issueSYNCOPE144 Description_2", task.getDescription());
-    }
-
-    @Test
-    public void issueSYNCOPE660() {
-        List<TaskExecTO> list = taskService.listJobs(JobStatusType.ALL);
-        int old_size = list.size();
-
-        SchedTaskTO task = new SchedTaskTO();
-        task.setName("issueSYNCOPE660");
-        task.setDescription("issueSYNCOPE660 Description");
-        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
-
-        Response response = taskService.create(task);
-        task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
-
-        list = taskService.listJobs(JobStatusType.ALL);
-        assertEquals(old_size + 1, list.size());
-
-        taskService.actionJob(task.getKey(), JobAction.START);
-
-        int i = 0, maxit = 50;
-
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-                // ignore
-            }
-
-            list = taskService.listJobs(JobStatusType.RUNNING);
-
-            assertNotNull(list);
-            i++;
-        } while (list.size() < 1 && i < maxit);
-
-        assertEquals(1, list.size());
-        assertEquals(task.getKey(), list.get(0).getTask(), 0);
-
-        taskService.actionJob(task.getKey(), JobAction.STOP);
-
-        i = 0;
-
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-                // ignore
-            }
-
-            list = taskService.listJobs(JobStatusType.RUNNING);
-
-            assertNotNull(list);
-            i++;
-        } while (list.size() >= 1 && i < maxit);
-
-        assertTrue(list.isEmpty());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
deleted file mode 100644
index d047347..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
+++ /dev/null
@@ -1,397 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Collection;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
-import org.apache.syncope.common.rest.api.service.RoleService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class SearchITCase extends AbstractITCase {
-
-    @Test
-    public void searchUser() {
-        // LIKE
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().
-                        is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
-        assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
-
-        for (UserTO user : matchingUsers.getResult()) {
-            assertNotNull(user);
-        }
-
-        // ISNULL
-        matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).build());
-        assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
-
-        Collection<UserTO> found = CollectionUtils.select(matchingUsers.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 2L || user.getKey() == 3L;
-            }
-        });
-        assertEquals(2, found.size());
-    }
-
-    @Test
-    public void searchByUsernameAndKey() {
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().
-                        is("username").equalTo("rossini").and("key").lessThan(2).query()).build());
-        assertNotNull(matchingUsers);
-        assertEquals(1, matchingUsers.getResult().size());
-        assertEquals("rossini", matchingUsers.getResult().iterator().next().getUsername());
-        assertEquals(1L, matchingUsers.getResult().iterator().next().getKey(), 0);
-    }
-
-    @Test
-    public void searchByGroupNameAndKey() {
-        PagedResult<GroupTO> groups = groupService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().
-                        is("name").equalTo("root").and("key").lessThan(2).query()).build());
-        assertNotNull(groups);
-        assertEquals(1, groups.getResult().size());
-        assertEquals("root", groups.getResult().iterator().next().getName());
-        assertEquals(1L, groups.getResult().iterator().next().getKey(), 0);
-    }
-
-    @Test
-    public void searchByGroup() {
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(1L).query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
-
-        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 1;
-            }
-        }));
-    }
-
-    @Test
-    public void searchByDynGroup() {
-        GroupTO group = GroupITCase.getBasicSampleTO("dynMembership");
-        group.setUDynMembershipCond("cool==true");
-        group = createGroup(group).getAny();
-        assertNotNull(group);
-
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(group.getKey()).query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
-
-        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 4;
-            }
-        }));
-    }
-
-    @Test
-    public void searchByRole() {
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles("Other").query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
-
-        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 1;
-            }
-        }));
-    }
-
-    @Test
-    public void searchByDynRole() {
-        RoleTO role = RoleITCase.getSampleRoleTO("dynMembership");
-        role.setDynMembershipCond("cool==true");
-        Response response = roleService.create(role);
-        role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
-        assertNotNull(role);
-
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(role.getKey()).query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
-
-        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 4;
-            }
-        }));
-    }
-
-    @Test
-    public void searchUserByResourceName() {
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
-
-        assertTrue(IterableUtils.matchesAny(matchingUsers.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 2;
-            }
-        }));
-    }
-
-    @Test
-    public void paginatedSearch() {
-        // LIKE
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().
-                        is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).page(1).size(2).build());
-        assertNotNull(matchingUsers);
-
-        assertFalse(matchingUsers.getResult().isEmpty());
-        for (UserTO user : matchingUsers.getResult()) {
-            assertNotNull(user);
-        }
-
-        // ISNULL
-        matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).page(2).size(2).
-                build());
-        assertNotNull(matchingUsers);
-        assertEquals(2, matchingUsers.getPage());
-        assertEquals(2, matchingUsers.getResult().size());
-    }
-
-    @Test
-    public void searchByBooleanAnyCond() {
-        PagedResult<GroupTO> groups = groupService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("show").equalTo("true").query()).build());
-        assertNotNull(groups);
-        assertFalse(groups.getResult().isEmpty());
-    }
-
-    @Test
-    public void searchByRelationshipAnyCond() {
-        PagedResult<GroupTO> groups = groupService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query()).build());
-        assertNotNull(groups);
-        assertEquals(1, groups.getResult().size());
-        assertEquals(6L, groups.getResult().iterator().next().getKey(), 0);
-    }
-
-    @Test
-    public void nested() {
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
-        assertNotNull(matchingUsers);
-
-        assertFalse(matchingUsers.getResult().isEmpty());
-        for (UserTO user : matchingUsers.getResult()) {
-            assertNotNull(user);
-        }
-    }
-
-    @Test
-    public void searchByType() {
-        PagedResult<AnyObjectTO> matching = anyObjectService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").query()).build());
-        assertNotNull(matching);
-
-        assertFalse(matching.getResult().isEmpty());
-        for (AnyObjectTO printer : matching.getResult()) {
-            assertNotNull(printer);
-        }
-
-        matching = anyObjectService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("UNEXISTING").query()).build());
-        assertNotNull(matching);
-
-        assertTrue(matching.getResult().isEmpty());
-    }
-
-    @Test
-    public void searchByRelationship() {
-        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                        inRelationships(2L).query()).
-                build());
-        assertNotNull(anyObjects);
-        assertTrue(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
-
-            @Override
-            public boolean evaluate(final AnyObjectTO anyObject) {
-                return anyObject.getKey() == 1L;
-            }
-        }));
-
-        PagedResult<UserTO> users = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationships(1L).query()).
-                build());
-        assertNotNull(users);
-        assertTrue(IterableUtils.matchesAny(users.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 4L;
-            }
-        }));
-    }
-
-    @Test
-    public void searchByRelationshipType() {
-        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                        inRelationshipTypes("neighborhood").query()).
-                build());
-        assertNotNull(anyObjects);
-        assertTrue(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
-
-            @Override
-            public boolean evaluate(final AnyObjectTO anyObject) {
-                return anyObject.getKey() == 1L;
-            }
-        }));
-        assertTrue(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
-
-            @Override
-            public boolean evaluate(final AnyObjectTO anyObject) {
-                return anyObject.getKey() == 2L;
-            }
-        }));
-
-        PagedResult<UserTO> users = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationshipTypes("neighborhood").query()).
-                build());
-        assertNotNull(users);
-        assertTrue(IterableUtils.matchesAny(users.getResult(), new Predicate<UserTO>() {
-
-            @Override
-            public boolean evaluate(final UserTO user) {
-                return user.getKey() == 4L;
-            }
-        }));
-    }
-
-    @Test
-    public void assignable() {
-        PagedResult<GroupTO> groups = groupService.search(
-                new AnySearchQuery.Builder().realm("/even/two").page(1).size(1000).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().isAssignable().
-                        and("name").equalTo("*").query()).
-                build());
-        assertNotNull(groups);
-        assertTrue(IterableUtils.matchesAny(groups.getResult(), new Predicate<GroupTO>() {
-
-            @Override
-            public boolean evaluate(final GroupTO group) {
-                return group.getKey() == 15L;
-            }
-        }));
-        assertFalse(IterableUtils.matchesAny(groups.getResult(), new Predicate<GroupTO>() {
-
-            @Override
-            public boolean evaluate(final GroupTO group) {
-                return group.getKey() == 16L;
-            }
-        }));
-
-        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
-                new AnySearchQuery.Builder().realm("/odd").
-                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").isAssignable().
-                        and("name").equalTo("*").query()).
-                build());
-        assertNotNull(anyObjects);
-        assertFalse(IterableUtils.matchesAny(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
-
-            @Override
-            public boolean evaluate(final AnyObjectTO anyObject) {
-                return anyObject.getKey() == 3L;
-            }
-        }));
-    }
-
-    @Test
-    public void orderBy() {
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
-                orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
-        assertNotNull(matchingUsers);
-
-        assertFalse(matchingUsers.getResult().isEmpty());
-        for (UserTO user : matchingUsers.getResult()) {
-            assertNotNull(user);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java
deleted file mode 100644
index 36214c9..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java
+++ /dev/null
@@ -1,99 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.SecurityQuestionTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class SecurityQuestionITCase extends AbstractITCase {
-
-    @Test
-    public void read() {
-        SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
-        assertNotNull(securityQuestionTO);
-    }
-
-    @Test
-    public void list() {
-        List<SecurityQuestionTO> securityQuestionTOs = securityQuestionService.list();
-        assertNotNull(securityQuestionTOs);
-        assertFalse(securityQuestionTOs.isEmpty());
-        for (SecurityQuestionTO instance : securityQuestionTOs) {
-            assertNotNull(instance);
-        }
-    }
-
-    @Test
-    public void create() {
-        SecurityQuestionTO securityQuestionTO = new SecurityQuestionTO();
-        securityQuestionTO.setContent("What is your favorite pet's name?");
-
-        Response response = securityQuestionService.create(securityQuestionTO);
-        SecurityQuestionTO actual = getObject(response.getLocation(), SecurityQuestionService.class,
-                SecurityQuestionTO.class);
-
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-        securityQuestionTO.setKey(actual.getKey());
-        assertEquals(actual, securityQuestionTO);
-    }
-
-    @Test
-    public void update() {
-        SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
-        securityQuestionTO.setContent("What is your favorite color?");
-
-        securityQuestionService.update(securityQuestionTO);
-        SecurityQuestionTO actual = securityQuestionService.read(securityQuestionTO.getKey());
-        assertNotNull(actual);
-        assertEquals(actual, securityQuestionTO);
-    }
-
-    @Test
-    public void delete() {
-        SecurityQuestionTO securityQuestion = new SecurityQuestionTO();
-        securityQuestion.setContent("What is your first pet's name?");
-
-        Response response = securityQuestionService.create(securityQuestion);
-        securityQuestion = getObject(response.getLocation(), SecurityQuestionService.class, SecurityQuestionTO.class);
-
-        securityQuestionService.delete(securityQuestion.getKey());
-
-        try {
-            securityQuestionService.read(securityQuestion.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-}


[13/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
new file mode 100644
index 0000000..dd8e7c1
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
@@ -0,0 +1,386 @@
+/*
+ * 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.fit.core;
+
+import org.apache.syncope.fit.ActivitiDetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.GenericType;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.patch.BooleanReplacePatchItem;
+import org.apache.syncope.common.lib.patch.MembershipPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class UserSelfITCase extends AbstractITCase {
+
+    @Test
+    public void selfRegistrationAllowed() {
+        assertTrue(syncopeService.info().isSelfRegAllowed());
+    }
+
+    @Test
+    public void create() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // 1. self-registration as admin: failure
+        try {
+            userSelfService.create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true);
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        // 2. self-registration as anonymous: works
+        SyncopeClient anonClient = clientFactory.create();
+        UserTO self = anonClient.getService(UserSelfService.class).
+                create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                }).getAny();
+        assertNotNull(self);
+        assertEquals("createApproval", self.getStatus());
+    }
+
+    @Test
+    public void createAndApprove() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // self-create user with membership: goes 'createApproval' with resources and membership but no propagation
+        UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
+        userTO.getMemberships().add(new MembershipTO.Builder().group(3L).build());
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        SyncopeClient anonClient = clientFactory.create();
+        userTO = anonClient.getService(UserSelfService.class).
+                create(userTO, true).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                }).getAny();
+        assertNotNull(userTO);
+        assertEquals("createApproval", userTO.getStatus());
+        assertFalse(userTO.getMemberships().isEmpty());
+        assertFalse(userTO.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+
+        // now approve and verify that propagation has happened
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        form = userWorkflowService.claimForm(form.getTaskId());
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        props.get("approve").setValue(Boolean.TRUE.toString());
+        form.getProperties().clear();
+        form.getProperties().addAll(props.values());
+        userTO = userWorkflowService.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey()));
+    }
+
+    @Test
+    public void read() {
+        UserService userService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserService.class);
+
+        try {
+            userService2.read(1L);
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create("rossini", ADMIN_PWD).self();
+        assertEquals("rossini", self.getValue().getUsername());
+    }
+
+    @Test
+    public void updateWithoutApproval() {
+        // 1. create user as admin
+        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org")).getAny();
+        assertNotNull(created);
+        assertFalse(created.getUsername().endsWith("XX"));
+
+        // 2. self-update (username) - works
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(created.getKey());
+        userPatch.setUsername(new StringReplacePatchItem.Builder().value(created.getUsername() + "XX").build());
+
+        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
+        UserTO updated = authClient.getService(UserSelfService.class).update(userPatch).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                }).getAny();
+        assertNotNull(updated);
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                ? "active" : "created", updated.getStatus());
+        assertTrue(updated.getUsername().endsWith("XX"));
+    }
+
+    @Test
+    public void updateWithApproval() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // 1. create user as admin
+        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org")).getAny();
+        assertNotNull(created);
+        assertFalse(created.getUsername().endsWith("XX"));
+
+        // 2. self-update (username + memberships + resource) - works but needs approval
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(created.getKey());
+        userPatch.setUsername(new StringReplacePatchItem.Builder().value(created.getUsername() + "XX").build());
+        userPatch.getMemberships().add(new MembershipPatch.Builder().
+                operation(PatchOperation.ADD_REPLACE).
+                membershipTO(new MembershipTO.Builder().group(7L).build()).
+                build());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
+        userPatch.setPassword(new PasswordPatch.Builder().
+                value("newPassword123").onSyncope(false).resource(RESOURCE_NAME_TESTDB).build());
+
+        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
+        UserTO updated = authClient.getService(UserSelfService.class).update(userPatch).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                }).getAny();
+        assertNotNull(updated);
+        assertEquals("updateApproval", updated.getStatus());
+        assertFalse(updated.getUsername().endsWith("XX"));
+        assertTrue(updated.getMemberships().isEmpty());
+
+        // no propagation happened
+        assertTrue(updated.getResources().isEmpty());
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+
+        // 3. approve self-update as admin
+        WorkflowFormTO form = userWorkflowService.getFormForUser(updated.getKey());
+        form = userWorkflowService.claimForm(form.getTaskId());
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        props.get("approve").setValue(Boolean.TRUE.toString());
+        form.getProperties().clear();
+        form.getProperties().addAll(props.values());
+        updated = userWorkflowService.submitForm(form);
+        assertNotNull(updated);
+        assertEquals("active", updated.getStatus());
+        assertTrue(updated.getUsername().endsWith("XX"));
+        assertEquals(1, updated.getMemberships().size());
+
+        // check that propagation also happened
+        assertTrue(updated.getResources().contains(RESOURCE_NAME_TESTDB));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey()));
+    }
+
+    @Test
+    public void delete() {
+        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org")).getAny();
+        assertNotNull(created);
+
+        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
+        UserTO deleted = authClient.getService(UserSelfService.class).delete().readEntity(
+                new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(deleted);
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                ? "deleteApproval" : null, deleted.getStatus());
+    }
+
+    @Test
+    public void issueSYNCOPE373() {
+        UserTO userTO = adminClient.self().getValue();
+        assertEquals(ADMIN_UNAME, userTO.getUsername());
+    }
+
+    @Test
+    public void passwordReset() {
+        // 0. ensure that password request DOES require security question
+        configurationService.set(attrTO("passwordReset.securityQuestion", "true"));
+
+        // 1. create an user with security question and answer
+        UserTO user = UserITCase.getUniqueSampleTO("pwdReset@syncope.apache.org");
+        user.setSecurityQuestion(1L);
+        user.setSecurityAnswer("Rossi");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        createUser(user);
+
+        // verify propagation (including password) on external db
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        String pwdOnResource = jdbcTemplate.queryForObject("SELECT password FROM test WHERE id=?", String.class,
+                user.getUsername());
+        assertTrue(StringUtils.isNotBlank(pwdOnResource));
+
+        // 2. verify that new user is able to authenticate
+        SyncopeClient authClient = clientFactory.create(user.getUsername(), "password123");
+        UserTO read = authClient.self().getValue();
+        assertNotNull(read);
+
+        // 3. request password reset (as anonymous) providing the expected security answer
+        SyncopeClient anonClient = clientFactory.create();
+        try {
+            anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "WRONG");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidSecurityAnswer, e.getType());
+        }
+        anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "Rossi");
+
+        // 4. get token (normally sent via e-mail, now reading as admin)
+        String token = userService.read(read.getKey()).getToken();
+        assertNotNull(token);
+
+        // 5. confirm password reset
+        try {
+            anonClient.getService(UserSelfService.class).confirmPasswordReset("WRONG TOKEN", "newPassword");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+            assertTrue(e.getMessage().contains("WRONG TOKEN"));
+        }
+        anonClient.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword123");
+
+        // 6. verify that password was reset and token removed
+        authClient = clientFactory.create(user.getUsername(), "newPassword123");
+        read = authClient.self().getValue();
+        assertNotNull(read);
+        assertNull(read.getToken());
+
+        // 7. verify that password was changed on external resource
+        String newPwdOnResource = jdbcTemplate.queryForObject("SELECT password FROM test WHERE id=?", String.class,
+                user.getUsername());
+        assertTrue(StringUtils.isNotBlank(newPwdOnResource));
+        assertNotEquals(pwdOnResource, newPwdOnResource);
+    }
+
+    @Test
+    public void passwordResetWithoutSecurityQuestion() {
+        // 0. disable security question for password reset
+        configurationService.set(attrTO("passwordReset.securityQuestion", "false"));
+
+        // 1. create an user with security question and answer
+        UserTO user = UserITCase.getUniqueSampleTO("pwdResetNoSecurityQuestion@syncope.apache.org");
+        createUser(user);
+
+        // 2. verify that new user is able to authenticate
+        SyncopeClient authClient = clientFactory.create(user.getUsername(), "password123");
+        UserTO read = authClient.self().getValue();
+        assertNotNull(read);
+
+        // 3. request password reset (as anonymous) with no security answer
+        SyncopeClient anonClient = clientFactory.create();
+        anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), null);
+
+        // 4. get token (normally sent via e-mail, now reading as admin)
+        String token = userService.read(read.getKey()).getToken();
+        assertNotNull(token);
+
+        // 5. confirm password reset
+        try {
+            anonClient.getService(UserSelfService.class).confirmPasswordReset("WRONG TOKEN", "newPassword");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+            assertTrue(e.getMessage().contains("WRONG TOKEN"));
+        }
+        anonClient.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword123");
+
+        // 6. verify that password was reset and token removed
+        authClient = clientFactory.create(user.getUsername(), "newPassword123");
+        read = authClient.self().getValue();
+        assertNotNull(read);
+        assertNull(read.getToken());
+
+        // 7. re-enable security question for password reset
+        configurationService.set(attrTO("passwordReset.securityQuestion", "true"));
+    }
+
+    @Test
+    public void mustChangePassword() {
+        // PRE: reset vivaldi's password
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(3L);
+        userPatch.setPassword(new PasswordPatch.Builder().value("password321").build());
+        userService.update(userPatch);
+
+        // 0. access as vivaldi -> succeed
+        SyncopeClient vivaldiClient = clientFactory.create("vivaldi", "password321");
+        Pair<Map<String, Set<String>>, UserTO> self = vivaldiClient.self();
+        assertFalse(self.getRight().isMustChangePassword());
+
+        // 1. update user vivaldi (3) requirig password update
+        userPatch = new UserPatch();
+        userPatch.setKey(3L);
+        userPatch.setMustChangePassword(new BooleanReplacePatchItem.Builder().value(true).build());
+        UserTO vivaldi = updateUser(userPatch).getAny();
+        assertTrue(vivaldi.isMustChangePassword());
+
+        // 2. attempt to access -> fail
+        try {
+            vivaldiClient.getService(ResourceService.class).list();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+            assertEquals("Please change your password first", e.getMessage());
+        }
+
+        // 3. change password
+        vivaldiClient.getService(UserSelfService.class).changePassword("password123");
+
+        // 4. verify it worked
+        self = clientFactory.create("vivaldi", "password123").self();
+        assertFalse(self.getRight().isMustChangePassword());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java
new file mode 100644
index 0000000..18b3cbf
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java
@@ -0,0 +1,309 @@
+/*
+ * 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.fit.core;
+
+import org.apache.syncope.fit.ActivitiDetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.rest.api.service.UserWorkflowService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class UserWorkflowITCase extends AbstractITCase {
+
+    @Test
+    public void createWithReject() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        // User with group 9 are defined in workflow as subject to approval
+        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
+
+        // 1. create user with group 9
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals(1, userTO.getMemberships().size());
+        assertEquals(9, userTO.getMemberships().get(0).getRightKey());
+        assertEquals("createApproval", userTO.getStatus());
+
+        // 2. request if there is any pending task for user just created
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        assertNotNull(form);
+        assertNotNull(form.getUserKey());
+        assertEquals(userTO.getKey(), form.getUserKey(), 0);
+        assertNotNull(form.getTaskId());
+        assertNull(form.getOwner());
+
+        // 3. claim task as rossini, with role "User manager" granting entitlement to claim forms but not in group 7,
+        // designated for approval in workflow definition: fail
+        UserTO rossini = userService.read(1L);
+        if (!rossini.getRoles().contains("User manager")) {
+            UserPatch userPatch = new UserPatch();
+            userPatch.setKey(1L);
+            userPatch.getRoles().add(new StringPatchItem.Builder().
+                    operation(PatchOperation.ADD_REPLACE).value("User manager").build());
+            rossini = updateUser(userPatch).getAny();
+        }
+        assertTrue(rossini.getRoles().contains("User manager"));
+
+        UserWorkflowService userService2 = clientFactory.create("rossini", ADMIN_PWD).
+                getService(UserWorkflowService.class);
+        try {
+            userService2.claimForm(form.getTaskId());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.Workflow, e.getType());
+        }
+
+        // 4. claim task from bellini, with role "User manager" and in group 7
+        UserWorkflowService userService3 = clientFactory.create("bellini", ADMIN_PWD).
+                getService(UserWorkflowService.class);
+        form = userService3.claimForm(form.getTaskId());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNotNull(form.getOwner());
+
+        // 5. reject user
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        props.get("approve").setValue(Boolean.FALSE.toString());
+        props.get("rejectReason").setValue("I don't like him.");
+        form.getProperties().clear();
+        form.getProperties().addAll(props.values());
+        userTO = userService3.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals("rejected", userTO.getStatus());
+
+        // 6. check that rejected user was not propagated to external resource (SYNCOPE-364)
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        Exception exception = null;
+        try {
+            jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
+                    new String[] { userTO.getUsername() }, Integer.class);
+        } catch (EmptyResultDataAccessException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+    }
+
+    @Test
+    public void createWithApproval() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // read forms *before* any operation
+        List<WorkflowFormTO> forms = userWorkflowService.getForms();
+        assertNotNull(forms);
+        int preForms = forms.size();
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("createWithApproval@syncope.apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        // User with group 9 are defined in workflow as subject to approval
+        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
+
+        // 1. create user with group 9 (and verify that no propagation occurred)
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertNotNull(result);
+        userTO = result.getAny();
+        assertEquals(1, userTO.getMemberships().size());
+        assertEquals(9, userTO.getMemberships().get(0).getRightKey());
+        assertEquals("createApproval", userTO.getStatus());
+        assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
+
+        assertTrue(result.getPropagationStatuses().isEmpty());
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+        Exception exception = null;
+        try {
+            jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
+                    new String[] { userTO.getUsername() }, Integer.class);
+        } catch (EmptyResultDataAccessException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+
+        // 2. request if there is any pending form for user just created
+        forms = userWorkflowService.getForms();
+        assertNotNull(forms);
+        assertEquals(preForms + 1, forms.size());
+
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNull(form.getOwner());
+
+        // 4. claim task (from admin)
+        form = userWorkflowService.claimForm(form.getTaskId());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNotNull(form.getOwner());
+
+        // 5. approve user (and verify that propagation occurred)
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        props.get("approve").setValue(Boolean.TRUE.toString());
+        form.getProperties().clear();
+        form.getProperties().addAll(props.values());
+        userTO = userWorkflowService.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+        assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
+
+        exception = null;
+        try {
+            final String username = jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class,
+                    userTO.getUsername());
+            assertEquals(userTO.getUsername(), username);
+        } catch (EmptyResultDataAccessException e) {
+            exception = e;
+        }
+        assertNull(exception);
+
+        // 6. update user
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+    }
+
+    @Test
+    public void issueSYNCOPE15() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // read forms *before* any operation
+        List<WorkflowFormTO> forms = userWorkflowService.getForms();
+        assertNotNull(forms);
+        int preForms = forms.size();
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("issueSYNCOPE15@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getMemberships().clear();
+
+        // User with group 9 are defined in workflow as subject to approval
+        userTO.getMemberships().add(new MembershipTO.Builder().group(9L).build());
+
+        // 1. create user with group 9 (and verify that no propagation occurred)
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertNotEquals(0L, userTO.getKey(), 0);
+        assertNotNull(userTO.getCreationDate());
+        assertNotNull(userTO.getCreator());
+        assertNotNull(userTO.getLastChangeDate());
+        assertNotNull(userTO.getLastModifier());
+        assertEquals(userTO.getCreationDate(), userTO.getLastChangeDate());
+
+        // 2. request if there is any pending form for user just created
+        forms = userWorkflowService.getForms();
+        assertEquals(preForms + 1, forms.size());
+
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        assertNotNull(form);
+
+        // 3. first claim ny bellini ....
+        UserWorkflowService userService3 = clientFactory.create("bellini", ADMIN_PWD).
+                getService(UserWorkflowService.class);
+        form = userService3.claimForm(form.getTaskId());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNotNull(form.getOwner());
+
+        // 4. second claim task by admin
+        form = userWorkflowService.claimForm(form.getTaskId());
+        assertNotNull(form);
+
+        // 5. approve user
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        props.get("approve").setValue(Boolean.TRUE.toString());
+        form.getProperties().clear();
+        form.getProperties().addAll(props.values());
+
+        // 6. submit approve
+        userTO = userWorkflowService.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals(preForms, userWorkflowService.getForms().size());
+        assertNull(userWorkflowService.getFormForUser(userTO.getKey()));
+
+        // 7. search approval into the history as well
+        forms = userWorkflowService.getFormsByName(userTO.getKey(), "Create approval");
+        assertFalse(forms.isEmpty());
+
+        int count = 0;
+        for (WorkflowFormTO hform : forms) {
+            if (form.getTaskId().equals(hform.getTaskId())) {
+                count++;
+
+                assertEquals("createApproval", hform.getKey());
+                assertNotNull(hform.getCreateTime());
+                assertNotNull(hform.getDueDate());
+                assertTrue(Boolean.parseBoolean(hform.getPropertyMap().get("approve").getValue()));
+                assertNull(hform.getPropertyMap().get("rejectReason").getValue());
+            }
+        }
+        assertEquals(1, count);
+
+        userService.delete(userTO.getKey());
+
+        try {
+            userService.read(userTO.getKey());
+            fail();
+        } catch (Exception ignore) {
+            assertNotNull(ignore);
+        }
+
+        try {
+            userWorkflowService.getFormsByName(userTO.getKey(), "Create approval");
+            fail();
+        } catch (Exception ignore) {
+            assertNotNull(ignore);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
new file mode 100644
index 0000000..0951eee
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
@@ -0,0 +1,678 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Locale;
+import java.util.Map;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.StatusPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.VirSchemaTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.StatusPatchType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class VirAttrITCase extends AbstractITCase {
+
+    @Test
+    public void issueSYNCOPE16() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("issue16@apache.org");
+        userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
+        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+
+        // 1. create user
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        // 2. check for virtual attribute value
+        userTO = userService.read(userTO.getKey());
+        assertNotNull(userTO);
+        assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getVirAttrs().add(attrTO("virtualdata", "virtualupdated"));
+
+        // 3. update virtual attribute
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+
+        // 4. check for virtual attribute value
+        userTO = userService.read(userTO.getKey());
+        assertNotNull(userTO);
+        assertEquals("virtualupdated", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+    }
+
+    @Test
+    public void issueSYNCOPE260() {
+        // create new virtual schema for the resource below
+        ResourceTO ws2 = resourceService.read(RESOURCE_NAME_WS2);
+        ProvisionTO provision = ws2.getProvision(AnyTypeKind.USER.name());
+        assertNotNull(provision);
+
+        VirSchemaTO virSchema = new VirSchemaTO();
+        virSchema.setKey("syncope260" + getUUIDString());
+        virSchema.setExtAttrName("companyName");
+        virSchema.setProvision(provision.getKey());
+        virSchema = createSchema(SchemaType.VIRTUAL, virSchema);
+        assertNotNull(virSchema);
+
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("syncope260" + getUUIDString());
+        newClass.getVirSchemas().add(virSchema.getKey());
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+
+        // ----------------------------------
+        // create user and check virtual attribute value propagation
+        // ----------------------------------
+        UserTO userTO = UserITCase.getUniqueSampleTO("260@a.com");
+        userTO.getAuxClasses().add(newClass.getKey());
+        userTO.getVirAttrs().add(attrTO(virSchema.getKey(), "virtualvalue"));
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertNotNull(result);
+        assertFalse(result.getPropagationStatuses().isEmpty());
+        assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().get(0).getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        userTO = result.getAny();
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
+        assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
+        // ----------------------------------
+
+        // ----------------------------------
+        // update user virtual attribute and check virtual attribute value update propagation
+        // ----------------------------------
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getVirAttrs().add(attrTO(virSchema.getKey(), "virtualvalue2"));
+
+        result = updateUser(userPatch);
+        assertNotNull(result);
+        assertFalse(result.getPropagationStatuses().isEmpty());
+        assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().get(0).getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        userTO = result.getAny();
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
+        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
+        // ----------------------------------
+
+        // ----------------------------------
+        // suspend/reactivate user and check virtual attribute value (unchanged)
+        // ----------------------------------
+        StatusPatch statusPatch = new StatusPatch();
+        statusPatch.setKey(userTO.getKey());
+        statusPatch.setType(StatusPatchType.SUSPEND);
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertEquals("suspended", userTO.getStatus());
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
+        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
+
+        statusPatch = new StatusPatch();
+        statusPatch.setKey(userTO.getKey());
+        statusPatch.setType(StatusPatchType.REACTIVATE);
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertEquals("active", userTO.getStatus());
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
+        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
+        // ----------------------------------
+
+        // ----------------------------------
+        // update user attribute and check virtual attribute value (unchanged)
+        // ----------------------------------
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("surname", "Surname2"));
+
+        result = updateUser(userPatch);
+        assertNotNull(result);
+        assertFalse(result.getPropagationStatuses().isEmpty());
+        assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().get(0).getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        userTO = result.getAny();
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
+        assertEquals("Surname2", connObjectTO.getPlainAttrMap().get("SURNAME").getValues().get(0));
+
+        // virtual attribute value did not change
+        assertFalse(connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().isEmpty());
+        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("COMPANYNAME").getValues().get(0));
+        // ----------------------------------
+    }
+
+    @Test
+    public void virAttrCache() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("virattrcache@apache.org");
+        userTO.getVirAttrs().clear();
+
+        AttrTO virAttrTO = new AttrTO();
+        virAttrTO.setSchema("virtualdata");
+        virAttrTO.getValues().add("virattrcache");
+        userTO.getVirAttrs().add(virAttrTO);
+
+        userTO.getMemberships().clear();
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+        // 1. create user
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+
+        // 2. check for virtual attribute value
+        actual = userService.read(actual.getKey());
+        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // 3. update virtual attribute directly
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+        String value = jdbcTemplate.queryForObject(
+                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+        assertEquals("virattrcache", value);
+
+        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
+
+        value = jdbcTemplate.queryForObject(
+                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+        assertEquals("virattrcache2", value);
+
+        // 4. check for cached attribute value
+        actual = userService.read(actual.getKey());
+        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(actual.getKey());
+        userPatch.getVirAttrs().add(attrTO("virtualdata", "virtualupdated"));
+
+        // 5. update virtual attribute
+        actual = updateUser(userPatch).getAny();
+        assertNotNull(actual);
+
+        // 6. check for virtual attribute value
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertEquals("virtualupdated", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+    }
+
+    @Test
+    public void issueSYNCOPE397() {
+        ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
+
+        // change mapping of resource-csv
+        MappingTO origMapping = SerializationUtils.clone(csv.getProvisions().get(0).getMapping());
+        try {
+            // remove this mapping
+            CollectionUtils.filterInverse(csv.getProvisions().get(0).getMapping().getItems(),
+                    new Predicate<MappingItemTO>() {
+
+                        @Override
+                        public boolean evaluate(final MappingItemTO item) {
+                            return "email".equals(item.getIntAttrName());
+                        }
+                    });
+
+            resourceService.update(csv);
+            csv = resourceService.read(RESOURCE_NAME_CSV);
+            assertNotNull(csv.getProvisions().get(0).getMapping());
+
+            // create new virtual schema for the resource below
+            ProvisionTO provision = csv.getProvision(AnyTypeKind.USER.name());
+            assertNotNull(provision);
+
+            VirSchemaTO virSchema = new VirSchemaTO();
+            virSchema.setKey("syncope397" + getUUIDString());
+            virSchema.setExtAttrName("email");
+            virSchema.setProvision(provision.getKey());
+            virSchema = createSchema(SchemaType.VIRTUAL, virSchema);
+            assertNotNull(virSchema);
+
+            AnyTypeClassTO newClass = new AnyTypeClassTO();
+            newClass.setKey("syncope397" + getUUIDString());
+            newClass.getVirSchemas().add(virSchema.getKey());
+            Response response = anyTypeClassService.create(newClass);
+            assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+            newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+
+            // create a new user
+            UserTO userTO = UserITCase.getUniqueSampleTO("397@syncope.apache.org");
+            userTO.getAuxClasses().add("csv");
+            userTO.getAuxClasses().add(newClass.getKey());
+            userTO.getResources().clear();
+            userTO.getMemberships().clear();
+            userTO.getDerAttrs().clear();
+            userTO.getVirAttrs().clear();
+
+            userTO.getDerAttrs().add(attrTO("csvuserid", null));
+            userTO.getDerAttrs().add(attrTO("cn", null));
+            userTO.getVirAttrs().add(attrTO(virSchema.getKey(), "test@testone.org"));
+            // assign resource-csv to user
+            userTO.getResources().add(RESOURCE_NAME_CSV);
+            // save user
+            userTO = createUser(userTO).getAny();
+            // make std controls about user
+            assertNotNull(userTO);
+            assertTrue(RESOURCE_NAME_CSV.equals(userTO.getResources().iterator().next()));
+            assertEquals("test@testone.org", userTO.getVirAttrs().iterator().next().getValues().get(0));
+
+            // update user
+            UserTO toBeUpdated = userService.read(userTO.getKey());
+            UserPatch userPatch = new UserPatch();
+            userPatch.setKey(toBeUpdated.getKey());
+            userPatch.setPassword(new PasswordPatch.Builder().value("password234").build());
+            // assign new resource to user
+            userPatch.getResources().add(new StringPatchItem.Builder().
+                    operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build());
+            // modify virtual attribute
+            userPatch.getVirAttrs().add(attrTO(virSchema.getKey(), "test@testoneone.com"));
+
+            // check Syncope change password
+            userPatch.setPassword(new PasswordPatch.Builder().
+                    value("password234").
+                    onSyncope(true).
+                    resource(RESOURCE_NAME_WS2).
+                    build());
+
+            ProvisioningResult<UserTO> result = updateUser(userPatch);
+            assertNotNull(result);
+            toBeUpdated = result.getAny();
+            assertTrue(toBeUpdated.getVirAttrs().iterator().next().getValues().contains("test@testoneone.com"));
+            // check if propagates correctly with assertEquals on size of tasks list
+            assertEquals(2, result.getPropagationStatuses().size());
+        } finally {
+            // restore mapping of resource-csv
+            csv.getProvisions().get(0).setMapping(origMapping);
+            resourceService.update(csv);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE442() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope442@apache.org");
+        userTO.getVirAttrs().clear();
+
+        AttrTO virAttrTO = new AttrTO();
+        virAttrTO.setSchema("virtualdata");
+        virAttrTO.getValues().add("virattrcache");
+        userTO.getVirAttrs().add(virAttrTO);
+
+        userTO.getMemberships().clear();
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+        // 1. create user
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        // 2. check for virtual attribute value
+        userTO = userService.read(userTO.getKey());
+        assertEquals("virattrcache", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // ----------------------------------------
+        // 3. change connector URL so that we are sure that any provided value will come from virtual cache
+        // ----------------------------------------
+        String jdbcURL = null;
+        ConnInstanceTO connInstanceTO = connectorService.readByResource(
+                RESOURCE_NAME_DBVIRATTR, Locale.ENGLISH.getLanguage());
+        for (ConnConfProperty prop : connInstanceTO.getConf()) {
+            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
+                jdbcURL = prop.getValues().iterator().next().toString();
+                prop.getValues().clear();
+                prop.getValues().add("jdbc:h2:tcp://localhost:9092/xxx");
+            }
+        }
+
+        connectorService.update(connInstanceTO);
+        // ----------------------------------------
+
+        // ----------------------------------------
+        // 4. update value on external resource
+        // ----------------------------------------
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+        String value = jdbcTemplate.queryForObject(
+                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
+        assertEquals("virattrcache", value);
+
+        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", userTO.getKey());
+
+        value = jdbcTemplate.queryForObject(
+                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
+        assertEquals("virattrcache2", value);
+        // ----------------------------------------
+
+        userTO = userService.read(userTO.getKey());
+        assertEquals("virattrcache", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // ----------------------------------------
+        // 5. restore connector URL, values can be read again from external resource
+        // ----------------------------------------
+        for (ConnConfProperty prop : connInstanceTO.getConf()) {
+            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
+                prop.getValues().clear();
+                prop.getValues().add(jdbcURL);
+            }
+        }
+
+        connectorService.update(connInstanceTO);
+        // ----------------------------------------
+
+        // cached value still in place...
+        userTO = userService.read(userTO.getKey());
+        assertEquals("virattrcache", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // force cache update by adding a resource which has virtualdata mapped for propagation
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build());
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+
+        userTO = userService.read(userTO.getKey());
+        assertEquals("virattrcache2", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+    }
+
+    @Test
+    public void issueSYNCOPE436() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope436@syncope.apache.org");
+        userTO.getMemberships().clear();
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_LDAP);
+        userTO.getVirAttrs().add(attrTO("virtualReadOnly", "readOnly"));
+        userTO = createUser(userTO).getAny();
+        // finding no values because the virtual attribute is readonly 
+        assertTrue(userTO.getVirAttrMap().get("virtualReadOnly").getValues().isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE453() {
+        final String resourceName = "issueSYNCOPE453-Res-" + getUUIDString();
+        final String groupName = "issueSYNCOPE453-Group-" + getUUIDString();
+
+        // -------------------------------------------
+        // Create a resource ad-hoc
+        // -------------------------------------------
+        ResourceTO resourceTO = new ResourceTO();
+
+        resourceTO.setKey(resourceName);
+        resourceTO.setConnector(107L);
+
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
+
+        MappingItemTO item = new MappingItemTO();
+        item.setIntAttrName("aLong");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setExtAttrName("ID");
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        item.setConnObjectKey(true);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("USERNAME");
+        item.setIntAttrName("username");
+        item.setIntMappingType(IntMappingType.Username);
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.getItems().add(item);
+
+        item = new MappingItemTO();
+        item.setExtAttrName("EMAIL");
+        item.setIntAttrName("rvirtualdata");
+        item.setIntMappingType(IntMappingType.GroupVirtualSchema);
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.getItems().add(item);
+
+        assertNotNull(getObject(
+                resourceService.create(resourceTO).getLocation(), ResourceService.class, ResourceTO.class));
+        // -------------------------------------------
+
+        // -------------------------------------------
+        // Create a VirAttrITCase ad-hoc
+        // -------------------------------------------
+        GroupTO groupTO = new GroupTO();
+        groupTO.setName(groupName);
+        groupTO.setRealm("/");
+        groupTO.getVirAttrs().add(attrTO("rvirtualdata", "ml@group.it"));
+        groupTO.getResources().add(RESOURCE_NAME_LDAP);
+        groupTO = createGroup(groupTO).getAny();
+        assertEquals(1, groupTO.getVirAttrs().size());
+        assertEquals("ml@group.it", groupTO.getVirAttrs().iterator().next().getValues().get(0));
+        // -------------------------------------------
+
+        // -------------------------------------------
+        // Create new user
+        // -------------------------------------------
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope453@syncope.apache.org");
+        userTO.getPlainAttrs().add(attrTO("aLong", "123"));
+        userTO.getResources().clear();
+        userTO.getResources().add(resourceName);
+        userTO.getVirAttrs().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getMemberships().clear();
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertEquals(2, result.getPropagationStatuses().size());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(1).getStatus());
+        userTO = result.getAny();
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+        final Map<String, Object> actuals = jdbcTemplate.queryForMap(
+                "SELECT id, surname, email FROM testsync WHERE id=?",
+                new Object[] { Integer.parseInt(userTO.getPlainAttrMap().get("aLong").getValues().get(0)) });
+
+        assertEquals(userTO.getPlainAttrMap().get("aLong").getValues().get(0), actuals.get("id").toString());
+        assertEquals("ml@group.it", actuals.get("email"));
+        // -------------------------------------------
+
+        // -------------------------------------------
+        // Delete resource and group ad-hoc
+        // -------------------------------------------
+        resourceService.delete(resourceName);
+        groupService.delete(groupTO.getKey());
+        // -------------------------------------------
+    }
+
+    @Test
+    public void issueSYNCOPE459() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope459@apache.org");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_LDAP);
+        userTO.getMemberships().clear();
+        userTO.getVirAttrs().clear();
+
+        userTO = createUser(userTO).getAny();
+
+        assertNotNull(userTO.getVirAttrMap().get("virtualReadOnly"));
+    }
+
+    @Test
+    public void issueSYNCOPE501() {
+        // 1. create user and propagate him on resource-db-virattr
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope501@apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getVirAttrs().clear();
+
+        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+        // virtualdata is mapped with username
+        userTO.getVirAttrs().add(attrTO("virtualdata", "syncope501@apache.org"));
+
+        userTO = createUser(userTO).getAny();
+
+        assertNotNull(userTO.getVirAttrMap().get("virtualdata"));
+        assertEquals("syncope501@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // 2. update virtual attribute
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        // change virtual attribute value
+        userPatch.getVirAttrs().add(attrTO("virtualdata", "syncope501_updated@apache.org"));
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+
+        // 3. check that user virtual attribute has really been updated 
+        assertFalse(userTO.getVirAttrMap().get("virtualdata").getValues().isEmpty());
+        assertEquals("syncope501_updated@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+    }
+
+    @Test
+    public void issueSYNCOPE691() {
+        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+        try {
+            ProvisionTO provision = ldap.getProvision(AnyTypeKind.USER.name());
+            assertNotNull(provision);
+            CollectionUtils.filterInverse(provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+
+                @Override
+                public boolean evaluate(final MappingItemTO item) {
+                    return "mail".equals(item.getExtAttrName());
+                }
+            });
+            provision.getVirSchemas().clear();
+
+            ldap.setKey(RESOURCE_NAME_LDAP + "691" + getUUIDString());
+            resourceService.create(ldap);
+
+            ldap = resourceService.read(ldap.getKey());
+            provision = ldap.getProvision(AnyTypeKind.USER.name());
+            assertNotNull(provision);
+
+            // create new virtual schema for the resource below
+            VirSchemaTO virSchema = new VirSchemaTO();
+            virSchema.setKey("syncope691" + getUUIDString());
+            virSchema.setExtAttrName("mail");
+            virSchema.setProvision(provision.getKey());
+            virSchema = createSchema(SchemaType.VIRTUAL, virSchema);
+            assertNotNull(virSchema);
+
+            AnyTypeClassTO newClass = new AnyTypeClassTO();
+            newClass.setKey("syncope691" + getUUIDString());
+            newClass.getVirSchemas().add(virSchema.getKey());
+            Response response = anyTypeClassService.create(newClass);
+            assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+            newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+
+            // create a new user
+            UserTO userTO = UserITCase.getUniqueSampleTO("syncope691@syncope.apache.org");
+            userTO.getAuxClasses().add(newClass.getKey());
+            userTO.getResources().clear();
+            userTO.getMemberships().clear();
+            userTO.getDerAttrs().clear();
+            userTO.getVirAttrs().clear();
+
+            AttrTO emailTO = new AttrTO();
+            emailTO.setSchema(virSchema.getKey());
+            emailTO.getValues().add("test@issue691.dom1.org");
+            emailTO.getValues().add("test@issue691.dom2.org");
+
+            userTO.getVirAttrs().add(emailTO);
+            // assign resource-ldap691 to user
+            userTO.getResources().add(ldap.getKey());
+            // save user
+            userTO = createUser(userTO).getAny();
+            // make std controls about user
+            assertNotNull(userTO);
+            assertTrue(ldap.getKey().equals(userTO.getResources().iterator().next()));
+
+            assertEquals(2, userTO.getVirAttrs().iterator().next().getValues().size(), 0);
+            assertTrue(userTO.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom1.org"));
+            assertTrue(userTO.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom2.org"));
+
+            // update user
+            UserPatch userPatch = new UserPatch();
+            userPatch.setKey(userTO.getKey());
+            // modify virtual attribute
+            userPatch.getVirAttrs().add(
+                    new AttrTO.Builder().schema(virSchema.getKey()).
+                    value("test@issue691.dom3.org").
+                    value("test@issue691.dom4.org").
+                    build());
+
+            UserTO updated = updateUser(userPatch).getAny();
+            assertNotNull(updated);
+            assertEquals(2, updated.getVirAttrs().iterator().next().getValues().size(), 0);
+            assertTrue(updated.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom3.org"));
+            assertTrue(updated.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom4.org"));
+        } finally {
+            try {
+                resourceService.delete(ldap.getKey());
+            } catch (Exception ignore) {
+                // ignore
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java
new file mode 100644
index 0000000..01ce60f
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java
@@ -0,0 +1,152 @@
+/*
+ * 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.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.VirSchemaTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.beans.SchemaQuery;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class VirSchemaITCase extends AbstractITCase {
+
+    @Test
+    public void list() {
+        List<VirSchemaTO> vSchemas = schemaService.list(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build());
+        assertFalse(vSchemas.isEmpty());
+        for (VirSchemaTO vSchemaTO : vSchemas) {
+            assertNotNull(vSchemaTO);
+        }
+    }
+
+    @Test
+    public void crud() {
+        ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
+        assertNotNull(csv);
+        assertEquals(1, csv.getProvisions().size());
+        assertTrue(csv.getProvisions().get(0).getVirSchemas().isEmpty());
+
+        VirSchemaTO schema = new VirSchemaTO();
+        schema.setKey("virtualTest" + getUUIDString());
+        schema.setExtAttrName("name");
+        schema.setProvision(csv.getProvisions().get(0).getKey());
+
+        schema = createSchema(SchemaType.VIRTUAL, schema);
+        assertNotNull(schema);
+        assertEquals(csv.getProvisions().get(0).getKey(), schema.getProvision(), 0);
+
+        csv = resourceService.read(RESOURCE_NAME_CSV);
+        assertNotNull(csv);
+        assertEquals(1, csv.getProvisions().size());
+        assertFalse(csv.getProvisions().get(0).getVirSchemas().isEmpty());
+
+        schema = schemaService.read(SchemaType.VIRTUAL, schema.getKey());
+        assertNotNull(schema);
+
+        schemaService.delete(SchemaType.VIRTUAL, schema.getKey());
+
+        try {
+            schemaService.read(SchemaType.VIRTUAL, schema.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+
+        csv = resourceService.read(RESOURCE_NAME_CSV);
+        assertNotNull(csv);
+        assertEquals(1, csv.getProvisions().size());
+        assertTrue(csv.getProvisions().get(0).getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void anonymous() {
+        SchemaService unauthenticated = clientFactory.create().getService(SchemaService.class);
+        try {
+            unauthenticated.list(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build());
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        SchemaService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(SchemaService.class);
+        assertFalse(anonymous.list(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build()).isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        VirSchemaTO actual = schemaService.read(SchemaType.VIRTUAL, "virtualdata");
+        assertNotNull(actual);
+
+        try {
+            createSchema(SchemaType.VIRTUAL, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createSchema(SchemaType.VIRTUAL, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        ResourceTO ws1 = resourceService.read(RESOURCE_NAME_WS1);
+        assertNotNull(ws1);
+        assertEquals(1, ws1.getProvisions().size());
+        assertTrue(ws1.getProvisions().get(0).getVirSchemas().isEmpty());
+
+        VirSchemaTO schema = new VirSchemaTO();
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+        schema.setExtAttrName("name");
+        schema.setProvision(ws1.getProvisions().get(0).getKey());
+
+        try {
+            createSchema(SchemaType.VIRTUAL, schema);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidVirSchema, e.getType());
+
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/WorkflowITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/WorkflowITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/WorkflowITCase.java
new file mode 100644
index 0000000..d111782
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/WorkflowITCase.java
@@ -0,0 +1,78 @@
+/*
+ * 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.fit.core;
+
+import org.apache.syncope.fit.ActivitiDetector;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class WorkflowITCase extends AbstractITCase {
+
+    private void exportDefinition(final AnyTypeKind type) throws IOException {
+        Response response = workflowService.exportDefinition(type);
+        assertTrue(response.getMediaType().toString().
+                startsWith(clientFactory.getContentType().getMediaType().toString()));
+        assertTrue(response.getEntity() instanceof InputStream);
+        String definition = IOUtils.toString((InputStream) response.getEntity());
+        assertNotNull(definition);
+        assertFalse(definition.isEmpty());
+    }
+
+    @Test
+    public void exportUserDefinition() throws IOException {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+        exportDefinition(AnyTypeKind.USER);
+    }
+
+    @Test
+    public void getGroupDefinition() throws IOException {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForGroups(syncopeService));
+        exportDefinition(AnyTypeKind.GROUP);
+    }
+
+    private void importDefinition(final AnyTypeKind type) throws IOException {
+        Response response = workflowService.exportDefinition(type);
+        String definition = IOUtils.toString((InputStream) response.getEntity());
+
+        workflowService.importDefinition(type, definition);
+    }
+
+    @Test
+    public void updateUserDefinition() throws IOException {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+        importDefinition(AnyTypeKind.USER);
+    }
+
+    @Test
+    public void updateGroupDefinition() throws IOException {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForGroups(syncopeService));
+        importDefinition(AnyTypeKind.GROUP);
+    }
+}


[14/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
new file mode 100644
index 0000000..00de99b
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
@@ -0,0 +1,2561 @@
+/*
+ * 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.fit.core;
+
+import org.apache.syncope.fit.ActivitiDetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.naming.NamingException;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.patch.AssociationPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.DeassociationPatch;
+import org.apache.syncope.common.lib.patch.MembershipPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.StatusPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.policy.AccountPolicyTO;
+import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
+import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.BulkActionResult.Status;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
+import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
+import org.apache.syncope.common.lib.types.StatusPatchType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
+import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
+import org.apache.syncope.fit.core.reference.DoubleValueLogicActions;
+import org.apache.syncope.fit.core.reference.TestAccountRuleConf;
+import org.apache.syncope.fit.core.reference.TestPasswordRuleConf;
+import org.apache.syncope.fit.AbstractITCase;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class UserITCase extends AbstractITCase {
+
+    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+        @Override
+        protected SimpleDateFormat initialValue() {
+            SimpleDateFormat sdf = new SimpleDateFormat();
+            sdf.applyPattern("yyyy-MM-dd");
+            return sdf;
+        }
+    };
+
+    private boolean getBooleanAttribute(final ConnObjectTO connObjectTO, final String attrName) {
+        return Boolean.parseBoolean(connObjectTO.getPlainAttrMap().get(attrName).getValues().get(0));
+    }
+
+    public static UserTO getUniqueSampleTO(final String email) {
+        return getSampleTO(getUUIDString() + email);
+    }
+
+    public static UserTO getSampleTO(final String email) {
+        UserTO userTO = new UserTO();
+        userTO.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO.setPassword("password123");
+        userTO.setUsername(email);
+
+        userTO.getPlainAttrs().add(attrTO("fullname", email));
+        userTO.getPlainAttrs().add(attrTO("firstname", email));
+        userTO.getPlainAttrs().add(attrTO("surname", "surname"));
+        userTO.getPlainAttrs().add(attrTO("type", "a type"));
+        userTO.getPlainAttrs().add(attrTO("userId", email));
+        userTO.getPlainAttrs().add(attrTO("email", email));
+        userTO.getPlainAttrs().add(attrTO("loginDate", DATE_FORMAT.get().format(new Date())));
+        userTO.getDerAttrs().add(attrTO("cn", null));
+        return userTO;
+    }
+
+    @Test
+    public void createUserWithNoPropagation() {
+        // get task list
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        long maxKey = tasks.getResult().iterator().next().getKey();
+
+        // create a new user
+        UserTO userTO = getUniqueSampleTO("xxx@xxx.xxx");
+        userTO.setPassword("password123");
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
+
+        createUser(userTO);
+
+        // get the new task list
+        tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        long newMaxKey = tasks.getResult().iterator().next().getKey();
+
+        assertTrue(newMaxKey > maxKey);
+
+        // get last task
+        PropagationTaskTO taskTO = taskService.read(newMaxKey, true);
+        assertNotNull(taskTO);
+        assertFalse(taskTO.getExecutions().isEmpty());
+        assertEquals(PropagationTaskExecStatus.NOT_ATTEMPTED.name(), taskTO.getExecutions().get(0).getStatus());
+    }
+
+    @Test
+    public void issue186() {
+        // 1. create an user with strict mandatory attributes only
+        UserTO userTO = new UserTO();
+        userTO.setRealm(SyncopeConstants.ROOT_REALM);
+        String userId = getUUIDString() + "issue186@syncope.apache.org";
+        userTO.setUsername(userId);
+        userTO.setPassword("password123");
+
+        userTO.getPlainAttrs().add(attrTO("userId", userId));
+        userTO.getPlainAttrs().add(attrTO("fullname", userId));
+        userTO.getPlainAttrs().add(attrTO("surname", userId));
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertTrue(userTO.getResources().isEmpty());
+
+        // 2. update assigning a resource forcing mandatory constraints: must fail with RequiredValuesMissing
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build());
+
+        try {
+            userTO = updateUser(userPatch).getAny();
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+
+        // 3. update assigning a resource NOT forcing mandatory constraints
+        // AND priority: must fail with PropagationException
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
+
+        ProvisioningResult<UserTO> result = updateUser(userPatch);
+        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
+        userTO = result.getAny();
+
+        // 4. update assigning a resource NOT forcing mandatory constraints
+        // BUT not priority: must succeed
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123456").build());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_CSV).build());
+
+        updateUser(userPatch);
+    }
+
+    @Test
+    public void enforceMandatoryCondition() {
+        UserTO userTO = getUniqueSampleTO("enforce@apache.org");
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+        userTO.setPassword("newPassword12");
+
+        AttrTO type = null;
+        for (AttrTO attr : userTO.getPlainAttrs()) {
+            if ("type".equals(attr.getSchema())) {
+                type = attr;
+            }
+        }
+        assertNotNull(type);
+        userTO.getPlainAttrs().remove(type);
+
+        try {
+            userTO = createUser(userTO).getAny();
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+
+        userTO.getPlainAttrs().add(type);
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+    }
+
+    @Test
+    public void enforceMandatoryConditionOnDerived() {
+        ResourceTO resourceTO = resourceService.read(RESOURCE_NAME_CSV);
+        assertNotNull(resourceTO);
+        resourceTO.setKey("resource-csv-enforcing");
+        resourceTO.setEnforceMandatoryCondition(true);
+
+        Response response = resourceService.create(resourceTO);
+        resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+        assertNotNull(resourceTO);
+
+        try {
+            UserTO userTO = getUniqueSampleTO("syncope222@apache.org");
+            userTO.getResources().add(resourceTO.getKey());
+            userTO.setPassword("newPassword12");
+
+            try {
+                userTO = createUser(userTO).getAny();
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+            }
+
+            userTO.getAuxClasses().add("csv");
+            userTO.getDerAttrs().add(new AttrTO.Builder().schema("csvuserid").build());
+
+            userTO = createUser(userTO).getAny();
+            assertNotNull(userTO);
+            assertEquals(Collections.singleton(resourceTO.getKey()), userTO.getResources());
+        } finally {
+            resourceService.delete(resourceTO.getKey());
+        }
+    }
+
+    @Test
+    public void createUserWithDbPropagation() {
+        UserTO userTO = getUniqueSampleTO("yyy@yyy.yyy");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertNotNull(result);
+        assertEquals(1, result.getPropagationStatuses().size());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithInvalidPassword() {
+        UserTO userTO = getSampleTO("invalidpasswd@syncope.apache.org");
+        userTO.setPassword("pass");
+        createUser(userTO);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithInvalidUsername() {
+        UserTO userTO = getSampleTO("invalidusername@syncope.apache.org");
+        userTO.setUsername("us");
+        userTO.setRealm("/odd");
+
+        createUser(userTO);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithInvalidPasswordByRes() {
+        UserTO userTO = getSampleTO("invalidPwdByRes@passwd.com");
+
+        // configured to be minLength=16
+        userTO.setPassword("password1");
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
+        createUser(userTO);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithInvalidPasswordByGroup() {
+        UserTO userTO = getSampleTO("invalidPwdByGroup@passwd.com");
+
+        // configured to be minLength=16
+        userTO.setPassword("password1");
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+
+        createUser(userTO);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithException() {
+        UserTO newUserTO = new UserTO();
+        newUserTO.getPlainAttrs().add(attrTO("userId", "userId@nowhere.org"));
+        createUser(newUserTO);
+    }
+
+    @Test
+    public void create() {
+        // get task list
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        long maxKey = tasks.getResult().iterator().next().getKey();
+        PropagationTaskTO taskTO = taskService.read(maxKey, true);
+
+        assertNotNull(taskTO);
+        int maxTaskExecutions = taskTO.getExecutions().size();
+
+        UserTO userTO = getUniqueSampleTO("a.b@c.com");
+
+        // add a membership
+        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+
+        // add an attribute with a non-existing schema: must be ignored
+        AttrTO attrWithInvalidSchemaTO = attrTO("invalid schema", "a value");
+        userTO.getPlainAttrs().add(attrWithInvalidSchemaTO);
+
+        // add an attribute with null value: must be ignored
+        userTO.getPlainAttrs().add(attrTO("activationDate", null));
+
+        // 1. create user
+        UserTO newUserTO = createUser(userTO).getAny();
+
+        assertNotNull(newUserTO);
+
+        // issue SYNCOPE-15
+        assertNotNull(newUserTO.getCreationDate());
+        assertNotNull(newUserTO.getCreator());
+        assertNotNull(newUserTO.getLastChangeDate());
+        assertNotNull(newUserTO.getLastModifier());
+        assertEquals(newUserTO.getCreationDate(), newUserTO.getLastChangeDate());
+
+        assertFalse(newUserTO.getPlainAttrs().contains(attrWithInvalidSchemaTO));
+
+        // check for changePwdDate
+        assertNotNull(newUserTO.getCreationDate());
+
+        // get the new task list
+        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        long newMaxKey = tasks.getResult().iterator().next().getKey();
+
+        // default configuration for ws-target-resource2:
+        // only failed executions have to be registered
+        // --> no more tasks/executions should be added
+        assertEquals(newMaxKey, maxKey);
+
+        // get last task
+        taskTO = taskService.read(newMaxKey, true);
+
+        assertNotNull(taskTO);
+        assertEquals(maxTaskExecutions, taskTO.getExecutions().size());
+
+        // 3. verify password
+        try {
+            Pair<Map<String, Set<String>>, UserTO> self =
+                    clientFactory.create(newUserTO.getUsername(), "password123").self();
+            assertNotNull(self);
+        } catch (AccessControlException e) {
+            fail("Credentials should be valid and not cause AccessControlException");
+        }
+
+        UserSelfService userSelfService2 = clientFactory.create(
+                newUserTO.getUsername(), "passwordXX").getService(UserSelfService.class);
+        try {
+            userSelfService2.read();
+            fail("Credentials are invalid, thus request should raise AccessControlException");
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        // 4. try (and fail) to create another user with same (unique) values
+        userTO = getSampleTO(userTO.getUsername());
+        AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
+        userIdAttr.getValues().clear();
+        userIdAttr.getValues().add("a.b@c.com");
+
+        try {
+            createUser(userTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.GenericPersistence, e.getType());
+        }
+    }
+
+    @Test
+    public void createWithRequiredValueMissing() {
+        UserTO userTO = getUniqueSampleTO("a.b@c.it");
+
+        AttrTO type = userTO.getPlainAttrMap().get("type");
+        userTO.getPlainAttrs().remove(type);
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+
+        // 1. create user without type (mandatory by UserSchema)
+        try {
+            createUser(userTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+
+        userTO.getPlainAttrs().add(attrTO("type", "F"));
+
+        AttrTO surname = userTO.getPlainAttrMap().get("surname");
+        userTO.getPlainAttrs().remove(surname);
+
+        // 2. create user without surname (mandatory when type == 'F')
+        try {
+            createUser(userTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void delete() {
+        try {
+            userService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        UserTO userTO = getSampleTO("qqgf.z@nn.com");
+
+        // specify a propagation
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        userTO = createUser(userTO).getAny();
+
+        long key = userTO.getKey();
+
+        ProvisioningResult<UserTO> result = deleteUser(key);
+        assertNotNull(result);
+        userTO = result.getAny();
+        assertEquals(key, userTO.getKey(), 0);
+        assertTrue(userTO.getPlainAttrs().isEmpty());
+
+        // check for propagation result
+        assertFalse(result.getPropagationStatuses().isEmpty());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+
+        try {
+            userService.delete(userTO.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void deleteByUsername() {
+        UserTO userTO = getSampleTO("delete.by.username@apache.org");
+
+        // specify a propagation
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        userTO = createUser(userTO).getAny();
+
+        long key = userTO.getKey();
+        userTO = userService.read(key);
+
+        ProvisioningResult<UserTO> result = deleteUser(userTO.getKey());
+        assertNotNull(result);
+        userTO = result.getAny();
+        assertEquals(key, userTO.getKey(), 0);
+        assertTrue(userTO.getPlainAttrs().isEmpty());
+
+        // check for propagation result
+        assertFalse(result.getPropagationStatuses().isEmpty());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+
+        try {
+            userService.read(userTO.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        PagedResult<UserTO> users = userService.list(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
+        assertNotNull(users);
+        assertFalse(users.getResult().isEmpty());
+
+        for (UserTO user : users.getResult()) {
+            assertNotNull(user);
+        }
+    }
+
+    @Test
+    public void paginatedList() {
+        PagedResult<UserTO> users = userService.list(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).page(1).size(2).build());
+        assertNotNull(users);
+        assertFalse(users.getResult().isEmpty());
+        assertEquals(2, users.getResult().size());
+
+        for (UserTO user : users.getResult()) {
+            assertNotNull(user);
+        }
+
+        users = userService.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                page(2).size(2).build());
+        assertNotNull(users);
+        assertEquals(2, users.getPage());
+        assertEquals(2, users.getResult().size());
+
+        users = userService.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                page(100).size(2).build());
+        assertNotNull(users);
+        assertTrue(users.getResult().isEmpty());
+    }
+
+    @Test
+    public void read() {
+        UserTO userTO = userService.read(1L);
+
+        assertNotNull(userTO);
+        assertNull(userTO.getPassword());
+        assertNotNull(userTO.getPlainAttrs());
+        assertFalse(userTO.getPlainAttrs().isEmpty());
+    }
+
+    @Test
+    public void readWithMailAddressAsUserName() {
+        UserTO userTO = createUser(getUniqueSampleTO("mail@domain.org")).getAny();
+        userTO = userService.read(userTO.getKey());
+        assertNotNull(userTO);
+    }
+
+    @Test
+    public void updateWithoutPassword() {
+        UserTO userTO = getUniqueSampleTO("updatewithout@password.com");
+
+        userTO = createUser(userTO).getAny();
+
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getPlainAttrs().add(new AttrPatch.Builder().operation(PatchOperation.DELETE).
+                attrTO(new AttrTO.Builder().schema("type").build()).
+                build());
+
+        userTO = updateUser(userPatch).getAny();
+
+        assertNotNull(userTO);
+        assertNotNull(userTO.getDerAttrMap());
+        assertFalse(userTO.getPlainAttrMap().containsKey("type"));
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void updateInvalidPassword() {
+        UserTO userTO = getSampleTO("updateinvalid@password.com");
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("pass").build());
+
+        userService.update(userPatch);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void updateSamePassword() {
+        UserTO userTO = getUniqueSampleTO("updatesame@password.com");
+        userTO.setRealm("/even/two");
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("password123").build());
+
+        userService.update(userPatch);
+    }
+
+    @Test
+    public void update() {
+        UserTO userTO = getUniqueSampleTO("g.h@t.com");
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+
+        userTO = createUser(userTO).getAny();
+
+        assertFalse(userTO.getDerAttrs().isEmpty());
+        assertEquals(1, userTO.getMemberships().size());
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("new2Password").build());
+
+        String newUserId = getUUIDString() + "t.w@spre.net";
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("userId", newUserId));
+
+        String newFullName = getUUIDString() + "g.h@t.com";
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("fullname", newFullName));
+
+        userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).
+                membershipTO(new MembershipTO.Builder().group(8L).build()).build());
+        userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).
+                membershipTO(userTO.getMemberships().get(0)).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+
+        // issue SYNCOPE-15
+        assertNotNull(userTO.getCreationDate());
+        assertNotNull(userTO.getCreator());
+        assertNotNull(userTO.getLastChangeDate());
+        assertNotNull(userTO.getLastModifier());
+        assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
+
+        assertEquals(1, userTO.getMemberships().size());
+        assertFalse(userTO.getDerAttrs().isEmpty());
+
+        AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
+        assertEquals(Collections.singletonList(newUserId), userIdAttr.getValues());
+
+        AttrTO fullNameAttr = userTO.getPlainAttrMap().get("fullname");
+        assertEquals(Collections.singletonList(newFullName), fullNameAttr.getValues());
+    }
+
+    @Test
+    public void updatePasswordOnly() {
+        int beforeTasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build()).getTotalCount();
+        assertFalse(beforeTasks <= 0);
+
+        UserTO userTO = getUniqueSampleTO("pwdonly@t.com");
+        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+
+        userTO = createUser(userTO).getAny();
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").resource(RESOURCE_NAME_WS2).build());
+
+        userTO = updateUser(userPatch).getAny();
+
+        // check for changePwdDate
+        assertNotNull(userTO.getChangePwdDate());
+
+        int afterTasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build()).getTotalCount();
+        assertFalse(beforeTasks <= 0);
+
+        assertTrue(beforeTasks < afterTasks);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void verifyTaskRegistration() {
+        // get task list
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        long maxKey = tasks.getResult().iterator().next().getKey();
+
+        // --------------------------------------
+        // Create operation
+        // --------------------------------------
+        UserTO userTO = getUniqueSampleTO("t@p.mode");
+
+        // add a membership
+        userTO.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+
+        // 1. create user
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        // get the new task list
+        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+        assertNotNull(tasks);
+        assertFalse(tasks.getResult().isEmpty());
+
+        long newMaxKey = tasks.getResult().iterator().next().getKey();
+
+        // default configuration for ws-target-resource2 during create:
+        // only failed executions have to be registered
+        // --> no more tasks/executions should be added
+        assertEquals(newMaxKey, maxKey);
+
+        // --------------------------------------
+        // Update operation
+        // --------------------------------------
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("surname", "surname2"));
+
+        userTO = updateUser(userPatch).getAny();
+
+        assertNotNull(userTO);
+
+        // get the new task list
+        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+
+        maxKey = newMaxKey;
+        newMaxKey = tasks.getResult().iterator().next().getKey();
+
+        // default configuration for ws-target-resource2 during update:
+        // all update executions have to be registered
+        assertTrue(newMaxKey > maxKey);
+
+        PropagationTaskTO taskTO = taskService.read(newMaxKey, true);
+
+        assertNotNull(taskTO);
+        assertEquals(1, taskTO.getExecutions().size());
+
+        // --------------------------------------
+        // Delete operation
+        // --------------------------------------
+        userService.delete(userTO.getKey());
+
+        // get the new task list
+        tasks = taskService.list(new TaskQuery.Builder().type(TaskType.PROPAGATION).page(1).size(1).build());
+
+        maxKey = newMaxKey;
+        newMaxKey = tasks.getResult().iterator().next().getKey();
+
+        // default configuration for ws-target-resource2: no delete executions have to be registered
+        // --> no more tasks/executions should be added
+        assertEquals(newMaxKey, maxKey);
+    }
+
+    @Test
+    public void createActivate() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        UserTO userTO = getUniqueSampleTO("createActivate@syncope.apache.org");
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(11L).build());
+
+        userTO = createUser(userTO).getAny();
+
+        assertNotNull(userTO);
+        assertNotNull(userTO.getToken());
+        assertNotNull(userTO.getTokenExpireTime());
+
+        assertEquals("created", userTO.getStatus());
+
+        StatusPatch statusPatch = new StatusPatch();
+        statusPatch.setKey(userTO.getKey());
+        statusPatch.setType(StatusPatchType.ACTIVATE);
+        statusPatch.setToken(userTO.getToken());
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+
+        assertNotNull(userTO);
+        assertNull(userTO.getToken());
+        assertNull(userTO.getTokenExpireTime());
+        assertEquals("active", userTO.getStatus());
+    }
+
+    @Test
+    public void suspendReactivate() {
+        UserTO userTO = getUniqueSampleTO("suspendReactivate@syncope.apache.org");
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
+
+        userTO = createUser(userTO).getAny();
+
+        assertNotNull(userTO);
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                ? "active"
+                : "created", userTO.getStatus());
+
+        StatusPatch statusPatch = new StatusPatch();
+        statusPatch.setKey(userTO.getKey());
+        statusPatch.setType(StatusPatchType.SUSPEND);
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+        assertEquals("suspended", userTO.getStatus());
+
+        statusPatch = new StatusPatch();
+        statusPatch.setKey(userTO.getKey());
+        statusPatch.setType(StatusPatchType.REACTIVATE);
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+    }
+
+    @Test
+    public void suspendReactivateOnResource() {
+        // Assert resources are present
+        ResourceTO dbTable = resourceService.read(RESOURCE_NAME_TESTDB);
+        assertNotNull(dbTable);
+        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+        assertNotNull(ldap);
+
+        // Create user with reference to resources
+        UserTO userTO = getUniqueSampleTO("suspreactonresource@syncope.apache.org");
+        userTO.getMemberships().clear();
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+        userTO.getResources().add(RESOURCE_NAME_LDAP);
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                ? "active"
+                : "created", userTO.getStatus());
+        long userKey = userTO.getKey();
+
+        // Suspend with effect on syncope, ldap and db => user should be suspended in syncope and all resources
+        StatusPatch statusPatch = new StatusPatch();
+        statusPatch.setKey(userKey);
+        statusPatch.setType(StatusPatchType.SUSPEND);
+        statusPatch.setOnSyncope(true);
+        statusPatch.getResources().add(RESOURCE_NAME_TESTDB);
+        statusPatch.getResources().add(RESOURCE_NAME_LDAP);
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+        assertEquals("suspended", userTO.getStatus());
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
+        assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userKey);
+        assertNotNull(connObjectTO);
+
+        // Suspend and reactivate only on ldap => db and syncope should still show suspended
+        statusPatch = new StatusPatch();
+        statusPatch.setKey(userKey);
+        statusPatch.setType(StatusPatchType.SUSPEND);
+        statusPatch.setOnSyncope(false);
+        statusPatch.getResources().add(RESOURCE_NAME_LDAP);
+        userService.status(statusPatch);
+        statusPatch.setType(StatusPatchType.REACTIVATE);
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+        assertEquals("suspended", userTO.getStatus());
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
+        assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+
+        // Reactivate on syncope and db => syncope and db should show the user as active
+        statusPatch = new StatusPatch();
+        statusPatch.setKey(userKey);
+        statusPatch.setType(StatusPatchType.REACTIVATE);
+        statusPatch.setOnSyncope(true);
+        statusPatch.getResources().add(RESOURCE_NAME_TESTDB);
+
+        userTO = userService.status(statusPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
+        assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+    }
+
+    @Test
+    public void updateMultivalueAttribute() {
+        UserTO userTO = getUniqueSampleTO("multivalue@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        AttrTO loginDate = userTO.getPlainAttrMap().get("loginDate");
+        assertNotNull(loginDate);
+        assertEquals(1, loginDate.getValues().size());
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+
+        loginDate.getValues().add("2000-01-01");
+        userPatch.getPlainAttrs().add(new AttrPatch.Builder().
+                operation(PatchOperation.ADD_REPLACE).attrTO(loginDate).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+
+        loginDate = userTO.getPlainAttrMap().get("loginDate");
+        assertNotNull(loginDate);
+        assertEquals(2, loginDate.getValues().size());
+    }
+
+    private void verifyAsyncResult(final List<PropagationStatus> statuses) {
+        assertEquals(3, statuses.size());
+
+        Map<String, PropagationStatus> byResource = new HashMap<>(3);
+        MapUtils.populateMap(byResource, statuses, new Transformer<PropagationStatus, String>() {
+
+            @Override
+            public String transform(final PropagationStatus status) {
+                return status.getResource();
+            }
+        });
+        assertEquals(PropagationTaskExecStatus.SUCCESS, byResource.get(RESOURCE_NAME_LDAP).getStatus());
+        assertTrue(byResource.get(RESOURCE_NAME_TESTDB).getStatus() == PropagationTaskExecStatus.CREATED
+                || byResource.get(RESOURCE_NAME_TESTDB).getStatus() == PropagationTaskExecStatus.SUCCESS);
+        assertTrue(byResource.get(RESOURCE_NAME_TESTDB2).getStatus() == PropagationTaskExecStatus.CREATED
+                || byResource.get(RESOURCE_NAME_TESTDB2).getStatus() == PropagationTaskExecStatus.SUCCESS);
+    }
+
+    @Test
+    public void async() {
+        UserService asyncService =
+                clientFactory.create(ADMIN_UNAME, ADMIN_PWD).nullPriorityAsync(UserService.class, true);
+
+        UserTO user = getUniqueSampleTO("async@syncope.apache.org");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        user.getResources().add(RESOURCE_NAME_TESTDB2);
+        user.getResources().add(RESOURCE_NAME_LDAP);
+
+        ProvisioningResult<UserTO> result = asyncService.create(user).readEntity(
+                new GenericType<ProvisioningResult<UserTO>>() {
+        });
+        assertNotNull(result);
+        verifyAsyncResult(result.getPropagationStatuses());
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(result.getAny().getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().
+                onSyncope(true).resources(RESOURCE_NAME_LDAP, RESOURCE_NAME_TESTDB, RESOURCE_NAME_TESTDB2).
+                value("password321").build());
+
+        result = asyncService.update(userPatch).readEntity(
+                new GenericType<ProvisioningResult<UserTO>>() {
+        });
+        assertNotNull(result);
+        verifyAsyncResult(result.getPropagationStatuses());
+
+        result = asyncService.delete(result.getAny().getKey()).readEntity(
+                new GenericType<ProvisioningResult<UserTO>>() {
+        });
+        assertNotNull(result);
+        verifyAsyncResult(result.getPropagationStatuses());
+    }
+
+    @Test(expected = EmptyResultDataAccessException.class)
+    public void issue213() {
+        UserTO userTO = getUniqueSampleTO("issue213@syncope.apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals(1, userTO.getResources().size());
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+        String username = jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class,
+                userTO.getUsername());
+
+        assertEquals(userTO.getUsername(), username);
+
+        UserPatch userPatch = new UserPatch();
+
+        userPatch.setKey(userTO.getKey());
+        userPatch.getResources().add(
+                new StringPatchItem.Builder().operation(PatchOperation.DELETE).value(RESOURCE_NAME_TESTDB).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertTrue(userTO.getResources().isEmpty());
+
+        jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
+    }
+
+    @Test
+    public void issue234() {
+        UserTO inUserTO = getUniqueSampleTO("issue234@syncope.apache.org");
+        inUserTO.getResources().add(RESOURCE_NAME_LDAP);
+
+        UserTO userTO = createUser(inUserTO).getAny();
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+
+        userPatch.setKey(userTO.getKey());
+        userPatch.setUsername(new StringReplacePatchItem.Builder().value("1" + userTO.getUsername()).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+        assertEquals("1" + inUserTO.getUsername(), userTO.getUsername());
+    }
+
+    @Test
+    public final void issue280() {
+        UserTO userTO = getUniqueSampleTO("issue280@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).
+                resource(RESOURCE_NAME_TESTDB).value("123password").build());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
+
+        ProvisioningResult<UserTO> result = updateUser(userPatch);
+        assertNotNull(result);
+
+        List<PropagationStatus> propagations = result.getPropagationStatuses();
+        assertNotNull(propagations);
+        assertEquals(1, propagations.size());
+
+        assertEquals(PropagationTaskExecStatus.SUCCESS, propagations.get(0).getStatus());
+
+        String resource = propagations.get(0).getResource();
+        assertEquals(RESOURCE_NAME_TESTDB, resource);
+    }
+
+    @Test
+    public void issue281() {
+        UserTO userTO = getUniqueSampleTO("issue281@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getResources().add(RESOURCE_NAME_CSV);
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertNotNull(result);
+
+        List<PropagationStatus> propagations = result.getPropagationStatuses();
+        assertNotNull(propagations);
+        assertEquals(1, propagations.size());
+        assertNotEquals(PropagationTaskExecStatus.SUCCESS, propagations.get(0).getStatus());
+
+        String resource = propagations.get(0).getResource();
+        assertEquals(RESOURCE_NAME_CSV, resource);
+    }
+
+    @Test
+    public void issue288() {
+        UserTO userTO = getSampleTO("issue288@syncope.apache.org");
+        userTO.getPlainAttrs().add(attrTO("aLong", "STRING"));
+
+        try {
+            createUser(userTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidValues, e.getType());
+        }
+    }
+
+    @Test
+    public void groupAttrPropagation() {
+        UserTO userTO = getUniqueSampleTO("checkGroupAttrPropagation@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(1L).build());
+
+        userTO.getResources().add(RESOURCE_NAME_CSV);
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertNotNull(actual.getDerAttrMap().get("csvuserid"));
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+        assertNotNull(connObjectTO);
+        assertEquals("sx-dx", connObjectTO.getPlainAttrMap().get("THEIRGROUP").getValues().get(0));
+    }
+
+    @Test
+    public void customPolicyRules() {
+        // Using custom policy rules with application/xml requires to overwrite
+        // org.apache.syncope.common.lib.policy.AbstractAccountRuleConf's and / or
+        // org.apache.syncope.common.lib.policy.AbstractPasswordRuleConf's
+        // @XmlSeeAlso - the power of JAXB :-/
+        Assume.assumeTrue(MediaType.APPLICATION_JSON_TYPE.equals(clientFactory.getContentType().getMediaType()));
+
+        AccountPolicyTO accountPolicy = new AccountPolicyTO();
+        accountPolicy.setDescription("Account Policy with custom rules");
+        accountPolicy.getRuleConfs().add(new TestAccountRuleConf());
+        accountPolicy = createPolicy(accountPolicy);
+        assertNotNull(accountPolicy);
+
+        PasswordPolicyTO passwordPolicy = new PasswordPolicyTO();
+        passwordPolicy.setDescription("Password Policy with custom rules");
+        passwordPolicy.getRuleConfs().add(new TestPasswordRuleConf());
+        passwordPolicy = createPolicy(passwordPolicy);
+        assertNotNull(passwordPolicy);
+
+        RealmTO realm = realmService.list("/even/two").get(0);
+        Long oldAccountPolicy = realm.getAccountPolicy();
+        realm.setAccountPolicy(accountPolicy.getKey());
+        Long oldPasswordPolicy = realm.getPasswordPolicy();
+        realm.setPasswordPolicy(passwordPolicy.getKey());
+        realmService.update(realm);
+
+        try {
+            UserTO user = getUniqueSampleTO("custompolicyrules@syncope.apache.org");
+            user.setRealm(realm.getFullPath());
+            try {
+                createUser(user);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.InvalidUser, e.getType());
+                assertTrue(e.getElements().iterator().next().startsWith("InvalidPassword"));
+            }
+
+            user.setPassword(user.getPassword() + "XXX");
+            try {
+                createUser(user);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.InvalidUser, e.getType());
+                assertTrue(e.getElements().iterator().next().startsWith("InvalidUsername"));
+            }
+
+            user.setUsername("YYY" + user.getUsername());
+            user = createUser(user).getAny();
+            assertNotNull(user);
+        } finally {
+            realm.setAccountPolicy(oldAccountPolicy);
+            realm.setPasswordPolicy(oldPasswordPolicy);
+            realmService.update(realm);
+
+            policyService.delete(passwordPolicy.getKey());
+            policyService.delete(accountPolicy.getKey());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE108() {
+        UserTO userTO = getUniqueSampleTO("syncope108@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(12L).build());
+        userTO.getMemberships().add(new MembershipTO.Builder().group(13L).build());
+
+        userTO.getResources().add(RESOURCE_NAME_CSV);
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals(2, userTO.getMemberships().size());
+        assertEquals(1, userTO.getResources().size());
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
+        assertNotNull(connObjectTO);
+
+        // -----------------------------------
+        // Remove the first membership: de-provisioning shouldn't happen
+        // -----------------------------------
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+
+        userPatch.getMemberships().add(new MembershipPatch.Builder().
+                operation(PatchOperation.DELETE).membershipTO(userTO.getMemberships().get(0)).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+        assertEquals(1, userTO.getMemberships().size());
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
+        assertNotNull(connObjectTO);
+        // -----------------------------------
+
+        // -----------------------------------
+        // Remove the resource assigned directly: de-provisioning shouldn't happen
+        // -----------------------------------
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+
+        userPatch.getResources().add(new StringPatchItem.Builder().operation(PatchOperation.DELETE).
+                value(userTO.getResources().iterator().next()).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+        assertEquals(1, userTO.getMemberships().size());
+        assertFalse(userTO.getResources().isEmpty());
+
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
+        assertNotNull(connObjectTO);
+        // -----------------------------------
+
+        // -----------------------------------
+        // Remove the first membership: de-provisioning should happen
+        // -----------------------------------
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+
+        userPatch.getMemberships().add(new MembershipPatch.Builder().
+                operation(PatchOperation.DELETE).membershipTO(userTO.getMemberships().get(0)).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+        assertTrue(userTO.getMemberships().isEmpty());
+        assertTrue(userTO.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
+            fail("Read should not succeeed");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE185() {
+        // 1. create user with LDAP resource, succesfully propagated
+        UserTO userTO = getSampleTO("syncope185@syncope.apache.org");
+        userTO.getVirAttrs().clear();
+        userTO.getResources().add(RESOURCE_NAME_LDAP);
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertNotNull(result);
+        assertFalse(result.getPropagationStatuses().isEmpty());
+        assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        userTO = result.getAny();
+
+        // 2. delete this user
+        userService.delete(userTO.getKey());
+
+        // 3. try (and fail) to find this user on the external LDAP resource
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
+            fail("This entry should not be present on this resource");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test()
+    public void issueSYNCOPE51() {
+        AttrTO defaultCA = configurationService.get("password.cipher.algorithm");
+        final String originalCAValue = defaultCA.getValues().get(0);
+        defaultCA.getValues().set(0, "MD5");
+        configurationService.set(defaultCA);
+
+        AttrTO newCA = configurationService.get(defaultCA.getSchema());
+        assertEquals(defaultCA, newCA);
+
+        UserTO userTO = getSampleTO("syncope51@syncope.apache.org");
+        userTO.setPassword("password");
+
+        try {
+            createUser(userTO);
+            fail("Create user should not succeed");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+            assertTrue(e.getElements().iterator().next().contains("MD5"));
+        }
+
+        defaultCA.getValues().set(0, originalCAValue);
+        configurationService.set(defaultCA);
+
+        AttrTO oldCA = configurationService.get(defaultCA.getSchema());
+        assertEquals(defaultCA, oldCA);
+    }
+
+    @Test
+    public void issueSYNCOPE267() {
+        // ----------------------------------
+        // create user and check virtual attribute value propagation
+        // ----------------------------------
+        UserTO userTO = getUniqueSampleTO("syncope267@apache.org");
+        userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertNotNull(result);
+        assertFalse(result.getPropagationStatuses().isEmpty());
+        assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(0).getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        userTO = result.getAny();
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey());
+        assertNotNull(connObjectTO);
+        assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("USERNAME").getValues().get(0));
+        // ----------------------------------
+
+        userTO = userService.read(userTO.getKey());
+
+        assertNotNull(userTO);
+        assertEquals(1, userTO.getVirAttrs().size());
+        assertEquals("virtualvalue", userTO.getVirAttrs().iterator().next().getValues().get(0));
+    }
+
+    @Test
+    public void issueSYNCOPE266() {
+        UserTO userTO = getUniqueSampleTO("syncope266@apache.org");
+        userTO.getResources().clear();
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+
+        // this resource has not a mapping for Password
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_UPDATE).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertNotNull(userTO);
+    }
+
+    @Test
+    public void issueSYNCOPE279() {
+        UserTO userTO = getUniqueSampleTO("syncope279@apache.org");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_TIMEOUT);
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertEquals(RESOURCE_NAME_TIMEOUT, result.getPropagationStatuses().get(0).getResource());
+        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
+        assertEquals(PropagationTaskExecStatus.FAILURE, result.getPropagationStatuses().get(0).getStatus());
+    }
+
+    @Test
+    public void issueSYNCOPE122() {
+        // 1. create user on testdb and testdb2
+        UserTO userTO = getUniqueSampleTO("syncope122@apache.org");
+        userTO.getResources().clear();
+
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+        userTO.getResources().add(RESOURCE_NAME_TESTDB2);
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB2));
+
+        final String pwdOnSyncope = userTO.getPassword();
+
+        ConnObjectTO userOnDb = resourceService.readConnObject(
+                RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
+        final AttrTO pwdOnTestDbAttr = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+        assertNotNull(pwdOnTestDbAttr);
+        assertNotNull(pwdOnTestDbAttr.getValues());
+        assertFalse(pwdOnTestDbAttr.getValues().isEmpty());
+        final String pwdOnTestDb = pwdOnTestDbAttr.getValues().iterator().next();
+
+        ConnObjectTO userOnDb2 = resourceService.readConnObject(
+                RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
+        final AttrTO pwdOnTestDb2Attr = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+        assertNotNull(pwdOnTestDb2Attr);
+        assertNotNull(pwdOnTestDb2Attr.getValues());
+        assertFalse(pwdOnTestDb2Attr.getValues().isEmpty());
+        final String pwdOnTestDb2 = pwdOnTestDb2Attr.getValues().iterator().next();
+
+        // 2. request to change password only on testdb (no Syncope, no testdb2)
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value(getUUIDString()).onSyncope(false).
+                resource(RESOURCE_NAME_TESTDB).build());
+
+        ProvisioningResult<UserTO> result = updateUser(userPatch);
+        userTO = result.getAny();
+
+        // 3a. Chech that only a single propagation took place
+        assertNotNull(result.getPropagationStatuses());
+        assertEquals(1, result.getPropagationStatuses().size());
+        assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().iterator().next().getResource());
+
+        // 3b. verify that password hasn't changed on Syncope
+        assertEquals(pwdOnSyncope, userTO.getPassword());
+
+        // 3c. verify that password *has* changed on testdb
+        userOnDb = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
+        final AttrTO pwdOnTestDbAttrAfter = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+        assertNotNull(pwdOnTestDbAttrAfter);
+        assertNotNull(pwdOnTestDbAttrAfter.getValues());
+        assertFalse(pwdOnTestDbAttrAfter.getValues().isEmpty());
+        assertNotEquals(pwdOnTestDb, pwdOnTestDbAttrAfter.getValues().iterator().next());
+
+        // 3d. verify that password hasn't changed on testdb2
+        userOnDb2 = resourceService.readConnObject(RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
+        final AttrTO pwdOnTestDb2AttrAfter = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+        assertNotNull(pwdOnTestDb2AttrAfter);
+        assertNotNull(pwdOnTestDb2AttrAfter.getValues());
+        assertFalse(pwdOnTestDb2AttrAfter.getValues().isEmpty());
+        assertEquals(pwdOnTestDb2, pwdOnTestDb2AttrAfter.getValues().iterator().next());
+    }
+
+    @Test
+    public void isseSYNCOPE136AES() {
+        // 1. read configured cipher algorithm in order to be able to restore it at the end of test
+        AttrTO pwdCipherAlgo = configurationService.get("password.cipher.algorithm");
+        final String origpwdCipherAlgo = pwdCipherAlgo.getValues().get(0);
+
+        // 2. set AES password cipher algorithm
+        pwdCipherAlgo.getValues().set(0, "AES");
+        configurationService.set(pwdCipherAlgo);
+
+        try {
+            // 3. create user with no resources
+            UserTO userTO = getUniqueSampleTO("syncope136_AES@apache.org");
+            userTO.getResources().clear();
+
+            userTO = createUser(userTO).getAny();
+            assertNotNull(userTO);
+
+            // 4. update user, assign a propagation priority resource but don't provide any password
+            UserPatch userPatch = new UserPatch();
+            userPatch.setKey(userTO.getKey());
+            userPatch.getResources().add(new StringPatchItem.Builder().
+                    operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
+            userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_WS1).build());
+
+            ProvisioningResult<UserTO> result = updateUser(userPatch);
+            assertNotNull(result);
+            userTO = result.getAny();
+            assertNotNull(userTO);
+
+            // 5. verify that propagation was successful
+            List<PropagationStatus> props = result.getPropagationStatuses();
+            assertNotNull(props);
+            assertEquals(1, props.size());
+            PropagationStatus prop = props.iterator().next();
+            assertNotNull(prop);
+            assertEquals(RESOURCE_NAME_WS1, prop.getResource());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
+        } finally {
+            // restore initial cipher algorithm
+            pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
+            configurationService.set(pwdCipherAlgo);
+        }
+    }
+
+    @Test
+    public void isseSYNCOPE136Random() {
+        // 1. create user with no resources
+        UserTO userTO = getUniqueSampleTO("syncope136_Random@apache.org");
+        userTO.getResources().clear();
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        // 2. update user, assign a propagation priority resource but don't provide any password
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
+        userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
+
+        ProvisioningResult<UserTO> result = updateUser(userPatch);
+        assertNotNull(result);
+
+        // 3. verify that propagation was successful
+        List<PropagationStatus> props = result.getPropagationStatuses();
+        assertNotNull(props);
+        assertEquals(1, props.size());
+        PropagationStatus prop = props.iterator().next();
+        assertNotNull(prop);
+        assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
+    }
+
+    @Test
+    public void mappingPurpose() {
+        UserTO userTO = getUniqueSampleTO("mpurpose@apache.org");
+        userTO.getAuxClasses().add("csv");
+
+        AttrTO csvuserid = new AttrTO();
+        csvuserid.setSchema("csvuserid");
+        userTO.getDerAttrs().add(csvuserid);
+
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_CSV);
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
+        assertNull(connObjectTO.getPlainAttrMap().get("email"));
+    }
+
+    @Test
+    public void issueSYNCOPE265() {
+        for (long key = 1; key <= 5; key++) {
+            UserPatch userPatch = new UserPatch();
+            userPatch.setKey(key);
+
+            userPatch.getPlainAttrs().add(attrAddReplacePatch("type", "a type"));
+
+            UserTO userTO = updateUser(userPatch).getAny();
+
+            assertEquals("a type", userTO.getPlainAttrMap().get("type").getValues().get(0));
+        }
+    }
+
+    @Test
+    public void bulkActions() {
+        BulkAction bulkAction = new BulkAction();
+
+        for (int i = 0; i < 10; i++) {
+            UserTO userTO = getUniqueSampleTO("bulk_" + i + "@apache.org");
+            bulkAction.getTargets().add(String.valueOf(createUser(userTO).getAny().getKey()));
+        }
+
+        // check for a fail
+        bulkAction.getTargets().add(String.valueOf(Long.MAX_VALUE));
+
+        assertEquals(11, bulkAction.getTargets().size());
+
+        bulkAction.setType(BulkAction.Type.SUSPEND);
+        BulkActionResult res = userService.bulk(bulkAction);
+        assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+        assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+        assertEquals("suspended", userService.read(
+                Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
+
+        bulkAction.setType(BulkAction.Type.REACTIVATE);
+        res = userService.bulk(bulkAction);
+        assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+        assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+        assertEquals("active", userService.read(
+                Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
+
+        bulkAction.setType(BulkAction.Type.DELETE);
+        res = userService.bulk(bulkAction);
+        assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+        assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+    }
+
+    @Test
+    public void issueSYNCOPE354() {
+        // change resource-ldap group mapping for including uniqueMember (need for assertions below)
+        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+            if ("description".equals(item.getExtAttrName())) {
+                item.setExtAttrName("uniqueMember");
+            }
+        }
+        resourceService.update(ldap);
+
+        // 1. create group with LDAP resource
+        GroupTO groupTO = new GroupTO();
+        groupTO.setName("SYNCOPE354-" + getUUIDString());
+        groupTO.setRealm("/");
+        groupTO.getResources().add(RESOURCE_NAME_LDAP);
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+
+        // 2. create user with LDAP resource and membership of the above group
+        UserTO userTO = getUniqueSampleTO("syncope354@syncope.apache.org");
+        userTO.getResources().add(RESOURCE_NAME_LDAP);
+        userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
+
+        userTO = createUser(userTO).getAny();
+        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+        // 3. read group on resource, check that user DN is included in uniqueMember
+        ConnObjectTO connObj = resourceService.readConnObject(
+                RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
+        assertNotNull(connObj);
+        assertTrue(connObj.getPlainAttrMap().get("uniqueMember").getValues().
+                contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
+
+        // 4. remove membership
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.DELETE).
+                membershipTO(userTO.getMemberships().get(0)).build());
+
+        userTO = updateUser(userPatch).getAny();
+        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+        // 5. read group on resource, check that user DN was removed from uniqueMember
+        connObj = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
+        assertNotNull(connObj);
+        assertFalse(connObj.getPlainAttrMap().get("uniqueMember").getValues().
+                contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
+
+        // 6. restore original resource-ldap group mapping
+        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+            if ("uniqueMember".equals(item.getExtAttrName())) {
+                item.setExtAttrName("description");
+            }
+        }
+        resourceService.update(ldap);
+    }
+
+    @Test
+    public void issueSYNCOPE357() throws IOException {
+        // 1. create group with LDAP resource
+        GroupTO groupTO = new GroupTO();
+        groupTO.setName("SYNCOPE357-" + getUUIDString());
+        groupTO.setRealm("/");
+        groupTO.getResources().add(RESOURCE_NAME_LDAP);
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+
+        // 2. create user with membership of the above group
+        UserTO userTO = getUniqueSampleTO("syncope357@syncope.apache.org");
+        userTO.getPlainAttrs().add(attrTO("obscure", "valueToBeObscured"));
+        userTO.getPlainAttrs().add(attrTO("photo",
+                Base64Utility.encode(IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
+        userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
+
+        userTO = createUser(userTO).getAny();
+        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+        assertNotNull(userTO.getPlainAttrMap().get("obscure"));
+        assertNotNull(userTO.getPlainAttrMap().get("photo"));
+
+        // 3. read user on resource
+        ConnObjectTO connObj = resourceService.readConnObject(
+                RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
+        assertNotNull(connObj);
+        AttrTO registeredAddress = connObj.getPlainAttrMap().get("registeredAddress");
+        assertNotNull(registeredAddress);
+        assertEquals(userTO.getPlainAttrMap().get("obscure").getValues(), registeredAddress.getValues());
+        AttrTO jpegPhoto = connObj.getPlainAttrMap().get("jpegPhoto");
+        assertNotNull(jpegPhoto);
+        assertEquals(userTO.getPlainAttrMap().get("photo").getValues(), jpegPhoto.getValues());
+
+        // 4. remove group
+        groupService.delete(groupTO.getKey());
+
+        // 5. try to read user on resource: fail
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE383() {
+        // 1. create user without resources
+        UserTO userTO = getUniqueSampleTO("syncope383@apache.org");
+        userTO.getResources().clear();
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        // 2. assign resource without specifying a new pwd and check propagation failure
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
+
+        ProvisioningResult<UserTO> result = updateUser(userPatch);
+        assertNotNull(result);
+        userTO = result.getAny();
+        assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
+        assertNotEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
+        userTO = result.getAny();
+
+        // 3. request to change password only on testdb
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(
+                new PasswordPatch.Builder().value(getUUIDString() + "abbcbcbddd123").resource(RESOURCE_NAME_TESTDB).
+                build());
+
+        result = updateUser(userPatch);
+        assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+    }
+
+    @Test
+    public void issueSYNCOPE402() {
+        // 1. create an user with strict mandatory attributes only
+        UserTO userTO = new UserTO();
+        userTO.setRealm(SyncopeConstants.ROOT_REALM);
+        String userId = getUUIDString() + "syncope402@syncope.apache.org";
+        userTO.setUsername(userId);
+        userTO.setPassword("password123");
+
+        userTO.getPlainAttrs().add(attrTO("userId", userId));
+        userTO.getPlainAttrs().add(attrTO("fullname", userId));
+        userTO.getPlainAttrs().add(attrTO("surname", userId));
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertTrue(userTO.getResources().isEmpty());
+
+        // 2. update assigning a resource NOT forcing mandatory constraints
+        // AND priority: must fail with PropagationException
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
+        ProvisioningResult<UserTO> result = updateUser(userPatch);
+
+        List<PropagationStatus> propagationStatuses = result.getPropagationStatuses();
+        PropagationStatus ws1PropagationStatus = null;
+        if (propagationStatuses != null) {
+            for (PropagationStatus propStatus : propagationStatuses) {
+                if (RESOURCE_NAME_WS1.equals(propStatus.getResource())) {
+                    ws1PropagationStatus = propStatus;
+                    break;
+                }
+            }
+        }
+        assertNotNull(ws1PropagationStatus);
+        assertEquals(RESOURCE_NAME_WS1, ws1PropagationStatus.getResource());
+        assertNotNull(ws1PropagationStatus.getFailureReason());
+        assertEquals(PropagationTaskExecStatus.FAILURE, ws1PropagationStatus.getStatus());
+    }
+
+    @Test
+    public void unlink() {
+        UserTO userTO = getUniqueSampleTO("unlink@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+        userTO.getResources().add(RESOURCE_NAME_CSV);
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+    }
+
+    @Test
+    public void link() {
+        UserTO userTO = getUniqueSampleTO("link@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setAction(ResourceAssociationAction.LINK);
+        associationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertFalse(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void unassign() {
+        UserTO userTO = getUniqueSampleTO("unassign@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+        userTO.getResources().add(RESOURCE_NAME_CSV);
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.UNASSIGN);
+        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void assign() {
+        UserTO userTO = getUniqueSampleTO("assign@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setValue("password");
+        associationPatch.setAction(ResourceAssociationAction.ASSIGN);
+        associationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertFalse(actual.getResources().isEmpty());
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+    }
+
+    @Test
+    public void deprovision() {
+        UserTO userTO = getUniqueSampleTO("deprovision@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+        userTO.getResources().add(RESOURCE_NAME_CSV);
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
+        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertFalse(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void provision() {
+        UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setValue("password");
+        associationPatch.setAction(ResourceAssociationAction.PROVISION);
+        associationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+    }
+
+    @Test
+    public void deprovisionUnlinked() {
+        UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerAttrs().clear();
+        userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
+        userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        UserTO actual = createUser(userTO).getAny();
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        AssociationPatch associationPatch = new AssociationPatch();
+        associationPatch.setKey(actual.getKey());
+        associationPatch.setValue("password");
+        associationPatch.setAction(ResourceAssociationAction.PROVISION);
+        associationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.associate(associationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+        DeassociationPatch deassociationPatch = new DeassociationPatch();
+        deassociationPatch.setKey(actual.getKey());
+        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
+        deassociationPatch.getResources().add(RESOURCE_NAME_CSV);
+
+        assertNotNull(userService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
+
+        actual = userService.read(actual.getKey());
+        assertNotNull(actual);
+        assertTrue(actual.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE420() {
+        RealmTO realm = realmService.list("/even/two").iterator().next();
+        assertNotNull(realm);
+        realm.getActionsClassNames().add(DoubleValueLogicActions.class.getName());
+        realmService.update(realm);
+
+        UserTO userTO = getUniqueSampleTO("syncope420@syncope.apache.org");
+        userTO.setRealm(realm.getFullPath());
+        userTO.getPlainAttrs().add(attrTO("makeItDouble", "3"));
+
+        userTO = createUser(userTO).getAny();
+        assertEquals("6", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("makeItDouble", "7"));
+
+        userTO = updateUser(userPatch).getAny();
+        assertEquals("14", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
+    }
+
+    @Test
+    public void issueSYNCOPE426() {
+        UserTO userTO = getUniqueSampleTO("syncope426@syncope.apache.org");
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
+        userTO = userService.update(userPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        }).getAny();
+        assertNotNull(userTO);
+    }
+
+    @Test
+    public void issueSYNCOPE435() {
+        // 1. create user without password
+        UserTO userTO = getUniqueSampleTO("syncope435@syncope.apache.org");
+        userTO.setPassword(null);
+        userTO = createUser(userTO, false).getAny();
+        assertNotNull(userTO);
+
+        // 2. try to update user by subscribing a resource - works but propagation is not even attempted
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
+
+        ProvisioningResult<UserTO> result = updateUser(userPatch);
+        assertNotNull(result);
+        userTO = result.getAny();
+        assertEquals(Collections.singleton(RESOURCE_NAME_WS1), userTO.getResources());
+        assertNotEquals(Propag

<TRUNCATED>

[20/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
new file mode 100644
index 0000000..27db9db
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -0,0 +1,454 @@
+/*
+ * 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.fit;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+import javax.sql.DataSource;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.apache.syncope.common.rest.api.service.CamelRouteService;
+import org.apache.syncope.common.rest.api.service.ConfigurationService;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.DomainService;
+import org.apache.syncope.common.rest.api.service.LoggerService;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.common.rest.api.service.PolicyService;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.GroupService;
+import org.apache.syncope.common.rest.api.service.RealmService;
+import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.common.rest.api.service.UserWorkflowService;
+import org.apache.syncope.common.rest.api.service.WorkflowService;
+import org.identityconnectors.common.security.Encryptor;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = { "classpath:testJDBCContext.xml" })
+public abstract class AbstractITCase {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractITCase.class);
+
+    protected static final String ADMIN_UNAME = "admin";
+
+    protected static final String ADMIN_PWD = "password";
+
+    protected static final String ADDRESS = "http://localhost:9080/syncope/rest";
+
+    protected static final String ENV_KEY_CONTENT_TYPE = "jaxrsContentType";
+
+    protected static final String RESOURCE_NAME_WS1 = "ws-target-resource-1";
+
+    protected static final String RESOURCE_NAME_WS2 = "ws-target-resource-2";
+
+    protected static final String RESOURCE_NAME_LDAP = "resource-ldap";
+
+    protected static final String RESOURCE_NAME_TESTDB = "resource-testdb";
+
+    protected static final String RESOURCE_NAME_TESTDB2 = "resource-testdb2";
+
+    protected static final String RESOURCE_NAME_CSV = "resource-csv";
+
+    protected static final String RESOURCE_NAME_DBSYNC = "resource-db-sync";
+
+    protected static final String RESOURCE_NAME_DBVIRATTR = "resource-db-virattr";
+
+    protected static final String RESOURCE_NAME_NOPROPAGATION = "ws-target-resource-nopropagation";
+
+    protected static final String RESOURCE_NAME_NOPROPAGATION2 = "ws-target-resource-nopropagation2";
+
+    protected static final String RESOURCE_NAME_NOPROPAGATION3 = "ws-target-resource-nopropagation3";
+
+    protected static final String RESOURCE_NAME_NOPROPAGATION4 = "ws-target-resource-nopropagation4";
+
+    protected static final String RESOURCE_NAME_RESETSYNCTOKEN = "ws-target-resource-update-resetsynctoken";
+
+    protected static final String RESOURCE_NAME_TIMEOUT = "ws-target-resource-timeout";
+
+    protected static final String RESOURCE_NAME_MAPPINGS1 = "ws-target-resource-list-mappings-1";
+
+    protected static final String RESOURCE_NAME_MAPPINGS2 = "ws-target-resource-list-mappings-2";
+
+    protected static final String RESOURCE_NAME_CREATE = "ws-target-resource-create";
+
+    protected static final String RESOURCE_NAME_CREATE_SINGLE = "ws-target-resource-create-single";
+
+    protected static final String RESOURCE_NAME_CREATE_WRONG = "ws-target-resource-create-wrong";
+
+    protected static final String RESOURCE_NAME_DELETE = "ws-target-resource-delete";
+
+    protected static final String RESOURCE_NAME_UPDATE = "ws-target-resource-update";
+
+    protected static final String RESOURCE_NAME_CREATE_NONE = "ws-target-resource-create-none";
+
+    protected static final String RESOURCE_NAME_DBSCRIPTED = "resource-db-scripted";
+
+    protected static String ANONYMOUS_UNAME;
+
+    protected static String ANONYMOUS_KEY;
+
+    protected static SyncopeClientFactoryBean clientFactory;
+
+    protected static SyncopeClient adminClient;
+
+    protected static SyncopeService syncopeService;
+
+    protected static DomainService domainService;
+
+    protected static AnyTypeClassService anyTypeClassService;
+
+    protected static AnyTypeService anyTypeService;
+
+    protected static RelationshipTypeService relationshipTypeService;
+
+    protected static RealmService realmService;
+
+    protected static AnyObjectService anyObjectService;
+
+    protected static RoleService roleService;
+
+    protected static UserService userService;
+
+    protected static UserSelfService userSelfService;
+
+    protected static UserWorkflowService userWorkflowService;
+
+    protected static GroupService groupService;
+
+    protected static ResourceService resourceService;
+
+    protected static ConfigurationService configurationService;
+
+    protected static ConnectorService connectorService;
+
+    protected static LoggerService loggerService;
+
+    protected static ReportService reportService;
+
+    protected static TaskService taskService;
+
+    protected static WorkflowService workflowService;
+
+    protected static NotificationService notificationService;
+
+    protected static SchemaService schemaService;
+
+    protected static PolicyService policyService;
+
+    protected static SecurityQuestionService securityQuestionService;
+
+    protected static CamelRouteService camelRouteService;
+
+    @Autowired
+    protected DataSource testDataSource;
+
+    @BeforeClass
+    public static void securitySetup() {
+        InputStream propStream = null;
+        try {
+            propStream = Encryptor.class.getResourceAsStream("/security.properties");
+            Properties props = new Properties();
+            props.load(propStream);
+
+            ANONYMOUS_UNAME = props.getProperty("anonymousUser");
+            ANONYMOUS_KEY = props.getProperty("anonymousKey");
+        } catch (Exception e) {
+            LOG.error("Could not read secretKey", e);
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+
+        assertNotNull(ANONYMOUS_UNAME);
+        assertNotNull(ANONYMOUS_KEY);
+    }
+
+    @BeforeClass
+    public static void restSetup() {
+        clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
+
+        String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
+        if (StringUtils.isNotBlank(envContentType)) {
+            clientFactory.setContentType(envContentType);
+        }
+        LOG.info("Performing IT with content type {}", clientFactory.getContentType().getMediaType());
+
+        adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
+
+        syncopeService = adminClient.getService(SyncopeService.class);
+        domainService = adminClient.getService(DomainService.class);
+        anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
+        anyTypeService = adminClient.getService(AnyTypeService.class);
+        relationshipTypeService = adminClient.getService(RelationshipTypeService.class);
+        realmService = adminClient.getService(RealmService.class);
+        anyObjectService = adminClient.getService(AnyObjectService.class);
+        roleService = adminClient.getService(RoleService.class);
+        userService = adminClient.getService(UserService.class);
+        userSelfService = adminClient.getService(UserSelfService.class);
+        userWorkflowService = adminClient.getService(UserWorkflowService.class);
+        groupService = adminClient.getService(GroupService.class);
+        resourceService = adminClient.getService(ResourceService.class);
+        configurationService = adminClient.getService(ConfigurationService.class);
+        connectorService = adminClient.getService(ConnectorService.class);
+        loggerService = adminClient.getService(LoggerService.class);
+        reportService = adminClient.getService(ReportService.class);
+        taskService = adminClient.getService(TaskService.class);
+        policyService = adminClient.getService(PolicyService.class);
+        workflowService = adminClient.getService(WorkflowService.class);
+        notificationService = adminClient.getService(NotificationService.class);
+        schemaService = adminClient.getService(SchemaService.class);
+        securityQuestionService = adminClient.getService(SecurityQuestionService.class);
+        camelRouteService = adminClient.getService(CamelRouteService.class);
+    }
+
+    protected static String getUUIDString() {
+        return UUID.randomUUID().toString().substring(0, 8);
+    }
+
+    protected static AttrTO attrTO(final String schema, final String value) {
+        return new AttrTO.Builder().schema(schema).value(value).build();
+    }
+
+    protected static AttrPatch attrAddReplacePatch(final String schema, final String value) {
+        return new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).attrTO(attrTO(schema, value)).build();
+    }
+
+    public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) {
+        WebClient webClient = WebClient.fromClient(WebClient.client(adminClient.getService(serviceClass)));
+        webClient.accept(clientFactory.getContentType().getMediaType()).to(location.toASCIIString(), false);
+
+        return webClient.get(resultClass);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <T extends AbstractSchemaTO> T createSchema(final SchemaType type, final T schemaTO) {
+        Response response = schemaService.create(type, schemaTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+
+        return (T) getObject(response.getLocation(), SchemaService.class, schemaTO.getClass());
+    }
+
+    protected RoleTO createRole(final RoleTO roleTO) {
+        Response response = roleService.create(roleTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return getObject(response.getLocation(), RoleService.class, RoleTO.class);
+    }
+
+    protected UserTO readUser(final String username) {
+        return userService.read(Long.valueOf(userService.getUserKey(username).getHeaderString(RESTHeaders.USER_KEY)));
+    }
+
+    protected ProvisioningResult<UserTO> createUser(final UserTO userTO) {
+        return createUser(userTO, true);
+    }
+
+    protected ProvisioningResult<UserTO> createUser(final UserTO userTO, final boolean storePassword) {
+        Response response = userService.create(userTO, storePassword);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+        });
+    }
+
+    protected ProvisioningResult<UserTO> updateUser(final UserPatch userPatch) {
+        return userService.update(userPatch).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                });
+    }
+
+    protected ProvisioningResult<UserTO> deleteUser(final Long key) {
+        return userService.delete(key).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                });
+    }
+
+    protected ProvisioningResult<AnyObjectTO> createAnyObject(final AnyObjectTO anyObjectTO) {
+        Response response = anyObjectService.create(anyObjectTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return response.readEntity(new GenericType<ProvisioningResult<AnyObjectTO>>() {
+        });
+    }
+
+    protected ProvisioningResult<AnyObjectTO> updateAnyObject(final AnyObjectPatch anyObjectPatch) {
+        return anyObjectService.update(anyObjectPatch).
+                readEntity(new GenericType<ProvisioningResult<AnyObjectTO>>() {
+                });
+    }
+
+    protected ProvisioningResult<AnyObjectTO> deleteAnyObject(final Long key) {
+        return anyObjectService.delete(key).
+                readEntity(new GenericType<ProvisioningResult<AnyObjectTO>>() {
+                });
+    }
+
+    protected ProvisioningResult<GroupTO> createGroup(final GroupTO groupTO) {
+        Response response = groupService.create(groupTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return response.readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
+        });
+    }
+
+    protected ProvisioningResult<GroupTO> updateGroup(final GroupPatch groupPatch) {
+        return groupService.update(groupPatch).
+                readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
+                });
+    }
+
+    protected ProvisioningResult<GroupTO> deleteGroup(final Long key) {
+        return groupService.delete(key).
+                readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
+                });
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <T extends AbstractPolicyTO> T createPolicy(final T policy) {
+        Response response = policyService.create(policy);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return (T) getObject(response.getLocation(), PolicyService.class, policy.getClass());
+    }
+
+    protected ResourceTO createResource(final ResourceTO resourceTO) {
+        Response response = resourceService.create(resourceTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes", "UseOfObsoleteCollectionType" })
+    protected InitialDirContext getLdapResourceDirContext(final String bindDn, final String bindPwd)
+            throws NamingException {
+        ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP);
+        final Map<String, ConnConfProperty> ldapConnConf =
+                connectorService.read(ldapRes.getConnector(), Locale.ENGLISH.getLanguage()).getConfMap();
+
+        Properties env = new Properties();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(Context.PROVIDER_URL, "ldap://" + ldapConnConf.get("host").getValues().get(0)
+                + ":" + ldapConnConf.get("port").getValues().get(0) + "/");
+        env.put(Context.SECURITY_AUTHENTICATION, "simple");
+        env.put(Context.SECURITY_PRINCIPAL,
+                bindDn == null ? ldapConnConf.get("principal").getValues().get(0) : bindDn);
+        env.put(Context.SECURITY_CREDENTIALS,
+                bindPwd == null ? ldapConnConf.get("credentials").getValues().get(0) : bindPwd);
+
+        return new InitialDirContext(env);
+    }
+
+    protected Object getLdapRemoteObject(final String bindDn, final String bindPwd, final String objectDn) {
+        InitialDirContext ctx = null;
+        try {
+            ctx = getLdapResourceDirContext(bindDn, bindPwd);
+            return ctx.lookup(objectDn);
+        } catch (Exception e) {
+            return null;
+        } finally {
+            if (ctx != null) {
+                try {
+                    ctx.close();
+                } catch (NamingException e) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    protected Object getLdapRemoteObject(final String objectDn) {
+        return getLdapRemoteObject(null, null, objectDn);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/ActivitiDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/ActivitiDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/ActivitiDetector.java
new file mode 100644
index 0000000..9a939c7
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/ActivitiDetector.java
@@ -0,0 +1,36 @@
+/*
+ * 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.fit;
+
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+
+public class ActivitiDetector {
+
+    public static boolean isActivitiEnabledForUsers(final SyncopeService syncopeService) {
+        return syncopeService.info().getUserWorkflowAdapter().contains("Activiti");
+    }
+
+    public static boolean isActivitiEnabledForGroups(final SyncopeService syncopeService) {
+        return syncopeService.info().getGroupWorkflowAdapter().contains("Activiti");
+    }
+
+    public static boolean isActivitiEnabledForAnyObjects(final SyncopeService syncopeService) {
+        return syncopeService.info().getAnyObjectWorkflowAdapter().contains("Activiti");
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/CamelDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/CamelDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/CamelDetector.java
new file mode 100644
index 0000000..5f9a81c
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/CamelDetector.java
@@ -0,0 +1,36 @@
+/*
+ * 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.fit;
+
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+
+public class CamelDetector {
+
+    public static boolean isCamelEnabledForUsers(final SyncopeService syncopeService) {
+        return syncopeService.info().getUserProvisioningManager().contains("Camel");
+    }
+
+    public static boolean isCamelEnabledForGroups(final SyncopeService syncopeService) {
+        return syncopeService.info().getGroupProvisioningManager().contains("Camel");
+    }
+
+    public static boolean isCamelEnabledForAnyObjects(final SyncopeService syncopeService) {
+        return syncopeService.info().getAnyObjectProvisioningManager().contains("Camel");
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
new file mode 100644
index 0000000..33e3ad3
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
@@ -0,0 +1,278 @@
+/*
+ * 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.fit.cli;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.syncope.client.cli.Command;
+import org.apache.syncope.client.cli.commands.connector.ConnectorCommand;
+import org.apache.syncope.client.cli.commands.entitlement.EntitlementCommand;
+import org.apache.syncope.client.cli.commands.group.GroupCommand;
+import org.apache.syncope.client.cli.commands.install.InstallCommand;
+import org.apache.syncope.client.cli.commands.policy.PolicyCommand;
+import org.apache.syncope.client.cli.commands.report.ReportCommand;
+import org.apache.syncope.client.cli.commands.role.RoleCommand;
+import org.apache.syncope.client.cli.commands.user.UserCommand;
+import org.apache.syncope.fit.AbstractITCase;
+import org.apache.syncope.fit.core.ExceptionMapperITCase;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class CLIITCase extends AbstractITCase {
+
+    private static final String SCRIPT_FILENAME = "syncopeadm";
+
+    private static ProcessBuilder PROCESS_BUILDER;
+
+    @BeforeClass
+    public static void install() {
+        Properties props = new Properties();
+        InputStream propStream = null;
+        try {
+            propStream = ExceptionMapperITCase.class.getResourceAsStream("/cli-test.properties");
+            props.load(propStream);
+
+            File workDir = new File(props.getProperty("cli-work.dir"));
+            PROCESS_BUILDER = new ProcessBuilder();
+            PROCESS_BUILDER.directory(workDir);
+
+            PROCESS_BUILDER.command(getCommand(
+                    new InstallCommand().getClass().getAnnotation(Command.class).name(),
+                    InstallCommand.Options.SETUP_DEBUG.getOptionName()));
+            Process process = PROCESS_BUILDER.start();
+            process.waitFor();
+
+            File cliPropertiesFile = new File(workDir + File.separator + "cli.properties");
+            assertTrue(cliPropertiesFile.exists());
+        } catch (IOException | InterruptedException e) {
+            fail(e.getMessage());
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+    }
+
+    private static String[] getCommand(final String... arguments) {
+        List<String> command = new ArrayList<>();
+
+        if (SystemUtils.IS_OS_WINDOWS) {
+            command.add("cmd");
+            command.add(SCRIPT_FILENAME + ".bat");
+        } else {
+            command.add("/bin/bash");
+            command.add(SCRIPT_FILENAME + ".sh");
+        }
+
+        CollectionUtils.addAll(command, arguments);
+
+        return command.toArray(new String[command.size()]);
+    }
+
+    @Test
+    public void runScriptWithoutOptions() {
+        try {
+            PROCESS_BUILDER.command(getCommand());
+            Process process = PROCESS_BUILDER.start();
+
+            String result = IOUtils.toString(process.getInputStream());
+            assertTrue(result.startsWith("\nUsage: Main [options]"));
+            assertTrue(result.contains(
+                    new EntitlementCommand().getClass().getAnnotation(Command.class).name()
+                    + " "
+                    + EntitlementCommand.EntitlementOptions.HELP.getOptionName()));
+            assertTrue(result.contains(
+                    new GroupCommand().getClass().getAnnotation(Command.class).name()
+                    + " "
+                    + GroupCommand.GroupOptions.HELP.getOptionName()));
+            process.destroy();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void entitlementCount() {
+        try {
+            PROCESS_BUILDER.command(getCommand(
+                    new EntitlementCommand().getClass().getAnnotation(Command.class).name(),
+                    EntitlementCommand.EntitlementOptions.LIST.getOptionName()));
+            Process process = PROCESS_BUILDER.start();
+
+            long entitlements = IterableUtils.countMatches(IOUtils.readLines(process.getInputStream()),
+                    new Predicate<String>() {
+
+                @Override
+                public boolean evaluate(final String line) {
+                    return line.startsWith("-");
+                }
+            });
+            assertEquals(syncopeService.info().getEntitlements().size(), entitlements);
+
+            process.destroy();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void connectorCount() {
+        try {
+            PROCESS_BUILDER.command(getCommand(
+                    new ConnectorCommand().getClass().getAnnotation(Command.class).name(),
+                    ConnectorCommand.ConnectorOptions.LIST_BUNDLES.getOptionName()));
+            Process process = PROCESS_BUILDER.start();
+
+            long bundles = IterableUtils.countMatches(IOUtils.readLines(process.getInputStream()),
+                    new Predicate<String>() {
+
+                @Override
+                public boolean evaluate(final String line) {
+                    return line.startsWith(" > BUNDLE NAME:");
+                }
+            });
+            assertEquals(connectorService.getBundles(null).size(), bundles);
+
+            process.destroy();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void userRead() {
+        final long userId1 = 1;
+        final long userId2 = 2;
+        final long userId3 = 3;
+        final long userId4 = 4;
+        final long userId5 = 5;
+        try {
+            PROCESS_BUILDER.command(getCommand(
+                    new UserCommand().getClass().getAnnotation(Command.class).name(),
+                    UserCommand.UserOptions.READ_BY_ID.getOptionName(),
+                    String.valueOf(userId1)));
+            Process process = PROCESS_BUILDER.start();
+            String result = IOUtils.toString(process.getInputStream());
+            assertTrue(result.contains("username: " + userService.read(userId1).getUsername()));
+            process.destroy();
+
+            PROCESS_BUILDER.command(getCommand(
+                    new UserCommand().getClass().getAnnotation(Command.class).name(),
+                    UserCommand.UserOptions.READ_BY_ID.getOptionName(),
+                    String.valueOf(userId1), String.valueOf(userId2),
+                    String.valueOf(userId3), String.valueOf(userId4), String.valueOf(userId5)));
+            Process process2 = PROCESS_BUILDER.start();
+            long users = IterableUtils.countMatches(IOUtils.readLines(process2.getInputStream()),
+                    new Predicate<String>() {
+
+                @Override
+                public boolean evaluate(final String line) {
+                    return line.startsWith(" > USER ID:");
+                }
+            });
+            assertEquals(5, users);
+
+            process2.destroy();
+
+            PROCESS_BUILDER.command(getCommand(
+                    new UserCommand().getClass().getAnnotation(Command.class).name(),
+                    UserCommand.UserOptions.READ_BY_ID.getOptionName(),
+                    String.valueOf(userId1), String.valueOf(userId2),
+                    String.valueOf(userId3), String.valueOf(userId4), String.valueOf(userId5)));
+            Process process3 = PROCESS_BUILDER.start();
+            String result3 = IOUtils.toString(process3.getInputStream());
+            assertTrue(
+                    result3.contains("username: " + userService.read(userId1).getUsername())
+                    && result3.contains("username: " + userService.read(userId2).getUsername())
+                    && result3.contains("username: " + userService.read(userId3).getUsername())
+                    && result3.contains("username: " + userService.read(userId4).getUsername())
+                    && result3.contains("username: " + userService.read(userId5).getUsername()));
+            process3.destroy();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void roleRead() {
+        final String roleId = "Search for realm evenTwo";
+        try {
+            PROCESS_BUILDER.command(getCommand(
+                    new RoleCommand().getClass().getAnnotation(Command.class).name(),
+                    RoleCommand.RoleOptions.READ.getOptionName(),
+                    roleId));
+            final Process process = PROCESS_BUILDER.start();
+            final String result = IOUtils.toString(process.getInputStream());
+            assertTrue(result.contains(roleService.read(roleId).getEntitlements().iterator().next()));
+
+            process.destroy();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void reportNotExists() {
+        try {
+            PROCESS_BUILDER.command(getCommand(
+                    new ReportCommand().getClass().getAnnotation(Command.class).name(),
+                    ReportCommand.ReportOptions.READ.getOptionName(),
+                    "2"));
+            final Process process = PROCESS_BUILDER.start();
+            final String result = IOUtils.toString(process.getInputStream());
+            assertTrue(result.contains("- Report 2 doesn't exist"));
+
+            process.destroy();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void policyError() {
+        try {
+            PROCESS_BUILDER.command(getCommand(
+                    new PolicyCommand().getClass().getAnnotation(Command.class).name(),
+                    PolicyCommand.PolicyOptions.READ.getOptionName(),
+                    "wrong"));
+            final Process process = PROCESS_BUILDER.start();
+            final String result = IOUtils.toString(process.getInputStream());
+            assertTrue(result.contains(
+                    "- Error reading wrong. It isn't a valid policy value because it isn't a boolean value"));
+
+            process.destroy();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
new file mode 100644
index 0000000..b557bdd
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
@@ -0,0 +1,100 @@
+/*
+ * 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.fit.console;
+
+import java.lang.reflect.InvocationTargetException;
+import javax.servlet.ServletContext;
+import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
+import org.apache.syncope.client.console.init.ConsoleInitializer;
+import org.apache.syncope.client.console.init.MIMETypesLoader;
+import org.apache.syncope.client.console.pages.Login;
+import org.apache.syncope.fit.AbstractITCase;
+import org.apache.wicket.Component;
+import org.apache.wicket.core.util.lang.PropertyResolver;
+import org.apache.wicket.markup.repeater.OddEvenItem;
+import org.apache.wicket.util.tester.FormTester;
+import org.apache.wicket.util.tester.WicketTester;
+import org.apache.wicket.util.visit.IVisit;
+import org.apache.wicket.util.visit.IVisitor;
+import org.junit.Before;
+
+public abstract class AbstractConsoleITCase extends AbstractITCase {
+
+    protected static final String KEY = "key";
+
+    protected WicketTester wicketTester;
+
+    protected SyncopeConsoleApplication testApplicaton;
+
+    @Before
+    public void setUp() {
+
+        testApplicaton = new SyncopeConsoleApplication() {
+
+            @Override
+            protected void init() {
+                final ServletContext ctx = getServletContext();
+                final ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
+                lookup.load();
+                ctx.setAttribute(ConsoleInitializer.CLASSPATH_LOOKUP, lookup);
+
+                final MIMETypesLoader mimeTypes = new MIMETypesLoader();
+                mimeTypes.load();
+                ctx.setAttribute(ConsoleInitializer.MIMETYPES_LOADER, mimeTypes);
+
+                super.init();
+            }
+        };
+
+        wicketTester = new WicketTester(testApplicaton);
+    }
+
+    protected void doLogin(final String user, final String passwd) {
+        wicketTester.startPage(Login.class);
+        wicketTester.assertRenderedPage(Login.class);
+
+        FormTester formTester = wicketTester.newFormTester("login");
+        formTester.setValue("username", user);
+        formTester.setValue("password", passwd);
+        formTester.submit("submit");
+    }
+
+    protected Component findComponentByProp(final String property, final String searchPath, final String key) {
+        Component component = wicketTester.getComponentFromLastRenderedPage(searchPath);
+
+        Component result = component.getPage().
+                visitChildren(OddEvenItem.class, new IVisitor<OddEvenItem<?>, Component>() {
+
+                    @Override
+                    public void component(final OddEvenItem<?> object, final IVisit<Component> visit) {
+
+                        try {
+                            if (PropertyResolver.getPropertyGetter(
+                                    property, object.getModelObject()).invoke(object.getModelObject()).equals(key)) {
+                                visit.stop(object);
+                            }
+                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+                            LOG.error("Error invoke method", ex);
+                        }
+                    }
+                });
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
new file mode 100644
index 0000000..b385ab2
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
@@ -0,0 +1,151 @@
+/*
+ * 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.fit.console;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.syncope.client.console.pages.Types;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Before;
+
+public abstract class AbstractTypesITCase extends AbstractConsoleITCase {
+
+    protected static final String PLAIN_DATATABLE_PATH = "content:tabbedPanel:panel:"
+            + "collapsePanel:tabs:0:body:content:searchContainer:resultTable";
+
+    protected static final String DATATABLE_PATH =
+            "content:tabbedPanel:panel:searchContainer:resultTable";
+
+    @Before
+    public void login() {
+        doLogin(ADMIN_UNAME, ADMIN_PWD);
+    }
+
+    protected void browsingToRelationshipType() {
+
+        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
+        wicketTester.assertRenderedPage(Types.class);
+
+        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:0:link");
+        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
+                AjaxFallbackDataTable.class);
+    }
+
+    protected void browsingToAnyTypes() {
+
+        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
+        wicketTester.assertRenderedPage(Types.class);
+
+        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:1:link");
+        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
+                AjaxFallbackDataTable.class);
+    }
+
+    protected void browsingToAnyTypeClasses() {
+
+        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
+        wicketTester.assertRenderedPage(Types.class);
+
+        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:2:link");
+        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
+                AjaxFallbackDataTable.class);
+    }
+
+    protected void browsingToPlainSchemas() {
+
+        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
+        wicketTester.assertRenderedPage(Types.class);
+
+        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:3:link");
+        wicketTester.assertComponent(PLAIN_DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
+                AjaxFallbackDataTable.class);
+    }
+
+    protected void createPlainSchema(final String key) {
+        browsingToPlainSchemas();
+        wicketTester.clickLink("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:container:content:add");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:"
+                + "collapsePanel:tabs:0:body:content:modal:form");
+        formTester.setValue("content:details:form:key:textField", key);
+        formTester.setValue("content:details:form:type:dropDownChoiceField", "3");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:"
+                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.cleanupFeedbackMessages();
+    }
+
+    protected void createAnyTypeClassWithoutSchema(final String name) {
+        browsingToAnyTypeClasses();
+
+        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue("content:anyTypeClassDetailsPanel:form:key:textField", name);
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.clearFeedbackMessages();
+    }
+
+    protected void createAnyType(final String name) {
+        browsingToAnyTypes();
+
+        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue("content:anyTypeDetailsPanel:container:form:key:textField", name);
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.clearFeedbackMessages();
+    }
+
+    protected void createRelationshipType(final String name) {
+        browsingToRelationshipType();
+
+        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue("content:relationshipTypeDetails:container:form:key:textField", name);
+        formTester.setValue(
+                "content:relationshipTypeDetails:container:form:description:textField", "test relationshipType");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.clearFeedbackMessages();
+        wicketTester.assertRenderedPage(Types.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java
new file mode 100644
index 0000000..9f44034
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java
@@ -0,0 +1,57 @@
+/*
+ * 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.fit.console;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Test;
+
+public class AjaxPalettePanelITCase extends AbstractConsoleITCase {
+
+    private static final IModel<List<String>> SELECTED = new ListModel<>(new ArrayList<>(Arrays.asList("A", "D")));
+
+    private static final ListModel<String> ALL = new ListModel<>(new ArrayList<>(Arrays.asList("A", "B", "C", "D")));
+
+    @Test
+    public void isRendered() {
+        TestPage<String, AjaxPalettePanel<String>> testPage =
+                new TestPage.Builder<String, AjaxPalettePanel<String>>().build(
+                        new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build(
+                        TestPage.FIELD, SELECTED, ALL));
+        wicketTester.startPage(testPage);
+
+        FormTester formTester = wicketTester.newFormTester(testPage.getForm().getId());
+        formTester.submit();
+
+        Collection<String> list = testPage.getFieldPanel().getModelCollection();
+        assertEquals(2, list.size());
+        Iterator<String> iterator = list.iterator();
+        assertEquals("A", iterator.next());
+        assertEquals("D", iterator.next());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxTextFieldITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxTextFieldITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxTextFieldITCase.java
new file mode 100644
index 0000000..8d51194
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxTextFieldITCase.java
@@ -0,0 +1,86 @@
+/*
+ * 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.fit.console;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.wicket.util.string.Strings;
+import org.apache.wicket.util.tester.FormTester;
+import org.apache.wicket.validation.validator.StringValidator;
+import org.junit.Test;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+public class AjaxTextFieldITCase extends AbstractConsoleITCase {
+
+    private final IModel<String> textModel = Model.of((String) null);
+
+    @Test
+    public void emptyInputConvertedToNull() {
+        TestPage<String, AjaxTextFieldPanel> testPage =
+                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
+                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
+        wicketTester.startPage(testPage);
+        FormTester formTester = wicketTester.newFormTester(testPage.getForm().getId());
+        formTester.setValue("field:textField", "");
+        formTester.submit();
+        assertNull(testPage.getFieldPanel().getField().getDefaultModelObject());
+    }
+
+    @Test
+    public void valueAttribute() {
+        TestPage<String, AjaxTextFieldPanel> testPage =
+                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
+                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
+        String text = "sometext";
+        textModel.setObject(text);
+        wicketTester.startPage(testPage);
+        assertTrue(wicketTester.getLastResponseAsString().contains(Strings.escapeMarkup(text)));
+    }
+
+    @Test
+    public void nullIsNotValidated() {
+        TestPage<String, AjaxTextFieldPanel> testPage =
+                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
+                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
+        testPage.getFieldPanel().getField().setRequired(false);
+        testPage.getFieldPanel().getField().add(StringValidator.minimumLength(2));
+        wicketTester.startPage(testPage);
+        FormTester formTester = wicketTester.newFormTester(testPage.getForm().getId());
+        formTester.setValue("field:textField", "");
+        formTester.submit();
+        assertNull(testPage.getFieldPanel().getDefaultModelObject());
+        assertTrue(testPage.getFieldPanel().getField().isValid());
+    }
+
+    @Test
+    public void requiredAttribute() {
+        TestPage<String, AjaxTextFieldPanel> testPage =
+                new TestPage.Builder<String, AjaxTextFieldPanel>().build(
+                        new AjaxTextFieldPanel(TestPage.FIELD, TestPage.FIELD, textModel));
+        testPage.getFieldPanel().setOutputMarkupId(true);
+        testPage.getFieldPanel().getField().setRequired(true);
+        wicketTester.startPage(testPage);
+        wicketTester.assertLabel("form:field:field-label", "field");
+        wicketTester.assertVisible("form:field:required");
+        wicketTester.assertVisible("form:field:externalAction");
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java
new file mode 100644
index 0000000..14cb876
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java
@@ -0,0 +1,139 @@
+/*
+ * 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.fit.console;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.syncope.client.console.pages.Types;
+import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Test;
+
+public class AnyTypeClassesITCase extends AbstractTypesITCase {
+
+    @Test
+    public void read() {
+        browsingToAnyTypeClasses();
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, "csv");
+        wicketTester.assertLabel(
+                result.getPageRelativePath() + ":cells:1:cell", "csv");
+
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:6:cell:panelEdit:editLink", IndicatingAjaxLink.class);
+
+        wicketTester.clickLink(
+                result.getPageRelativePath() + ":cells:6:cell:panelEdit:editLink");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", BaseModal.class);
+    }
+
+    @Test
+    public void create() {
+        browsingToAnyTypeClasses();
+        final String anyTypeClassTest = "anyTypeClassTest";
+
+        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue("content:anyTypeClassDetailsPanel:form:key:textField", anyTypeClassTest);
+        formTester.setValue(
+                "content:anyTypeClassDetailsPanel:form:container:derSchemas:paletteField:recorder", "mderiveddata");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.clearFeedbackMessages();
+        wicketTester.assertRenderedPage(Types.class);
+
+        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:2:link");
+        wicketTester.assertComponent(DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable",
+                AjaxFallbackDataTable.class);
+
+        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassTest);
+
+        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:4:cell", "[mderiveddata]");
+    }
+
+    @Test
+    public void update() {
+        final String plainSchema = "anyPlainSchema";
+        createPlainSchema(plainSchema);
+        browsingToAnyTypeClasses();
+
+        wicketTester.assertComponent(
+                DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:"
+                + "body:rows:1:cells:6:cell:panelEdit:editLink", IndicatingAjaxLink.class);
+
+        wicketTester.clickLink(
+                DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:body:rows:1:cells:6:cell:panelEdit:editLink");
+
+        final FormTester formTester =
+                wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue(
+                "content:anyTypeClassDetailsPanel:form:container:plainSchemas:paletteField:recorder", plainSchema);
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+    }
+
+    @Test
+    public void delete() {
+        final String anyTypeClassName = "zStringDelete";
+        createAnyTypeClassWithoutSchema(anyTypeClassName);
+        browsingToAnyTypeClasses();
+        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassName);
+
+        assertNotNull(result);
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:6:cell:panelDelete:deleteLink",
+                IndicatingOnConfirmAjaxLink.class);
+
+        wicketTester.getRequest().addParameter("confirm", "true");
+        wicketTester.clickLink(
+                wicketTester.getComponentFromLastRenderedPage(
+                        result.getPageRelativePath() + ":cells:6:cell:panelDelete:deleteLink"));
+
+        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
+                result.getPageRelativePath() + ":cells:6:cell:panelDelete:deleteLink"), "click");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.cleanupFeedbackMessages();
+        result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassName);
+
+        assertNull(result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java
new file mode 100644
index 0000000..e468476
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java
@@ -0,0 +1,139 @@
+/*
+ * 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.fit.console;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.syncope.client.console.pages.Types;
+import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Test;
+
+public class AnyTypesITCase extends AbstractTypesITCase {
+
+    @Test
+    public void read() {
+        browsingToAnyTypes();
+        wicketTester.assertComponent(
+                DATATABLE_PATH
+                + ":tablePanel:groupForm:"
+                + "checkgroup:dataTable:body:rows:1:cells:1:cell", Label.class);
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, "GROUP");
+
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:4:cell:panelEdit:editLink", IndicatingAjaxLink.class);
+
+        wicketTester.clickLink(
+                result.getPageRelativePath() + ":cells:4:cell:panelEdit:editLink");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", BaseModal.class);
+    }
+
+    @Test
+    public void create() {
+        browsingToAnyTypes();
+        final String anyTypeTest = "anyTypeTest2";
+
+        wicketTester.clickLink("content:tabbedPanel:panel:container:content:add");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue("content:anyTypeDetailsPanel:container:form:key:textField", anyTypeTest);
+        formTester.setValue(
+                "content:anyTypeDetailsPanel:container:form:classes:paletteField:recorder", "csv");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.clearFeedbackMessages();
+        wicketTester.assertRenderedPage(Types.class);
+
+        wicketTester.clickLink("content:tabbedPanel:tabs-container:tabs:1:link");
+        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, anyTypeTest);
+
+        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:1:cell", anyTypeTest);
+        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:3:cell", "[csv]");
+    }
+
+    @Test
+    public void update() {
+        final String name = "anyTypeClassUpdate";
+        createAnyTypeClassWithoutSchema(name);
+        browsingToAnyTypes();
+
+        wicketTester.assertComponent(
+                DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:"
+                + "body:rows:1:cells:4:cell:panelEdit:editLink", IndicatingAjaxLink.class);
+
+        wicketTester.clickLink(
+                DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:body:rows:1:cells:4:cell:panelEdit:editLink");
+
+        final FormTester formTester =
+                wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue(
+                "content:anyTypeDetailsPanel:container:form:classes:paletteField:recorder", name + ",minimal group");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+    }
+
+    @Test
+    public void delete() {
+        final String name = "anyTypeDelete";
+        createAnyType(name);
+        browsingToAnyTypes();
+
+        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, name);
+
+        assertNotNull(result);
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:4:cell:panelDelete:deleteLink",
+                IndicatingOnConfirmAjaxLink.class);
+
+        wicketTester.getRequest().addParameter("confirm", "true");
+        wicketTester.clickLink(
+                wicketTester.getComponentFromLastRenderedPage(
+                        result.getPageRelativePath() + ":cells:4:cell:panelDelete:deleteLink"));
+
+        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
+                result.getPageRelativePath() + ":cells:4:cell:panelDelete:deleteLink"), "onclick");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.cleanupFeedbackMessages();
+        result = findComponentByProp(KEY, DATATABLE_PATH, name);
+
+        assertNull(result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BaseITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BaseITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BaseITCase.java
new file mode 100644
index 0000000..7a83927
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BaseITCase.java
@@ -0,0 +1,94 @@
+/*
+ * 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.fit.console;
+
+import org.apache.syncope.client.console.pages.Dashboard;
+import org.apache.syncope.client.console.pages.Layouts;
+import org.apache.syncope.client.console.pages.Login;
+import org.apache.syncope.client.console.pages.Logs;
+import org.apache.syncope.client.console.pages.Notifications;
+import org.apache.syncope.client.console.pages.Policies;
+import org.apache.syncope.client.console.pages.Realms;
+import org.apache.syncope.client.console.pages.Reports;
+import org.apache.syncope.client.console.pages.Roles;
+import org.apache.syncope.client.console.pages.SecurityQuestions;
+import org.apache.syncope.client.console.pages.Types;
+import org.apache.syncope.client.console.pages.Workflow;
+import org.apache.syncope.client.console.topology.Topology;
+import org.junit.Test;
+
+public class BaseITCase extends AbstractConsoleITCase {
+
+    @Test
+    public void loginPage() {
+        wicketTester.startPage(Login.class);
+        wicketTester.assertRenderedPage(Login.class);
+    }
+
+    @Test
+    public void successfullyLogin() {
+        doLogin(ADMIN_UNAME, ADMIN_PWD);
+        wicketTester.assertRenderedPage(Dashboard.class);
+    }
+
+    @Test
+    public void unsuccessfullyLogin() {
+        doLogin(ADMIN_UNAME, ADMIN_PWD + 1);
+        wicketTester.assertRenderedPage(Login.class);
+    }
+
+    @Test
+    public void browsingBookmarkablePageLink() {
+        doLogin(ADMIN_UNAME, ADMIN_PWD);
+        wicketTester.assertRenderedPage(Dashboard.class);
+
+        wicketTester.clickLink("realmsLI:realms");
+        wicketTester.assertRenderedPage(Realms.class);
+
+        wicketTester.clickLink("topologyLI:topology");
+        wicketTester.assertRenderedPage(Topology.class);
+
+        wicketTester.clickLink("reportsLI:reports");
+        wicketTester.assertRenderedPage(Reports.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:workflowLI:workflow");
+        wicketTester.assertRenderedPage(Workflow.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:logsLI:logs");
+        wicketTester.assertRenderedPage(Logs.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:securityquestionsLI:securityquestions");
+        wicketTester.assertRenderedPage(SecurityQuestions.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:typesLI:types");
+        wicketTester.assertRenderedPage(Types.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:rolesLI:roles");
+        wicketTester.assertRenderedPage(Roles.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:policiesLI:policies");
+        wicketTester.assertRenderedPage(Policies.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:layoutsLI:layouts");
+        wicketTester.assertRenderedPage(Layouts.class);
+
+        wicketTester.clickLink("configurationLI:configurationUL:notificationsLI:notifications");
+        wicketTester.assertRenderedPage(Notifications.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypeITCase.java
new file mode 100644
index 0000000..6eea05b
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypeITCase.java
@@ -0,0 +1,121 @@
+/*
+ * 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.fit.console;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Test;
+
+public class RelationshipTypeITCase extends AbstractTypesITCase {
+
+    @Test
+    public void read() {
+        browsingToRelationshipType();
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, "inclusion");
+
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:1:cell", Label.class);
+
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:3:cell:panelEdit:editLink", IndicatingAjaxLink.class);
+
+        wicketTester.clickLink(
+                result.getPageRelativePath() + ":cells:3:cell:panelEdit:editLink");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:modal", BaseModal.class);
+    }
+
+    @Test
+    public void create() {
+        final String name = "relationshipTypeTest";
+        createRelationshipType(name);
+        browsingToRelationshipType();
+
+        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, name);
+
+        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:1:cell", name);
+        wicketTester.assertLabel(result.getPageRelativePath() + ":cells:2:cell", "test relationshipType");
+    }
+
+    @Test
+    public void update() {
+        final String name = "relationshipTypeUpdate";
+        createRelationshipType(name);
+        browsingToRelationshipType();
+
+        wicketTester.assertComponent(
+                DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:"
+                + "body:rows:1:cells:3:cell:panelEdit:editLink", IndicatingAjaxLink.class);
+
+        wicketTester.clickLink(
+                DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:body:rows:1:cells:3:cell:panelEdit:editLink");
+
+        final FormTester formTester =
+                wicketTester.newFormTester("content:tabbedPanel:panel:modal:form");
+        formTester.setValue(
+                "content:relationshipTypeDetails:container:form:description:textField", "new description");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:modal:dialog:footer:inputs:0:submit");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+    }
+
+    @Test
+    public void delete() {
+        final String name = "relationshipTypeDelete";
+        createRelationshipType(name);
+        browsingToRelationshipType();
+
+        wicketTester.assertComponent(DATATABLE_PATH, AjaxDataTablePanel.class);
+
+        Component result = findComponentByProp(KEY, DATATABLE_PATH, name);
+
+        assertNotNull(result);
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink",
+                IndicatingOnConfirmAjaxLink.class);
+
+        wicketTester.getRequest().addParameter("confirm", "true");
+        wicketTester.clickLink(
+                wicketTester.getComponentFromLastRenderedPage(
+                        result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"));
+
+        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
+                result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"), "onclick");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.cleanupFeedbackMessages();
+        result = findComponentByProp(KEY, DATATABLE_PATH, name);
+
+        assertNull(result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java
new file mode 100644
index 0000000..f731ca9
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java
@@ -0,0 +1,156 @@
+/*
+ * 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.fit.console;
+
+import static org.junit.Assert.assertNull;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.syncope.client.console.pages.Types;
+import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Test;
+
+public class SchemasITCase extends AbstractTypesITCase {
+
+    @Test
+    public void readPlainSchema() {
+        browsingToPlainSchemas();
+        wicketTester.assertLabel(
+                PLAIN_DATATABLE_PATH
+                + ":tablePanel:groupForm:"
+                + "checkgroup:dataTable:body:rows:1:cells:1:cell", "aLong");
+
+        wicketTester.assertComponent(
+                PLAIN_DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:"
+                + "body:rows:1:cells:7:cell:panelEdit:editLink", IndicatingAjaxLink.class);
+
+        wicketTester.clickLink(
+                PLAIN_DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:dataTable:"
+                + "body:rows:1:cells:7:cell:panelEdit:editLink");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:"
+                + "panel:collapsePanel:tabs:0:body:content:modal:"
+                + "form:content:kindForm:kind:dropDownChoiceField", DropDownChoice.class);
+    }
+
+    @Test
+    public void createPlainSchema() {
+        browsingToPlainSchemas();
+        wicketTester.clickLink("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:container:content:add");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:"
+                + "collapsePanel:tabs:0:body:content:modal:form");
+        formTester.setValue("content:details:form:key:textField", "zBoolean");
+        formTester.setValue("content:details:form:type:dropDownChoiceField", "3");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:"
+                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.cleanupFeedbackMessages();
+        wicketTester.assertRenderedPage(Types.class);
+    }
+
+    @Test
+    public void updatePlainSchema() {
+        browsingToPlainSchemas();
+
+        Component result = findComponentByProp(KEY, PLAIN_DATATABLE_PATH, "firstname");
+
+        wicketTester.assertLabel(
+                result.getPageRelativePath() + ":cells:1:cell", "firstname");
+
+        wicketTester.clickLink(
+                result.getPageRelativePath() + ":cells:7:cell:panelEdit:editLink");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:"
+                + "panel:collapsePanel:tabs:0:body:content:modal:"
+                + "form:content:kindForm:kind:dropDownChoiceField", DropDownChoice.class);
+
+        final FormTester formTester =
+                wicketTester.newFormTester("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal:form");
+        formTester.setValue("content:details:form:multivalue:checkboxField", "true");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:"
+                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit", true);
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+    }
+
+    @Test
+    public void deletePlainSchema() {
+        browsingToPlainSchemas();
+        //create new Plain Schema
+        final String schemaName = "zStringDelete";
+        wicketTester.clickLink("content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:container:content:add");
+
+        wicketTester.assertComponent(
+                "content:tabbedPanel:panel:collapsePanel:tabs:0:body:content:modal", Modal.class);
+
+        final FormTester formTester = wicketTester.newFormTester("content:tabbedPanel:panel:"
+                + "collapsePanel:tabs:0:body:content:modal:form");
+        formTester.setValue("content:details:form:key:textField", schemaName);
+        formTester.setValue("content:details:form:type:dropDownChoiceField", "0");
+
+        wicketTester.clickLink("content:tabbedPanel:panel:"
+                + "collapsePanel:tabs:0:body:content:modal:dialog:footer:inputs:0:submit");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");;
+
+        wicketTester.cleanupFeedbackMessages();
+
+        //delete plain schema
+        wicketTester.clickLink(
+                PLAIN_DATATABLE_PATH
+                + ":tablePanel:groupForm:checkgroup:"
+                + "dataTable:topToolbars:toolbars:1:span:navigator:last");
+
+        wicketTester.assertComponent(PLAIN_DATATABLE_PATH, AjaxDataTablePanel.class);
+
+        Component result = findComponentByProp(KEY, PLAIN_DATATABLE_PATH, schemaName);
+
+        wicketTester.assertComponent(
+                result.getPageRelativePath() + ":cells:7:cell:panelDelete:deleteLink",
+                IndicatingOnConfirmAjaxLink.class);
+
+        wicketTester.getRequest().addParameter("confirm", "true");
+        wicketTester.clickLink(
+                wicketTester.getComponentFromLastRenderedPage(
+                        result.getPageRelativePath() + ":cells:7:cell:panelDelete:deleteLink"));
+
+        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
+                result.getPageRelativePath() + ":cells:7:cell:panelDelete:deleteLink"), "onclick");
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        assertNull(findComponentByProp(KEY, PLAIN_DATATABLE_PATH, schemaName));
+    }
+}


[10/21] syncope git commit: [SYNCOPE-152] Moving console IT under fit/core-reference in order to speed-up the total build time

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
deleted file mode 100644
index 0f80766..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ /dev/null
@@ -1,938 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.security.AccessControlException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.AnyOperations;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AssociationPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.DeassociationPatch;
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.patch.LongReplacePatchItem;
-import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.AnyTypeTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.TypeExtensionTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.ResourceAssociationAction;
-import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
-import org.apache.syncope.common.lib.types.SchemaType;
-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.GroupService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class GroupITCase extends AbstractITCase {
-
-    public static GroupTO getBasicSampleTO(final String name) {
-        GroupTO groupTO = new GroupTO();
-        groupTO.setRealm(SyncopeConstants.ROOT_REALM);
-        groupTO.setName(name + getUUIDString());
-        return groupTO;
-    }
-
-    public static GroupTO getSampleTO(final String name) {
-        GroupTO groupTO = getBasicSampleTO(name);
-
-        groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
-
-        groupTO.getResources().add(RESOURCE_NAME_LDAP);
-        return groupTO;
-    }
-
-    @Test
-    public void create() {
-        GroupTO groupTO = getSampleTO("lastGroup");
-        groupTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
-        groupTO.setGroupOwner(8L);
-
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-
-        assertNotNull(groupTO.getVirAttrMap());
-        assertNotNull(groupTO.getVirAttrMap().get("rvirtualdata").getValues());
-        assertFalse(groupTO.getVirAttrMap().get("rvirtualdata").getValues().isEmpty());
-        assertEquals("rvirtualvalue", groupTO.getVirAttrMap().get("rvirtualdata").getValues().get(0));
-
-        assertTrue(groupTO.getResources().contains(RESOURCE_NAME_LDAP));
-
-        ConnObjectTO connObjectTO =
-                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
-        assertNotNull(connObjectTO);
-        assertNotNull(connObjectTO.getPlainAttrMap().get("owner"));
-
-        // SYNCOPE-515: remove ownership
-        GroupPatch groupPatch = new GroupPatch();
-        groupPatch.setKey(groupTO.getKey());
-        groupPatch.setGroupOwner(new LongReplacePatchItem());
-
-        assertNull(updateGroup(groupPatch).getAny().getGroupOwner());
-    }
-
-    @Test
-    public void delete() {
-        try {
-            groupService.delete(0L);
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName("toBeDeleted" + getUUIDString());
-        groupTO.setRealm("/even");
-
-        groupTO.getResources().add(RESOURCE_NAME_LDAP);
-
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-
-        GroupTO deletedGroup = deleteGroup(groupTO.getKey()).getAny();
-        assertNotNull(deletedGroup);
-
-        try {
-            groupService.read(deletedGroup.getKey());
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-        }
-    }
-
-    @Test
-    public void list() {
-        PagedResult<GroupTO> groupTOs =
-                groupService.list(new AnyListQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
-        assertNotNull(groupTOs);
-        assertTrue(groupTOs.getResult().size() >= 8);
-        for (GroupTO groupTO : groupTOs.getResult()) {
-            assertNotNull(groupTO);
-        }
-    }
-
-    @Test
-    public void read() {
-        GroupTO groupTO = groupService.read(1L);
-
-        assertNotNull(groupTO);
-        assertNotNull(groupTO.getPlainAttrs());
-        assertFalse(groupTO.getPlainAttrs().isEmpty());
-    }
-
-    @Test
-    public void selfRead() {
-        UserTO userTO = userService.read(1L);
-        assertNotNull(userTO);
-
-        assertTrue(userTO.getMembershipMap().containsKey(1L));
-        assertFalse(userTO.getMembershipMap().containsKey(3L));
-
-        GroupService groupService2 = clientFactory.create("rossini", ADMIN_PWD).getService(GroupService.class);
-
-        try {
-            groupService2.read(3L);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
-        }
-
-        List<GroupTO> groups = groupService2.own();
-        assertNotNull(groups);
-        assertTrue(IterableUtils.matchesAny(groups, new Predicate<GroupTO>() {
-
-            @Override
-            public boolean evaluate(final GroupTO group) {
-                return 1L == group.getKey();
-            }
-        }));
-    }
-
-    @Test
-    public void update() {
-        GroupTO groupTO = getSampleTO("latestGroup" + getUUIDString());
-        groupTO = createGroup(groupTO).getAny();
-
-        assertEquals(1, groupTO.getPlainAttrs().size());
-
-        GroupPatch groupPatch = new GroupPatch();
-        groupPatch.setKey(groupTO.getKey());
-        String modName = "finalGroup" + getUUIDString();
-        groupPatch.setName(new StringReplacePatchItem.Builder().value(modName).build());
-        groupPatch.getPlainAttrs().add(attrAddReplacePatch("show", "FALSE"));
-
-        groupTO = updateGroup(groupPatch).getAny();
-
-        assertEquals(modName, groupTO.getName());
-        assertEquals(2, groupTO.getPlainAttrs().size());
-
-        groupTO.getPlainAttrMap().get("show").getValues().clear();
-
-        groupTO = groupService.update(groupTO).readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
-        }).getAny();
-
-        assertFalse(groupTO.getPlainAttrMap().containsKey("show"));
-    }
-
-    @Test
-    public void patch() {
-        GroupTO original = getBasicSampleTO("patch");
-        original.setUDynMembershipCond("(($groups==3;$resources!=ws-target-resource-1);aLong==1)");
-        original.getADynMembershipConds().put(
-                "PRINTER",
-                "(($groups==7;cool==ss);$resources==ws-target-resource-2);$type==PRINTER");
-
-        GroupTO updated = createGroup(original).getAny();
-
-        updated.getPlainAttrs().add(new AttrTO.Builder().schema("icon").build());
-        updated.getPlainAttrs().add(new AttrTO.Builder().schema("show").build());
-        updated.getPlainAttrs().add(new AttrTO.Builder().schema("rderived_sx").value("sx").build());
-        updated.getPlainAttrs().add(new AttrTO.Builder().schema("rderived_dx").value("dx").build());
-        updated.getPlainAttrs().add(new AttrTO.Builder().schema("title").value("mr").build());
-
-        original = groupService.read(updated.getKey());
-
-        GroupPatch patch = AnyOperations.diff(updated, original, true);
-        GroupTO group = updateGroup(patch).getAny();
-
-        Map<String, AttrTO> attrs = group.getPlainAttrMap();
-        assertFalse(attrs.containsKey("icon"));
-        assertFalse(attrs.containsKey("show"));
-        assertEquals(Collections.singletonList("sx"), attrs.get("rderived_sx").getValues());
-        assertEquals(Collections.singletonList("dx"), attrs.get("rderived_dx").getValues());
-        assertEquals(Collections.singletonList("mr"), attrs.get("title").getValues());
-    }
-
-    @Test
-    public void updateAsGroupOwner() {
-        // 1. read group as admin
-        GroupTO groupTO = groupService.read(6L);
-
-        // issue SYNCOPE-15
-        assertNotNull(groupTO.getCreationDate());
-        assertNotNull(groupTO.getLastChangeDate());
-        assertEquals("admin", groupTO.getCreator());
-        assertEquals("admin", groupTO.getLastModifier());
-
-        // 2. prepare update
-        GroupPatch groupPatch = new GroupPatch();
-        groupPatch.setKey(groupTO.getKey());
-        groupPatch.setName(new StringReplacePatchItem.Builder().value("Director").build());
-
-        // 3. try to update as verdi, not owner of group 6 - fail
-        GroupService groupService2 = clientFactory.create("verdi", ADMIN_PWD).getService(GroupService.class);
-
-        try {
-            groupService2.update(groupPatch);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        // 4. update as puccini, owner of group 6 - success
-        GroupService groupService3 = clientFactory.create("puccini", ADMIN_PWD).getService(GroupService.class);
-
-        groupTO = groupService3.update(groupPatch).readEntity(new GenericType<ProvisioningResult<GroupTO>>() {
-        }).getAny();
-        assertEquals("Director", groupTO.getName());
-
-        // issue SYNCOPE-15
-        assertNotNull(groupTO.getCreationDate());
-        assertNotNull(groupTO.getLastChangeDate());
-        assertEquals("admin", groupTO.getCreator());
-        assertEquals("puccini", groupTO.getLastModifier());
-        assertTrue(groupTO.getCreationDate().before(groupTO.getLastChangeDate()));
-    }
-
-    @Test
-    public void unlink() {
-        GroupTO actual = createGroup(getSampleTO("unlink")).getAny();
-        assertNotNull(actual);
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
-    }
-
-    @Test
-    public void link() {
-        GroupTO groupTO = getSampleTO("link");
-        groupTO.getResources().clear();
-
-        GroupTO actual = createGroup(groupTO).getAny();
-        assertNotNull(actual);
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setAction(ResourceAssociationAction.LINK);
-        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertFalse(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void unassign() {
-        GroupTO actual = createGroup(getSampleTO("unassign")).getAny();
-        assertNotNull(actual);
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.UNASSIGN);
-        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void assign() {
-        GroupTO groupTO = getSampleTO("assign");
-        groupTO.getResources().clear();
-
-        GroupTO actual = createGroup(groupTO).getAny();
-        assertNotNull(actual);
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setAction(ResourceAssociationAction.ASSIGN);
-        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertFalse(actual.getResources().isEmpty());
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
-    }
-
-    @Test
-    public void deprovision() {
-        GroupTO actual = createGroup(getSampleTO("deprovision")).getAny();
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
-        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertNotNull(actual);
-        assertFalse(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void provision() {
-        GroupTO groupTO = getSampleTO("assign" + getUUIDString());
-        groupTO.getResources().clear();
-
-        GroupTO actual = createGroup(groupTO).getAny();
-        assertNotNull(actual);
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setAction(ResourceAssociationAction.PROVISION);
-        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertTrue(actual.getResources().isEmpty());
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
-    }
-
-    @Test
-    public void deprovisionUnlinked() {
-        GroupTO groupTO = getSampleTO("assign" + getUUIDString());
-        groupTO.getResources().clear();
-
-        GroupTO actual = createGroup(groupTO).getAny();
-        assertNotNull(actual);
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-
-        AssociationPatch associationPatch = new AssociationPatch();
-        associationPatch.setKey(actual.getKey());
-        associationPatch.setAction(ResourceAssociationAction.PROVISION);
-        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertTrue(actual.getResources().isEmpty());
-
-        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
-
-        DeassociationPatch deassociationPatch = new DeassociationPatch();
-        deassociationPatch.setKey(actual.getKey());
-        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
-        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-
-        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
-
-        actual = groupService.read(actual.getKey());
-        assertNotNull(actual);
-        assertTrue(actual.getResources().isEmpty());
-
-        try {
-            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
-            fail();
-        } catch (Exception e) {
-            assertNotNull(e);
-        }
-    }
-
-    @Test
-    public void createWithMandatorySchema() {
-        // 1. create a mandatory schema
-        PlainSchemaTO badge = new PlainSchemaTO();
-        badge.setKey("badge" + getUUIDString());
-        badge.setMandatoryCondition("true");
-        schemaService.create(SchemaType.PLAIN, badge);
-
-        // 2. create a group *without* an attribute for that schema: it works
-        GroupTO groupTO = getSampleTO("lastGroup");
-        assertFalse(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-        assertFalse(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
-
-        // 3. add the new mandatory schema to the default group type
-        AnyTypeTO type = anyTypeService.read(AnyTypeKind.GROUP.name());
-        String typeClassName = type.getClasses().get(0);
-        AnyTypeClassTO typeClass = anyTypeClassService.read(typeClassName);
-        typeClass.getPlainSchemas().add(badge.getKey());
-        anyTypeClassService.update(typeClass);
-        typeClass = anyTypeClassService.read(typeClassName);
-        assertTrue(typeClass.getPlainSchemas().contains(badge.getKey()));
-
-        try {
-            // 4. update group: failure since no values are provided and it is mandatory
-            GroupPatch groupPatch = new GroupPatch();
-            groupPatch.setKey(groupTO.getKey());
-
-            try {
-                updateGroup(groupPatch);
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-            }
-
-            // 5. also add an actual attribute for badge - it will work        
-            groupPatch.getPlainAttrs().add(attrAddReplacePatch(badge.getKey(), "xxxxxxxxxx"));
-
-            groupTO = updateGroup(groupPatch).getAny();
-            assertNotNull(groupTO);
-            assertTrue(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
-        } finally {
-            // restore the original group class
-            typeClass.getPlainSchemas().remove(badge.getKey());
-            anyTypeClassService.update(typeClass);
-            typeClass = anyTypeClassService.read(typeClassName);
-            assertFalse(typeClass.getPlainSchemas().contains(badge.getKey()));
-        }
-    }
-
-    @Test
-    public void anonymous() {
-        GroupService unauthenticated = clientFactory.create().getService(GroupService.class);
-        try {
-            unauthenticated.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build());
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        GroupService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(GroupService.class);
-        assertFalse(anonymous.list(new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build()).
-                getResult().isEmpty());
-    }
-
-    @Test
-    public void uDynMembership() {
-        assertTrue(userService.read(4L).getDynGroups().isEmpty());
-
-        GroupTO group = getBasicSampleTO("uDynMembership");
-        group.setUDynMembershipCond("cool==true");
-        group = createGroup(group).getAny();
-        assertNotNull(group);
-
-        assertTrue(userService.read(4L).getDynGroups().contains(group.getKey()));
-
-        GroupPatch patch = new GroupPatch();
-        patch.setKey(group.getKey());
-        patch.setUDynMembershipCond("cool==false");
-        groupService.update(patch);
-
-        assertTrue(userService.read(4L).getDynGroups().isEmpty());
-    }
-
-    @Test
-    public void aDynMembership() {
-        String fiql = SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").is("location").notNullValue().query();
-
-        // 1. create group with a given aDynMembership condition
-        GroupTO group = getBasicSampleTO("aDynMembership");
-        group.getADynMembershipConds().put("PRINTER", fiql);
-        group = createGroup(group).getAny();
-        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
-
-        group = groupService.read(group.getKey());
-        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
-
-        // verify that the condition is dynamically applied
-        AnyObjectTO newAny = AnyObjectITCase.getSampleTO("aDynMembership");
-        newAny.getResources().clear();
-        newAny = createAnyObject(newAny).getAny();
-        assertNotNull(newAny.getPlainAttrMap().get("location"));
-        assertTrue(anyObjectService.read(1L).getDynGroups().contains(group.getKey()));
-        assertTrue(anyObjectService.read(2L).getDynGroups().contains(group.getKey()));
-        assertTrue(anyObjectService.read(newAny.getKey()).getDynGroups().contains(group.getKey()));
-
-        // 2. update group and change aDynMembership condition
-        fiql = SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").is("location").nullValue().query();
-
-        GroupPatch patch = new GroupPatch();
-        patch.setKey(group.getKey());
-        patch.getADynMembershipConds().put("PRINTER", fiql);
-
-        group = updateGroup(patch).getAny();
-        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
-
-        group = groupService.read(group.getKey());
-        assertEquals(fiql, group.getADynMembershipConds().get("PRINTER"));
-
-        // verify that the condition is dynamically applied
-        AnyObjectPatch anyPatch = new AnyObjectPatch();
-        anyPatch.setKey(newAny.getKey());
-        anyPatch.getPlainAttrs().add(new AttrPatch.Builder().
-                operation(PatchOperation.DELETE).
-                attrTO(new AttrTO.Builder().schema("location").build()).
-                build());
-        newAny = updateAnyObject(anyPatch).getAny();
-        assertNull(newAny.getPlainAttrMap().get("location"));
-        assertFalse(anyObjectService.read(1L).getDynGroups().contains(group.getKey()));
-        assertFalse(anyObjectService.read(2L).getDynGroups().contains(group.getKey()));
-        assertTrue(anyObjectService.read(newAny.getKey()).getDynGroups().contains(group.getKey()));
-    }
-
-    @Test
-    public void capabilitiesOverride() {
-        // resource with no capability override
-        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
-        assertNotNull(ldap);
-        assertFalse(ldap.isOverrideCapabilities());
-        assertTrue(ldap.getCapabilitiesOverride().isEmpty());
-
-        // connector with all required for create and update
-        ConnInstanceTO conn = connectorService.read(ldap.getConnector(), null);
-        assertNotNull(conn);
-        assertTrue(conn.getCapabilities().contains(ConnectorCapability.CREATE));
-        assertTrue(conn.getCapabilities().contains(ConnectorCapability.UPDATE));
-
-        try {
-            // 1. create succeeds
-            GroupTO group = getSampleTO("syncope714");
-            group.getPlainAttrs().add(attrTO("title", "first"));
-            group.getResources().add(RESOURCE_NAME_LDAP);
-
-            ProvisioningResult<GroupTO> result = createGroup(group);
-            assertNotNull(result);
-            assertEquals(1, result.getPropagationStatuses().size());
-            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-            group = result.getAny();
-
-            // 2. update succeeds
-            GroupPatch patch = new GroupPatch();
-            patch.setKey(group.getKey());
-            patch.getPlainAttrs().add(new AttrPatch.Builder().
-                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "second")).build());
-
-            result = updateGroup(patch);
-            assertNotNull(result);
-            assertEquals(1, result.getPropagationStatuses().size());
-            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-            group = result.getAny();
-
-            // 3. set capability override with only search allowed, but not enable
-            ldap.getCapabilitiesOverride().add(ConnectorCapability.SEARCH);
-            resourceService.update(ldap);
-            ldap = resourceService.read(RESOURCE_NAME_LDAP);
-            assertNotNull(ldap);
-            assertFalse(ldap.isOverrideCapabilities());
-            assertEquals(1, ldap.getCapabilitiesOverride().size());
-            assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
-
-            // 4. update succeeds again
-            patch = new GroupPatch();
-            patch.setKey(group.getKey());
-            patch.getPlainAttrs().add(new AttrPatch.Builder().
-                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "third")).build());
-
-            result = updateGroup(patch);
-            assertNotNull(result);
-            assertEquals(1, result.getPropagationStatuses().size());
-            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-            group = result.getAny();
-
-            // 5. enable capability override
-            ldap.setOverrideCapabilities(true);
-            resourceService.update(ldap);
-            ldap = resourceService.read(RESOURCE_NAME_LDAP);
-            assertNotNull(ldap);
-            assertTrue(ldap.isOverrideCapabilities());
-            assertEquals(1, ldap.getCapabilitiesOverride().size());
-            assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
-
-            // 6. update now fails
-            patch = new GroupPatch();
-            patch.setKey(group.getKey());
-            patch.getPlainAttrs().add(new AttrPatch.Builder().
-                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "fourth")).build());
-
-            result = updateGroup(patch);
-            assertNotNull(result);
-            assertEquals(1, result.getPropagationStatuses().size());
-            assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
-            assertEquals(PropagationTaskExecStatus.NOT_ATTEMPTED, result.getPropagationStatuses().get(0).getStatus());
-        } finally {
-            ldap.getCapabilitiesOverride().clear();
-            ldap.setOverrideCapabilities(false);
-            resourceService.update(ldap);
-        }
-    }
-
-    @Test
-    public void typeExtensions() {
-        TypeExtensionTO typeExtension = new TypeExtensionTO();
-        typeExtension.setAnyType(AnyTypeKind.USER.name());
-        typeExtension.getAuxClasses().add("csv");
-
-        GroupTO groupTO = getBasicSampleTO("typeExtensions");
-        groupTO.getTypeExtensions().add(typeExtension);
-
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-        assertEquals(1, groupTO.getTypeExtensions().size());
-        assertEquals(1, groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().size());
-        assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().contains("csv"));
-
-        typeExtension = new TypeExtensionTO();
-        typeExtension.setAnyType(AnyTypeKind.USER.name());
-        typeExtension.getAuxClasses().add("csv");
-        typeExtension.getAuxClasses().add("other");
-
-        GroupPatch groupPatch = new GroupPatch();
-        groupPatch.setKey(groupTO.getKey());
-        groupPatch.getTypeExtensions().add(typeExtension);
-
-        groupTO = updateGroup(groupPatch).getAny();
-        assertNotNull(groupTO);
-        assertEquals(1, groupTO.getTypeExtensions().size());
-        assertEquals(2, groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().size());
-        assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().contains("csv"));
-        assertTrue(groupTO.getTypeExtension(AnyTypeKind.USER.name()).getAuxClasses().contains("other"));
-    }
-
-    @Test
-    public void issue178() {
-        GroupTO groupTO = new GroupTO();
-        String groupName = "torename" + getUUIDString();
-        groupTO.setName(groupName);
-        groupTO.setRealm("/");
-
-        GroupTO actual = createGroup(groupTO).getAny();
-
-        assertNotNull(actual);
-        assertEquals(groupName, actual.getName());
-
-        GroupPatch groupPatch = new GroupPatch();
-        groupPatch.setKey(actual.getKey());
-        String renamedGroup = "renamed" + getUUIDString();
-        groupPatch.setName(new StringReplacePatchItem.Builder().value(renamedGroup).build());
-
-        actual = updateGroup(groupPatch).getAny();
-        assertNotNull(actual);
-        assertEquals(renamedGroup, actual.getName());
-    }
-
-    @Test
-    public void issueSYNCOPE632() {
-        GroupTO groupTO = null;
-        try {
-            // 1. create new LDAP resource having ConnObjectKey mapped to a derived attribute
-            ResourceTO newLDAP = resourceService.read(RESOURCE_NAME_LDAP);
-            newLDAP.setKey("new-ldap");
-            newLDAP.setPropagationPriority(0);
-
-            for (ProvisionTO provision : newLDAP.getProvisions()) {
-                provision.getVirSchemas().clear();
-            }
-
-            MappingTO mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).getMapping();
-
-            MappingItemTO connObjectKey = mapping.getConnObjectKeyItem();
-            connObjectKey.setIntMappingType(IntMappingType.GroupDerivedSchema);
-            connObjectKey.setIntAttrName("displayProperty");
-            connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
-            mapping.setConnObjectKeyItem(connObjectKey);
-            mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
-
-            MappingItemTO description = new MappingItemTO();
-            description.setIntMappingType(IntMappingType.GroupKey);
-            description.setExtAttrName("description");
-            description.setPurpose(MappingPurpose.BOTH);
-            mapping.add(description);
-
-            newLDAP = createResource(newLDAP);
-            assertNotNull(newLDAP);
-
-            // 2. create a group and give the resource created above
-            groupTO = getSampleTO("lastGroup" + getUUIDString());
-            groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
-            groupTO.getPlainAttrs().add(attrTO("show", "true"));
-            groupTO.getDerAttrs().add(attrTO("displayProperty", null));
-            groupTO.getResources().clear();
-            groupTO.getResources().add("new-ldap");
-
-            groupTO = createGroup(groupTO).getAny();
-            assertNotNull(groupTO);
-
-            // 3. update the group
-            GroupPatch groupPatch = new GroupPatch();
-            groupPatch.setKey(groupTO.getKey());
-            groupPatch.getPlainAttrs().add(attrAddReplacePatch("icon", "anotherIcon"));
-
-            groupTO = updateGroup(groupPatch).getAny();
-            assertNotNull(groupTO);
-
-            // 4. check that a single group exists in LDAP for the group created and updated above
-            int entries = 0;
-            DirContext ctx = null;
-            try {
-                ctx = getLdapResourceDirContext(null, null);
-
-                SearchControls ctls = new SearchControls();
-                ctls.setReturningAttributes(new String[] { "*", "+" });
-                ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
-
-                NamingEnumeration<SearchResult> result =
-                        ctx.search("ou=groups,o=isp", "(description=" + groupTO.getKey() + ")", ctls);
-                while (result.hasMore()) {
-                    result.next();
-                    entries++;
-                }
-            } catch (Exception e) {
-                // ignore
-            } finally {
-                if (ctx != null) {
-                    try {
-                        ctx.close();
-                    } catch (NamingException e) {
-                        // ignore
-                    }
-                }
-            }
-
-            assertEquals(1, entries);
-        } finally {
-            if (groupTO != null) {
-                groupService.delete(groupTO.getKey());
-            }
-            resourceService.delete("new-ldap");
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE717() {
-        String doubleSchemaName = "double" + getUUIDString();
-
-        // 1. create double schema without conversion pattern
-        PlainSchemaTO schema = new PlainSchemaTO();
-        schema.setKey(doubleSchemaName);
-        schema.setType(AttrSchemaType.Double);
-
-        schema = createSchema(SchemaType.PLAIN, schema);
-        assertNotNull(schema);
-        assertNull(schema.getConversionPattern());
-
-        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
-        assertNotNull(minimalGroup);
-        minimalGroup.getPlainSchemas().add(doubleSchemaName);
-        anyTypeClassService.update(minimalGroup);
-
-        // 2. create group, provide valid input value
-        GroupTO groupTO = getBasicSampleTO("syncope717");
-        groupTO.getPlainAttrs().add(attrTO(doubleSchemaName, "11.23"));
-
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-        assertEquals("11.23", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
-
-        // 3. update schema, set conversion pattern
-        schema.setConversionPattern("0.000");
-        schemaService.update(SchemaType.PLAIN, schema);
-
-        // 4. re-read group, verify that pattern was applied
-        groupTO = groupService.read(groupTO.getKey());
-        assertNotNull(groupTO);
-        assertEquals("11.230", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
-
-        // 5. modify group with new double value
-        GroupPatch patch = new GroupPatch();
-        patch.setKey(groupTO.getKey());
-        patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO(doubleSchemaName, "11.257")).build());
-
-        groupTO = updateGroup(patch).getAny();
-        assertNotNull(groupTO);
-        assertEquals("11.257", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
-
-        // 6. update schema, unset conversion pattern
-        schema.setConversionPattern(null);
-        schemaService.update(SchemaType.PLAIN, schema);
-
-        // 7. modify group with new double value, verify that no pattern is applied
-        patch = new GroupPatch();
-        patch.setKey(groupTO.getKey());
-        patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO(doubleSchemaName, "11.23")).build());
-
-        groupTO = updateGroup(patch).getAny();
-        assertNotNull(groupTO);
-        assertEquals("11.23", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
deleted file mode 100644
index 236d169..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
+++ /dev/null
@@ -1,230 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.text.ParseException;
-import java.util.List;
-import javax.ws.rs.core.Response;
-import javax.xml.ws.WebServiceException;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.EventCategoryTO;
-import org.apache.syncope.common.lib.to.LoggerTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
-import org.apache.syncope.common.lib.types.AuditLoggerName;
-import org.apache.syncope.common.lib.types.LoggerLevel;
-import org.apache.syncope.common.lib.types.LoggerType;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.rest.api.LoggerWrapper;
-import org.apache.syncope.core.logic.ReportLogic;
-import org.apache.syncope.core.logic.ResourceLogic;
-import org.apache.syncope.core.logic.GroupLogic;
-import org.apache.syncope.core.logic.UserLogic;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class LoggerITCase extends AbstractITCase {
-
-    @Test
-    public void listLogs() {
-        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
-        assertNotNull(loggers);
-        assertFalse(loggers.isEmpty());
-        for (LoggerTO logger : loggers) {
-            assertNotNull(logger);
-        }
-    }
-
-    @Test
-    public void listAudits() throws ParseException {
-        List<LoggerTO> audits = loggerService.list(LoggerType.AUDIT);
-
-        assertNotNull(audits);
-        assertFalse(audits.isEmpty());
-        for (LoggerTO audit : audits) {
-            assertNotNull(AuditLoggerName.fromLoggerName(audit.getKey()));
-        }
-    }
-
-    @Test
-    public void setLevel() {
-        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
-        assertNotNull(loggers);
-        int startSize = loggers.size();
-
-        LoggerTO logger = new LoggerTO();
-        logger.setKey("TEST");
-        logger.setLevel(LoggerLevel.INFO);
-        loggerService.update(LoggerType.LOG, logger);
-        logger = loggerService.read(LoggerType.LOG, logger.getKey());
-        assertNotNull(logger);
-        assertEquals(LoggerLevel.INFO, logger.getLevel());
-
-        loggers = loggerService.list(LoggerType.LOG);
-        assertNotNull(loggers);
-        assertEquals(startSize + 1, loggers.size());
-
-        // TEST Delete
-        loggerService.delete(LoggerType.LOG, "TEST");
-        loggers = loggerService.list(LoggerType.LOG);
-        assertNotNull(loggers);
-        assertEquals(startSize, loggers.size());
-    }
-
-    @Test
-    public void enableDisableAudit() {
-        AuditLoggerName auditLoggerName = new AuditLoggerName(
-                EventCategoryType.REST,
-                ReportLogic.class.getSimpleName(),
-                null,
-                "deleteExecution",
-                AuditElements.Result.FAILURE);
-
-        List<AuditLoggerName> audits = LoggerWrapper.wrap(loggerService.list(LoggerType.AUDIT));
-        assertNotNull(audits);
-        assertFalse(audits.contains(auditLoggerName));
-
-        LoggerTO loggerTO = new LoggerTO();
-        loggerTO.setKey(auditLoggerName.toLoggerName());
-        loggerTO.setLevel(LoggerLevel.DEBUG);
-        loggerService.update(LoggerType.AUDIT, loggerTO);
-
-        audits = LoggerWrapper.wrap(loggerService.list(LoggerType.AUDIT));
-        assertNotNull(audits);
-        assertTrue(audits.contains(auditLoggerName));
-
-        loggerService.delete(LoggerType.AUDIT, auditLoggerName.toLoggerName());
-
-        audits = LoggerWrapper.wrap(loggerService.list(LoggerType.AUDIT));
-        assertNotNull(audits);
-        assertFalse(audits.contains(auditLoggerName));
-    }
-
-    @Test
-    public void listAuditEvents() {
-        final List<EventCategoryTO> events = loggerService.events();
-
-        boolean found = false;
-
-        for (EventCategoryTO eventCategoryTO : events) {
-            if (UserLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
-                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
-                assertTrue(eventCategoryTO.getEvents().contains("create"));
-                assertTrue(eventCategoryTO.getEvents().contains("list"));
-                assertFalse(eventCategoryTO.getEvents().contains("doCreate"));
-                assertFalse(eventCategoryTO.getEvents().contains("setStatusOnWfAdapter"));
-                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
-                found = true;
-            }
-        }
-        assertTrue(found);
-
-        found = false;
-        for (EventCategoryTO eventCategoryTO : events) {
-            if (GroupLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
-                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
-                assertTrue(eventCategoryTO.getEvents().contains("create"));
-                assertTrue(eventCategoryTO.getEvents().contains("list"));
-                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
-                found = true;
-            }
-        }
-        assertTrue(found);
-
-        found = false;
-        for (EventCategoryTO eventCategoryTO : events) {
-            if (ResourceLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
-                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
-                assertTrue(eventCategoryTO.getEvents().contains("create"));
-                assertTrue(eventCategoryTO.getEvents().contains("read"));
-                assertTrue(eventCategoryTO.getEvents().contains("delete"));
-                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
-                found = true;
-            }
-        }
-        assertTrue(found);
-
-        found = false;
-        for (EventCategoryTO eventCategoryTO : events) {
-            if (AnyTypeKind.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
-                if (RESOURCE_NAME_LDAP.equals(eventCategoryTO.getSubcategory())
-                        && EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()) {
-                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
-                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
-                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
-                    found = true;
-                }
-            }
-        }
-        assertTrue(found);
-
-        found = false;
-        for (EventCategoryTO eventCategoryTO : events) {
-            if (AnyTypeKind.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
-                if (RESOURCE_NAME_CSV.equals(eventCategoryTO.getSubcategory())
-                        && EventCategoryType.PROPAGATION == eventCategoryTO.getType()) {
-                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
-                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
-                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
-                    found = true;
-                }
-            }
-        }
-        assertTrue(found);
-
-        found = false;
-        for (EventCategoryTO eventCategoryTO : events) {
-            if (EventCategoryType.TASK == eventCategoryTO.getType()
-                    && "TestSampleJobDelegate".equals(eventCategoryTO.getCategory())) {
-                found = true;
-            }
-        }
-        assertTrue(found);
-
-        found = false;
-        for (EventCategoryTO eventCategoryTO : events) {
-            if (EventCategoryType.TASK == eventCategoryTO.getType()
-                    && "SyncJobDelegate".equals(eventCategoryTO.getCategory())) {
-                found = true;
-            }
-        }
-        assertTrue(found);
-    }
-
-    @Test
-    public void issueSYNCOPE708() {
-        try {
-            loggerService.read(LoggerType.LOG, "notExists");
-            fail("Reading non-existing logger, it should go in exception");
-        } catch (final WebServiceException ex) {
-            fail("Exception is WebServiceException but it should be SyncopeClientException");
-        } catch (final SyncopeClientException ex) {
-            assertEquals(Response.Status.NOT_FOUND, ex.getType().getResponseStatus());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
deleted file mode 100644
index 8458181..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
+++ /dev/null
@@ -1,222 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import java.security.AccessControlException;
-import java.util.List;
-import java.util.Locale;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.LoggerType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.SyncMode;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
-import org.apache.syncope.common.rest.api.beans.SchemaQuery;
-import org.apache.syncope.common.rest.api.service.ConnectorService;
-import org.apache.syncope.common.rest.api.service.DomainService;
-import org.apache.syncope.common.rest.api.service.LoggerService;
-import org.apache.syncope.common.rest.api.service.RealmService;
-import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.common.rest.api.service.UserService;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class MultitenancyITCase extends AbstractITCase {
-
-    @BeforeClass
-    public static void restSetup() {
-        clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("Two");
-
-        String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
-        if (StringUtils.isNotBlank(envContentType)) {
-            clientFactory.setContentType(envContentType);
-        }
-        LOG.info("Performing IT with content type {}", clientFactory.getContentType().getMediaType());
-
-        adminClient = clientFactory.create(ADMIN_UNAME, "password2");
-    }
-
-    @Test
-    public void masterOnly() {
-        try {
-            adminClient.getService(DomainService.class).read("Two");
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        try {
-            adminClient.getService(LoggerService.class).list(LoggerType.LOG);
-            fail();
-        } catch (AccessControlException e) {
-            assertNotNull(e);
-        }
-
-        adminClient.getService(LoggerService.class).list(LoggerType.AUDIT);
-    }
-
-    @Test
-    public void readPlainSchemas() {
-        assertEquals(17, adminClient.getService(SchemaService.class).
-                list(new SchemaQuery.Builder().type(SchemaType.PLAIN).build()).size());
-    }
-
-    @Test
-    public void readRealm() {
-        List<RealmTO> realms = adminClient.getService(RealmService.class).list();
-        assertEquals(1, realms.size());
-        assertEquals(SyncopeConstants.ROOT_REALM, realms.get(0).getName());
-    }
-
-    @Test
-    public void createUser() {
-        assertNull(adminClient.getService(RealmService.class).list().get(0).getPasswordPolicy());
-
-        UserTO user = new UserTO();
-        user.setRealm(SyncopeConstants.ROOT_REALM);
-        user.setUsername(getUUIDString());
-        user.setPassword("password");
-
-        Response response = adminClient.getService(UserService.class).create(user);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
-
-        user = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
-        }).getAny();
-        assertNotNull(user);
-    }
-
-    @Test
-    public void createResourceAndSync() {
-        // read connector
-        ConnInstanceTO conn = adminClient.getService(ConnectorService.class).read(100L, Locale.ENGLISH.getLanguage());
-        assertNotNull(conn);
-        assertEquals("LDAP", conn.getDisplayName());
-
-        // prepare resource
-        ResourceTO resource = new ResourceTO();
-        resource.setKey("new-ldap-resource");
-        resource.setConnector(conn.getKey());
-
-        ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType(AnyTypeKind.USER.name());
-        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
-        resource.getProvisions().add(provisionTO);
-
-        MappingTO mapping = new MappingTO();
-        mapping.setConnObjectLink("'uid=' + username + ',ou=people,o=isp'");
-        provisionTO.setMapping(mapping);
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntAttrName("username");
-        item.setIntMappingType(IntMappingType.Username);
-        item.setExtAttrName("cn");
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        item = new MappingItemTO();
-        item.setPassword(true);
-        item.setIntMappingType(IntMappingType.Password);
-        item.setExtAttrName("userPassword");
-        item.setPurpose(MappingPurpose.BOTH);
-        item.setMandatoryCondition("true");
-        mapping.add(item);
-
-        item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserKey);
-        item.setPurpose(MappingPurpose.BOTH);
-        item.setExtAttrName("sn");
-        item.setMandatoryCondition("true");
-        mapping.add(item);
-
-        item = new MappingItemTO();
-        item.setIntAttrName("email");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        item.setExtAttrName("mail");
-        mapping.add(item);
-
-        // create resource
-        Response response = adminClient.getService(ResourceService.class).create(resource);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
-        resource = adminClient.getService(ResourceService.class).read(resource.getKey());
-        assertNotNull(resource);
-
-        // create sync task
-        SyncTaskTO task = new SyncTaskTO();
-        task.setName("LDAP Sync Task");
-        task.setActive(true);
-        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        task.setResource(resource.getKey());
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        task.setPerformCreate(true);
-
-        response = adminClient.getService(TaskService.class).create(task);
-        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
-        task = adminClient.getService(TaskService.class).read(
-                Long.valueOf(StringUtils.substringAfterLast(response.getLocation().toASCIIString(), "/")), true);
-        assertNotNull(resource);
-
-        // synchronize
-        TaskExecTO execution = AbstractTaskITCase.execProvisioningTask(
-                adminClient.getService(TaskService.class), task.getKey(), 50, false);
-
-        // verify execution status
-        String status = execution.getStatus();
-        assertNotNull(status);
-        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(status));
-
-        // verify that synchronized user is found
-        PagedResult<UserTO> matchingUsers = adminClient.getService(UserService.class).search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertEquals(1, matchingUsers.getResult().size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java
deleted file mode 100644
index f1c4c89..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java
+++ /dev/null
@@ -1,174 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.NotificationTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.common.rest.api.service.NotificationService;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class NotificationITCase extends AbstractITCase {
-
-    private NotificationTO buildNotificationTO() {
-        NotificationTO notificationTO = new NotificationTO();
-        notificationTO.setTraceLevel(TraceLevel.SUMMARY);
-        notificationTO.getEvents().add("create");
-
-        notificationTO.getAbouts().put(AnyTypeKind.USER.name(),
-                SyncopeClient.getUserSearchConditionBuilder().
-                is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
-
-        notificationTO.setRecipientAttrName("email");
-        notificationTO.setRecipientAttrType(IntMappingType.UserPlainSchema);
-
-        notificationTO.setSender("syncope@syncope.apache.org");
-        notificationTO.setSubject("Test notification");
-        notificationTO.setTemplate("test");
-        return notificationTO;
-    }
-
-    @Test
-    public void read() {
-        NotificationTO notificationTO = notificationService.read(10L);
-        assertNotNull(notificationTO);
-    }
-
-    @Test
-    public void list() {
-        List<NotificationTO> notificationTOs = notificationService.list();
-        assertNotNull(notificationTOs);
-        assertFalse(notificationTOs.isEmpty());
-        for (NotificationTO instance : notificationTOs) {
-            assertNotNull(instance);
-        }
-    }
-
-    @Test
-    public void create() {
-        NotificationTO notificationTO = buildNotificationTO();
-        notificationTO.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
-
-        Response response = notificationService.create(notificationTO);
-        NotificationTO actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
-
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-        notificationTO.setKey(actual.getKey());
-        assertEquals(actual, notificationTO);
-    }
-
-    @Test
-    public void update() {
-        NotificationTO notificationTO = notificationService.read(10L);
-        notificationTO.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
-
-        notificationService.update(notificationTO);
-        NotificationTO actual = notificationService.read(notificationTO.getKey());
-        assertNotNull(actual);
-        assertEquals(actual, notificationTO);
-    }
-
-    @Test
-    public void delete() {
-        NotificationTO notification = buildNotificationTO();
-        notification.setSelfAsRecipient(true);
-        Response response = notificationService.create(notification);
-        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
-
-        notificationService.delete(notification.getKey());
-
-        try {
-            notificationService.read(notification.getKey());
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.NotFound, e.getType());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE83() {
-        NotificationTO notificationTO = buildNotificationTO();
-        notificationTO.setSelfAsRecipient(true);
-
-        NotificationTO actual = null;
-        try {
-            Response response = notificationService.create(notificationTO);
-            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
-        } catch (SyncopeClientException e) {
-            assertNotNull(e);
-        }
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-        notificationTO.setKey(actual.getKey());
-        assertEquals(actual, notificationTO);
-    }
-
-    @Test
-    public void issueSYNCOPE445() {
-        NotificationTO notificationTO = buildNotificationTO();
-        notificationTO.getStaticRecipients().add("syncope445@syncope.apache.org");
-
-        NotificationTO actual = null;
-        try {
-            Response response = notificationService.create(notificationTO);
-            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
-        } catch (SyncopeClientException e) {
-            assertNotNull(e);
-        }
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-        notificationTO.setKey(actual.getKey());
-        assertEquals(actual, notificationTO);
-    }
-
-    @Test
-    public void issueSYNCOPE446() {
-        NotificationTO notificationTO = buildNotificationTO();
-        notificationTO.getStaticRecipients().add("syncope446@syncope.apache.org");
-        notificationTO.getAbouts().put(AnyTypeKind.GROUP.name(),
-                SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("citizen").query());
-
-        NotificationTO actual = null;
-        try {
-            Response response = notificationService.create(notificationTO);
-            actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
-        } catch (SyncopeClientException e) {
-            assertNotNull(e);
-        }
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-        notificationTO.setKey(actual.getKey());
-        assertEquals(actual, notificationTO);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/17d5d892/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
deleted file mode 100644
index 43de365..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
+++ /dev/null
@@ -1,398 +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.fit.core.reference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import com.icegreen.greenmail.util.GreenMail;
-import com.icegreen.greenmail.util.ServerSetup;
-import java.io.InputStream;
-import java.util.Properties;
-import javax.mail.Flags;
-import javax.mail.Folder;
-import javax.mail.Message;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.NotificationTO;
-import org.apache.syncope.common.lib.to.NotificationTaskTO;
-import org.apache.syncope.common.lib.to.TaskExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
-import org.apache.syncope.common.rest.api.service.NotificationService;
-import org.apache.syncope.core.logic.notification.NotificationJob;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class NotificationTaskITCase extends AbstractTaskITCase {
-
-    private static final String MAIL_ADDRESS = "notificationtest@syncope.apache.org";
-
-    private static final String POP3_HOST = "localhost";
-
-    private static final int POP3_PORT = 1110;
-
-    private static String SMTP_HOST;
-
-    private static int SMTP_PORT;
-
-    private static GreenMail greenMail;
-
-    @BeforeClass
-    public static void startGreenMail() {
-        Properties props = new Properties();
-        InputStream propStream = null;
-        try {
-            propStream = ExceptionMapperITCase.class.getResourceAsStream("/mail.properties");
-            props.load(propStream);
-        } catch (Exception e) {
-            LOG.error("Could not load /mail.properties", e);
-        } finally {
-            IOUtils.closeQuietly(propStream);
-        }
-
-        SMTP_HOST = props.getProperty("smtpHost");
-        assertNotNull(SMTP_HOST);
-        SMTP_PORT = Integer.parseInt(props.getProperty("smtpPort"));
-        assertNotNull(SMTP_PORT);
-
-        ServerSetup[] config = new ServerSetup[2];
-        config[0] = new ServerSetup(SMTP_PORT, SMTP_HOST, ServerSetup.PROTOCOL_SMTP);
-        config[1] = new ServerSetup(POP3_PORT, POP3_HOST, ServerSetup.PROTOCOL_POP3);
-        greenMail = new GreenMail(config);
-        greenMail.start();
-    }
-
-    @AfterClass
-    public static void stopGreenMail() {
-        if (greenMail != null) {
-            greenMail.stop();
-        }
-    }
-
-    private boolean verifyMail(final String sender, final String subject, final String mailAddress) throws Exception {
-        LOG.info("Waiting for notification to be sent...");
-        greenMail.waitForIncomingEmail(1);
-
-        boolean found = false;
-        Session session = Session.getDefaultInstance(System.getProperties());
-        session.setDebug(true);
-        Store store = session.getStore("pop3");
-        store.connect(POP3_HOST, POP3_PORT, mailAddress, mailAddress);
-
-        Folder inbox = store.getFolder("INBOX");
-        assertNotNull(inbox);
-        inbox.open(Folder.READ_WRITE);
-
-        Message[] messages = inbox.getMessages();
-        for (Message message : messages) {
-            if (sender.equals(message.getFrom()[0].toString()) && subject.equals(message.getSubject())) {
-                found = true;
-                message.setFlag(Flags.Flag.DELETED, true);
-            }
-        }
-
-        inbox.close(true);
-        store.close();
-        return found;
-    }
-
-    @Test
-    public void notifyByMail() throws Exception {
-        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
-        String subject = "Test notification " + getUUIDString();
-        String recipient = createNotificationTask(true, true, TraceLevel.ALL, sender, subject);
-        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getExecutions().isEmpty());
-
-        execNotificationTask(taskService, taskTO.getKey(), 50);
-
-        assertTrue(verifyMail(sender, subject, recipient));
-
-        // verify message body
-        taskTO = taskService.read(taskTO.getKey(), true);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.isExecuted());
-        assertNotNull(taskTO.getTextBody());
-        assertTrue("Notification mail text doesn't contain expected content.",
-                taskTO.getTextBody().contains("Your email address is " + recipient + "."));
-        assertTrue("Notification mail text doesn't contain expected content.",
-                taskTO.getTextBody().contains("Your email address inside a link: "
-                        + "http://localhost/?email=" + recipient.replaceAll("@", "%40") + " ."));
-    }
-
-    @Test
-    public void notifyByMailEmptyAbout() throws Exception {
-        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
-        String subject = "Test notification " + getUUIDString();
-        String recipient = createNotificationTask(true, false, TraceLevel.ALL, sender, subject);
-        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getExecutions().isEmpty());
-
-        execNotificationTask(taskService, taskTO.getKey(), 50);
-
-        assertTrue(verifyMail(sender, subject, recipient));
-    }
-
-    @Test
-    public void notifyByMailWithRetry() throws Exception {
-        // 1. Set higher number of retries
-        AttrTO origMaxRetries = configurationService.get("notification.maxRetries");
-
-        configurationService.set(attrTO(origMaxRetries.getSchema(), "10"));
-
-        // 2. Stop mail server to force errors while sending out e-mails
-        stopGreenMail();
-
-        try {
-            // 3. create notification and user
-            String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
-            String subject = "Test notification " + getUUIDString();
-            createNotificationTask(true, true, TraceLevel.ALL, sender, subject);
-            NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-            assertNotNull(taskTO);
-            assertTrue(taskTO.getExecutions().isEmpty());
-
-            // 4. verify notification could not be delivered
-            execTask(taskService, taskTO.getKey(), NotificationJob.Status.NOT_SENT.name(), 5, false);
-
-            taskTO = taskService.read(taskTO.getKey(), true);
-            assertNotNull(taskTO);
-            assertFalse(taskTO.isExecuted());
-            assertFalse(taskTO.getExecutions().isEmpty());
-            for (TaskExecTO exec : taskTO.getExecutions()) {
-                assertEquals(NotificationJob.Status.NOT_SENT.name(), exec.getStatus());
-            }
-        } finally {
-            // start mail server again
-            startGreenMail();
-            // reset number of retries
-            configurationService.set(origMaxRetries);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE81() {
-        String sender = "syncope81@syncope.apache.org";
-        createNotificationTask(true, true, TraceLevel.ALL, sender, "Test notification");
-        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getExecutions().isEmpty());
-
-        // generate an execution in order to verify the deletion of a notification task with one or more executions
-        execNotificationTask(taskService, taskTO.getKey(), 50);
-
-        taskTO = taskService.read(taskTO.getKey(), true);
-        assertTrue(taskTO.isExecuted());
-        assertFalse(taskTO.getExecutions().isEmpty());
-
-        taskService.delete(taskTO.getKey());
-    }
-
-    @Test
-    public void issueSYNCOPE86() {
-        // 1. create notification task
-        String sender = "syncope86@syncope.apache.org";
-        createNotificationTask(true, true, TraceLevel.ALL, sender, "Test notification");
-
-        // 2. get NotificationTaskTO for user just created
-        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getExecutions().isEmpty());
-
-        try {
-            // 3. execute the generated NotificationTask
-            execNotificationTask(taskService, taskTO.getKey(), 50);
-
-            // 4. verify
-            taskTO = taskService.read(taskTO.getKey(), true);
-            assertNotNull(taskTO);
-            assertTrue(taskTO.isExecuted());
-            assertEquals(1, taskTO.getExecutions().size());
-        } finally {
-            // Remove execution to make test re-runnable
-            taskService.deleteExecution(taskTO.getExecutions().get(0).getKey());
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE192() throws Exception {
-        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
-        String subject = "Test notification " + getUUIDString();
-        String recipient = createNotificationTask(true, true, TraceLevel.NONE, sender, subject);
-        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getExecutions().isEmpty());
-
-        taskService.execute(new ExecuteQuery.Builder().key(taskTO.getKey()).build());
-
-        try {
-            Thread.sleep(5);
-        } catch (InterruptedException e) {
-        }
-
-        assertTrue(verifyMail(sender, subject, recipient));
-
-        // verify that last exec status was updated
-        taskTO = taskService.read(taskTO.getKey(), true);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.isExecuted());
-        assertTrue(taskTO.getExecutions().isEmpty());
-        assertTrue(StringUtils.isNotBlank(taskTO.getLatestExecStatus()));
-    }
-
-    @Test
-    public void issueSYNCOPE445() throws Exception {
-        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
-        String subject = "Test notification " + getUUIDString();
-        String recipient = createNotificationTask(
-                true, true, TraceLevel.ALL, sender, subject, "syncope445@syncope.apache.org");
-        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getExecutions().isEmpty());
-
-        execNotificationTask(taskService, taskTO.getKey(), 50);
-
-        assertTrue(verifyMail(sender, subject, recipient));
-
-        // verify task
-        taskTO = taskService.read(taskTO.getKey(), true);
-        assertTrue(taskTO.isExecuted());
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getRecipients().contains("syncope445@syncope.apache.org"));
-    }
-
-    @Test
-    public void issueSYNCOPE446() throws Exception {
-        // 1. Create notification
-        NotificationTO notification = new NotificationTO();
-        notification.setTraceLevel(TraceLevel.ALL);
-        notification.getEvents().add("[REST]:[GroupLogic]:[]:[create]:[SUCCESS]");
-
-        String groupName = "group" + getUUIDString();
-        notification.getAbouts().put(AnyTypeKind.GROUP.name(),
-                SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo(groupName).query());
-
-        notification.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(8L).query());
-        notification.setSelfAsRecipient(false);
-        notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
-        notification.getStaticRecipients().add(MAIL_ADDRESS);
-        notification.setRecipientsProviderClassName(TestNotificationRecipientsProvider.class.getName());
-
-        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
-        notification.setSender(sender);
-        String subject = "Test notification " + getUUIDString();
-        notification.setSubject(subject);
-        notification.setTemplate("optin");
-        notification.setActive(true);
-
-        Response response = notificationService.create(notification);
-        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
-        assertNotNull(notification);
-        assertEquals(TestNotificationRecipientsProvider.class.getName(), notification.getRecipientsProviderClassName());
-
-        // 2. create group
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName(groupName);
-        groupTO.setRealm("/even/two");
-        groupTO = createGroup(groupTO).getAny();
-        assertNotNull(groupTO);
-
-        // 3. verify
-        NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
-        assertNotNull(taskTO);
-        assertTrue(taskTO.getRecipients().containsAll(
-                new TestNotificationRecipientsProvider().provideRecipients(null)));
-
-        execNotificationTask(taskService, taskTO.getKey(), 50);
-
-        assertTrue(verifyMail(sender, subject, MAIL_ADDRESS));
-    }
-
-    @Test
-    public void issueSYNCOPE492() throws Exception {
-        String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
-        String subject = "Test notification " + getUUIDString();
-        createNotificationTask(false, true, TraceLevel.NONE, sender, subject, "syncope445@syncope.apache.org");
-
-        // verify that no task was created for disabled notification
-        assertNull(findNotificationTaskBySender(sender));
-    }
-
-    private String createNotificationTask(final boolean active, final boolean includeAbout, final TraceLevel traceLevel,
-            final String sender, final String subject, final String... staticRecipients) {
-
-        // 1. Create notification
-        NotificationTO notification = new NotificationTO();
-        notification.setTraceLevel(traceLevel);
-        notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
-
-        if (includeAbout) {
-            notification.getAbouts().put(AnyTypeKind.USER.name(),
-                    SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
-        }
-
-        notification.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().inGroups(8L).query());
-        notification.setSelfAsRecipient(true);
-        notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
-        if (staticRecipients != null) {
-            CollectionUtils.addAll(notification.getStaticRecipients(), staticRecipients);
-        }
-
-        notification.setSender(sender);
-        notification.setSubject(subject);
-        notification.setTemplate("optin");
-        notification.setActive(active);
-
-        Response response = notificationService.create(notification);
-        notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
-        assertNotNull(notification);
-
-        // 2. create user
-        UserTO userTO = UserITCase.getUniqueSampleTO(MAIL_ADDRESS);
-        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        return userTO.getUsername();
-    }
-
-}