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 2015/12/31 09:20:13 UTC

[3/4] syncope git commit: [SYNCOPE-156] provides material button for types by changing to be compliant to the standard use of search tables + fixes some notifications & icons

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
index 03a836d..17cfbe0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
@@ -43,7 +43,7 @@ import org.apache.wicket.model.ResourceModel;
 /**
  * Modal window with Connector form.
  */
-public class ConnectorModal extends AbstractResourceModal {
+public class ConnectorModal extends AbstractResourceModal<Serializable> {
 
     private static final long serialVersionUID = -2025535531121434050L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
index 46237ab..58aa653 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -32,7 +33,7 @@ import org.apache.wicket.model.IModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public abstract class DataTablePanel<T, S> extends Panel {
+public abstract class DataTablePanel<T extends Serializable, S> extends Panel {
 
     private static final long serialVersionUID = -7264400471578272966L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java
index f23cecb..bee0c05 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java
@@ -18,16 +18,17 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import java.io.Serializable;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.model.Model;
 
-public class FailureMessageModal extends AbstractModalPanel {
+public class FailureMessageModal<T extends Serializable> extends AbstractModalPanel<T> {
 
     private static final long serialVersionUID = 9216117990503199258L;
 
-    public FailureMessageModal(final BaseModal<?> modal, final PageReference pageRef, final String failureMessage) {
+    public FailureMessageModal(final BaseModal<T> modal, final PageReference pageRef, final String failureMessage) {
         super(modal, pageRef);
         final Label executionFailureMessage;
         if (!failureMessage.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
index 8670265..27d27b6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
@@ -168,7 +168,7 @@ public class GroupSearchResultPanel extends AnyObjectSearchResultPanel<GroupTO>
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
-                        target.add(modal.setContent(new GroupDisplayAttributesModalPage(
+                        target.add(modal.setContent(new GroupDisplayAttributesModalPage<>(
                                 modal, page.getPageReference(), schemaNames, dSchemaNames)));
 
                         modal.header(new ResourceModel("any.attr.display", ""));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalPanel.java
index 681c1f2..11a9f78 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalPanel.java
@@ -18,13 +18,16 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import java.io.Serializable;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.request.component.IRequestableComponent;
 
-public interface ModalPanel extends IRequestableComponent {
+public interface ModalPanel<T extends Serializable> extends IRequestableComponent, Serializable {
 
     void onSubmit(final AjaxRequestTarget target, final Form<?> form);
 
     void onError(final AjaxRequestTarget target, final Form<?> form);
+
+    T getItem();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/NotificationPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/NotificationPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/NotificationPanel.java
index 03102ae..d38cfad 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/NotificationPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/NotificationPanel.java
@@ -61,10 +61,12 @@ public class NotificationPanel extends FeedbackPanel {
     public void refresh(final AjaxRequestTarget target) {
         if (anyMessage()) {
             for (FeedbackMessage message : getCurrentMessages()) {
-                if (anyErrorMessage()) {
+                if (message.isError()) {
                     notification.error(target, message.getMessage());
-                } else {
+                } else if (message.isSuccess() || message.isInfo()) {
                     notification.success(target, message.getMessage());
+                } else {
+                    notification.warn(target, message.getMessage());
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index 48bd345..1755341 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -22,6 +22,7 @@ import com.googlecode.wicket.jquery.core.panel.LabelPanel;
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AnyObjectRestClient;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
@@ -160,7 +161,7 @@ public abstract class Realm extends Panel {
                         pageReference).setRealm(realmTO.getFullPath()).
                         addNewItemPanelBuilder(new UserWizardBuilder(
                                 BaseModal.CONTENT_ID, userTO, anyTypeTO.getClasses(), pageRef)).
-                        //addNotificationPanel(BasePage.class.cast(this.pageRef.getPage()).getPopupComponent()).
+                        addNotificationPanel(BasePage.class.cast(this.pageRef.getPage()).getNotificationPanel()).
                         build(id);
                 MetaDataRoleAuthorizationStrategy.authorize(panel, WebPage.RENDER, StandardEntitlement.USER_LIST);
                 break;
@@ -174,7 +175,7 @@ public abstract class Realm extends Panel {
                         pageReference).setRealm(realmTO.getFullPath()).
                         addNewItemPanelBuilder(new GroupWizardBuilder(
                                 BaseModal.CONTENT_ID, groupTO, anyTypeTO.getClasses(), pageRef)).
-                        //addNotificationPanel(BasePage.class.cast(this.pageRef.getPage()).getFeedbackPanel).
+                        addNotificationPanel(BasePage.class.cast(this.pageRef.getPage()).getNotificationPanel()).
                         build(id);
                 // list of group is available to all authenticated users
                 break;
@@ -189,7 +190,7 @@ public abstract class Realm extends Panel {
                         pageReference).setRealm(realmTO.getFullPath()).
                         addNewItemPanelBuilder(new AnyWizardBuilder<AnyObjectTO>(
                                 BaseModal.CONTENT_ID, anyObjectTO, anyTypeTO.getClasses(), pageRef)).
-                        //addNotificationPanel(BasePage.class.cast(this.pageRef.getPage()).getPopupComponent()).
+                        addNotificationPanel(BasePage.class.cast(this.pageRef.getPage()).getNotificationPanel()).
                         build(id);
                 MetaDataRoleAuthorizationStrategy.authorize(panel, WebPage.RENDER,
                         String.format("%s_%s", anyObjectTO.getType(), AnyEntitlement.LIST));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
index b7692fb..4912dfd 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.panels;
 
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.RealmRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.to.RealmTO;
@@ -28,20 +29,18 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.markup.html.form.Form;
 
-public class RealmModalPanel extends AbstractModalPanel {
+public class RealmModalPanel extends AbstractModalPanel<RealmTO> {
 
     private static final long serialVersionUID = -4285220460543213901L;
 
     private final RealmRestClient realmRestClient = new RealmRestClient();
 
-    private RealmTO realmTO;
-
     private boolean newRealm = false;
 
     private final String parentPath;
 
     public RealmModalPanel(
-            final BaseModal<?> modal,
+            final BaseModal<RealmTO> modal,
             final PageReference pageRef,
             final RealmTO realmTO,
             final String parentPath,
@@ -51,7 +50,7 @@ public class RealmModalPanel extends AbstractModalPanel {
     }
 
     public RealmModalPanel(
-            final BaseModal<?> modal,
+            final BaseModal<RealmTO> modal,
             final PageReference pageRef,
             final RealmTO realmTO,
             final String parentPath,
@@ -61,7 +60,6 @@ public class RealmModalPanel extends AbstractModalPanel {
         super(modal, pageRef);
 
         this.newRealm = newRealm;
-        this.realmTO = realmTO;
         this.parentPath = parentPath;
 
         final RealmDetails realmDetail = new RealmDetails("details", realmTO);
@@ -81,13 +79,13 @@ public class RealmModalPanel extends AbstractModalPanel {
             } else {
                 realmRestClient.update(updatedRealmTO);
             }
-            
+
             info(getString(Constants.OPERATION_SUCCEEDED));
             closeAction(target, form);
         } catch (Exception e) {
             LOG.error("While creating or updating realm", e);
             error(getString(Constants.ERROR) + ": " + e.getMessage());
-            modal.getNotificationPanel().refresh(target);
         }
+        BasePage.class.cast(pageRef.getPage()).getNotificationPanel().refresh(target);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeDetailsPanel.java
index e1fd9fc..ef53d05 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeDetailsPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.RelationshipTypeTO;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -31,32 +30,27 @@ public class RelationshipTypeDetailsPanel extends Panel {
 
     private static final long serialVersionUID = -4962850669086306255L;
 
-    private final RelationshipTypeTO relationshipTypeTO;
-
     public RelationshipTypeDetailsPanel(
             final String id,
-            final BaseModal<RelationshipTypeTO> modal) {
+            final RelationshipTypeTO relationshipTypeTO) {
         super(id);
 
-        this.relationshipTypeTO = modal.getFormModel();
-
         final WebMarkupContainer container = new WebMarkupContainer("container");
         container.setOutputMarkupId(true);
         add(container);
 
         final Form<RelationshipTypeTO> form = new Form<>("form");
-        form.setModel(new CompoundPropertyModel<>(this.relationshipTypeTO));
+        form.setModel(new CompoundPropertyModel<>(relationshipTypeTO));
         container.add(form);
 
-        final AjaxTextFieldPanel key =
-                new AjaxTextFieldPanel("key", getString("key"), new PropertyModel<String>(relationshipTypeTO, "key"));
+        final AjaxTextFieldPanel key = new AjaxTextFieldPanel("key", getString("key"), new PropertyModel<String>(
+                relationshipTypeTO, "key"));
         key.addRequiredLabel();
         key.setEnabled(key.getModelObject() == null || key.getModelObject().isEmpty());
         form.add(key);
 
-        final AjaxTextFieldPanel description =
-                new AjaxTextFieldPanel("description", 
-                        getString("description"), new PropertyModel<String>(relationshipTypeTO, "description"));
+        final AjaxTextFieldPanel description = new AjaxTextFieldPanel("description",
+                getString("description"), new PropertyModel<String>(relationshipTypeTO, "description"));
         description.addRequiredLabel();
         form.add(description);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeModalPanel.java
index dd11959..4cbfa5a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypeModalPanel.java
@@ -18,47 +18,27 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.to.RelationshipTypeTO;
-import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.markup.html.form.Form;
 
-public class RelationshipTypeModalPanel extends AbstractModalPanel {
+public class RelationshipTypeModalPanel extends AbstractModalPanel<RelationshipTypeTO> {
 
     private static final long serialVersionUID = 1602285111803121341L;
 
-    private final boolean createFlag;
+    private final RelationshipTypeTO relationshipTypeTO;
 
     public RelationshipTypeModalPanel(
             final BaseModal<RelationshipTypeTO> modal,
-            final PageReference pageRef, final boolean createFlag) {
+            final RelationshipTypeTO relationshipTypeTO,
+            final PageReference pageRef) {
         super(modal, pageRef);
-
-        this.createFlag = createFlag;
-        add(new RelationshipTypeDetailsPanel("relationshipTypeDetails", modal));
+        this.relationshipTypeTO = relationshipTypeTO;
+        add(new RelationshipTypeDetailsPanel("relationshipTypeDetails", this.relationshipTypeTO));
     }
 
     @Override
-    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-        try {
-            final RelationshipTypeTO updateRelationshipTypeTO = RelationshipTypeTO.class.cast(form.getModelObject());
-
-            if (createFlag) {
-                SyncopeConsoleSession.get().getService(RelationshipTypeService.class).create(updateRelationshipTypeTO);
-            } else {
-                SyncopeConsoleSession.get().getService(RelationshipTypeService.class).update(updateRelationshipTypeTO);
-            }
-
-            info(getString(Constants.OPERATION_SUCCEEDED));
-            modal.close(target);
-        } catch (Exception e) {
-            LOG.error("While creating or updating RelationshipTypeTO", e);
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
-            modal.getNotificationPanel().refresh(target);
-        }
+    public RelationshipTypeTO getItem() {
+        return this.relationshipTypeTO;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypePanel.java
index 2467a4a..f4c64e4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypePanel.java
@@ -18,69 +18,137 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import static org.apache.syncope.client.console.panels.AbstractModalPanel.LOG;
+
 import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 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.SearchableDataProvider;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.RelationshipTypePanel.RelationshipTypeProvider;
+import org.apache.syncope.client.console.rest.BaseRestClient;
 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.ActionLinksPanel;
+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.RelationshipTypeTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
 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.event.Broadcast;
 import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
 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.extensions.markup.html.repeater.util.SortableDataProvider;
-import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.repeater.Item;
 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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO> {
+public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO, RelationshipTypeProvider> {
 
     private static final long serialVersionUID = -3731778000138547357L;
 
-    private static final Logger LOG = LoggerFactory.getLogger(RelationshipTypePanel.class);
+    private final String pageID = "RelationshipTypes";
 
-    private static final String PAGINATOR_ROWS_KEYS = Constants.PREF_RELATIONSHIPTYPE_PAGINATOR_ROWS;
+    public RelationshipTypePanel(
+            final String id, final Builder<RelationshipTypeTO, RelationshipTypeTO, BaseRestClient> builder) {
+        super(id, builder);
+    }
 
-    private final BaseModal<RelationshipTypeTO> modal;
+    public RelationshipTypePanel(final String id, final PageReference pageRef) {
+        super(id, new Builder<RelationshipTypeTO, RelationshipTypeTO, BaseRestClient>(null, pageRef) {
 
-    public RelationshipTypePanel(
-            final String panelId,
-            final PageReference pageReference,
-            final BaseModal<RelationshipTypeTO> modal) {
-        super(panelId, pageReference);
+            private static final long serialVersionUID = 8769126634538601689L;
+
+            @Override
+            protected WizardMgtPanel<RelationshipTypeTO> newInstance(final String id) {
+                return new RelationshipTypePanel(id, this);
+            }
+        });
+
+        this.addNewItemPanelBuilder(new AbstractModalPanelBuilder<RelationshipTypeTO>(
+                BaseModal.CONTENT_ID, new RelationshipTypeTO(), pageRef) {
+
+            private static final long serialVersionUID = -6388405037134399367L;
+
+            @Override
+            public ModalPanel<RelationshipTypeTO> build(final int index, final boolean edit) {
+                final RelationshipTypeTO modelObject = newModelObject();
+                return new RelationshipTypeModalPanel(modal, modelObject, pageRef) {
+
+                    private static final long serialVersionUID = -6227956682141146094L;
+
+                    @Override
+                    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                        try {
+                            if (getOriginalItem() == null || StringUtils.isBlank(getOriginalItem().getKey())) {
+                                SyncopeConsoleSession.get().
+                                        getService(RelationshipTypeService.class).create(modelObject);
+                            } else {
+                                SyncopeConsoleSession.get().
+                                        getService(RelationshipTypeService.class).update(modelObject);
+                            }
+
+                            info(getString(Constants.OPERATION_SUCCEEDED));
+                            modal.close(target);
+                        } catch (Exception e) {
+                            LOG.error("While creating or updating RelationshipTypeTO", e);
+                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+                            modal.getNotificationPanel().refresh(target);
+                        }
+                    }
+                };
+            }
+
+            @Override
+            protected void onCancelInternal(final RelationshipTypeTO modelObject) {
+            }
 
-        this.pageRows = prefMan.getPaginatorRows(getRequest(), PAGINATOR_ROWS_KEYS);
-        this.modal = modal;
+            @Override
+            protected void onApplyInternal(final RelationshipTypeTO modelObject) {
+            }
+        }, true);
 
-        final WebMarkupContainer container = new WebMarkupContainer("container");
-        container.setOutputMarkupId(true);
-        add(container);
+        initResultTable();
+        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.RELATIONSHIPTYPE_CREATE);
+    }
+
+    @Override
+    protected RelationshipTypeProvider dataProvider() {
+        return new RelationshipTypeProvider(rows);
+    }
+
+    @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_RELATIONSHIPTYPE_PAGINATOR_ROWS;
+    }
+
+    @Override
+    protected Collection<ActionLink.ActionType> getBulkActions() {
+        return Collections.<ActionLink.ActionType>emptyList();
+    }
 
-        buildDataTable(container, getColumns(container, pageReference),
-                new RelationshipTypePanel.RelationshipTypeProvider(), PAGINATOR_ROWS_KEYS);
+    @Override
+    protected String getPageId() {
+        return pageID;
     }
 
-    private List<IColumn<RelationshipTypeTO, String>> getColumns(
-            final WebMarkupContainer webContainer, final PageReference pageReference) {
+    @Override
+    protected List<IColumn<RelationshipTypeTO, String>> getColumns() {
 
         final List<IColumn<RelationshipTypeTO, String>> columns = new ArrayList<>();
 
@@ -89,9 +157,8 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
             if (field != null && !Modifier.isStatic(field.getModifiers())) {
                 final String fieldName = field.getName();
 
-                final IColumn<RelationshipTypeTO, String> column =
-                        new PropertyColumn<RelationshipTypeTO, String>(
-                                new ResourceModel(field.getName()), field.getName(), field.getName()) {
+                final IColumn<RelationshipTypeTO, String> column = new PropertyColumn<RelationshipTypeTO, String>(
+                        new ResourceModel(field.getName()), field.getName(), field.getName()) {
 
                     private static final long serialVersionUID = 3282547854226892169L;
 
@@ -126,7 +193,8 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
 
                 final RelationshipTypeTO relationshipTypeTO = model.getObject();
 
-                final ActionLinksPanel.Builder<Serializable> actionLinks = ActionLinksPanel.builder(pageReference);
+                final ActionLinksPanel.Builder<Serializable> actionLinks
+                        = ActionLinksPanel.builder(page.getPageReference());
                 actionLinks.setDisableIndicator(true);
                 actionLinks.addWithRoles(new ActionLink<Serializable>() {
 
@@ -134,11 +202,8 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
-                        modal.header(Model.of(relationshipTypeTO.getKey()));
-                        modal.setFormModel(relationshipTypeTO);
-                        target.add(modal.setContent(new RelationshipTypeModalPanel(modal, pageReference, false)));
-                        modal.addSumbitButton();
-                        modal.show(true);
+                        send(RelationshipTypePanel.this, Broadcast.EXACT,
+                                new AjaxWizard.EditItemActionEvent<RelationshipTypeTO>(model.getObject(), target));
                     }
                 }, ActionLink.ActionType.EDIT, StandardEntitlement.RELATIONSHIPTYPE_UPDATE).addWithRoles(
                         new ActionLink<Serializable>() {
@@ -151,7 +216,7 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
                             SyncopeConsoleSession.get().getService(
                                     RelationshipTypeService.class).delete(relationshipTypeTO.getKey());
                             info(getString(Constants.OPERATION_SUCCEEDED));
-                            target.add(webContainer);
+                            target.add(container);
                         } catch (Exception e) {
                             LOG.error("While deleting RelationshipType", e);
                             error(getString(Constants.ERROR) + ": " + e.getMessage());
@@ -168,22 +233,21 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
 
     }
 
-    private final class RelationshipTypeProvider extends SortableDataProvider<RelationshipTypeTO, String> {
+    protected final class RelationshipTypeProvider extends SearchableDataProvider<RelationshipTypeTO> {
 
         private static final long serialVersionUID = -185944053385660794L;
 
         private final SortableDataProviderComparator<RelationshipTypeTO> comparator;
 
-        private RelationshipTypeProvider() {
-            super();
-            setSort("key", SortOrder.ASCENDING);
+        private RelationshipTypeProvider(final int paginatorRows) {
+            super(paginatorRows);
             comparator = new SortableDataProviderComparator<>(this);
         }
 
         @Override
         public Iterator<RelationshipTypeTO> iterator(final long first, final long count) {
-            final List<RelationshipTypeTO> list =
-                    SyncopeConsoleSession.get().getService(RelationshipTypeService.class).list();
+            final List<RelationshipTypeTO> list = SyncopeConsoleSession.get().getService(RelationshipTypeService.class).
+                    list();
             Collections.sort(list, comparator);
             return list.subList((int) first, (int) first + (int) count).iterator();
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
index 3864322..f649ee0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
@@ -48,8 +48,10 @@ import org.apache.wicket.model.ResourceModel;
 
 /**
  * Modal window with Resource form.
+ *
+ * @param <T>
  */
-public class ResourceModal extends AbstractResourceModal {
+public class ResourceModal<T extends Serializable> extends AbstractResourceModal<T> {
 
     private static final long serialVersionUID = 1734415311027284221L;
 
@@ -60,7 +62,7 @@ public class ResourceModal extends AbstractResourceModal {
     private final boolean createFlag;
 
     public ResourceModal(
-            final BaseModal<Serializable> modal,
+            final BaseModal<T> modal,
             final PageReference pageRef,
             final IModel<ResourceTO> model,
             final boolean createFlag) {
@@ -91,37 +93,39 @@ public class ResourceModal extends AbstractResourceModal {
         builder.setItems(model.getObject().getProvisions());
         builder.includes("anyType", "objectClass");
 
-        builder.addAction(new ActionLink<ProvisionTO>() {
+        builder.
+                addAction(new ActionLink<ProvisionTO>() {
 
-            private static final long serialVersionUID = -3722207913631435504L;
+                    private static final long serialVersionUID = -3722207913631435504L;
 
-            @Override
-            public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
-                send(pageRef.getPage(), Broadcast.DEPTH,
-                        new AjaxWizard.NewItemActionEvent<>(provisionTO, 2, target));
-            }
-        }, ActionLink.ActionType.MAPPING, StandardEntitlement.RESOURCE_UPDATE).addAction(new ActionLink<ProvisionTO>() {
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+                        send(pageRef.getPage(), Broadcast.DEPTH,
+                                new AjaxWizard.NewItemActionEvent<>(provisionTO, 2, target));
+                    }
+                }, ActionLink.ActionType.MAPPING, StandardEntitlement.RESOURCE_UPDATE).
+                addAction(new ActionLink<ProvisionTO>() {
 
-            private static final long serialVersionUID = -3722207913631435514L;
+                    private static final long serialVersionUID = -3722207913631435514L;
 
-            @Override
-            public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
-                send(pageRef.getPage(), Broadcast.DEPTH,
-                        new AjaxWizard.NewItemActionEvent<>(provisionTO, 3, target));
-            }
-        }, ActionLink.ActionType.ACCOUNT_LINK, StandardEntitlement.RESOURCE_UPDATE).addAction(
-                new ActionLink<ProvisionTO>() {
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+                        send(pageRef.getPage(), Broadcast.DEPTH,
+                                new AjaxWizard.NewItemActionEvent<>(provisionTO, 3, target));
+                    }
+                }, ActionLink.ActionType.ACCOUNT_LINK, StandardEntitlement.RESOURCE_UPDATE).
+                addAction(new ActionLink<ProvisionTO>() {
 
-            private static final long serialVersionUID = -3722207913631435524L;
+                    private static final long serialVersionUID = -3722207913631435524L;
 
-            @Override
-            public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
-                provisionTO.setSyncToken(null);
-                send(pageRef.getPage(), Broadcast.DEPTH,
-                        new AjaxWizard.NewItemFinishEvent<>(provisionTO, target));
-            }
-        }, ActionLink.ActionType.RESET_TIME, StandardEntitlement.RESOURCE_UPDATE).addAction(
-                        new ActionLink<ProvisionTO>() {
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+                        provisionTO.setSyncToken(null);
+                        send(pageRef.getPage(), Broadcast.DEPTH,
+                                new AjaxWizard.NewItemFinishEvent<>(provisionTO, target));
+                    }
+                }, ActionLink.ActionType.RESET_TIME, StandardEntitlement.RESOURCE_UPDATE).
+                addAction(new ActionLink<ProvisionTO>() {
 
                     private static final long serialVersionUID = -3722207913631435534L;
 
@@ -130,8 +134,8 @@ public class ResourceModal extends AbstractResourceModal {
                         send(pageRef.getPage(), Broadcast.DEPTH,
                                 new AjaxWizard.NewItemActionEvent<>(SerializationUtils.clone(provisionTO), target));
                     }
-                }, ActionLink.ActionType.CLONE, StandardEntitlement.RESOURCE_CREATE).addAction(
-                        new ActionLink<ProvisionTO>() {
+                }, ActionLink.ActionType.CLONE, StandardEntitlement.RESOURCE_CREATE).
+                addAction(new ActionLink<ProvisionTO>() {
 
                     private static final long serialVersionUID = -3722207913631435544L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
index c84ff3c..6e2492c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
@@ -39,6 +39,7 @@ import org.apache.syncope.common.lib.to.RoleTO;
 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.event.Broadcast;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
@@ -54,8 +55,11 @@ public class RoleSearchResultPanel
 
     protected RoleSearchResultPanel(final String id, final Builder builder) {
         super(id, builder);
+
         modal.size(Modal.Size.Large);
         initResultTable();
+
+        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.ROLE_CREATE);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaModalPanel.java
index f822471..bb30f7b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaModalPanel.java
@@ -32,7 +32,7 @@ import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
 
-public class SchemaModalPanel extends AbstractModalPanel {
+public class SchemaModalPanel extends AbstractModalPanel<AbstractSchemaTO> {
 
     private static final long serialVersionUID = -4681998932778822125L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
index 03899e9..48cdd9d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import static org.apache.wicket.Component.ENABLE;
+
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.Collapsible;
 import java.io.Serializable;
 import java.lang.reflect.Field;
@@ -41,12 +43,15 @@ 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.SelectChoiceRenderer;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
 import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
 import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
@@ -74,8 +79,7 @@ public class SchemasPanel extends Panel {
 
     private static final long serialVersionUID = -1140213992451232279L;
 
-    private static final Map<SchemaType, String> PAGINATOR_ROWS_KEYS =
-            new HashMap<SchemaType, String>() {
+    private static final Map<SchemaType, String> PAGINATOR_ROWS_KEYS = new HashMap<SchemaType, String>() {
 
         private static final long serialVersionUID = 3109256773218160485L;
 
@@ -106,15 +110,32 @@ public class SchemasPanel extends Panel {
 
     private final BaseModal<AbstractSchemaTO> modal;
 
-    public SchemasPanel(final String id, final PageReference pageReference, final BaseModal<AbstractSchemaTO> modal) {
+    public SchemasPanel(final String id, final PageReference pageRef, final BaseModal<AbstractSchemaTO> modal) {
         super(id);
 
-        this.pageReference = pageReference;
+        this.pageReference = pageRef;
         this.modal = modal;
 
         final Collapsible collapsible = new Collapsible("collapsePanel", buildTabList());
         collapsible.setOutputMarkupId(true);
         add(collapsible);
+
+        final IndicatingAjaxLink<Void> schemaLink = new IndicatingAjaxLink<Void>("createSchema") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                modal.header(new ResourceModel("createSchema"));
+                modal.setFormModel(new PlainSchemaTO());
+                target.add(modal.setContent(new SchemaModalPanel(modal, pageRef, true)));
+                modal.addSumbitButton();
+                modal.show(true);
+            }
+        };
+
+        add(schemaLink);
+        MetaDataRoleAuthorizationStrategy.authorize(schemaLink, ENABLE, StandardEntitlement.SCHEMA_CREATE);
     }
 
     private List<ITab> buildTabList() {
@@ -171,8 +192,8 @@ public class SchemasPanel extends Panel {
                         }
                     });
                 } else {
-                    final IColumn<AbstractSchemaTO, String> column =
-                            new PropertyColumn<AbstractSchemaTO, String>(new ResourceModel(field), field, field) {
+                    final IColumn<AbstractSchemaTO, String> column = new PropertyColumn<AbstractSchemaTO, String>(
+                            new ResourceModel(field), field, field) {
 
                         private static final long serialVersionUID = 3282547854226892169L;
 
@@ -291,9 +312,8 @@ public class SchemasPanel extends Panel {
             final List<IColumn<AbstractSchemaTO, String>> tableCols = getColumns(schemaContainer,
                     schemaType, COL_NAMES.get(schemaType));
 
-            final AjaxFallbackDataTable<AbstractSchemaTO, String> table =
-                    new AjaxFallbackDataTable<>("datatable",
-                            tableCols, new SchemaProvider(schemaType), pageRows, schemaContainer);
+            final AjaxFallbackDataTable<AbstractSchemaTO, String> table = new AjaxFallbackDataTable<>("datatable",
+                    tableCols, new SchemaProvider(schemaType), pageRows, schemaContainer);
             table.setOutputMarkupId(true);
             schemaContainer.add(table);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionDetailsPanel.java
index b6ab809..d7a70a1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionDetailsPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.SecurityQuestionTO;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -31,9 +30,7 @@ public class SecurityQuestionDetailsPanel extends Panel {
 
     private static final long serialVersionUID = 6278708606604582875L;
 
-    public SecurityQuestionDetailsPanel(
-            final String id,
-            final BaseModal<SecurityQuestionTO> modal) {
+    public SecurityQuestionDetailsPanel(final String id, final SecurityQuestionTO securityQuestionTO) {
         super(id);
 
         final WebMarkupContainer container = new WebMarkupContainer("container");
@@ -43,7 +40,6 @@ public class SecurityQuestionDetailsPanel extends Panel {
 
         final Form<SecurityQuestionTO> form = new Form<>("form");
 
-        final SecurityQuestionTO securityQuestionTO = modal.getFormModel();
         form.setModel(new CompoundPropertyModel<>(securityQuestionTO));
         container.add(form);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionModalPanel.java
index e3d083c..671a494 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionModalPanel.java
@@ -27,27 +27,30 @@ import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.form.Form;
 
-public class SecurityQuestionModalPanel extends AbstractModalPanel {
+public class SecurityQuestionModalPanel extends AbstractModalPanel<SecurityQuestionTO> {
 
     private static final long serialVersionUID = 4024126489500665435L;
 
-    private final boolean createFlag;
+    private final SecurityQuestionTO securityQuestionTO;
 
     public SecurityQuestionModalPanel(
             final BaseModal<SecurityQuestionTO> modal,
-            final PageReference pageRef,
-            final boolean createFlag) {
+            final SecurityQuestionTO securityQuestionTO,
+            final PageReference pageRef) {
         super(modal, pageRef);
-        this.createFlag = createFlag;
-        add(new SecurityQuestionDetailsPanel("securityQuestionDetailsPanel", modal));
+        this.securityQuestionTO = securityQuestionTO;
+        add(new SecurityQuestionDetailsPanel("securityQuestionDetailsPanel", getItem()));
+    }
+
+    @Override
+    public final SecurityQuestionTO getItem() {
+        return this.securityQuestionTO;
     }
 
     @Override
     public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
         try {
-            final SecurityQuestionTO securityQuestionTO = SecurityQuestionTO.class.cast(form.getModelObject());
-
-            if (createFlag) {
+            if (securityQuestionTO.getKey() == 0) {
                 SyncopeConsoleSession.get().getService(SecurityQuestionService.class).create(securityQuestionTO);
             } else {
                 SyncopeConsoleSession.get().getService(SecurityQuestionService.class).update(securityQuestionTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
index 45e80fe..bc83d03 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
@@ -18,70 +18,120 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import static org.apache.wicket.Component.ENABLE;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 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.SearchableDataProvider;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.pages.AbstractBasePage;
+import org.apache.syncope.client.console.panels.SecurityQuestionsPanel.SecurityQuestionsProvider;
+import org.apache.syncope.client.console.rest.BaseRestClient;
 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.ActionLinksPanel;
+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.SecurityQuestionTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
 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.event.Broadcast;
 import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
 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.extensions.markup.html.repeater.util.SortableDataProvider;
-import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.repeater.Item;
 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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class SecurityQuestionsPanel extends AbstractTypesPanel<SecurityQuestionTO> {
+public class SecurityQuestionsPanel extends AbstractSearchResultPanel<
+        SecurityQuestionTO, SecurityQuestionTO, SecurityQuestionsProvider, BaseRestClient> {
 
     private static final long serialVersionUID = 3323019773236588850L;
 
-    private static final Logger LOG = LoggerFactory.getLogger(SecurityQuestionsPanel.class);
+    private final String pageID = "SecurityQuestions";
+
+    public SecurityQuestionsPanel(final String id, final PageReference pageRef) {
+        super(id, new Builder<SecurityQuestionTO, SecurityQuestionTO, BaseRestClient>(null, pageRef) {
+
+            private static final long serialVersionUID = 8769126634538601689L;
+
+            @Override
+            protected WizardMgtPanel<SecurityQuestionTO> newInstance(final String id) {
+                return new SecurityQuestionsPanel(id, this);
+            }
+        });
+
+        this.addNewItemPanelBuilder(new AbstractModalPanelBuilder<SecurityQuestionTO>(
+                BaseModal.CONTENT_ID, new SecurityQuestionTO(), pageRef) {
+
+            private static final long serialVersionUID = -6388405037134399367L;
+
+            @Override
+            public ModalPanel<SecurityQuestionTO> build(final int index, final boolean edit) {
+                final SecurityQuestionTO modelObject = newModelObject();
+                return new SecurityQuestionModalPanel(modal, modelObject, pageRef);
+            }
+
+            @Override
+            protected void onCancelInternal(final SecurityQuestionTO modelObject) {
+            }
+
+            @Override
+            protected void onApplyInternal(final SecurityQuestionTO modelObject) {
+            }
+        }, true);
 
-    private static final String PAGINATOR_ROWS_KEYS = Constants.PREF_SECURITY_QUESTIONS_PAGINATOR_ROWS;
+        setFooterVisibility(true);
+        modal.addSumbitButton();
+        modal.size(Modal.Size.Large);
+        initResultTable();
 
-    private final BaseModal<SecurityQuestionTO> modal;
+        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.SECURITY_QUESTION_CREATE);
+    }
 
     public SecurityQuestionsPanel(
-            final String id, final PageReference pageReference, final BaseModal<SecurityQuestionTO> modal) {
-        super(id, pageReference);
-        this.pageRows = prefMan.getPaginatorRows(getRequest(), PAGINATOR_ROWS_KEYS);
-        this.modal = modal;
+            final String id, final Builder<SecurityQuestionTO, SecurityQuestionTO, BaseRestClient> builder) {
+        super(id, builder);
+    }
+
+    @Override
+    protected SecurityQuestionsProvider dataProvider() {
+        return new SecurityQuestionsProvider(rows);
+    }
 
-        final WebMarkupContainer container = new WebMarkupContainer("container");
-        container.setOutputMarkupId(true);
-        add(container);
+    @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_SECURITY_QUESTIONS_PAGINATOR_ROWS;
+    }
 
-        buildDataTable(container,
-                getColumns(container, pageReference),
-                new SecurityQuestionsPanel.SecurityQuestionsProvider(),
-                PAGINATOR_ROWS_KEYS);
+    @Override
+    protected Collection<ActionLink.ActionType> getBulkActions() {
+        return Collections.<ActionLink.ActionType>emptyList();
+    }
 
+    @Override
+    protected String getPageId() {
+        return pageID;
     }
 
-    private List<IColumn<SecurityQuestionTO, String>> getColumns(
-            final WebMarkupContainer webContainer, final PageReference pageReference) {
+    @Override
+    protected List<IColumn<SecurityQuestionTO, String>> getColumns() {
 
         final List<IColumn<SecurityQuestionTO, String>> columns = new ArrayList<>();
 
@@ -145,7 +195,8 @@ public class SecurityQuestionsPanel extends AbstractTypesPanel<SecurityQuestionT
 
                 final SecurityQuestionTO securityQuestionTO = model.getObject();
 
-                final ActionLinksPanel.Builder<Serializable> actionLinks = ActionLinksPanel.builder(pageReference);
+                final ActionLinksPanel.Builder<Serializable> actionLinks
+                        = ActionLinksPanel.builder(page.getPageReference());
                 actionLinks.setDisableIndicator(true);
                 actionLinks
                         .addWithRoles(new ActionLink<Serializable>() {
@@ -154,12 +205,9 @@ public class SecurityQuestionsPanel extends AbstractTypesPanel<SecurityQuestionT
 
                             @Override
                             public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
-                                modal.header(Model.of(String.valueOf(securityQuestionTO.getKey())));
-                                modal.setFormModel(securityQuestionTO);
-                                target.add(modal.setContent(
-                                        new SecurityQuestionModalPanel(modal, pageReference, false)));
-                                modal.addSumbitButton();
-                                modal.show(true);
+                                send(SecurityQuestionsPanel.this, Broadcast.EXACT,
+                                        new AjaxWizard.EditItemActionEvent<SecurityQuestionTO>(
+                                                model.getObject(), target));
                             }
                         }, ActionLink.ActionType.EDIT, StandardEntitlement.SECURITY_QUESTION_UPDATE)
                         .addWithRoles(new ActionLink<Serializable>() {
@@ -172,7 +220,7 @@ public class SecurityQuestionsPanel extends AbstractTypesPanel<SecurityQuestionT
                                     SyncopeConsoleSession.get().getService(SecurityQuestionService.class
                                     ).delete(securityQuestionTO.getKey());
                                     info(getString(Constants.OPERATION_SUCCEEDED));
-                                    target.add(webContainer);
+                                    target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting SecutiryQuestionTO", e);
                                     error(getString(Constants.ERROR) + ": " + e.getMessage());
@@ -190,15 +238,14 @@ public class SecurityQuestionsPanel extends AbstractTypesPanel<SecurityQuestionT
 
     }
 
-    private final class SecurityQuestionsProvider extends SortableDataProvider<SecurityQuestionTO, String> {
+    protected final class SecurityQuestionsProvider extends SearchableDataProvider<SecurityQuestionTO> {
 
         private static final long serialVersionUID = -185944053385660794L;
 
         private final SortableDataProviderComparator<SecurityQuestionTO> comparator;
 
-        private SecurityQuestionsProvider() {
-            super();
-            setSort("key", SortOrder.ASCENDING);
+        private SecurityQuestionsProvider(final int paginatorRows) {
+            super(paginatorRows);
             comparator = new SortableDataProviderComparator<>(this);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
index 6f5a985..c7501c6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.panels;
 
 import java.io.Serializable;
 import java.lang.reflect.Field;
-import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -126,15 +125,16 @@ public class UserSearchResultPanel extends AnyObjectSearchResultPanel<UserTO> {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
-                        final IModel<AnyHandler<UserTO>> formModel =
-                                new CompoundPropertyModel<>(new AnyHandler<UserTO>(model.getObject()));
+                        final IModel<AnyHandler<UserTO>> formModel
+                                = new CompoundPropertyModel<>(new AnyHandler<UserTO>(model.getObject()));
                         modal.setFormModel(formModel);
 
                         target.add(modal.setContent(new StatusModal<>(
                                 modal, page.getPageReference(), formModel.getObject().getInnerObject())));
 
-                        modal.header(new Model<>(MessageFormat.format(
-                                getString("any.edit"), model.getObject().getKey())));
+                        modal.header(new Model<>(
+                                getString("any.edit", new Model<>(new AnyHandler<UserTO>(model.getObject())))));
+
                         modal.show(true);
                     }
                 }, ActionLink.ActionType.MANAGE_RESOURCES, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() {
@@ -143,15 +143,16 @@ public class UserSearchResultPanel extends AnyObjectSearchResultPanel<UserTO> {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
-                        final IModel<AnyHandler<UserTO>> formModel =
-                                new CompoundPropertyModel<>(new AnyHandler<UserTO>(model.getObject()));
+                        final IModel<AnyHandler<UserTO>> formModel
+                                = new CompoundPropertyModel<>(new AnyHandler<UserTO>(model.getObject()));
                         modal.setFormModel(formModel);
 
                         target.add(modal.setContent(new StatusModal<>(
                                 modal, page.getPageReference(), formModel.getObject().getInnerObject(), true)));
 
-                        modal.header(new Model<>(MessageFormat.format(
-                                getString("any.edit"), model.getObject().getKey())));
+                        modal.header(new Model<>(
+                                getString("any.edit", new Model<>(new AnyHandler<UserTO>(model.getObject())))));
+
                         modal.show(true);
                     }
                 }, ActionLink.ActionType.ENABLE, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() {
@@ -209,7 +210,7 @@ public class UserSearchResultPanel extends AnyObjectSearchResultPanel<UserTO> {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
-                        target.add(modal.setContent(new UserDisplayAttributesModalPage(
+                        target.add(modal.setContent(new UserDisplayAttributesModalPage<>(
                                 modal, page.getPageReference(), schemaNames, dSchemaNames)));
 
                         modal.header(new ResourceModel("any.attr.display", ""));

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
index 17ee0ce..2478b61 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
@@ -24,7 +24,6 @@ import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.console.panels.NotificationPanel;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.rest.SchemaRestClient;
@@ -64,8 +63,6 @@ public abstract class AbstractSearchPanel extends Panel {
 
     protected IModel<List<Pair<Long, String>>> groupNames;
 
-    protected NotificationPanel searchFeedback;
-
     protected IModel<List<SearchClause>> model;
 
     protected WebMarkupContainer searchFormContainer;
@@ -127,28 +124,6 @@ public abstract class AbstractSearchPanel extends Panel {
         searchFormContainer.setOutputMarkupId(true);
         add(searchFormContainer);
 
-//        searchFeedback = new NotificationPanel("searchFeedback", new IFeedbackMessageFilter() {
-//
-//            private static final long serialVersionUID = 6895024863321391672L;
-//
-//            @Override
-//            public boolean accept(final FeedbackMessage message) {
-//                boolean result;
-//
-//                // messages reported on the session have a null reporter
-//                if (message.getReporter() == null) {
-//                    result = false;
-//                } else {
-//                    // only accept messages coming from the children of the search form container
-//                    result = searchFormContainer.contains(message.getReporter(), true);
-//                }
-//
-//                return result;
-//            }
-//        });
-//        searchFeedback.setOutputMarkupId(true);
-//        add(searchFeedback);
-
         final SearchClausePanel searchClausePanel = new SearchClausePanel("panel", "panel",
                 Model.of(new SearchClause()),
                 required,
@@ -217,10 +192,6 @@ public abstract class AbstractSearchPanel extends Panel {
         };
     }
 
-    public NotificationPanel getSearchFeedback() {
-        return searchFeedback;
-    }
-
     public IModel<List<SearchClause>> getModel() {
         return this.model;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index 6a6733e..e3bc2be 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -43,7 +43,7 @@ public class ResourceRestClient extends BaseRestClient {
         return new ArrayList<>(SyncopeConsoleSession.get().getSyncopeTO().getPropagationActions());
     }
 
-    public static List<ResourceTO> getAll() {
+    public List<ResourceTO> getAll() {
         List<ResourceTO> resources = null;
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index e11e234..1a904a1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -32,6 +32,7 @@ import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.AbstractResourceModal.CreateEvent;
+import org.apache.syncope.client.console.panels.NotificationPanel;
 import org.apache.syncope.client.console.rest.BaseRestClient;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
@@ -92,48 +93,48 @@ public class Topology extends BasePage {
     private final LoadableDetachableModel<Map<String, List<ConnInstanceTO>>> connModel
             = new LoadableDetachableModel<Map<String, List<ConnInstanceTO>>>() {
 
-                private static final long serialVersionUID = 5275935387613157432L;
+        private static final long serialVersionUID = 5275935387613157432L;
 
-                @Override
-                protected Map<String, List<ConnInstanceTO>> load() {
-                    final Map<String, List<ConnInstanceTO>> res = new HashMap<>();
-
-                    for (ConnInstanceTO conn : connectorRestClient.getAllConnectors()) {
-                        final List<ConnInstanceTO> conns;
-                        if (res.containsKey(conn.getLocation())) {
-                            conns = res.get(conn.getLocation());
-                        } else {
-                            conns = new ArrayList<>();
-                            res.put(conn.getLocation(), conns);
-                        }
-                        conns.add(conn);
-                    }
-
-                    return res;
+        @Override
+        protected Map<String, List<ConnInstanceTO>> load() {
+            final Map<String, List<ConnInstanceTO>> res = new HashMap<>();
+
+            for (ConnInstanceTO conn : connectorRestClient.getAllConnectors()) {
+                final List<ConnInstanceTO> conns;
+                if (res.containsKey(conn.getLocation())) {
+                    conns = res.get(conn.getLocation());
+                } else {
+                    conns = new ArrayList<>();
+                    res.put(conn.getLocation(), conns);
                 }
-            };
+                conns.add(conn);
+            }
+
+            return res;
+        }
+    };
 
     private final LoadableDetachableModel<Pair<List<URI>, List<URI>>> csModel
             = new LoadableDetachableModel<Pair<List<URI>, List<URI>>>() {
 
-                private static final long serialVersionUID = 5275935387613157433L;
+        private static final long serialVersionUID = 5275935387613157433L;
 
-                @Override
-                protected Pair<List<URI>, List<URI>> load() {
-                    final List<URI> connectorServers = new ArrayList<>();
-                    final List<URI> filePaths = new ArrayList<>();
-
-                    for (String location : SyncopeConsoleSession.get().getSyncopeTO().getConnIdLocations()) {
-                        if (location.startsWith(CONNECTOR_SERVER_LOCATION_PREFIX)) {
-                            connectorServers.add(URI.create(location));
-                        } else {
-                            filePaths.add(URI.create(location));
-                        }
-                    }
-
-                    return Pair.of(connectorServers, filePaths);
+        @Override
+        protected Pair<List<URI>, List<URI>> load() {
+            final List<URI> connectorServers = new ArrayList<>();
+            final List<URI> filePaths = new ArrayList<>();
+
+            for (String location : SyncopeConsoleSession.get().getSyncopeTO().getConnIdLocations()) {
+                if (location.startsWith(CONNECTOR_SERVER_LOCATION_PREFIX)) {
+                    connectorServers.add(URI.create(location));
+                } else {
+                    filePaths.add(URI.create(location));
                 }
-            };
+            }
+
+            return Pair.of(connectorServers, filePaths);
+        }
+    };
 
     protected enum SupportedOperation {
 
@@ -144,7 +145,15 @@ public class Topology extends BasePage {
     }
 
     public Topology() {
-        modal = new BaseModal<>("resource-modal");
+        modal = new BaseModal<Serializable>("resource-modal") {
+
+            private static final long serialVersionUID = -5912673052161214766L;
+
+            @Override
+            public NotificationPanel getNotificationPanel() {
+                return Topology.this.notificationPanel;
+            }
+        };
         add(modal.size(Modal.Size.Large));
 
         modal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
@@ -154,11 +163,6 @@ public class Topology extends BasePage {
             @Override
             public void onClose(final AjaxRequestTarget target) {
                 modal.show(false);
-
-//                if (isModalResult()) {
-//                    info(getString(Constants.OPERATION_SUCCEEDED));
-//                    notificationPanel.refresh(target);
-//                }
             }
         });
 
@@ -398,37 +402,37 @@ public class Topology extends BasePage {
                 final ListView<TopologyNode> innerListView = new ListView<TopologyNode>("resources",
                         new ArrayList<>(connections.get(connectorId).values())) {
 
-                            private static final long serialVersionUID = 1L;
+                    private static final long serialVersionUID = 1L;
 
-                            private final int size = getModelObject().size() + 1;
+                    private final int size = getModelObject().size() + 1;
 
-                            @Override
-                            protected void populateItem(final ListItem<TopologyNode> item) {
-                                final TopologyNode topologynode = item.getModelObject();
-                                final TopologyNode parent = connectors.get(connectorId);
+                    @Override
+                    protected void populateItem(final ListItem<TopologyNode> item) {
+                        final TopologyNode topologynode = item.getModelObject();
+                        final TopologyNode parent = connectors.get(connectorId);
 
-                                // Set position
-                                int kx = size >= 16 ? 800 : (48 * size);
-                                int ky = size < 4 ? 100 : size < 6 ? 350 : 750;
+                        // Set position
+                        int kx = size >= 16 ? 800 : (48 * size);
+                        int ky = size < 4 ? 100 : size < 6 ? 350 : 750;
 
-                                final double hpos;
-                                if (parent == null || parent.getY() < syncopeTopologyNode.getY()) {
-                                    hpos = Math.PI;
-                                } else {
-                                    hpos = 0.0;
-                                }
+                        final double hpos;
+                        if (parent == null || parent.getY() < syncopeTopologyNode.getY()) {
+                            hpos = Math.PI;
+                        } else {
+                            hpos = 0.0;
+                        }
 
-                                int x = (int) Math.round((parent == null ? origX : parent.getX())
-                                        + kx * Math.cos(hpos + Math.PI * (item.getIndex() + 1) / size));
-                                int y = (int) Math.round((parent == null ? origY : parent.getY())
-                                        + ky * Math.sin(hpos + Math.PI * (item.getIndex() + 1) / size));
+                        int x = (int) Math.round((parent == null ? origX : parent.getX())
+                                + kx * Math.cos(hpos + Math.PI * (item.getIndex() + 1) / size));
+                        int y = (int) Math.round((parent == null ? origY : parent.getY())
+                                + ky * Math.sin(hpos + Math.PI * (item.getIndex() + 1) / size));
 
-                                topologynode.setX(x);
-                                topologynode.setY(y);
+                        topologynode.setX(x);
+                        topologynode.setY(y);
 
-                                item.add(topologyNodePanel("res", topologynode));
-                            }
-                        };
+                        item.add(topologyNodePanel("res", topologynode));
+                    }
+                };
 
                 innerListView.setOutputMarkupId(true);
                 item.add(innerListView);

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
index 3c6f72c..a7bd832 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
@@ -35,12 +35,15 @@ import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.IAjaxIndicatorAware;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.panel.Fragment;
@@ -117,6 +120,21 @@ public class TopologyNodePanel extends Panel implements IAjaxIndicatorAware {
         BasePage.class.cast(pageRef.getPage()).setWindowClosedCallback(modal, null);
     }
 
+    @Override
+    public final MarkupContainer add(final Component... childs) {
+        return super.add(childs);
+    }
+
+    @Override
+    public final Component add(final Behavior... behaviors) {
+        return super.add(behaviors);
+    }
+
+    @Override
+    public final Component setMarkupId(final String markupId) {
+        return super.setMarkupId(markupId);
+    }
+
     private Fragment getSyncopeFragment() {
         return new Fragment("actions", "syncopeActions", this);
     }
@@ -173,7 +191,7 @@ public class TopologyNodePanel extends Panel implements IAjaxIndicatorAware {
                 ((AbstractBasePage) getPage()).getNotificationPanel().refresh(target);
             }
         };
-        
+
         fragment.add(delete);
         delete.add(new ConfirmationModalBehavior());
 
@@ -192,7 +210,7 @@ public class TopologyNodePanel extends Panel implements IAjaxIndicatorAware {
                 final IModel<ResourceTO> model = new CompoundPropertyModel<>(modelObject);
                 modal.setFormModel(model);
 
-                target.add(modal.setContent(new ResourceModal(modal, pageRef, model, true)));
+                target.add(modal.setContent(new ResourceModal<>(modal, pageRef, model, true)));
 
                 modal.header(new Model<>(MessageFormat.format(getString("resource.new"), node.getKey())));
 
@@ -271,7 +289,7 @@ public class TopologyNodePanel extends Panel implements IAjaxIndicatorAware {
                 final IModel<ResourceTO> model = new CompoundPropertyModel<>(modelObject);
                 modal.setFormModel(model);
 
-                target.add(modal.setContent(new ResourceModal(modal, pageRef, model, false)));
+                target.add(modal.setContent(new ResourceModal<>(modal, pageRef, model, false)));
 
                 modal.header(new Model<>(MessageFormat.format(getString("resource.edit"), node.getKey())));
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
index 566991e..ab602b6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
@@ -33,8 +33,10 @@ import org.apache.syncope.client.console.panels.NotificationPanel;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.buttons.DefaultModalCloseButton;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.buttons.PrimaryModalButton;
 import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.WindowClosedCallback;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -82,7 +84,7 @@ public class BaseModal<T extends Serializable> extends Modal<T> implements Notif
         form = new Form<>(FORM);
         add(form);
 
-        content = new AbstractModalPanel(this, null) {
+        content = new AbstractModalPanel<T>(this, null) {
 
             private static final long serialVersionUID = 1L;
 
@@ -105,7 +107,21 @@ public class BaseModal<T extends Serializable> extends Modal<T> implements Notif
         addButton(new DefaultModalCloseButton());
         setUseKeyboard(true);
         setFadeIn(true);
+    }
 
+    @Override
+    public final Component add(final Behavior... behaviors) {
+        return super.add(behaviors);
+    }
+
+    @Override
+    public final MarkupContainer add(final Component... childs) {
+        return super.add(childs);
+    }
+
+    @Override
+    public final MarkupContainer addOrReplace(final Component... childs) {
+        return super.addOrReplace(childs);
     }
 
     @Override
@@ -131,11 +147,14 @@ public class BaseModal<T extends Serializable> extends Modal<T> implements Notif
         return form.getModelObject();
     }
 
-    public ModalPanel getContent() {
-        return ModalPanel.class.cast(content);
+    public ModalPanel<T> getContent() {
+        if (content instanceof ModalPanel) {
+            return (ModalPanel<T>) content;
+        }
+        throw new IllegalStateException();
     }
 
-    public BaseModal<T> setContent(final ModalPanel component) {
+    public BaseModal<T> setContent(final ModalPanel<T> component) {
         if (component instanceof Panel) {
             return setInternalContent(Panel.class.cast(component));
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/6a93860d/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractModalPanelBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractModalPanelBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractModalPanelBuilder.java
new file mode 100644
index 0000000..88b79c5
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractModalPanelBuilder.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.wizards;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.client.console.panels.ModalPanel;
+import org.apache.wicket.PageReference;
+
+public abstract class AbstractModalPanelBuilder<T extends Serializable> implements Serializable {
+
+    private static final long serialVersionUID = 5241745929825564456L;
+
+    protected final String id;
+
+    protected final PageReference pageRef;
+
+    private final T defaultItem;
+
+    private T item;
+
+    /**
+     * Construct.
+     *
+     * @param id The component id
+     * @param defaultItem default item.
+     * @param pageRef Caller page reference.
+     */
+    public AbstractModalPanelBuilder(final String id, final T defaultItem, final PageReference pageRef) {
+        this.id = id;
+        this.defaultItem = defaultItem;
+        this.pageRef = pageRef;
+    }
+
+    public abstract ModalPanel<T> build(final int index, final boolean edit);
+
+    protected abstract void onCancelInternal(T modelObject);
+
+    protected abstract void onApplyInternal(T modelObject);
+
+    protected T getOriginalItem() {
+        return item;
+    }
+
+    public T getDefaultItem() {
+        return defaultItem;
+    }
+
+    protected T newModelObject() {
+        if (item == null) {
+            // keep the original item: the which one before the changes performed during wizard browsing
+            item = SerializationUtils.clone(defaultItem);
+        }
+
+        // instantiate a new model object and return it
+        return SerializationUtils.clone(item);
+    }
+
+    /**
+     * Replaces the default value provided with the constructor and nullify working item object.
+     *
+     * @param item new value.
+     * @return the current wizard factory instance.
+     */
+    public AbstractModalPanelBuilder<T> setItem(final T item) {
+        this.item = item;
+        return this;
+    }
+
+    public PageReference getPageReference() {
+        return pageRef;
+    }
+}