You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2017/05/05 22:23:51 UTC

[10/11] syncope git commit: [SYNCOPE-1047] Replaces ActionLinksPanel with TogglePanel

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/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
index ff4d622..8ea0cea 100644
--- 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
@@ -31,11 +31,11 @@ import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AnyObjectRestClient;
 import org.apache.syncope.client.console.status.AnyStatusModal;
 import org.apache.syncope.client.console.tasks.AnyPropagationTasks;
-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.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.AnyWrapper;
@@ -71,20 +71,50 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
     }
 
     @Override
+    public ActionsPanel<Serializable> getHeader(final String componentId) {
+        final ActionsPanel<Serializable> panel = super.getHeader(componentId);
+
+        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.addSubmitButton();
+                displayAttributeModal.header(new ResourceModel("any.attr.display"));
+                displayAttributeModal.show(true);
+            }
+
+            @Override
+            protected boolean statusCondition(final Serializable modelObject) {
+                return wizardInModal;
+            }
+        }, ActionType.CHANGE_VIEW, AnyEntitlement.READ.getFor(type)).hideLabel();
+        return panel;
+    }
+
+    @Override
     protected List<IColumn<AnyObjectTO, String>> getColumns() {
         final List<IColumn<AnyObjectTO, String>> columns = new ArrayList<>();
+        final List<IColumn<AnyObjectTO, String>> prefcolumns = new ArrayList<>();
+
+        columns.add(new KeyPropertyColumn<AnyObjectTO>(
+                new ResourceModel(Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME), Constants.KEY_FIELD_NAME));
 
         for (String name : prefMan.getList(
                 getRequest(), String.format(Constants.PREF_ANY_OBJECT_DETAILS_VIEW, type))) {
-
-            addPropertyColumn(name, ReflectionUtils.findField(AnyObjectTO.class, name), columns);
+            if (!Constants.KEY_FIELD_NAME.equalsIgnoreCase(name)) {
+                addPropertyColumn(name, ReflectionUtils.findField(AnyObjectTO.class, name), prefcolumns);
+            }
         }
 
         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));
+                prefcolumns.add(new AttrColumn<AnyObjectTO>(name, SchemaType.PLAIN));
             }
         }
 
@@ -92,171 +122,132 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                 getRequest(), String.format(Constants.PREF_ANY_OBJECT_DER_ATTRS_VIEW, type))) {
 
             if (dSchemaNames.contains(name)) {
-                columns.add(new AttrColumn<AnyObjectTO>(name, SchemaType.DERIVED));
+                prefcolumns.add(new AttrColumn<AnyObjectTO>(name, SchemaType.DERIVED));
             }
         }
 
         // Add defaults in case of no selection
-        if (columns.isEmpty()) {
+        if (prefcolumns.isEmpty()) {
             for (String name : AnyObjectDisplayAttributesModalPanel.DEFAULT_SELECTION) {
-                addPropertyColumn(name, ReflectionUtils.findField(AnyObjectTO.class, name), columns);
+                addPropertyColumn(name, ReflectionUtils.findField(AnyObjectTO.class, name), prefcolumns);
             }
 
-            prefMan.setList(getRequest(), getResponse(),
-                    String.format(Constants.PREF_ANY_OBJECT_DETAILS_VIEW, type),
+            prefMan.setList(getRequest(), getResponse(), Constants.PREF_ANY_OBJECT_DETAILS_VIEW,
                     Arrays.asList(AnyObjectDisplayAttributesModalPanel.DEFAULT_SELECTION));
         }
 
-        columns.add(new ActionColumn<AnyObjectTO, String>(new ResourceModel("actions")) {
+        columns.addAll(prefcolumns);
+        return columns;
+    }
+
+    @Override
+    public ActionsPanel<AnyObjectTO> getActions(final IModel<AnyObjectTO> model) {
+        final ActionsPanel<AnyObjectTO> panel = super.getActions(model);
+
+        panel.add(new ActionLink<AnyObjectTO>() {
 
-            private static final long serialVersionUID = -3503023501954863131L;
+            private static final long serialVersionUID = -7978723352517770644L;
 
             @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 = -7978723352517770644L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                        send(AnyObjectDirectoryPanel.this, Broadcast.EXACT,
-                                new AjaxWizard.EditItemActionEvent<>(
-                                        new AnyWrapper<>(new AnyObjectRestClient().read(model.getObject().getKey())),
-                                        target));
-                    }
-                }, ActionType.EDIT, AnyEntitlement.READ.getFor(type)).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(null);
-                        send(AnyObjectDirectoryPanel.this, Broadcast.EXACT,
-                                new AjaxWizard.NewItemActionEvent<>(new AnyWrapper<>(clone), target));
-                    }
-
-                    @Override
-                    protected boolean statusCondition(final AnyObjectTO modelObject) {
-                        return addAjaxLink.isVisibleInHierarchy();
-                    }
-                }, ActionType.CLONE, AnyEntitlement.CREATE.getFor(type)).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());
-                            SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                            target.add(container);
-                        } catch (SyncopeClientException e) {
-                            LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
-                        }
-                        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                    }
-                }, ActionType.DELETE, AnyEntitlement.DELETE.getFor(type));
-
-                if (wizardInModal) {
-                    panel.add(new ActionLink<AnyObjectTO>() {
-
-                        private static final long serialVersionUID = -7978723352517770645L;
-
-                        @Override
-                        public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                            final IModel<AnyWrapper<AnyObjectTO>> formModel = new CompoundPropertyModel<>(
-                                    new AnyWrapper<>(model.getObject()));
-                            altDefaultModal.setFormModel(formModel);
-
-                            target.add(altDefaultModal.setContent(new AnyStatusModal<>(
-                                    altDefaultModal,
-                                    pageRef,
-                                    formModel.getObject().getInnerObject(),
-                                    "resourceName",
-                                    false)));
-
-                            altDefaultModal.header(new Model<>(
-                                    getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
-
-                            altDefaultModal.show(true);
-                        }
-                    }, ActionType.MANAGE_RESOURCES, AnyEntitlement.READ.getFor(type)).add(
-                            new ActionLink<AnyObjectTO>() {
-
-                        private static final long serialVersionUID = -7978723352517770644L;
-
-                        @Override
-                        public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                            target.add(utilityModal.setContent(new AnyPropagationTasks(
-                                    utilityModal, AnyTypeKind.ANY_OBJECT, model.getObject().getKey(), pageRef)));
-
-                            utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
-                            utilityModal.show(true);
-                        }
-                    }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<AnyObjectTO>() {
-
-                                private static final long serialVersionUID = -7978723352517770644L;
-
-                                @Override
-                                public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                                    target.add(utilityModal.setContent(
-                                            new NotificationTasks(AnyTypeKind.ANY_OBJECT, model.getObject().getKey(),
-                                                    pageRef)));
-                                    utilityModal.header(new StringResourceModel("any.notification.tasks", model));
-                                    utilityModal.show(true);
-                                    target.add(utilityModal);
-                                }
-                            }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST);
-                }
+            public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                send(AnyObjectDirectoryPanel.this, Broadcast.EXACT,
+                        new AjaxWizard.EditItemActionEvent<>(
+                                new AnyWrapper<>(new AnyObjectRestClient().read(model.getObject().getKey())),
+                                target));
+            }
+        }, ActionType.EDIT, AnyEntitlement.READ.getFor(type));
+        panel.add(new ActionLink<AnyObjectTO>() {
 
-                return panel.build(componentId, model.getObject());
+            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(null);
+                send(AnyObjectDirectoryPanel.this, Broadcast.EXACT,
+                        new AjaxWizard.NewItemActionEvent<>(new AnyWrapper<>(clone), target));
             }
 
             @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.addSubmitButton();
-                        displayAttributeModal.header(new ResourceModel("any.attr.display"));
-                        displayAttributeModal.show(true);
-                    }
-
-                    @Override
-                    protected boolean statusCondition(final Serializable modelObject) {
-                        return wizardInModal;
-                    }
-                }, ActionType.CHANGE_VIEW, AnyEntitlement.READ.getFor(type)).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);
-                        }
-                    }
-                }, ActionType.RELOAD, AnyEntitlement.SEARCH.getFor(type));
-
-                return panel.build(componentId);
+            protected boolean statusCondition(final AnyObjectTO modelObject) {
+                return addAjaxLink.isVisibleInHierarchy();
             }
+        }, ActionType.CLONE, AnyEntitlement.CREATE.getFor(type));
+
+        if (wizardInModal) {
+            panel.add(new ActionLink<AnyObjectTO>() {
+
+                private static final long serialVersionUID = -7978723352517770645L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                    final IModel<AnyWrapper<AnyObjectTO>> formModel = new CompoundPropertyModel<>(
+                            new AnyWrapper<>(model.getObject()));
+                    altDefaultModal.setFormModel(formModel);
+
+                    target.add(altDefaultModal.setContent(new AnyStatusModal<>(
+                            altDefaultModal,
+                            pageRef,
+                            formModel.getObject().getInnerObject(),
+                            "resourceName",
+                            false)));
+
+                    altDefaultModal.header(new Model<>(
+                            getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
+
+                    altDefaultModal.show(true);
+                }
+            }, ActionType.MANAGE_RESOURCES, AnyEntitlement.READ.getFor(type));
+            panel.add(
+                    new ActionLink<AnyObjectTO>() {
+
+                private static final long serialVersionUID = -7978723352517770644L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                    target.add(utilityModal.setContent(new AnyPropagationTasks(
+                            utilityModal, AnyTypeKind.ANY_OBJECT, model.getObject().getKey(), pageRef)));
+
+                    utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
+                    utilityModal.show(true);
+                }
+            }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST);
+            panel.add(new ActionLink<AnyObjectTO>() {
+
+                private static final long serialVersionUID = -7978723352517770644L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                    target.add(utilityModal.setContent(
+                            new NotificationTasks(AnyTypeKind.ANY_OBJECT, model.getObject().getKey(),
+                                    pageRef)));
+                    utilityModal.header(new StringResourceModel("any.notification.tasks", model));
+                    utilityModal.show(true);
+                    target.add(utilityModal);
+                }
+            }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST);
         }
-        );
 
-        return columns;
+        panel.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());
+                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    target.add(container);
+                } catch (SyncopeClientException e) {
+                    LOG.error("While deleting object {}", model.getObject().getKey(), e);
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName() : e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+            }
+        }, ActionType.DELETE, AnyEntitlement.DELETE.getFor(type), true);
 
+        return panel;
     }
 
     public static class Builder extends AnyDirectoryPanel.Builder<AnyObjectTO, AnyObjectRestClient> {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDisplayAttributesModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDisplayAttributesModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDisplayAttributesModalPanel.java
index 39f30ad..6462d11 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDisplayAttributesModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDisplayAttributesModalPanel.java
@@ -35,7 +35,7 @@ public class AnyObjectDisplayAttributesModalPanel<T extends Serializable> extend
 
     private static final long serialVersionUID = 5194630813773543054L;
 
-    public static final String[] DEFAULT_SELECTION = { "key", "name" };
+    public static final String[] DEFAULT_SELECTION = { "name" };
 
     public AnyObjectDisplayAttributesModalPanel(
             final BaseModal<T> modal,

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
index 09edf19..0e489f3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
@@ -33,10 +33,9 @@ import org.apache.syncope.client.console.commons.DirectoryDataProvider;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
-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.BooleanPropertyColumn;
 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.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.AbstractModalPanelBuilder;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
@@ -153,67 +152,44 @@ public class AnyTypeClassesPanel extends TypesDirectoryPanel<
             }
         }
 
-        columns.add(new ActionColumn<AnyTypeClassTO, String>(new ResourceModel("actions")) {
-
-            private static final long serialVersionUID = 906457126287899096L;
-
-            @Override
-            public ActionLinksPanel<AnyTypeClassTO> getActions(
-                    final String componentId, final IModel<AnyTypeClassTO> model) {
+        return columns;
+    }
 
-                ActionLinksPanel<AnyTypeClassTO> panel = ActionLinksPanel.<AnyTypeClassTO>builder().
-                        add(new ActionLink<AnyTypeClassTO>() {
+    @Override
+    public ActionsPanel<AnyTypeClassTO> getActions(final IModel<AnyTypeClassTO> model) {
+        final ActionsPanel<AnyTypeClassTO> panel = super.getActions(model);
 
-                            private static final long serialVersionUID = -3722207913631435501L;
+        panel.add(new ActionLink<AnyTypeClassTO>() {
 
-                            @Override
-                            public void onClick(final AjaxRequestTarget target, final AnyTypeClassTO ignore) {
-                                send(AnyTypeClassesPanel.this, Broadcast.EXACT,
-                                        new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
-                            }
-                        }, ActionLink.ActionType.EDIT, StandardEntitlement.ANYTYPECLASS_UPDATE).
-                        add(new ActionLink<AnyTypeClassTO>() {
-
-                            private static final long serialVersionUID = -3722207913631435501L;
-
-                            @Override
-                            public void onClick(final AjaxRequestTarget target, final AnyTypeClassTO ignore) {
-                                try {
-                                    restClient.delete(model.getObject().getKey());
-                                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                                    target.add(container);
-                                } catch (Exception e) {
-                                    LOG.error("While deleting {}", model.getObject(), e);
-                                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                            ? e.getClass().getName() : e.getMessage());
-                                }
-                                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                            }
-                        }, ActionLink.ActionType.DELETE, StandardEntitlement.ANYTYPECLASS_DELETE).
-                        build(componentId);
-
-                return panel;
-            }
+            private static final long serialVersionUID = -3722207913631435501L;
 
             @Override
-            public ActionLinksPanel<AnyTypeClassTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<AnyTypeClassTO> panel = ActionLinksPanel.builder();
+            public void onClick(final AjaxRequestTarget target, final AnyTypeClassTO ignore) {
+                send(AnyTypeClassesPanel.this, Broadcast.EXACT,
+                        new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+            }
+        }, ActionLink.ActionType.EDIT, StandardEntitlement.ANYTYPECLASS_UPDATE);
 
-                return panel.add(new ActionLink<AnyTypeClassTO>() {
+        panel.add(new ActionLink<AnyTypeClassTO>() {
 
-                    private static final long serialVersionUID = -1140254463922516111L;
+            private static final long serialVersionUID = -3722207913631435501L;
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final AnyTypeClassTO ignore) {
-                        if (target != null) {
-                            target.add(container);
-                        }
-                    }
-                }, ActionLink.ActionType.RELOAD).build(componentId);
+            @Override
+            public void onClick(final AjaxRequestTarget target, final AnyTypeClassTO ignore) {
+                try {
+                    restClient.delete(model.getObject().getKey());
+                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    target.add(container);
+                } catch (Exception e) {
+                    LOG.error("While deleting {}", model.getObject(), e);
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName() : e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
-        });
+        }, ActionLink.ActionType.DELETE, StandardEntitlement.ANYTYPECLASS_DELETE, true);
 
-        return columns;
+        return panel;
     }
 
     protected final class AnyTypeClassProvider extends DirectoryDataProvider<AnyTypeClassTO> {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
index b354055..f08d13e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
@@ -32,12 +32,10 @@ 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.pages.BasePage;
-import org.apache.syncope.client.console.panels.AnyTypesPanel.AnyTypeProvider;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
-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.BooleanPropertyColumn;
 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.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.AbstractModalPanelBuilder;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
@@ -53,7 +51,7 @@ import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.ResourceModel;
 
-public class AnyTypesPanel extends TypesDirectoryPanel<AnyTypeTO, AnyTypeProvider, AnyTypeRestClient> {
+public class AnyTypesPanel extends TypesDirectoryPanel<AnyTypeTO, AnyTypesPanel.AnyTypeProvider, AnyTypeRestClient> {
 
     private static final long serialVersionUID = 3905038169553185171L;
 
@@ -152,69 +150,45 @@ public class AnyTypesPanel extends TypesDirectoryPanel<AnyTypeTO, AnyTypeProvide
             }
         }
 
-        columns.add(new ActionColumn<AnyTypeTO, String>(new ResourceModel("actions")) {
-
-            private static final long serialVersionUID = 906457126287899096L;
-
-            @Override
-            public ActionLinksPanel<AnyTypeTO> getActions(
-                    final String componentId, final IModel<AnyTypeTO> model) {
-
-                ActionLinksPanel<AnyTypeTO> panel = ActionLinksPanel.<AnyTypeTO>builder().
-                        add(new ActionLink<AnyTypeTO>() {
+        return columns;
+    }
 
-                            private static final long serialVersionUID = -3722207913631435501L;
+    @Override
+    public ActionsPanel<AnyTypeTO> getActions(final IModel<AnyTypeTO> model) {
+        final ActionsPanel<AnyTypeTO> panel = super.getActions(model);
 
-                            @Override
-                            public void onClick(final AjaxRequestTarget target, final AnyTypeTO ignore) {
-                                send(AnyTypesPanel.this, Broadcast.EXACT,
-                                        new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
-                            }
-                        }, ActionLink.ActionType.EDIT, StandardEntitlement.ANYTYPE_UPDATE).
-                        add(new ActionLink<AnyTypeTO>() {
-
-                            private static final long serialVersionUID = -3722207913631435501L;
-
-                            @Override
-                            public void onClick(final AjaxRequestTarget target, final AnyTypeTO ignore) {
-                                try {
-                                    restClient.delete(model.getObject().getKey());
-                                    SyncopeConsoleSession.get().refreshAuth();
-
-                                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                                    target.add(container);
-                                } catch (Exception e) {
-                                    LOG.error("While deleting {}", model.getObject(), e);
-                                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                            ? e.getClass().getName() : e.getMessage());
-                                }
-                                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                            }
-                        }, ActionLink.ActionType.DELETE, StandardEntitlement.ANYTYPE_DELETE).
-                        build(componentId);
+        panel.add(new ActionLink<AnyTypeTO>() {
 
-                return panel;
-            }
+            private static final long serialVersionUID = -3722207913631435501L;
 
             @Override
-            public ActionLinksPanel<AnyTypeTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<AnyTypeTO> panel = ActionLinksPanel.builder();
-
-                return panel.add(new ActionLink<AnyTypeTO>() {
+            public void onClick(final AjaxRequestTarget target, final AnyTypeTO ignore) {
+                send(AnyTypesPanel.this, Broadcast.EXACT,
+                        new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+            }
+        }, ActionLink.ActionType.EDIT, StandardEntitlement.ANYTYPE_UPDATE);
+        panel.add(new ActionLink<AnyTypeTO>() {
 
-                    private static final long serialVersionUID = -1140254463922516111L;
+            private static final long serialVersionUID = -3722207913631435501L;
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final AnyTypeTO ignore) {
-                        if (target != null) {
-                            target.add(container);
-                        }
-                    }
-                }, ActionLink.ActionType.RELOAD).build(componentId);
+            @Override
+            public void onClick(final AjaxRequestTarget target, final AnyTypeTO ignore) {
+                try {
+                    restClient.delete(model.getObject().getKey());
+                    SyncopeConsoleSession.get().refreshAuth();
+
+                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    target.add(container);
+                } catch (Exception e) {
+                    LOG.error("While deleting {}", model.getObject(), e);
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName() : e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
-        });
+        }, ActionLink.ActionType.DELETE, StandardEntitlement.ANYTYPE_DELETE, true);
 
-        return columns;
+        return panel;
     }
 
     protected final class AnyTypeProvider extends DirectoryDataProvider<AnyTypeTO> {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
index 59af452..ec92a2e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
@@ -30,7 +30,10 @@ import org.apache.syncope.client.console.rest.RestClient;
 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.wicket.markup.html.form.ActionLinksTogglePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+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;
@@ -40,6 +43,8 @@ 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.IModel;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -71,7 +76,7 @@ public abstract class DirectoryPanel<
 
     /**
      * 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.
+     * show results about entity list and search.
      */
     protected final boolean filtered;
 
@@ -85,7 +90,7 @@ public abstract class DirectoryPanel<
     private AjaxDataTablePanel<T, String> resultTable;
 
     /**
-     * Data provider used to search for users.
+     * Data provider used to search for entities.
      */
     protected DP dataProvider;
 
@@ -94,12 +99,14 @@ public abstract class DirectoryPanel<
      */
     protected final BasePage page;
 
-    protected String itemKeyFieldName = "key";
+    protected String itemKeyFieldName = Constants.KEY_FIELD_NAME;
 
     protected final BaseModal<W> altDefaultModal = new BaseModal<>("outer");
 
     protected final BaseModal<W> displayAttributeModal = new BaseModal<>("outer");
 
+    private final ActionLinksTogglePanel<T> actionTogglePanel;
+
     /**
      * Create simple unfiltered search result panel.
      * Use the available builder for powerfull configuration options.
@@ -132,6 +139,9 @@ public abstract class DirectoryPanel<
         super(id, wizardInModal);
         setOutputMarkupId(true);
 
+        actionTogglePanel = new ActionLinksTogglePanel<T>("outer", builder.getPageRef());
+        addOuterObject(actionTogglePanel);
+
         addOuterObject(altDefaultModal);
         addOuterObject(displayAttributeModal);
 
@@ -144,7 +154,7 @@ public abstract class DirectoryPanel<
 
         this.restClient = builder.restClient;
 
-        // Container for user search result
+        // Container for entity search result
         container = new WebMarkupContainer("searchContainer");
         container.setOutputMarkupId(true);
         addInnerObject(container);
@@ -217,6 +227,29 @@ public abstract class DirectoryPanel<
         });
         paginatorForm.add(rowsChooser);
         // ---------------------------
+
+        // ---------------------------
+        // Table handling
+        // ---------------------------
+        container.add(getHeader("tablehandling"));
+        // ---------------------------
+    }
+
+    protected ActionsPanel<Serializable> getHeader(final String componentId) {
+        final ActionsPanel<Serializable> panel = new ActionsPanel<>(componentId, null);
+
+        panel.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, StandardEntitlement.USER_SEARCH).hideLabel();
+        return panel;
     }
 
     public void search(final AjaxRequestTarget target) {
@@ -241,8 +274,22 @@ public abstract class DirectoryPanel<
                 ? (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()).
+        AjaxDataTablePanel.Builder<T, String> resultTableBuilder = new AjaxDataTablePanel.Builder<T, String>(
+                dataProvider, page.getPageReference()) {
+
+            private static final long serialVersionUID = 2205322679547329123L;
+
+            @Override
+            protected ActionsPanel<T> getActions(final IModel<T> model) {
+                return DirectoryPanel.this.getActions(model);
+            }
+
+            @Override
+            protected ActionLinksTogglePanel<T> getTogglePanel() {
+                return DirectoryPanel.this.getTogglePanel();
+            }
+
+        }.
                 setColumns(getColumns()).
                 setRowsPerPage(rows).
                 setBulkActions(getBulkActions(), restClient, itemKeyFieldName).
@@ -299,6 +346,14 @@ public abstract class DirectoryPanel<
         send(getParent(), Broadcast.BREADTH, data);
     }
 
+    protected ActionsPanel<T> getActions(final IModel<T> model) {
+        return model == null ? new ActionsPanel<>("actions", new Model<T>()) : new ActionsPanel<>("actions", model);
+    }
+
+    protected ActionLinksTogglePanel<T> getTogglePanel() {
+        return actionTogglePanel;
+    }
+
     public static class EventDataWrapper {
 
         private AjaxRequestTarget target;
@@ -341,7 +396,7 @@ public abstract class DirectoryPanel<
 
         /**
          * 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.
+         * By using this attribute it is possible to force this panel to show results about entity list and search.
          */
         protected boolean filtered = false;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
index 118c415..04ec300 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
@@ -36,12 +36,12 @@ import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.status.AnyStatusModal;
 import org.apache.syncope.client.console.tasks.AnyPropagationTasks;
-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.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
 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.wicket.markup.html.form.ActionLink.ActionType;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.AnyWrapper;
@@ -183,223 +183,234 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
     }
 
     @Override
+    public ActionsPanel<Serializable> getHeader(final String componentId) {
+        final ActionsPanel<Serializable> panel = super.getHeader(componentId);
+
+        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 GroupDisplayAttributesModalPanel<>(
+                        displayAttributeModal, page.getPageReference(), pSchemaNames, dSchemaNames)));
+                displayAttributeModal.header(new ResourceModel("any.attr.display"));
+                displayAttributeModal.show(true);
+            }
+        }, ActionType.CHANGE_VIEW, StandardEntitlement.GROUP_READ).hideLabel();
+        return panel;
+    }
+
+    @Override
     protected List<IColumn<GroupTO, String>> getColumns() {
+
         final List<IColumn<GroupTO, String>> columns = new ArrayList<>();
+        final List<IColumn<GroupTO, String>> prefcolumns = new ArrayList<>();
+
+        columns.add(new KeyPropertyColumn<GroupTO>(
+                new ResourceModel(Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME), Constants.KEY_FIELD_NAME));
 
         for (String name : prefMan.getList(getRequest(), Constants.PREF_GROUP_DETAILS_VIEW)) {
-            addPropertyColumn(name, ReflectionUtils.findField(GroupTO.class, name), columns);
+            if (!Constants.KEY_FIELD_NAME.equalsIgnoreCase(name)) {
+                addPropertyColumn(name, ReflectionUtils.findField(GroupTO.class, name), prefcolumns);
+            }
         }
 
         for (String name : prefMan.getList(getRequest(), Constants.PREF_GROUP_PLAIN_ATTRS_VIEW)) {
             if (pSchemaNames.contains(name)) {
-                columns.add(new AttrColumn<GroupTO>(name, SchemaType.PLAIN));
+                prefcolumns.add(new AttrColumn<GroupTO>(name, SchemaType.PLAIN));
             }
         }
 
         for (String name : prefMan.getList(getRequest(), Constants.PREF_GROUP_DER_ATTRS_VIEW)) {
             if (dSchemaNames.contains(name)) {
-                columns.add(new AttrColumn<GroupTO>(name, SchemaType.DERIVED));
+                prefcolumns.add(new AttrColumn<GroupTO>(name, SchemaType.DERIVED));
             }
         }
 
         // Add defaults in case of no selection
-        if (columns.isEmpty()) {
+        if (prefcolumns.isEmpty()) {
             for (String name : GroupDisplayAttributesModalPanel.DEFAULT_SELECTION) {
-                addPropertyColumn(name, ReflectionUtils.findField(GroupTO.class, name), columns);
+                addPropertyColumn(name, ReflectionUtils.findField(GroupTO.class, name), prefcolumns);
             }
 
             prefMan.setList(getRequest(), getResponse(), Constants.PREF_GROUP_DETAILS_VIEW,
                     Arrays.asList(GroupDisplayAttributesModalPanel.DEFAULT_SELECTION));
         }
 
-        columns.add(new ActionColumn<GroupTO, String>(new ResourceModel("actions")) {
+        columns.addAll(prefcolumns);
+        return columns;
+    }
 
-            private static final long serialVersionUID = -3503023501954863131L;
+    @Override
+    public ActionsPanel<GroupTO> getActions(final IModel<GroupTO> model) {
+        final ActionsPanel<GroupTO> panel = super.getActions(model);
 
-            @Override
-            public ActionLinksPanel<GroupTO> getActions(final String componentId, final IModel<GroupTO> model) {
-                final ActionLinksPanel.Builder<GroupTO> panel = ActionLinksPanel.builder();
+        panel.add(new ActionLink<GroupTO>() {
 
-                panel.add(new ActionLink<GroupTO>() {
+            private static final long serialVersionUID = -7978723352517770644L;
 
-                    private static final long serialVersionUID = -7978723352517770645L;
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                send(GroupDirectoryPanel.this, Broadcast.EXACT,
+                        new AjaxWizard.EditItemActionEvent<>(new GroupWrapper(
+                                restClient.read(model.getObject().getKey())), target));
+            }
+        }, ActionType.EDIT, StandardEntitlement.GROUP_READ);
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        templates.setTargetObject(model.getObject());
-                        templates.toggle(target, true);
-                    }
+        panel.add(new ActionLink<GroupTO>() {
 
-                    @Override
-                    public boolean isIndicatorEnabled() {
-                        return false;
-                    }
-                }, ActionType.MEMBERS, StandardEntitlement.GROUP_READ).add(new ActionLink<GroupTO>() {
+            private static final long serialVersionUID = 6242834621660352855L;
 
-                    private static final long serialVersionUID = -7978723352517770645L;
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                GroupTO clone = SerializationUtils.clone(model.getObject());
+                clone.setKey(null);
+                send(GroupDirectoryPanel.this, Broadcast.EXACT,
+                        new AjaxWizard.NewItemActionEvent<>(new GroupWrapper(clone), target));
+            }
+        }, ActionType.CLONE, StandardEntitlement.GROUP_CREATE);
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        IModel<AnyWrapper<GroupTO>> formModel = new CompoundPropertyModel<>(
-                                new AnyWrapper<>(model.getObject()));
-                        altDefaultModal.setFormModel(formModel);
-
-                        target.add(altDefaultModal.setContent(new AnyStatusModal<>(
-                                altDefaultModal,
-                                pageRef,
-                                formModel.getObject().getInnerObject(),
-                                "resourceName",
-                                false)));
-
-                        altDefaultModal.header(new Model<>(
-                                getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
-
-                        altDefaultModal.show(true);
-                    }
-                }, ActionType.MANAGE_RESOURCES, StandardEntitlement.GROUP_READ).add(new ActionLink<GroupTO>() {
+        panel.add(new ActionLink<GroupTO>() {
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+            private static final long serialVersionUID = 6242834621660352855L;
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        send(GroupDirectoryPanel.this, Broadcast.EXACT,
-                                new AjaxWizard.EditItemActionEvent<>(new GroupWrapper(
-                                        restClient.read(model.getObject().getKey())), target));
-                    }
-                }, ActionType.EDIT, StandardEntitlement.GROUP_READ).add(new ActionLink<GroupTO>() {
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                target.add(typeExtensionsModal.setContent(new TypeExtensionDirectoryPanel(
+                        typeExtensionsModal, model.getObject(), pageRef)));
+                typeExtensionsModal.header(new StringResourceModel("typeExtensions", model));
+                typeExtensionsModal.show(true);
+            }
+        }, ActionType.TYPE_EXTENSIONS, StandardEntitlement.GROUP_UPDATE);
 
-                    private static final long serialVersionUID = 6242834621660352855L;
+        panel.add(new ActionLink<GroupTO>() {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        target.add(typeExtensionsModal.setContent(new TypeExtensionDirectoryPanel(
-                                typeExtensionsModal, model.getObject(), pageRef)));
-                        typeExtensionsModal.header(new StringResourceModel("typeExtensions", model));
-                        typeExtensionsModal.show(true);
-                    }
-                }, ActionType.TYPE_EXTENSIONS, StandardEntitlement.GROUP_UPDATE).add(new ActionLink<GroupTO>() {
+            private static final long serialVersionUID = -7978723352517770645L;
 
-                    private static final long serialVersionUID = 6242834621660352855L;
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                templates.setTargetObject(model.getObject());
+                templates.toggle(target, true);
+            }
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        GroupTO clone = SerializationUtils.clone(model.getObject());
-                        clone.setKey(null);
-                        send(GroupDirectoryPanel.this, Broadcast.EXACT,
-                                new AjaxWizard.NewItemActionEvent<>(new GroupWrapper(clone), target));
-                    }
-                }, ActionType.CLONE, StandardEntitlement.GROUP_CREATE).add(new ActionLink<GroupTO>() {
+            @Override
+            public boolean isIndicatorEnabled() {
+                return false;
+            }
+        }, ActionType.MEMBERS, StandardEntitlement.GROUP_READ);
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+        panel.add(new ActionLink<GroupTO>() {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        target.add(utilityModal.setContent(new AnyPropagationTasks(
-                                utilityModal, AnyTypeKind.GROUP, model.getObject().getKey(), pageRef)));
-                        utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
-                        utilityModal.show(true);
-                    }
-                }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<GroupTO>() {
+            private static final long serialVersionUID = -7978723352517770644L;
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                try {
+                    restClient.bulkMembersAction(model.getObject().getKey(), BulkMembersActionType.PROVISION);
+                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    target.add(container);
+                } catch (SyncopeClientException e) {
+                    LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName() : e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+            }
+        }, ActionType.PROVISION_MEMBERS,
+                String.format("%s,%s", StandardEntitlement.TASK_CREATE, StandardEntitlement.TASK_EXECUTE));
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        target.add(utilityModal.setContent(
-                                new NotificationTasks(AnyTypeKind.GROUP, model.getObject().getKey(), pageRef)));
-                        utilityModal.header(new StringResourceModel("any.notification.tasks", model));
-                        utilityModal.show(true);
-                    }
-                }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<GroupTO>() {
+        panel.add(
+                new ActionLink<GroupTO>() {
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+            private static final long serialVersionUID = -7978723352517770644L;
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        try {
-                            restClient.delete(model.getObject().getETagValue(), model.getObject().getKey());
-                            SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                            target.add(container);
-                        } catch (SyncopeClientException e) {
-                            LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
-                        }
-                        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                    }
-                }, ActionType.DELETE, StandardEntitlement.GROUP_DELETE).add(new ActionLink<GroupTO>() {
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                try {
+                    restClient.bulkMembersAction(model.getObject().getKey(), BulkMembersActionType.DEPROVISION);
+                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    target.add(container);
+                } catch (SyncopeClientException e) {
+                    LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName() : e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+            }
+        }, ActionType.DEPROVISION_MEMBERS,
+                String.format("%s,%s", StandardEntitlement.TASK_CREATE, StandardEntitlement.TASK_EXECUTE));
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+        panel.add(new ActionLink<GroupTO>() {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        try {
-                            restClient.bulkMembersAction(model.getObject().getKey(), BulkMembersActionType.PROVISION);
-                            SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                            target.add(container);
-                        } catch (SyncopeClientException e) {
-                            LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
-                        }
-                        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                    }
-                }, ActionType.PROVISION_MEMBERS,
-                        String.format("%s,%s", StandardEntitlement.TASK_CREATE, StandardEntitlement.TASK_EXECUTE)).add(
-                        new ActionLink<GroupTO>() {
+            private static final long serialVersionUID = -7978723352517770645L;
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                IModel<AnyWrapper<GroupTO>> formModel = new CompoundPropertyModel<>(
+                        new AnyWrapper<>(model.getObject()));
+                altDefaultModal.setFormModel(formModel);
+
+                target.add(altDefaultModal.setContent(new AnyStatusModal<>(
+                        altDefaultModal,
+                        pageRef,
+                        formModel.getObject().getInnerObject(),
+                        "resourceName",
+                        false)));
+
+                altDefaultModal.header(new Model<>(
+                        getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
+
+                altDefaultModal.show(true);
+            }
+        }, ActionType.MANAGE_RESOURCES, StandardEntitlement.GROUP_READ);
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                        try {
-                            restClient.bulkMembersAction(model.getObject().getKey(), BulkMembersActionType.DEPROVISION);
-                            SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                            target.add(container);
-                        } catch (SyncopeClientException e) {
-                            LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
-                        }
-                        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                    }
-                }, ActionType.DEPROVISION_MEMBERS,
-                        String.format("%s,%s", StandardEntitlement.TASK_CREATE, StandardEntitlement.TASK_EXECUTE));
+        panel.add(new ActionLink<GroupTO>() {
 
-                return panel.build(componentId);
-            }
+            private static final long serialVersionUID = -7978723352517770644L;
 
             @Override
-            public ActionLinksPanel<Serializable> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder();
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                target.add(utilityModal.setContent(new AnyPropagationTasks(
+                        utilityModal, AnyTypeKind.GROUP, model.getObject().getKey(), pageRef)));
+                utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
+                utilityModal.show(true);
+            }
+        }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST);
 
-                return panel.add(new ActionLink<Serializable>() {
+        panel.add(new ActionLink<GroupTO>() {
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+            private static final long serialVersionUID = -7978723352517770644L;
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
-                        target.add(displayAttributeModal.setContent(new GroupDisplayAttributesModalPanel<>(
-                                displayAttributeModal, page.getPageReference(), pSchemaNames, dSchemaNames)));
-                        displayAttributeModal.header(new ResourceModel("any.attr.display"));
-                        displayAttributeModal.show(true);
-                    }
-                }, ActionType.CHANGE_VIEW, StandardEntitlement.GROUP_READ).add(
-                        new ActionLink<Serializable>() {
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                target.add(utilityModal.setContent(
+                        new NotificationTasks(AnyTypeKind.GROUP, model.getObject().getKey(), pageRef)));
+                utilityModal.header(new StringResourceModel("any.notification.tasks", model));
+                utilityModal.show(true);
+            }
+        }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST);
 
-                    private static final long serialVersionUID = -7978723352517770644L;
+        panel.add(new ActionLink<GroupTO>() {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
-                        if (target != null) {
-                            target.add(container);
-                        }
-                    }
-                }, ActionType.RELOAD).build(componentId);
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                try {
+                    restClient.delete(model.getObject().getETagValue(), model.getObject().getKey());
+                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    target.add(container);
+                } catch (SyncopeClientException e) {
+                    LOG.error("While deleting object {}", model.getObject().getKey(), e);
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName() : e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
-        });
+        }, ActionType.DELETE, StandardEntitlement.GROUP_DELETE, true);
 
-        return columns;
+        return panel;
     }
 
     public static class Builder extends AnyDirectoryPanel.Builder<GroupTO, GroupRestClient> {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDisplayAttributesModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDisplayAttributesModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDisplayAttributesModalPanel.java
index 43b8b93..89d8dc9 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDisplayAttributesModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDisplayAttributesModalPanel.java
@@ -35,7 +35,7 @@ public class GroupDisplayAttributesModalPanel<T extends Serializable> extends Di
 
     private static final long serialVersionUID = 5194630813773543054L;
 
-    public static final String[] DEFAULT_SELECTION = { "key", "name" };
+    public static final String[] DEFAULT_SELECTION = { "name" };
 
     public GroupDisplayAttributesModalPanel(
             final BaseModal<T> modal,

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index e015621..16c4b77 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -31,7 +31,7 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormChoiceComponentUpdatingBehavior;
 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.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.wicket.Component;
@@ -97,7 +97,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             final List<T> list,
             final Class<T> reference,
             final List<String> includes,
-            final ActionLinksPanel.Builder<T> actions,
+            final ActionsPanel<T> actions,
             final CheckAvailability check,
             final boolean reuseItem,
             final boolean wizardInModal,
@@ -179,7 +179,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
                     }
                 };
                 beanItem.add(fields);
-                beanItem.add(actions.build("actions", bean));
+                beanItem.add(actions.clone("actions", new Model<>(bean)));
             }
         };
         beans.setOutputMarkupId(true);
@@ -227,7 +227,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
 
         private final List<String> includes = new ArrayList<>();
 
-        private final ActionLinksPanel.Builder<T> actions;
+        private final ActionsPanel<T> actions;
 
         private List<T> items;
 
@@ -241,7 +241,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             super(pageRef);
             this.reference = reference;
             this.items = null;
-            this.actions = ActionLinksPanel.<T>builder();
+            this.actions = new ActionsPanel<T>("actions", null);
         }
 
         public Builder<T> setModel(final IModel<? extends Collection<T>> model) {
@@ -313,7 +313,24 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
          */
         public Builder<T> addAction(
                 final ActionLink<T> link, final ActionLink.ActionType type, final String entitlements) {
-            actions.add(link, type, entitlements);
+            return addAction(link, type, entitlements, false);
+        }
+
+        /**
+         * Add item action (the given order is ignored.
+         *
+         * @param link action link.
+         * @param type action type.
+         * @param entitlements entitlements.
+         * @param onConfirm specify TRUE to ask for confirmation.
+         * @return current builder object.
+         */
+        public Builder<T> addAction(
+                final ActionLink<T> link,
+                final ActionLink.ActionType type,
+                final String entitlements,
+                final boolean onConfirm) {
+            actions.add(link, type, entitlements, onConfirm).hideLabel();
             return this;
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f8b61e78/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
new file mode 100644
index 0000000..cfac249
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
@@ -0,0 +1,212 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+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.commons.DirectoryDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.rest.ConfRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+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.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.client.console.wizards.AbstractModalPanelBuilder;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.common.lib.to.AttrTO;
+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.ajax.markup.html.modal.ModalWindow.WindowClosedCallback;
+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.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
+
+public class ParametersDirectoryPanel
+        extends DirectoryPanel<AttrTO, AttrTO, ParametersDirectoryPanel.ParametersProvider, ConfRestClient> {
+
+    private static final long serialVersionUID = 2765863608539154422L;
+
+    private final SchemaRestClient schemaRestClient = new SchemaRestClient();
+
+    private final BaseModal<AttrTO> modalDetails = new BaseModal<AttrTO>("modalDetails") {
+
+        private static final long serialVersionUID = 389935548143327858L;
+
+        @Override
+        protected void onConfigure() {
+            super.onConfigure();
+            setFooterVisible(true);
+        }
+    };
+
+    public ParametersDirectoryPanel(final String id, final PageReference pageRef) {
+        super(id, new Builder<AttrTO, AttrTO, ConfRestClient>(new ConfRestClient(), pageRef) {
+
+            private static final long serialVersionUID = 8769126634538601689L;
+
+            @Override
+            protected WizardMgtPanel<AttrTO> newInstance(final String id, final boolean wizardInModal) {
+                throw new UnsupportedOperationException();
+            }
+        });
+
+        itemKeyFieldName = "schema";
+        disableCheckBoxes();
+
+        modalDetails.setWindowClosedCallback(new WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                modalDetails.show(false);
+                target.add(container);
+            }
+        });
+
+        addInnerObject(modalDetails);
+
+        this.addNewItemPanelBuilder(new AbstractModalPanelBuilder<AttrTO>(new AttrTO(), pageRef) {
+
+            private static final long serialVersionUID = 1995192603527154740L;
+
+            @Override
+            public WizardModalPanel<AttrTO> build(final String id, final int index, final AjaxWizard.Mode mode) {
+                return new ParametersCreateModalPanel(modal, newModelObject(), pageRef);
+            }
+        }, true);
+        modal.size(Modal.Size.Medium);
+        initResultTable();
+
+        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, StandardEntitlement.CONFIGURATION_SET);
+    }
+
+    public ParametersDirectoryPanel(final String id, final Builder<AttrTO, AttrTO, ConfRestClient> builder) {
+        super(id, builder);
+    }
+
+    @Override
+    protected ParametersProvider dataProvider() {
+        return new ParametersProvider(rows);
+    }
+
+    @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_PARAMETERS_PAGINATOR_ROWS;
+    }
+
+    @Override
+    protected Collection<ActionLink.ActionType> getBulkActions() {
+        return Collections.<ActionLink.ActionType>singletonList(ActionLink.ActionType.DELETE);
+    }
+
+    @Override
+    protected List<IColumn<AttrTO, String>> getColumns() {
+        final List<IColumn<AttrTO, String>> columns = new ArrayList<>();
+        columns.add(new PropertyColumn<AttrTO, String>(new ResourceModel("schema"), "schema"));
+        columns.add(new PropertyColumn<AttrTO, String>(new ResourceModel("values"), "values"));
+        return columns;
+    }
+
+    @Override
+    public ActionsPanel<AttrTO> getActions(final IModel<AttrTO> model) {
+        final ActionsPanel<AttrTO> panel = super.getActions(model);
+
+        panel.add(new ActionLink<AttrTO>() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target, final AttrTO ignore) {
+                target.add(modalDetails);
+                modalDetails.addSubmitButton();
+                modalDetails.header(new StringResourceModel("any.edit"));
+                modalDetails.setContent(new ParametersEditModalPanel(modalDetails, model.getObject(), pageRef));
+                modalDetails.show(true);
+            }
+        }, ActionLink.ActionType.EDIT, StandardEntitlement.CONFIGURATION_SET);
+
+        panel.add(new ActionLink<AttrTO>() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target, final AttrTO ignore) {
+                try {
+                    restClient.delete(model.getObject().getSchema());
+                    schemaRestClient.deletePlainSchema(model.getObject().getSchema());
+                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    target.add(container);
+                } catch (Exception e) {
+                    LOG.error("While deleting {}", model.getObject(), e);
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName() : e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+            }
+        }, ActionLink.ActionType.DELETE, StandardEntitlement.CONFIGURATION_DELETE);
+
+        return panel;
+    }
+
+    protected final class ParametersProvider extends DirectoryDataProvider<AttrTO> {
+
+        private static final long serialVersionUID = -185944053385660794L;
+
+        private final SortableDataProviderComparator<AttrTO> comparator;
+
+        private ParametersProvider(final int paginatorRows) {
+            super(paginatorRows);
+            setSort("schema", SortOrder.ASCENDING);
+            comparator = new SortableDataProviderComparator<>(this);
+        }
+
+        @Override
+        public Iterator<AttrTO> iterator(final long first, final long count) {
+            final List<AttrTO> list = restClient.list();
+            Collections.sort(list, comparator);
+            return list.subList((int) first, (int) first + (int) count).iterator();
+        }
+
+        @Override
+        public long size() {
+            return restClient.list().size();
+        }
+
+        @Override
+        public IModel<AttrTO> model(final AttrTO object) {
+            return new CompoundPropertyModel<>(object);
+        }
+    }
+}