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:35 UTC

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

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();
+}