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/03/31 17:29:04 UTC

[10/10] syncope git commit: [SYNCOPE-156] Internal refactoring

[SYNCOPE-156] Internal refactoring


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

Branch: refs/heads/master
Commit: 3e8912c35062ebfc98037e36001408f80208f3d6
Parents: ef80e01
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Mar 31 17:04:20 2016 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Mar 31 17:28:38 2016 +0200

----------------------------------------------------------------------
 .../approvals/ApprovalDirectoryPanel.java       | 215 +++++++++++
 .../approvals/ApprovalSearchResultPanel.java    | 215 -----------
 .../client/console/commons/AnyDataProvider.java |   2 +-
 .../console/commons/DirectoryDataProvider.java  |  38 ++
 .../console/commons/RoleDataProvider.java       |   2 +-
 .../console/commons/SearchableDataProvider.java |  38 --
 .../console/commons/TaskDataProvider.java       |   2 +-
 .../status/AbstractStatusBeanProvider.java      |   4 +-
 .../syncope/client/console/pages/Approvals.java |   4 +-
 .../syncope/client/console/pages/Roles.java     |   4 +-
 .../panels/AbstractSearchResultPanel.java       | 367 -------------------
 .../console/panels/AbstractTypesPanel.java      |  38 --
 .../console/panels/AjaxDataTablePanel.java      |   2 +-
 .../console/panels/AnyDirectoryPanel.java       | 192 ++++++++++
 .../console/panels/AnyObjectDirectoryPanel.java | 241 ++++++++++++
 .../panels/AnyObjectSearchResultPanel.java      | 241 ------------
 .../syncope/client/console/panels/AnyPanel.java |  22 +-
 .../console/panels/AnySearchResultPanel.java    | 192 ----------
 .../console/panels/AnyTypeClassesPanel.java     |   6 +-
 .../client/console/panels/AnyTypesPanel.java    |   6 +-
 .../client/console/panels/DirectoryPanel.java   | 367 +++++++++++++++++++
 .../console/panels/GroupDirectoryPanel.java     | 232 ++++++++++++
 .../console/panels/GroupSearchResultPanel.java  | 232 ------------
 .../client/console/panels/ParametersPanel.java  |   6 +-
 .../console/panels/RelationshipTypesPanel.java  |   6 +-
 .../console/panels/RoleDirectoryPanel.java      | 177 +++++++++
 .../console/panels/RoleSearchResultPanel.java   | 178 ---------
 .../client/console/panels/SchemaTypePanel.java  |   6 +-
 .../console/panels/SecurityQuestionsPanel.java  |   6 +-
 .../console/panels/TypesDirectoryPanel.java     |  38 ++
 .../console/panels/UserDirectoryPanel.java      | 286 +++++++++++++++
 .../console/panels/UserSearchResultPanel.java   | 286 ---------------
 .../AnyObjectSelectionDirectoryPanel.java       |  79 ++++
 .../AnyObjectSelectionSearchResultPanel.java    |  79 ----
 .../search/AnySelectionDirectoryPanel.java      | 218 +++++++++++
 .../search/AnySelectionSearchResultPanel.java   | 218 -----------
 .../search/GroupSelectionDirectoryPanel.java    |  79 ++++
 .../search/GroupSelectionSearchResultPanel.java |  79 ----
 .../search/UserSelectionDirectoryPanel.java     |  79 ++++
 .../search/UserSelectionSearchResultPanel.java  |  79 ----
 .../console/status/StatusDirectoryPanel.java    | 277 ++++++++++++++
 .../client/console/status/StatusModal.java      |   2 +-
 .../console/status/StatusSearchResultPanel.java | 277 --------------
 .../tasks/PropagationTaskDirectoryPanel.java    | 225 ++++++++++++
 .../tasks/PropagationTaskSearchResultPanel.java | 225 ------------
 .../client/console/tasks/PropagationTasks.java  |   2 +-
 .../tasks/ProvisioningTaskDirectoryPanel.java   | 128 +++++++
 .../ProvisioningTaskSearchResultPanel.java      | 128 -------
 .../console/tasks/PullTaskDirectoryPanel.java   |  49 +++
 .../tasks/PullTaskSearchResultPanel.java        |  49 ---
 .../syncope/client/console/tasks/PullTasks.java |   2 +-
 .../console/tasks/PushTaskDirectoryPanel.java   |  52 +++
 .../tasks/PushTaskSearchResultPanel.java        |  52 ---
 .../syncope/client/console/tasks/PushTasks.java |   2 +-
 .../console/tasks/SchedTaskDirectoryPanel.java  | 315 ++++++++++++++++
 .../tasks/SchedTaskSearchResultPanel.java       | 315 ----------------
 .../client/console/tasks/SchedTasks.java        |   2 +-
 .../console/tasks/TaskDirectoryPanel.java       | 116 ++++++
 .../client/console/tasks/TaskExecutions.java    |   8 +-
 .../console/tasks/TaskSearchResultPanel.java    | 116 ------
 .../client/console/widgets/JobWidget.java       |  12 +-
 .../ReconciliationDetailsModalPanel.java        |   8 +-
 .../console/widgets/ReconciliationWidget.java   |   8 +-
 .../client/console/wizards/any/Ownership.java   |  38 +-
 .../console/wizards/any/Relationships.java      |  20 +-
 .../panels/AbstractConnectorConfPanel.html      |  29 +-
 .../panels/AbstractSearchResultPanel.html       |  48 ---
 .../panels/AbstractSearchResultPanel.properties |  37 --
 .../AbstractSearchResultPanel_it.properties     |  37 --
 .../AbstractSearchResultPanel_pt_BR.properties  |  37 --
 .../panels/AbstractTypesPanel.properties        |  19 -
 .../panels/AbstractTypesPanel_it.properties     |  19 -
 .../panels/AbstractTypesPanel_pt_BR.properties  |  19 -
 .../client/console/panels/DirectoryPanel.html   |  43 +++
 .../console/panels/DirectoryPanel.properties    |  37 ++
 .../console/panels/DirectoryPanel_it.properties |  37 ++
 .../panels/DirectoryPanel_pt_BR.properties      |  37 ++
 .../panels/RoleDirectoryPanel.properties        |  18 +
 .../panels/RoleDirectoryPanel_it.properties     |  18 +
 .../panels/RoleDirectoryPanel_pt_BR.properties  |  18 +
 .../panels/RoleSearchResultPanel.properties     |  18 -
 .../panels/RoleSearchResultPanel_it.properties  |  18 -
 .../RoleSearchResultPanel_pt_BR.properties      |  18 -
 .../panels/TypesDirectoryPanel.properties       |  19 +
 .../panels/TypesDirectoryPanel_it.properties    |  19 +
 .../panels/TypesDirectoryPanel_pt_BR.properties |  19 +
 .../PropagationTaskDirectoryPanel.properties    |  22 ++
 .../PropagationTaskDirectoryPanel_it.properties |  22 ++
 ...opagationTaskDirectoryPanel_pt_BR.properties |  22 ++
 .../PropagationTaskSearchResultPanel.properties |  22 --
 ...opagationTaskSearchResultPanel_it.properties |  22 --
 ...gationTaskSearchResultPanel_pt_BR.properties |  22 --
 .../console/tasks/SchedTaskDirectoryPanel.html  |  23 ++
 .../tasks/SchedTaskDirectoryPanel.properties    |  28 ++
 .../tasks/SchedTaskDirectoryPanel_it.properties |  28 ++
 .../SchedTaskDirectoryPanel_pt_BR.properties    |  28 ++
 .../tasks/SchedTaskSearchResultPanel.html       |  23 --
 .../tasks/SchedTaskSearchResultPanel.properties |  28 --
 .../SchedTaskSearchResultPanel_it.properties    |  28 --
 .../SchedTaskSearchResultPanel_pt_BR.properties |  28 --
 .../console/tasks/TaskDirectoryPanel.properties |  24 ++
 .../tasks/TaskDirectoryPanel_it.properties      |  24 ++
 .../tasks/TaskDirectoryPanel_pt_BR.properties   |  24 ++
 .../tasks/TaskSearchResultPanel.properties      |  24 --
 .../tasks/TaskSearchResultPanel_it.properties   |  24 --
 .../TaskSearchResultPanel_pt_BR.properties      |  24 --
 .../client/console/pages/CamelRoutes.java       |  11 +-
 .../panels/CamelRoutesDirectoryPanel.java       | 225 ++++++++++++
 .../client/console/panels/CamelRoutesPanel.java | 225 ------------
 .../panels/CamelRoutesDirectoryPanel.properties |  20 +
 .../CamelRoutesDirectoryPanel_it.properties     |  20 +
 .../CamelRoutesDirectoryPanel_pt_BR.properties  |  20 +
 .../console/panels/CamelRoutesPanel.properties  |  20 -
 .../panels/CamelRoutesPanel_it.properties       |  20 -
 .../panels/CamelRoutesPanel_pt_BR.properties    |  20 -
 115 files changed, 4308 insertions(+), 4316 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
new file mode 100644
index 0000000..bfe72e0
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
@@ -0,0 +1,215 @@
+/*
+ * 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.client.console.approvals;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.DirectoryDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.DirectoryPanel;
+import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
+import org.apache.syncope.client.console.approvals.ApprovalDirectoryPanel.ApprovalProvider;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class ApprovalDirectoryPanel
+        extends DirectoryPanel<WorkflowFormTO, WorkflowFormTO, ApprovalProvider, UserWorkflowRestClient> {
+
+    private static final long serialVersionUID = -7122136682275797903L;
+
+    public ApprovalDirectoryPanel(final String id, final PageReference pageReference) {
+        super(id, pageReference, false);
+        disableCheckBoxes();
+
+        setFooterVisibility(true);
+        modal.addSumbitButton();
+        modal.size(Modal.Size.Large);
+
+        restClient = new UserWorkflowRestClient();
+
+        initResultTable();
+
+        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.WORKFLOW_FORM_SUBMIT);
+    }
+
+    @Override
+    protected List<IColumn<WorkflowFormTO, String>> getColumns() {
+
+        List<IColumn<WorkflowFormTO, String>> columns = new ArrayList<>();
+        columns.add(new PropertyColumn<WorkflowFormTO, String>(
+                new ResourceModel("taskId"), "taskId", "taskId"));
+        columns.add(new PropertyColumn<WorkflowFormTO, String>(
+                new ResourceModel("key"), "key", "key"));
+        columns.add(new PropertyColumn<WorkflowFormTO, String>(
+                new ResourceModel("description"), "description", "description"));
+        columns.add(new DatePropertyColumn<WorkflowFormTO>(
+                new ResourceModel("createTime"), "createTime", "createTime"));
+        columns.add(new DatePropertyColumn<WorkflowFormTO>(
+                new ResourceModel("dueDate"), "dueDate", "dueDate"));
+        columns.add(new PropertyColumn<WorkflowFormTO, String>(new ResourceModel("owner"), "owner", "owner"));
+        columns.add(new ActionColumn<WorkflowFormTO, String>(new ResourceModel("actions")) {
+
+            private static final long serialVersionUID = -3503023501954863133L;
+
+            @Override
+            public ActionLinksPanel<WorkflowFormTO> getActions(
+                    final String componentId, final IModel<WorkflowFormTO> model) {
+                final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
+
+                panel.add(new ActionLink<WorkflowFormTO>() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
+                        try {
+                            restClient.claimForm(model.getObject().getTaskId());
+                            info(getString(Constants.OPERATION_SUCCEEDED));
+                        } catch (SyncopeClientException scee) {
+                            error(getString(Constants.ERROR) + ": " + scee.getMessage());
+                        }
+                        SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+                        target.add(container);
+                    }
+                }, ActionLink.ActionType.CLAIM, StandardEntitlement.WORKFLOW_FORM_CLAIM);
+
+                panel.add(new ActionLink<WorkflowFormTO>() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
+                        final IModel<WorkflowFormTO> formModel = new CompoundPropertyModel<>(model.getObject());
+                        modal.setFormModel(formModel);
+
+                        target.add(modal.setContent(new ApprovalModal(modal, pageRef, model.getObject())));
+                        modal.header(new Model<>(getString("approval.edit", new Model<>(model.getObject()))));
+
+                        modal.show(true);
+                    }
+
+                    @Override
+                    protected boolean statusCondition(final WorkflowFormTO modelObject) {
+                        return SyncopeConsoleSession.get().getSelfTO().getUsername().
+                                equals(model.getObject().getOwner());
+                    }
+
+                }, ActionLink.ActionType.EDIT, StandardEntitlement.WORKFLOW_FORM_READ);
+
+                return panel.build(componentId);
+            }
+
+            @Override
+            public ActionLinksPanel<WorkflowFormTO> getHeader(final String componentId) {
+                final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
+
+                return panel.add(new ActionLink<WorkflowFormTO>() {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
+                        if (target != null) {
+                            target.add(container);
+                        }
+                    }
+                }, ActionLink.ActionType.RELOAD, StandardEntitlement.WORKFLOW_FORM_LIST).build(componentId);
+            }
+        });
+
+        return columns;
+    }
+
+    @Override
+    protected ApprovalProvider dataProvider() {
+        return new ApprovalProvider(rows);
+    }
+
+    @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_WORKFLOW_FORM_PAGINATOR_ROWS;
+    }
+
+    public static class ApprovalProvider extends DirectoryDataProvider<WorkflowFormTO> {
+
+        private static final long serialVersionUID = -2311716167583335852L;
+
+        private final SortableDataProviderComparator<WorkflowFormTO> comparator;
+
+        private final UserWorkflowRestClient restClient = new UserWorkflowRestClient();
+
+        public ApprovalProvider(final int paginatorRows) {
+            super(paginatorRows);
+            setSort("createTime", SortOrder.DESCENDING);
+            this.comparator = new SortableDataProviderComparator<>(this);
+        }
+
+        @Override
+        public Iterator<WorkflowFormTO> iterator(final long first, final long count) {
+            final List<WorkflowFormTO> list = restClient.getForms();
+            Collections.sort(list, comparator);
+            return list.subList((int) first, (int) first + (int) count).iterator();
+        }
+
+        @Override
+        public long size() {
+            return restClient.getForms().size();
+        }
+
+        @Override
+        public IModel<WorkflowFormTO> model(final WorkflowFormTO configuration) {
+            return new AbstractReadOnlyModel<WorkflowFormTO>() {
+
+                private static final long serialVersionUID = -2566070996511906708L;
+
+                @Override
+                public WorkflowFormTO getObject() {
+                    return configuration;
+                }
+            };
+        }
+    }
+
+    @Override
+    protected Collection<ActionLink.ActionType> getBulkActions() {
+        return Collections.<ActionLink.ActionType>emptyList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java
deleted file mode 100644
index 2d97bf0..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java
+++ /dev/null
@@ -1,215 +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.client.console.approvals;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.SearchableDataProvider;
-import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
-import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
-import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
-import org.apache.syncope.client.console.approvals.ApprovalSearchResultPanel.ApprovalProvider;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.model.AbstractReadOnlyModel;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.ResourceModel;
-
-public class ApprovalSearchResultPanel
-        extends AbstractSearchResultPanel<WorkflowFormTO, WorkflowFormTO, ApprovalProvider, UserWorkflowRestClient> {
-
-    private static final long serialVersionUID = -7122136682275797903L;
-
-    public ApprovalSearchResultPanel(final String id, final PageReference pageReference) {
-        super(id, pageReference, false);
-        disableCheckBoxes();
-
-        setFooterVisibility(true);
-        modal.addSumbitButton();
-        modal.size(Modal.Size.Large);
-
-        restClient = new UserWorkflowRestClient();
-
-        initResultTable();
-
-        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.WORKFLOW_FORM_SUBMIT);
-    }
-
-    @Override
-    protected List<IColumn<WorkflowFormTO, String>> getColumns() {
-
-        List<IColumn<WorkflowFormTO, String>> columns = new ArrayList<>();
-        columns.add(new PropertyColumn<WorkflowFormTO, String>(
-                new ResourceModel("taskId"), "taskId", "taskId"));
-        columns.add(new PropertyColumn<WorkflowFormTO, String>(
-                new ResourceModel("key"), "key", "key"));
-        columns.add(new PropertyColumn<WorkflowFormTO, String>(
-                new ResourceModel("description"), "description", "description"));
-        columns.add(new DatePropertyColumn<WorkflowFormTO>(
-                new ResourceModel("createTime"), "createTime", "createTime"));
-        columns.add(new DatePropertyColumn<WorkflowFormTO>(
-                new ResourceModel("dueDate"), "dueDate", "dueDate"));
-        columns.add(new PropertyColumn<WorkflowFormTO, String>(new ResourceModel("owner"), "owner", "owner"));
-        columns.add(new ActionColumn<WorkflowFormTO, String>(new ResourceModel("actions")) {
-
-            private static final long serialVersionUID = -3503023501954863133L;
-
-            @Override
-            public ActionLinksPanel<WorkflowFormTO> getActions(
-                    final String componentId, final IModel<WorkflowFormTO> model) {
-                final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
-
-                panel.add(new ActionLink<WorkflowFormTO>() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
-                        try {
-                            restClient.claimForm(model.getObject().getTaskId());
-                            info(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (SyncopeClientException scee) {
-                            error(getString(Constants.ERROR) + ": " + scee.getMessage());
-                        }
-                        SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
-                        target.add(container);
-                    }
-                }, ActionLink.ActionType.CLAIM, StandardEntitlement.WORKFLOW_FORM_CLAIM);
-
-                panel.add(new ActionLink<WorkflowFormTO>() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
-                        final IModel<WorkflowFormTO> formModel = new CompoundPropertyModel<>(model.getObject());
-                        modal.setFormModel(formModel);
-
-                        target.add(modal.setContent(new ApprovalModal(modal, pageRef, model.getObject())));
-                        modal.header(new Model<>(getString("approval.edit", new Model<>(model.getObject()))));
-
-                        modal.show(true);
-                    }
-
-                    @Override
-                    protected boolean statusCondition(final WorkflowFormTO modelObject) {
-                        return SyncopeConsoleSession.get().getSelfTO().getUsername().
-                                equals(model.getObject().getOwner());
-                    }
-
-                }, ActionLink.ActionType.EDIT, StandardEntitlement.WORKFLOW_FORM_READ);
-
-                return panel.build(componentId);
-            }
-
-            @Override
-            public ActionLinksPanel<WorkflowFormTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
-
-                return panel.add(new ActionLink<WorkflowFormTO>() {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
-                        if (target != null) {
-                            target.add(container);
-                        }
-                    }
-                }, ActionLink.ActionType.RELOAD, StandardEntitlement.WORKFLOW_FORM_LIST).build(componentId);
-            }
-        });
-
-        return columns;
-    }
-
-    @Override
-    protected ApprovalProvider dataProvider() {
-        return new ApprovalProvider(rows);
-    }
-
-    @Override
-    protected String paginatorRowsKey() {
-        return Constants.PREF_WORKFLOW_FORM_PAGINATOR_ROWS;
-    }
-
-    public static class ApprovalProvider extends SearchableDataProvider<WorkflowFormTO> {
-
-        private static final long serialVersionUID = -2311716167583335852L;
-
-        private final SortableDataProviderComparator<WorkflowFormTO> comparator;
-
-        private final UserWorkflowRestClient restClient = new UserWorkflowRestClient();
-
-        public ApprovalProvider(final int paginatorRows) {
-            super(paginatorRows);
-            setSort("createTime", SortOrder.DESCENDING);
-            this.comparator = new SortableDataProviderComparator<>(this);
-        }
-
-        @Override
-        public Iterator<WorkflowFormTO> iterator(final long first, final long count) {
-            final List<WorkflowFormTO> list = restClient.getForms();
-            Collections.sort(list, comparator);
-            return list.subList((int) first, (int) first + (int) count).iterator();
-        }
-
-        @Override
-        public long size() {
-            return restClient.getForms().size();
-        }
-
-        @Override
-        public IModel<WorkflowFormTO> model(final WorkflowFormTO configuration) {
-            return new AbstractReadOnlyModel<WorkflowFormTO>() {
-
-                private static final long serialVersionUID = -2566070996511906708L;
-
-                @Override
-                public WorkflowFormTO getObject() {
-                    return configuration;
-                }
-            };
-        }
-    }
-
-    @Override
-    protected Collection<ActionLink.ActionType> getBulkActions() {
-        return Collections.<ActionLink.ActionType>emptyList();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
index 05d18e3..65298b2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
@@ -27,7 +27,7 @@ import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 
-public class AnyDataProvider<T extends AnyTO> extends SearchableDataProvider<T> {
+public class AnyDataProvider<T extends AnyTO> extends DirectoryDataProvider<T> {
 
     private static final long serialVersionUID = 6267494272884913376L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/commons/DirectoryDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/DirectoryDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/DirectoryDataProvider.java
new file mode 100644
index 0000000..d7bb122
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/DirectoryDataProvider.java
@@ -0,0 +1,38 @@
+/*
+ * 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.client.console.commons;
+
+import java.io.Serializable;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+
+public abstract class DirectoryDataProvider<T extends Serializable> extends SortableDataProvider<T, String> {
+
+    private static final long serialVersionUID = 6267494272884913376L;
+
+    protected final int paginatorRows;
+
+    public DirectoryDataProvider(final int paginatorRows) {
+        super();
+        this.paginatorRows = paginatorRows;
+
+        // default sorting
+        setSort("key", SortOrder.ASCENDING);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/commons/RoleDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/RoleDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/RoleDataProvider.java
index 5d85ec5..2285b08 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/RoleDataProvider.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/RoleDataProvider.java
@@ -26,7 +26,7 @@ import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 
-public class RoleDataProvider extends SearchableDataProvider<RoleTO> {
+public class RoleDataProvider extends DirectoryDataProvider<RoleTO> {
 
     private static final long serialVersionUID = 6267494272884913376L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/commons/SearchableDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/SearchableDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/SearchableDataProvider.java
deleted file mode 100644
index 37701a7..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/SearchableDataProvider.java
+++ /dev/null
@@ -1,38 +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.client.console.commons;
-
-import java.io.Serializable;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
-
-public abstract class SearchableDataProvider<T extends Serializable> extends SortableDataProvider<T, String> {
-
-    private static final long serialVersionUID = 6267494272884913376L;
-
-    protected final int paginatorRows;
-
-    public SearchableDataProvider(final int paginatorRows) {
-        super();
-        this.paginatorRows = paginatorRows;
-
-        // default sorting
-        setSort("key", SortOrder.ASCENDING);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/commons/TaskDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/TaskDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/TaskDataProvider.java
index 163b079..f56805a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/TaskDataProvider.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/TaskDataProvider.java
@@ -25,7 +25,7 @@ import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 
-public abstract class TaskDataProvider<T extends AbstractTaskTO> extends SearchableDataProvider<T> {
+public abstract class TaskDataProvider<T extends AbstractTaskTO> extends DirectoryDataProvider<T> {
 
     private static final long serialVersionUID = -20112718133295756L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/commons/status/AbstractStatusBeanProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/AbstractStatusBeanProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/AbstractStatusBeanProvider.java
index 22e948b..48227e0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/AbstractStatusBeanProvider.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/AbstractStatusBeanProvider.java
@@ -21,13 +21,13 @@ package org.apache.syncope.client.console.commons.status;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.syncope.client.console.commons.SearchableDataProvider;
+import org.apache.syncope.client.console.commons.DirectoryDataProvider;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.model.AbstractReadOnlyModel;
 import org.apache.wicket.model.IModel;
 
-public abstract class AbstractStatusBeanProvider extends SearchableDataProvider<StatusBean> {
+public abstract class AbstractStatusBeanProvider extends DirectoryDataProvider<StatusBean> {
 
     private static final long serialVersionUID = 4287357360778016173L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
index a93d7c3..0dbc4db 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.client.console.pages;
 
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
-import org.apache.syncope.client.console.approvals.ApprovalSearchResultPanel;
+import org.apache.syncope.client.console.approvals.ApprovalDirectoryPanel;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
@@ -36,6 +36,6 @@ public class Approvals extends BasePage {
         content.setOutputMarkupId(true);
         body.add(content);
 
-        content.add(new ApprovalSearchResultPanel("wfPanel", getPageReference()));
+        content.add(new ApprovalDirectoryPanel("wfPanel", getPageReference()));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
index dd993de..c760b6b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.client.console.pages;
 
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
-import org.apache.syncope.client.console.panels.RoleSearchResultPanel;
+import org.apache.syncope.client.console.panels.RoleDirectoryPanel;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.role.RoleHandler;
@@ -42,7 +42,7 @@ public class Roles extends BasePage {
         body.add(content);
 
         WizardMgtPanel<RoleHandler> rolesPanel =
-                new RoleSearchResultPanel.Builder(getPageReference()) {
+                new RoleDirectoryPanel.Builder(getPageReference()) {
 
             private static final long serialVersionUID = -5960765294082359003L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
deleted file mode 100644
index 66de748..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
+++ /dev/null
@@ -1,367 +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.client.console.panels;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.List;
-import org.apache.syncope.client.console.PreferenceManager;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.SearchableDataProvider;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.rest.BaseRestClient;
-import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wizards.WizardMgtPanel;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.event.Broadcast;
-import org.apache.wicket.event.IEvent;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.DropDownChoice;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.model.PropertyModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractSearchResultPanel<
-        T extends Serializable, W extends Serializable, DP extends SearchableDataProvider<T>, E extends BaseRestClient>
-        extends WizardMgtPanel<W> {
-
-    private static final long serialVersionUID = -9170191461250434024L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractSearchResultPanel.class);
-
-    /**
-     * Application preferences.
-     */
-    protected PreferenceManager prefMan = new PreferenceManager();
-
-    protected E restClient;
-
-    /**
-     * Number of rows per page.
-     */
-    protected int rows;
-
-    /**
-     * Container used to refresh table.
-     */
-    protected final WebMarkupContainer container;
-
-    /**
-     * Specify if results are about a filtered search or not. Using this attribute it is possible to use this panel to
-     * show results about user list and user search.
-     */
-    protected final boolean filtered;
-
-    private boolean checkBoxEnabled;
-
-    private boolean showPaginator;
-
-    /**
-     * Result table.
-     */
-    private AjaxDataTablePanel<T, String> resultTable;
-
-    /**
-     * Data provider used to search for users.
-     */
-    protected DP dataProvider;
-
-    /**
-     * Owner page.
-     */
-    protected final BasePage page;
-
-    protected String itemKeyFieldName = "key";
-
-    /**
-     * Create simple unfiltered search result panel.
-     * Use the available builder for powerfull configuration options.
-     *
-     * @param id panel id.
-     * @param pageRef page reference.
-     */
-    public AbstractSearchResultPanel(final String id, final PageReference pageRef) {
-        this(id, pageRef, true);
-    }
-
-    public AbstractSearchResultPanel(final String id, final PageReference pageRef, final boolean wizardInModal) {
-        this(id, new Builder<T, W, E>(null, pageRef) {
-
-            private static final long serialVersionUID = -8424727765826509309L;
-
-            @Override
-            protected WizardMgtPanel<W> newInstance(final String id) {
-                throw new UnsupportedOperationException("Not supported yet.");
-            }
-        }.setFiltered(false), wizardInModal);
-        setPageRef(pageRef);
-    }
-
-    protected AbstractSearchResultPanel(final String id, final Builder<T, W, E> builder) {
-        this(id, builder, true);
-    }
-
-    protected AbstractSearchResultPanel(final String id, final Builder<T, W, E> builder, final boolean wizardInModal) {
-        super(id, wizardInModal);
-        setOutputMarkupId(true);
-
-        this.page = (BasePage) builder.getPageRef().getPage();
-
-        this.filtered = builder.filtered;
-        this.checkBoxEnabled = builder.checkBoxEnabled;
-        this.showPaginator = builder.showPaginator;
-
-        this.restClient = builder.restClient;
-
-        // Container for user search result
-        container = new WebMarkupContainer("searchContainer");
-        container.setOutputMarkupId(true);
-        addInnerObject(container);
-
-        rows = prefMan.getPaginatorRows(getRequest(), paginatorRowsKey());
-
-        setWindowClosedReloadCallback(modal);
-        setWindowClosedReloadCallback(altDefaultModal);
-        setWindowClosedReloadCallback(displayAttributeModal);
-
-        altDefaultModal.size(Modal.Size.Medium);
-        displayAttributeModal.size(Modal.Size.Medium);
-    }
-
-    protected abstract DP dataProvider();
-
-    protected abstract String paginatorRowsKey();
-
-    protected abstract List<IColumn<T, String>> getColumns();
-
-    protected void initResultTable() {
-        // ---------------------------
-        // Result table initialization
-        // ---------------------------
-        updateResultTable(false);
-        // ---------------------------
-
-        // ---------------------------
-        // Rows-per-page selector
-        // ---------------------------
-        final Form<?> paginatorForm = new Form<>("paginator");
-        paginatorForm.setOutputMarkupPlaceholderTag(true);
-        paginatorForm.setVisible(showPaginator);
-        container.add(paginatorForm);
-
-        final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
-                "rowsChooser", new PropertyModel<Integer>(this, "rows"), prefMan.getPaginatorChoices());
-
-        rowsChooser.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                prefMan.set(getRequest(), getResponse(), paginatorRowsKey(), String.valueOf(rows));
-
-                final EventDataWrapper data = new EventDataWrapper();
-                data.setTarget(target);
-                data.setRows(rows);
-
-                send(getParent(), Broadcast.BREADTH, data);
-            }
-        });
-        paginatorForm.add(rowsChooser);
-        // ---------------------------
-    }
-
-    public void search(final AjaxRequestTarget target) {
-        target.add(container);
-    }
-
-    private void updateResultTable(final boolean create) {
-        updateResultTable(create, rows);
-    }
-
-    private void updateResultTable(final boolean create, final int rows) {
-        dataProvider = dataProvider();
-
-        final int currentPage = resultTable != null
-                ? (create ? (int) resultTable.getPageCount() - 1 : (int) resultTable.getCurrentPage()) : 0;
-
-        // take care of restClient handle: maybe not useful to keep into
-        AjaxDataTablePanel.Builder<T, String> resultTableBuilder = new AjaxDataTablePanel.Builder<>(
-                dataProvider, page.getPageReference()).
-                setColumns(getColumns()).
-                setRowsPerPage(rows).
-                setBulkActions(getBulkActions(), restClient, itemKeyFieldName).
-                setContainer(container);
-
-        if (!checkBoxEnabled) {
-            resultTableBuilder.disableCheckBoxes();
-        }
-
-        resultTableCustomChanges(resultTableBuilder);
-        resultTable = resultTableBuilder.build("resultTable");
-
-        resultTable.setCurrentPage(currentPage);
-        resultTable.setOutputMarkupId(true);
-        container.addOrReplace(resultTable);
-    }
-
-    /**
-     * Caled before build. Override it to customize result table.
-     *
-     * @param resultTableBuilder result table builder.
-     */
-    protected void resultTableCustomChanges(final AjaxDataTablePanel.Builder<T, String> resultTableBuilder) {
-
-    }
-
-    public AbstractSearchResultPanel<T, W, DP, E> disableCheckBoxes() {
-        this.checkBoxEnabled = false;
-        return this;
-    }
-
-    @Override
-    public void onEvent(final IEvent<?> event) {
-        if (event.getPayload() instanceof EventDataWrapper) {
-            final EventDataWrapper data = (EventDataWrapper) event.getPayload();
-
-            if (data.getRows() < 1) {
-                updateResultTable(data.isCreate());
-            } else {
-                updateResultTable(data.isCreate(), data.getRows());
-            }
-
-            if (AbstractSearchResultPanel.this.container.isVisibleInHierarchy()) {
-                data.getTarget().add(AbstractSearchResultPanel.this.container);
-            }
-        }
-        super.onEvent(event);
-    }
-
-    protected void setWindowClosedReloadCallback(final BaseModal<?> modal) {
-        modal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
-
-            private static final long serialVersionUID = 8804221891699487139L;
-
-            @Override
-            public void onClose(final AjaxRequestTarget target) {
-                modal.show(false);
-
-                final EventDataWrapper data = new EventDataWrapper();
-                data.setTarget(target);
-                data.setRows(rows);
-
-                send(getParent(), Broadcast.BREADTH, data);
-            }
-        });
-    }
-
-    public static class EventDataWrapper {
-
-        private AjaxRequestTarget target;
-
-        private boolean create;
-
-        private int rows;
-
-        public AjaxRequestTarget getTarget() {
-            return target;
-        }
-
-        public void setTarget(final AjaxRequestTarget target) {
-            this.target = target;
-        }
-
-        public boolean isCreate() {
-            return create;
-        }
-
-        public void setCreate(final boolean create) {
-            this.create = create;
-        }
-
-        public int getRows() {
-            return rows;
-        }
-
-        public void setRows(final int rows) {
-            this.rows = rows;
-        }
-    }
-
-    protected abstract Collection<ActionLink.ActionType> getBulkActions();
-
-    public abstract static class Builder<T extends Serializable, W extends Serializable, E extends BaseRestClient>
-            extends WizardMgtPanel.Builder<W> {
-
-        private static final long serialVersionUID = 5088962796986706805L;
-
-        /**
-         * Specify if results are about a filtered search or not.
-         * By using this attribute it is possible to force this panel to show results about user list and user search.
-         */
-        protected boolean filtered = false;
-
-        protected boolean checkBoxEnabled = true;
-
-        protected boolean showPaginator = true;
-
-        /**
-         * Filter used in case of filtered search.
-         */
-        protected String fiql;
-
-        protected final E restClient;
-
-        protected Builder(final E restClient, final PageReference pageRef) {
-            super(pageRef);
-            this.restClient = restClient;
-        }
-
-        public Builder<T, W, E> setFiltered(final boolean filtered) {
-            this.filtered = filtered;
-            return this;
-        }
-
-        public Builder<T, W, E> disableCheckBoxes() {
-            this.checkBoxEnabled = false;
-            return this;
-        }
-
-        public Builder<T, W, E> hidePaginator() {
-            this.showPaginator = false;
-            return this;
-        }
-
-        public Builder<T, W, E> setFiql(final String fiql) {
-            this.fiql = fiql;
-            return this;
-        }
-
-        private PageReference getPageRef() {
-            return this.pageRef;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTypesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTypesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTypesPanel.java
deleted file mode 100644
index 9d6ff26..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTypesPanel.java
+++ /dev/null
@@ -1,38 +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.client.console.panels;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import org.apache.syncope.client.console.commons.SearchableDataProvider;
-import org.apache.syncope.client.console.rest.BaseRestClient;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.wicket.PageReference;
-
-public abstract class AbstractTypesPanel<T extends AbstractBaseBean, DP extends SearchableDataProvider<T>>
-        extends AbstractSearchResultPanel<T, T, DP, BaseRestClient> {
-
-    private static final long serialVersionUID = 7890071604330629259L;
-
-    public AbstractTypesPanel(final String id, final PageReference pageRef) {
-        super(id, pageRef);
-        setFooterVisibility(true);
-        modal.addSumbitButton();
-        modal.size(Modal.Size.Large);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
index 9662753..5ed0c7e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -29,7 +29,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.syncope.client.console.bulk.BulkActionModal;
 import org.apache.syncope.client.console.bulk.BulkContent;
-import org.apache.syncope.client.console.panels.AbstractSearchResultPanel.EventDataWrapper;
+import org.apache.syncope.client.console.panels.DirectoryPanel.EventDataWrapper;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
 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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
new file mode 100644
index 0000000..e8c1306
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -0,0 +1,192 @@
+/*
+ * 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.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.commons.AnyDataProvider;
+import org.apache.syncope.client.console.commons.SerializableTransformer;
+import org.apache.syncope.client.console.commons.status.ConnObjectWrapper;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wizards.any.AnyHandler;
+import org.apache.syncope.client.console.wizards.any.StatusPanel;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.util.ListModel;
+
+public abstract class AnyDirectoryPanel<T extends AnyTO>
+        extends DirectoryPanel<T, AnyHandler<T>, AnyDataProvider<T>, AbstractAnyRestClient<T>> {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected final SchemaRestClient schemaRestClient = new SchemaRestClient();
+
+    protected final List<String> pSchemaNames;
+
+    protected final List<String> dSchemaNames;
+
+    /**
+     * Filter used in case of filtered search.
+     */
+    protected String fiql;
+
+    /**
+     * Realm related to current panel.
+     */
+    protected final String realm;
+
+    /**
+     * Any type related to current panel.
+     */
+    protected final String type;
+
+    protected AnyDirectoryPanel(final String id, final Builder<T> builder) {
+        super(id, builder);
+        this.realm = builder.realm;
+        this.type = builder.type;
+        this.fiql = builder.fiql;
+
+        modal.size(Modal.Size.Large);
+        altDefaultModal.size(Modal.Size.Large);
+
+        this.pSchemaNames = new ArrayList<>();
+        for (AnyTypeClassTO anyTypeClassTO : AnyDirectoryPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) {
+            this.pSchemaNames.addAll(anyTypeClassTO.getPlainSchemas());
+        }
+        this.dSchemaNames = new ArrayList<>();
+        for (AnyTypeClassTO anyTypeClassTO : AnyDirectoryPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) {
+            this.dSchemaNames.addAll(anyTypeClassTO.getDerSchemas());
+        }
+
+        initResultTable();
+    }
+
+    @Override
+    protected AnyDataProvider<T> dataProvider() {
+        final AnyDataProvider<T> dp = new AnyDataProvider<>(restClient, rows, filtered, realm, type);
+        return dp.setFIQL(this.fiql);
+    }
+
+    public void search(final String fiql, final AjaxRequestTarget target) {
+        this.fiql = fiql;
+        dataProvider.setFIQL(fiql);
+        super.search(target);
+    }
+
+    @Override
+    protected Collection<ActionLink.ActionType> getBulkActions() {
+        final List<ActionLink.ActionType> bulkActions = new ArrayList<>();
+
+        bulkActions.add(ActionLink.ActionType.DELETE);
+        bulkActions.add(ActionLink.ActionType.SUSPEND);
+        bulkActions.add(ActionLink.ActionType.REACTIVATE);
+
+        return bulkActions;
+    }
+
+    public interface AnyDirectoryPanelBuilder extends Serializable {
+
+        List<AnyTypeClassTO> getAnyTypeClassTOs();
+    }
+
+    public abstract static class Builder<T extends AnyTO>
+            extends DirectoryPanel.Builder<T, AnyHandler<T>, AbstractAnyRestClient<T>>
+            implements AnyDirectoryPanelBuilder {
+
+        private static final long serialVersionUID = -6828423611982275640L;
+
+        /**
+         * Realm related to current panel.
+         */
+        protected String realm = "/";
+
+        /**
+         * Any type related to current panel.
+         */
+        protected final String type;
+
+        private final List<AnyTypeClassTO> anyTypeClassTOs;
+
+        public Builder(
+                final List<AnyTypeClassTO> anyTypeClassTOs,
+                final AbstractAnyRestClient<T> restClient,
+                final String type,
+                final PageReference pageRef) {
+
+            super(restClient, pageRef);
+            this.anyTypeClassTOs = anyTypeClassTOs;
+            this.type = type;
+        }
+
+        public Builder<T> setRealm(final String realm) {
+            this.realm = realm;
+            return this;
+        }
+
+        @Override
+        public List<AnyTypeClassTO> getAnyTypeClassTOs() {
+            return this.anyTypeClassTOs;
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected Panel customResultBody(final String panelId, final AnyHandler<T> item, final Serializable result) {
+        if (!(result instanceof ProvisioningResult)) {
+            throw new IllegalStateException("Unsupported result type");
+        }
+
+        return new StatusPanel(
+                panelId,
+                ((ProvisioningResult<T>) result).getAny(),
+                new ListModel<>(new ArrayList<StatusBean>()),
+                CollectionUtils.collect(
+                        ((ProvisioningResult<T>) result).getPropagationStatuses(),
+                        new SerializableTransformer<PropagationStatus, Pair<ConnObjectTO, ConnObjectWrapper>>() {
+
+                    private static final long serialVersionUID = -4931455531906427515L;
+
+                    @Override
+                    public Pair<ConnObjectTO, ConnObjectWrapper> transform(final PropagationStatus input) {
+                        ConnObjectTO before = input.getBeforeObj();
+                        ConnObjectWrapper afterObjWrapper = new ConnObjectWrapper(
+                                ((ProvisioningResult<T>) result).getAny(),
+                                input.getResource(),
+                                input.getAfterObj());
+                        return Pair.of(before, afterObjWrapper);
+                    }
+
+                }, new ArrayList<Pair<ConnObjectTO, ConnObjectWrapper>>()),
+                pageRef);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3e8912c3/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
new file mode 100644
index 0000000..0f5d517
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
@@ -0,0 +1,241 @@
+/*
+ * 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.client.console.panels;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.AnyObjectRestClient;
+import org.apache.syncope.client.console.status.StatusModal;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.any.AnyHandler;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.types.AnyEntitlement;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.springframework.util.ReflectionUtils;
+
+public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO> {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected AnyObjectDirectoryPanel(final String id, final Builder builder) {
+        super(id, builder);
+    }
+
+    @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_ANYOBJECT_PAGINATOR_ROWS;
+    }
+
+    @Override
+    protected List<IColumn<AnyObjectTO, String>> getColumns() {
+        final List<IColumn<AnyObjectTO, String>> columns = new ArrayList<>();
+
+        for (String name : prefMan.getList(
+                getRequest(), String.format(Constants.PREF_ANY_OBJECT_DETAILS_VIEW, type))) {
+
+            final Field field = ReflectionUtils.findField(AnyObjectTO.class, name);
+
+            if (field != null && field.getType().equals(Date.class)) {
+                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
+            } else {
+                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
+            }
+        }
+
+        for (String name : prefMan.getList(
+                getRequest(), String.format(Constants.PREF_ANY_OBJECT_PLAIN_ATTRS_VIEW, type))) {
+
+            if (pSchemaNames.contains(name)) {
+                columns.add(new AttrColumn<AnyObjectTO>(name, SchemaType.PLAIN));
+            }
+        }
+
+        for (String name : prefMan.getList(
+                getRequest(), String.format(Constants.PREF_ANY_OBJECT_DER_ATTRS_VIEW, type))) {
+
+            if (dSchemaNames.contains(name)) {
+                columns.add(new AttrColumn<AnyObjectTO>(name, SchemaType.DERIVED));
+            }
+        }
+
+        // Add defaults in case of no selection
+        if (columns.isEmpty()) {
+            for (String name : AnyObjectDisplayAttributesModalPanel.DEFAULT_SELECTION) {
+                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
+            }
+
+            prefMan.setList(getRequest(), getResponse(),
+                    String.format(Constants.PREF_ANY_OBJECT_DETAILS_VIEW, type),
+                    Arrays.asList(AnyObjectDisplayAttributesModalPanel.DEFAULT_SELECTION));
+        }
+
+        setWindowClosedReloadCallback(displayAttributeModal);
+
+        columns.add(new ActionColumn<AnyObjectTO, String>(new ResourceModel("actions")) {
+
+            private static final long serialVersionUID = -3503023501954863131L;
+
+            @Override
+            public ActionLinksPanel<AnyObjectTO> getActions(final String componentId, final IModel<AnyObjectTO> model) {
+                final ActionLinksPanel.Builder<AnyObjectTO> panel = ActionLinksPanel.builder();
+
+                panel.add(new ActionLink<AnyObjectTO>() {
+
+                    private static final long serialVersionUID = -7978723352517770645L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                        final IModel<AnyHandler<AnyObjectTO>> formModel =
+                                new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
+                        altDefaultModal.setFormModel(formModel);
+
+                        target.add(altDefaultModal.setContent(new StatusModal<>(
+                                altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
+
+                        altDefaultModal.header(new Model<>(
+                                getString("any.edit", new Model<>(new AnyHandler<>(model.getObject())))));
+
+                        altDefaultModal.show(true);
+                    }
+                }, ActionLink.ActionType.MANAGE_RESOURCES, StandardEntitlement.USER_READ).
+                        add(new ActionLink<AnyObjectTO>() {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                                send(AnyObjectDirectoryPanel.this, Broadcast.EXACT,
+                                        new AjaxWizard.EditItemActionEvent<>(
+                                                new AnyHandler<>(new AnyObjectRestClient().read(model.getObject().
+                                                        getKey())),
+                                                target));
+                            }
+                        }, ActionLink.ActionType.EDIT, String.format("%s_%s", type, AnyEntitlement.READ)).
+                        add(new ActionLink<AnyObjectTO>() {
+
+                            private static final long serialVersionUID = -7978723352517770645L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                                final AnyObjectTO clone = SerializationUtils.clone(model.getObject());
+                                clone.setKey(0L);
+                                send(AnyObjectDirectoryPanel.this, Broadcast.EXACT,
+                                        new AjaxWizard.NewItemActionEvent<>(new AnyHandler<>(clone), target));
+                            }
+                        }, ActionLink.ActionType.CLONE, StandardEntitlement.USER_CREATE).
+                        add(new ActionLink<AnyObjectTO>() {
+
+                            private static final long serialVersionUID = -7978723352517770646L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                                try {
+                                    restClient.delete(model.getObject().getETagValue(), model.getObject().getKey());
+                                    info(getString(Constants.OPERATION_SUCCEEDED));
+                                    target.add(container);
+                                } catch (SyncopeClientException e) {
+                                    LOG.error("While deleting object {}", model.getObject().getKey(), e);
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
+                                }
+                                SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+                            }
+                        }, ActionLink.ActionType.DELETE, String.format("%s_%s", type, AnyEntitlement.DELETE));
+
+                return panel.build(componentId, model.getObject());
+            }
+
+            @Override
+            public ActionLinksPanel<Serializable> getHeader(final String componentId) {
+                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder();
+
+                panel.add(new ActionLink<Serializable>() {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+                        target.add(displayAttributeModal.setContent(new AnyObjectDisplayAttributesModalPanel<>(
+                                displayAttributeModal, page.getPageReference(), pSchemaNames, dSchemaNames, type)));
+                        displayAttributeModal.addSumbitButton();
+                        displayAttributeModal.header(new ResourceModel("any.attr.display"));
+                        displayAttributeModal.show(true);
+                    }
+                }, ActionLink.ActionType.CHANGE_VIEW, String.format("%s_%s", type, AnyEntitlement.READ)).add(
+                        new ActionLink<Serializable>() {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+                        if (target != null) {
+                            target.add(container);
+                        }
+                    }
+                }, ActionLink.ActionType.RELOAD, String.format("%s_%s", type, AnyEntitlement.SEARCH));
+
+                return panel.build(componentId);
+            }
+        }
+        );
+
+        return columns;
+
+    }
+
+    public static class Builder extends AnyDirectoryPanel.Builder<AnyObjectTO> {
+
+        private static final long serialVersionUID = -6828423611982275641L;
+
+        public Builder(final List<AnyTypeClassTO> anyTypeClassTOs, final String type, final PageReference pageRef) {
+            super(anyTypeClassTOs, new AnyObjectRestClient(), type, pageRef);
+            setShowResultPage(true);
+        }
+
+        @Override
+        protected WizardMgtPanel<AnyHandler<AnyObjectTO>> newInstance(final String id) {
+            return new AnyObjectDirectoryPanel(id, this);
+        }
+    }
+}