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 2016/01/12 16:32:17 UTC

[1/2] syncope git commit: [SYNCOPE-156] provides any object create/update result page + several refactorings

Repository: syncope
Updated Branches:
  refs/heads/master d5296cadd -> 03d7de338


http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
index d868180..2b9ec69 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
@@ -77,7 +77,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
 
     protected abstract void onCancelInternal();
 
-    protected abstract void onApplyInternal();
+    protected abstract Serializable onApplyInternal();
 
     /**
      * @see org.apache.wicket.extensions.wizard.Wizard#onCancel()
@@ -102,15 +102,21 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
     public final void onFinish() {
         final AjaxRequestTarget target = RequestCycle.get().find(AjaxRequestTarget.class);
         try {
-            onApplyInternal();
-            send(AjaxWizard.this, Broadcast.BUBBLE, new NewItemFinishEvent<>(item, target));
+            final Serializable res = onApplyInternal();
+            send(AjaxWizard.this, Broadcast.BUBBLE, new NewItemFinishEvent<>(item, target).setResult(res));
         } catch (Exception e) {
+            System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1 " + e);
+            e.printStackTrace();
             LOG.warn("Wizard error on finish", e);
             error(getString("wizard.apply.error"));
             feedbackPanel.refresh(target);
+        } catch (Throwable t) {
+            System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2 " + t);
+            t.printStackTrace();
         }
     }
 
+    @Override
     public T getItem() {
         return item;
     }
@@ -207,7 +213,9 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
 
     public static class NewItemFinishEvent<T> extends NewItemEvent<T> {
 
-        private static final String EVENT_DESCRIPTION = "cancel";
+        private static final String EVENT_DESCRIPTION = "finish";
+
+        private Serializable result;
 
         public NewItemFinishEvent(final T item, final AjaxRequestTarget target) {
             super(item, target);
@@ -217,6 +225,15 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
         public String getEventDescription() {
             return NewItemFinishEvent.EVENT_DESCRIPTION;
         }
+
+        public NewItemFinishEvent<T> setResult(final Serializable result) {
+            this.result = result;
+            return this;
+        }
+
+        public Serializable getResult() {
+            return result;
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java
index 0afa9f4..d1dc756 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java
@@ -57,8 +57,8 @@ public abstract class AjaxWizardBuilder<T extends Serializable> extends Abstract
             }
 
             @Override
-            protected void onApplyInternal() {
-                AjaxWizardBuilder.this.onApplyInternal(modelObject);
+            protected Serializable onApplyInternal() {
+                return AjaxWizardBuilder.this.onApplyInternal(modelObject);
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardButtonBar.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardButtonBar.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardButtonBar.java
index 2711e28..90ca57b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardButtonBar.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardButtonBar.java
@@ -16,6 +16,8 @@
 package org.apache.syncope.client.console.wizards;
 
 import org.apache.syncope.client.console.panels.NotificationPanel;
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.IWizardModel;
 import org.apache.wicket.extensions.wizard.IWizardStep;
@@ -125,4 +127,8 @@ public class AjaxWizardButtonBar extends WizardButtonBar {
         });
     }
 
+    @Override
+    public final MarkupContainer addOrReplace(final Component... childs) {
+        return super.addOrReplace(childs);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
index f9abcdc..c1e7c96 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
@@ -23,6 +23,7 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.ModalPanel;
 import org.apache.syncope.client.console.panels.NotificationPanel;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wizards.any.ResultPage;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.PageReference;
@@ -44,6 +45,8 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
 
     private static final long serialVersionUID = 1L;
 
+    protected PageReference pageRef;
+
     private final WebMarkupContainer container;
 
     private final Fragment initialFragment;
@@ -56,6 +59,10 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
 
     private boolean footerVisibility = false;
 
+    private boolean showResultPage = false;
+
+    private final boolean wizardInModal;
+
     /**
      * Modal window.
      */
@@ -71,8 +78,6 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
 
     };
 
-    private final boolean wizardInModal;
-
     protected WizardMgtPanel(final String id) {
         this(id, false);
     }
@@ -106,6 +111,16 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
         initialFragment.add(addAjaxLink);
     }
 
+    public <B extends AbstractModalPanelBuilder<T>> WizardMgtPanel<T> setPageRef(final PageReference pageRef) {
+        this.pageRef = pageRef;
+        return this;
+    }
+
+    public <B extends AbstractModalPanelBuilder<T>> WizardMgtPanel<T> setShowResultPage(final boolean showResultPage) {
+        this.showResultPage = showResultPage;
+        return this;
+    }
+
     @Override
     public final MarkupContainer add(final Component... childs) {
         return super.add(childs);
@@ -146,15 +161,41 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
                     fragment.add(Component.class.cast(modalPanel));
                     container.addOrReplace(fragment);
                 }
-            } else {
-                if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
-                    if (notificationPanel != null) {
-                        getSession().info(getString(Constants.OPERATION_SUCCEEDED));
-                        notificationPanel.refresh(target);
-                    }
+            } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
+                if (wizardInModal) {
+                    modal.show(false);
+                    modal.close(target);
+                } else {
+                    container.addOrReplace(initialFragment);
+                }
+            } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
+                if (notificationPanel != null) {
+                    getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+                    notificationPanel.refresh(target);
                 }
 
-                if (wizardInModal) {
+                if (wizardInModal && showResultPage) {
+                    modal.setContent(new ResultPage<T>(
+                            item,
+                            AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult(),
+                            pageRef) {
+
+                        private static final long serialVersionUID = 1L;
+
+                        @Override
+                        protected void closeAction(final AjaxRequestTarget target) {
+                            modal.show(false);
+                            modal.close(target);
+                        }
+
+                        @Override
+                        protected Panel customResultBody(
+                                final String id, final T item, final Serializable result) {
+                            return WizardMgtPanel.this.customResultBody(id, item, result);
+                        }
+                    });
+                    target.add(modal.getForm());
+                } else if (wizardInModal) {
                     modal.show(false);
                     modal.close(target);
                 } else {
@@ -167,6 +208,17 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
         super.onEvent(event);
     }
 
+    /*
+     * Override this method to specify your custom result body panel.
+     */
+    protected Panel customResultBody(final String panelId, final T item, final Serializable result) {
+        return new Panel(panelId) {
+
+            private static final long serialVersionUID = 5538299138211283825L;
+
+        };
+    }
+
     protected <B extends AbstractModalPanelBuilder<T>> WizardMgtPanel<T> addNewItemPanelBuilder(
             final B panelBuilder, final boolean newItemDefaultButtonEnabled) {
         this.newItemPanelBuilder = panelBuilder;
@@ -201,6 +253,8 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
 
         private NotificationPanel notificationPanel;
 
+        private boolean showResultPage = false;
+
         protected Builder(final PageReference pageRef) {
             this.pageRef = pageRef;
         }
@@ -215,10 +269,16 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
          */
         public WizardMgtPanel<T> build(final String id) {
             return newInstance(id).
+                    setPageRef(pageRef).
+                    setShowResultPage(showResultPage).
                     addNewItemPanelBuilder(newItemPanelBuilder, newItemDefaultButtonEnabled).
                     addNotificationPanel(notificationPanel);
         }
 
+        public void setShowResultPage(final boolean showResultPage) {
+            this.showResultPage = showResultPage;
+        }
+
         public Builder<T> addNewItemPanelBuilder(final AbstractModalPanelBuilder<T> panelBuilder) {
             this.newItemPanelBuilder = panelBuilder;
             return this;

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
index 62707cc..5625732 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
@@ -16,128 +16,55 @@
 package org.apache.syncope.client.console.wizards.any;
 
 import java.io.Serializable;
-import java.util.ArrayList;
+
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
+
+import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.extensions.wizard.WizardModel;
-import org.apache.wicket.extensions.wizard.WizardStep;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.ResourceModel;
-import org.apache.wicket.model.StringResourceModel;
-
-public class AnyObjectWizardBuilder extends AjaxWizardBuilder<AnyTO> implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    private final AnyTO anyTO;
 
-    private final LoadableDetachableModel<List<String>> anyTypes = new LoadableDetachableModel<List<String>>() {
+public class AnyObjectWizardBuilder extends AnyWizardBuilder<AnyObjectTO> implements Serializable {
 
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        protected List<String> load() {
-            final List<String> currentlyAdded = new ArrayList<>();
-            return currentlyAdded;
-        }
-    };
-
-    /**
-     * The object type specification step.
-     */
-    private final class ObjectType extends WizardStep {
-
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * Construct.
-         */
-        ObjectType(final AnyTO item) {
-            super(new ResourceModel("type.title", StringUtils.EMPTY),
-                    new ResourceModel("type.summary", StringUtils.EMPTY), new Model<AnyTO>(item));
-
-            add(new AjaxDropDownChoicePanel<String>("type", "type", new PropertyModel<String>(item, "anyType"), false).
-                    setChoices(anyTypes).
-                    setStyleSheet("form-control").
-                    setRequired(true));
-
-            add(new TextField<String>(
-                    "class", new PropertyModel<String>(item, "objectClass")).setRequired(true));
-        }
-    }
-
-    /**
-     * Mapping definition step.
-     */
-    private final class Mapping extends WizardStep {
-
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * Construct.
-         */
-        Mapping(final AnyTO item) {
-            setTitleModel(new ResourceModel("mapping.title", "Mapping"));
-            setSummaryModel(new StringResourceModel("mapping.summary", this, new Model<AnyTO>(item)));
-        }
-    }
-
-    /**
-     * AccountLink specification step.
-     */
-    private final class ConnObjectLink extends WizardStep {
-
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * Construct.
-         */
-        ConnObjectLink(final AnyTO item) {
-            super(new ResourceModel("link.title", StringUtils.EMPTY),
-                    new ResourceModel("link.summary", StringUtils.EMPTY));
-
-            final WebMarkupContainer connObjectLinkContainer = new WebMarkupContainer("connObjectLinkContainer");
-            connObjectLinkContainer.setOutputMarkupId(true);
-            add(connObjectLinkContainer);
-        }
-    }
+    private static final long serialVersionUID = -2480279868319546243L;
 
     /**
      * Construct.
      *
      * @param id The component id
-     * @param anyTO external resource to be updated.
+     * @param anyObjectTO any object TO.
+     * @param anyTypeClasses any type classes
      * @param pageRef Caller page reference.
      */
-    public AnyObjectWizardBuilder(final String id, final AnyTO anyTO, final PageReference pageRef) {
-        super(id, new AnyObjectTO(), pageRef);
-        this.anyTO = anyTO;
+    public AnyObjectWizardBuilder(
+            final String id,
+            final AnyObjectTO anyObjectTO,
+            final List<String> anyTypeClasses,
+            final PageReference pageRef) {
+        super(id, anyObjectTO, anyTypeClasses, pageRef);
     }
 
     @Override
-    protected WizardModel buildModelSteps(final AnyTO modelObject, final WizardModel wizardModel) {
-        wizardModel.add(new ObjectType(modelObject));
-        wizardModel.add(new Mapping(modelObject));
-        wizardModel.add(new ConnObjectLink(modelObject));
-        return wizardModel;
-    }
-
-    @Override
-    protected void onCancelInternal(final AnyTO modelObject) {
-        // d nothing
-    }
+    protected Serializable onApplyInternal(final AnyHandler<AnyObjectTO> modelObject) {
+        final AnyObjectTO obj = modelObject.getInnerObject();
+
+        final ProvisioningResult<AnyObjectTO> actual;
+
+        if (obj.getKey() == 0) {
+            actual = anyTypeRestClient.create(AnyObjectTO.class.cast(obj));
+        } else {
+            final AnyObjectPatch patch = AnyOperations.diff(obj, getOriginalItem().getInnerObject(), false);
+
+            // update user just if it is changed
+            if (!patch.isEmpty()) {
+                actual = anyTypeRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
+            } else {
+                actual = new ProvisioningResult<>();
+                actual.setAny(obj);
+            }
+        }
 
-    @Override
-    protected void onApplyInternal(final AnyTO modelObject) {
-        // do nothing
+        return actual;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index 5add93d..676c6b9 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -24,18 +24,14 @@ import org.apache.syncope.client.console.commons.Mode;
 import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
-import org.apache.syncope.common.lib.AnyOperations;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.extensions.wizard.WizardModel;
 import org.apache.wicket.model.util.ListModel;
 
-public class AnyWizardBuilder<T extends AnyTO> extends AjaxWizardBuilder<AnyHandler<T>>
+public abstract class AnyWizardBuilder<T extends AnyTO> extends AjaxWizardBuilder<AnyHandler<T>>
         implements Serializable {
 
     private static final long serialVersionUID = -2480279868319546243L;
@@ -113,36 +109,11 @@ public class AnyWizardBuilder<T extends AnyTO> extends AjaxWizardBuilder<AnyHand
         // do nothing
     }
 
-    @Override
-    protected void onApplyInternal(final AnyHandler<T> modelObject) {
-        final T obj = modelObject.getInnerObject();
-
-        if (!(obj instanceof AnyObjectTO)) {
-            throw new IllegalArgumentException();
-        }
-
-        final ProvisioningResult<AnyObjectTO> actual;
-
-        if (obj.getKey() == 0) {
-            actual = anyTypeRestClient.create(AnyObjectTO.class.cast(obj));
-        } else {
-            final AnyObjectPatch patch = AnyOperations.diff(obj, getOriginalItem().getInnerObject(), false);
-
-            // update user just if it is changed
-            if (!patch.isEmpty()) {
-                actual = anyTypeRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
-            }
-        }
-    }
-
     protected AnyWizardBuilder<T> addOptionalDetailsPanel(
             final AnyHandler<T> modelObject, final WizardModel wizardModel) {
         if (modelObject.getInnerObject().getKey() > 0) {
             wizardModel.add(new Details<T>(
-                    modelObject,
-                    new ListModel<>(Collections.<StatusBean>emptyList()),
-                    pageRef,
-                    true));
+                    modelObject, new ListModel<>(Collections.<StatusBean>emptyList()), pageRef, true));
         }
         return this;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java
index a525613..fc51315 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java
@@ -22,13 +22,20 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.commons.ConnIdSpecialAttributeName;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
-import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.Component;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
@@ -39,16 +46,19 @@ public class ConnObjectPanel extends Panel {
 
     private static final long serialVersionUID = -6469290753080058487L;
 
-    public ConnObjectPanel(final String id, final ConnObjectTO connObjectTO) {
+    public ConnObjectPanel(final String id, final Pair<ConnObjectTO, ConnObjectTO> connObjectTOs) {
         super(id);
 
-        IModel<List<AttrTO>> formProps = new LoadableDetachableModel<List<AttrTO>>() {
+        final IModel<List<AttrTO>> formProps = new LoadableDetachableModel<List<AttrTO>>() {
 
             private static final long serialVersionUID = 5275935387613157437L;
 
             @Override
             protected List<AttrTO> load() {
-                List<AttrTO> attrs = new ArrayList<>(connObjectTO.getPlainAttrs());
+                List<AttrTO> attrs = new ArrayList<>(connObjectTOs == null || connObjectTOs.getRight() == null
+                        ? Collections.<AttrTO>emptyList()
+                        : connObjectTOs.getRight().getPlainAttrs());
+
                 Collections.sort(attrs, new Comparator<AttrTO>() {
 
                     @Override
@@ -67,6 +77,10 @@ public class ConnObjectPanel extends Panel {
             }
         };
 
+        final Map<String, AttrTO> beforeProfile = connObjectTOs.getLeft() == null
+                ? null
+                : connObjectTOs.getLeft().getPlainAttrMap();
+
         final ListView<AttrTO> propView = new ListView<AttrTO>("propView", formProps) {
 
             private static final long serialVersionUID = 3109256773218160485L;
@@ -75,24 +89,71 @@ public class ConnObjectPanel extends Panel {
             protected void populateItem(final ListItem<AttrTO> item) {
                 final AttrTO prop = item.getModelObject();
 
-                Label label = new Label("key", prop.getSchema());
-                item.add(label);
-
-                Panel field;
-                if (prop.getValues().isEmpty()) {
-                    field = new AjaxTextFieldPanel("attribute", prop.getSchema(), new Model<String>());
-                } else if (prop.getValues().size() == 1) {
-                    field = new AjaxTextFieldPanel("attribute",
-                            prop.getSchema(), new Model<String>(prop.getValues().get(0)));
+                final Fragment valueFragment;
+                if (beforeProfile == null) {
+                    valueFragment = new Fragment("value", "singleValue", ConnObjectPanel.this);
+                    valueFragment.add(getValuePanel("attribute", prop.getSchema(), prop));
                 } else {
-                    field = new MultiFieldPanel.Builder<String>(new ListModel<String>(prop.getValues())).build(
-                            "attribute",
-                            prop.getSchema(),
-                            new AjaxTextFieldPanel("panel", prop.getSchema(), new Model<String>()));
+                    final AttrTO before = beforeProfile.get(prop.getSchema());
+
+                    valueFragment = new Fragment("value", "doubleValue", ConnObjectPanel.this);
+                    valueFragment.add(getValuePanel("oldAttribute", prop.getSchema(), before));
+                    valueFragment.add(getValuePanel("newAttribute", prop.getSchema(), prop));
+
+                    if (before == null
+                            || (CollectionUtils.isNotEmpty(prop.getValues())
+                            && CollectionUtils.isEmpty(before.getValues()))
+                            || (CollectionUtils.isEmpty(prop.getValues())
+                            && CollectionUtils.isNotEmpty(before.getValues()))
+                            || (CollectionUtils.isNotEmpty(prop.getValues())
+                            && CollectionUtils.isNotEmpty(before.getValues())
+                            && prop.getValues().size() != before.getValues().size())
+                            || (CollectionUtils.isNotEmpty(prop.getValues())
+                            && CollectionUtils.isNotEmpty(before.getValues())
+                            && !prop.getValues().equals(before.getValues()))) {
+                        valueFragment.add(new Behavior() {
+
+                            private static final long serialVersionUID = 3109256773218160485L;
+
+                            @Override
+                            public void onComponentTag(final Component component, final ComponentTag tag) {
+                                tag.put("class", "highlight");
+                            }
+                        });
+                    }
                 }
-                item.add(field);
+                item.add(valueFragment);
             }
         };
         add(propView);
     }
+
+    /**
+     * Get panel for attribute value (not remote status).
+     *
+     * @param id component id to be replaced with the fragment content.
+     * @param attrTO remote attribute.
+     * @return fragment.
+     */
+    private Panel getValuePanel(final String id, final String schemaName, final AttrTO attrTO) {
+        Panel field;
+        if (attrTO == null) {
+            field = new AjaxTextFieldPanel(id, schemaName, new Model<String>());
+        } else if (CollectionUtils.isEmpty(attrTO.getValues())) {
+            field = new AjaxTextFieldPanel(id, schemaName, new Model<String>());
+        } else if (ConnIdSpecialAttributeName.PASSWORD.equals(schemaName)) {
+            field = new AjaxTextFieldPanel(id, schemaName, new Model<String>("********"));
+        } else if (attrTO.getValues().size() == 1) {
+            field = new AjaxTextFieldPanel(id, schemaName, new Model<String>(attrTO.getValues().get(0)));
+        } else {
+            field = new MultiFieldPanel.Builder<String>(new ListModel<String>(attrTO.getValues())).build(
+                    id,
+                    schemaName,
+                    new AjaxTextFieldPanel("panel", schemaName, new Model<String>()));
+        }
+
+        field.setEnabled(false);
+        return field;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
index ed4c227..7bbae5b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
@@ -15,6 +15,7 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
+import java.io.Serializable;
 import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.client.console.commons.status.StatusBean;
@@ -62,7 +63,7 @@ public class GroupWizardBuilder extends AnyWizardBuilder<GroupTO> {
     }
 
     @Override
-    protected void onApplyInternal(final AnyHandler<GroupTO> modelObject) {
+    protected Serializable onApplyInternal(final AnyHandler<GroupTO> modelObject) {
         final ProvisioningResult<GroupTO> actual;
 
         GroupTO toBeProcessed = modelObject instanceof GroupHandler
@@ -76,8 +77,12 @@ public class GroupWizardBuilder extends AnyWizardBuilder<GroupTO> {
             // update user just if it is changed
             if (!patch.isEmpty()) {
                 actual = groupRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
+            } else {
+                actual = null;
             }
         }
+
+        return actual;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
new file mode 100644
index 0000000..060a027
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
@@ -0,0 +1,77 @@
+/*
+ * 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.wizards.any;
+
+import java.io.Serializable;
+import org.apache.syncope.client.console.panels.ModalPanel;
+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.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+
+/**
+ *
+ * @param <T> item input type
+ */
+public abstract class ResultPage<T extends Serializable> extends Panel implements ModalPanel<T> {
+
+    private static final long serialVersionUID = -1619945285130369086L;
+
+    private final T item;
+
+    public ResultPage(final T item, final Serializable result, final PageReference pageRef) {
+        super(BaseModal.CONTENT_ID);
+        setOutputMarkupId(true);
+        this.item = item;
+
+        add(customResultBody("customResultBody", item, result));
+
+        add(ActionLinksPanel.<T>builder(pageRef).add(new ActionLink<T>() {
+
+            private static final long serialVersionUID = 3257738274365467945L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target, final T ignore) {
+                closeAction(target);
+            }
+        }, ActionLink.ActionType.CLOSE).build("action").setRenderBodyOnly(true));
+    }
+
+    protected abstract void closeAction(final AjaxRequestTarget target);
+
+    protected abstract Panel customResultBody(final String panleId, final T item, final Serializable result);
+
+    @Override
+    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+        throw new UnsupportedOperationException("Unsupported operation.");
+    }
+
+    @Override
+    public void onError(final AjaxRequestTarget target, final Form<?> form) {
+        throw new UnsupportedOperationException("Unsupported operation.");
+    }
+
+    @Override
+    public T getItem() {
+        return this.item;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index 0f2c16f..77f9355 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -18,11 +18,18 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
+import static org.apache.syncope.client.console.commons.status.Status.ACTIVE;
+import static org.apache.syncope.client.console.commons.status.Status.SUSPENDED;
+
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SerializableTransformer;
 import org.apache.syncope.client.console.commons.status.ConnObjectWrapper;
 import org.apache.syncope.client.console.commons.status.Status;
 import org.apache.syncope.client.console.commons.status.StatusBean;
@@ -32,6 +39,7 @@ import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -59,40 +67,64 @@ public class StatusPanel extends Panel implements IHeaderContributor {
 
     private static final long serialVersionUID = -4064294905566247728L;
 
-    private UserRestClient userRestClient = new UserRestClient();
-
-    private GroupRestClient groupRestClient = new GroupRestClient();
+    private final UserRestClient userRestClient = new UserRestClient();
 
-    private final List<ConnObjectWrapper> connObjects;
+    private final GroupRestClient groupRestClient = new GroupRestClient();
 
-    private final Map<String, StatusBean> initialStatusBeanMap;
+    private Map<String, StatusBean> initialStatusBeanMap;
 
     private final StatusUtils statusUtils;
 
-    private final ListViewPanel<?> listViewPanel;
+    private ListViewPanel<?> listViewPanel;
 
-    private final TransparentWebMarkupContainer container;
+    private TransparentWebMarkupContainer container;
 
-    private final Fragment resourceListFragment;
+    private Fragment resourceListFragment;
 
     public <T extends AnyTO> StatusPanel(
             final String id,
             final T any,
             final IModel<List<StatusBean>> model,
             final PageReference pageRef) {
+        super(id);
+        statusUtils = new StatusUtils(any instanceof GroupTO ? groupRestClient : userRestClient);
+        init(any, model,
+                CollectionUtils.collect(statusUtils.getConnectorObjects(any),
+                        new SerializableTransformer<ConnObjectWrapper, Pair<ConnObjectTO, ConnObjectWrapper>>() {
+
+                    private static final long serialVersionUID = 2658691884036294287L;
+
+                    @Override
+                    public Pair<ConnObjectTO, ConnObjectWrapper> transform(final ConnObjectWrapper input) {
+                        return Pair.of(null, input);
+                    }
 
+                }, new ArrayList<Pair<ConnObjectTO, ConnObjectWrapper>>()), pageRef);
+    }
+
+    public <T extends AnyTO> StatusPanel(
+            final String id,
+            final T any,
+            final IModel<List<StatusBean>> model,
+            final List<Pair<ConnObjectTO, ConnObjectWrapper>> connObjects,
+            final PageReference pageRef) {
         super(id);
+        statusUtils = new StatusUtils(any instanceof GroupTO ? groupRestClient : userRestClient);
+        init(any, model, connObjects, pageRef);
+    }
+
+    private void init(
+            final AnyTO any,
+            final IModel<List<StatusBean>> model,
+            final List<Pair<ConnObjectTO, ConnObjectWrapper>> connObjects,
+            final PageReference pageRef) {
 
         container = new TransparentWebMarkupContainer("container");
         container.setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true);
         add(container);
 
         resourceListFragment = new Fragment("content", "resources", this);
-        container.addOrReplace(resourceListFragment);
-
-        statusUtils = new StatusUtils(any instanceof GroupTO ? groupRestClient : userRestClient);
-
-        connObjects = statusUtils.getConnectorObjects(any);
+        container.addOrReplace(resourceListFragment.setRenderBodyOnly(true));
 
         final List<StatusBean> statusBeans = new ArrayList<>(connObjects.size() + 1);
         initialStatusBeanMap = new LinkedHashMap<>(connObjects.size() + 1);
@@ -119,7 +151,8 @@ public class StatusPanel extends Panel implements IHeaderContributor {
         statusBeans.add(syncope);
         initialStatusBeanMap.put(syncope.getResourceName(), syncope);
 
-        for (ConnObjectWrapper entry : connObjects) {
+        for (Pair<ConnObjectTO, ConnObjectWrapper> pair : connObjects) {
+            ConnObjectWrapper entry = pair.getRight();
             final StatusBean statusBean = statusUtils.getStatusBean(entry.getAny(),
                     entry.getResourceName(),
                     entry.getConnObjectTO(),
@@ -146,18 +179,18 @@ public class StatusPanel extends Panel implements IHeaderContributor {
                             if (null != bean.getStatus()) {
                                 switch (bean.getStatus()) {
                                     case OBJECT_NOT_FOUND:
-                                        tag.put("class", "glyphicon glyphicon-remove-circle");
+                                        tag.put("class", Constants.NOT_FOUND_ICON);
                                         break;
                                     case UNDEFINED:
                                     case CREATED:
                                     case NOT_YET_SUBMITTED:
-                                        tag.put("class", "glyphicon glyphicon-question-sign");
+                                        tag.put("class", Constants.UNDEFINED_ICON);
                                         break;
                                     case SUSPENDED:
-                                        tag.put("class", "glyphicon glyphicon-ban-circle");
+                                        tag.put("class", Constants.SUSPENDED_ICON);
                                         break;
                                     case ACTIVE:
-                                        tag.put("class", "glyphicon glyphicon-ok-circle");
+                                        tag.put("class", Constants.ACTIVE_ICON);
                                         break;
                                     default:
                                         break;
@@ -186,13 +219,16 @@ public class StatusPanel extends Panel implements IHeaderContributor {
 
             @Override
             protected boolean statusCondition(final StatusBean bean) {
-                return statusUtils.getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects) != null;
+                final Pair<ConnObjectTO, ConnObjectTO> pair
+                        = getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects);
+
+                return pair != null && pair.getRight() != null;
             }
 
             @Override
             public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
                 final Fragment remoteObjectFragment = new Fragment("content", "remoteObject", StatusPanel.this);
-                container.addOrReplace(remoteObjectFragment);
+                container.addOrReplace(remoteObjectFragment.setRenderBodyOnly(true));
 
                 remoteObjectFragment.add(new AjaxLink<StatusBean>("back") {
 
@@ -200,7 +236,7 @@ public class StatusPanel extends Panel implements IHeaderContributor {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
-                        container.addOrReplace(resourceListFragment);
+                        container.addOrReplace(resourceListFragment.setRenderBodyOnly(true));
                         target.add(container);
                     }
                 });
@@ -208,8 +244,10 @@ public class StatusPanel extends Panel implements IHeaderContributor {
                 remoteObjectFragment.add(
                         new Label("resource", new ResourceModel(bean.getResourceName(), bean.getResourceName())));
 
-                remoteObjectFragment.add(new ConnObjectPanel("remoteObject",
-                        statusUtils.getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects)));
+                final Pair<ConnObjectTO, ConnObjectTO> res
+                        = getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects);
+
+                remoteObjectFragment.add(new ConnObjectPanel("remoteObject", res == null ? null : res));
 
                 target.add(container);
             }
@@ -226,4 +264,18 @@ public class StatusPanel extends Panel implements IHeaderContributor {
     public Map<String, StatusBean> getInitialStatusBeanMap() {
         return initialStatusBeanMap;
     }
+
+    private Pair<ConnObjectTO, ConnObjectTO> getConnObjectTO(
+            final Long anyKey, final String resourceName, final List<Pair<ConnObjectTO, ConnObjectWrapper>> objects) {
+
+        for (Pair<ConnObjectTO, ConnObjectWrapper> object : objects) {
+            if (anyKey.equals(object.getRight().getAny().getKey())
+                    && resourceName.equalsIgnoreCase(object.getRight().getResourceName())) {
+
+                return Pair.of(object.getLeft(), object.getRight().getConnObjectTO());
+            }
+        }
+
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index 28245b9..835b51a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -15,6 +15,7 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
@@ -56,7 +57,7 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> {
     }
 
     @Override
-    protected void onApplyInternal(final AnyHandler<UserTO> modelObject) {
+    protected Serializable onApplyInternal(final AnyHandler<UserTO> modelObject) {
         final ProvisioningResult<UserTO> actual;
 
         final UserTO inner = modelObject.getInnerObject();
@@ -72,8 +73,12 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> {
             // update user just if it is changed
             if (!patch.isEmpty()) {
                 actual = userRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
+            } else {
+                actual = null;
             }
         }
+
+        return actual;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
index 4d60aab..b74b86c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder.java
@@ -247,7 +247,8 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> imple
     }
 
     @Override
-    protected void onApplyInternal(final ProvisionTO modelObject) {
+    protected Serializable onApplyInternal(final ProvisionTO modelObject) {
         this.resourceTO.getProvisions().add(modelObject);
+        return null;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wizards/role/RoleWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/role/RoleWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/role/RoleWizardBuilder.java
index 7801a6e..68d2119 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/role/RoleWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/role/RoleWizardBuilder.java
@@ -16,6 +16,7 @@
 package org.apache.syncope.client.console.wizards.role;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.Collapsible;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -74,7 +75,7 @@ public class RoleWizardBuilder extends AjaxWizardBuilder<RoleHandler> {
     }
 
     @Override
-    protected void onApplyInternal(final RoleHandler modelObject) {
+    protected Serializable onApplyInternal(final RoleHandler modelObject) {
         modelObject.fillDynamicConditions();
         if (getOriginalItem() == null || getOriginalItem().getInnerObject() == null
                 || StringUtils.isBlank(getOriginalItem().getInnerObject().getKey())) {
@@ -82,6 +83,7 @@ public class RoleWizardBuilder extends AjaxWizardBuilder<RoleHandler> {
         } else {
             groupRestClient.update(modelObject.getInnerObject());
         }
+        return null;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 20f0946..d9bd850 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -261,6 +261,13 @@ div#resource-modal.modal-lg {
   width: 1200px;
 }
 
+.details {
+  max-height: 380px;
+  overflow-x: hidden;
+  overflow-y: auto;
+  display: block
+}
+
 /**
   BEGIN - Style for Information panel
 */
@@ -468,3 +475,22 @@ START - DataTable
 /**
 END - DataTable
 */
+
+/**
+START - Resukt page
+*/
+.attribute {
+  padding: 0px 4px 0px 4px; 
+}
+
+.left {
+  float:left; 
+  width: 50%; 
+}
+
+span.highlight .attribute label {
+  color : red;
+}
+/**
+END - Resukt page
+*/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.html
deleted file mode 100644
index 647a311..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.html
+++ /dev/null
@@ -1,226 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:head>
-    <style>
-      div#propagation {
-        font-size: 8px;
-        height: auto;
-        margin-top: 3px;
-        text-align: left;
-      }
-
-      div#status {
-        float: left;
-        height: 25px;
-        margin-top: 3px;
-        text-align: center;
-        width: 8%;
-      }
-
-      div.assignment {
-        border: 1px solid #DDDDDD;
-        display: inline-table;
-        margin-bottom: 20px;
-        width: 100%;
-      }
-
-      div.assignments {
-        color: #555555;
-        display: inline-table;
-        margin-top: 20px;
-        width: 100%;
-      }
-
-      div.header {
-        display: inline-table;
-        margin: 5px;
-        width: 98%;
-      }
-
-      div.profile div#row{
-        display: inline-table;
-        width:100%;
-        vertical-align: middle;
-      }
-
-      div.profile {
-        background-color: #EEEEEE;
-        color: #555555;
-        display: inline-table;
-        margin: 0px 5px 5px 5px;
-        width: 98%;
-      }
-
-      div#name {
-        border-bottom: 1px solid #DDDDDD;
-        display: table-cell;
-        height: 15px;
-        width: 220px;
-        padding: 0px 5px 0px 5px;
-        vertical-align: middle;
-      }
-
-      div#value {
-        border-bottom: 1px solid #DDDDDD;
-        border-left: 1px solid #DDDDDD;
-        display: table-cell;
-        height: 15px;
-        width: 38%;
-        padding: 0px 5px 0px 5px;
-        overflow: hidden;
-        vertical-align: middle;
-      }
-
-      div#resource {
-        display: table-cell;
-        width: 220px;
-        height: 30px;
-        padding: 10px 0px 5px 0px;
-      }
-
-      div#resource img{
-        width: 12px;
-        height: 12px;
-        position: relative;
-        left: 3px;
-        top: 1px;
-        opacity: 1;
-      }
-
-      div#attrhead {
-        display: table-cell;
-        border-left: 1px solid #DDDDDD;
-        width: 38%;
-        height: 30px;
-        padding: 3px 0px 5px 0px;
-        text-align: center;
-        vertical-align: middle;
-        font-size: 11px;
-      }
-    </style>
-  </wicket:head>
-  <wicket:extend>
-
-    <wicket:fragment wicket:id="propagationResultFrag">
-      <p class="ui-widget ui-corner-all ui-widget-header">
-        <wicket:message key="operationResult"/>&nbsp;<span wicket:id="info"/>
-      </p>
-
-      <div class="assignments">
-        <div wicket:id="resources" class="assignment">
-
-          <span wicket:id="attrhead">[Attributes head]</span>
-
-          <div class="profile">
-            <span wicket:id="attrs">
-              <div id="row">
-                <div id="name">
-                  <span wicket:id="attrName">[Attribute name]</span>
-                </div>
-                <div id="value">
-                  <span wicket:id="beforeValue">[Before value]</span>
-                </div>
-                <div id="value">
-                  <span wicket:id="afterValue">[After value]</span>
-                </div>
-              </div>
-            </span>
-          </div>
-        </div>
-      </div>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="userSelfResultFrag">
-      <p><wicket:message key="selfResult"/></p>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="remoteStatusFrag">
-      <img wicket:id="status"/>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="attrValueFrag">
-      <span wicket:id="value">[After value]</span>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="attrHeadFrag">
-      <div class="header alt">
-        <div id="resource">
-          <div>
-            <span wicket:id="resource">[resource name]</span>
-            <a wicket:id="showFailureWindow" href="#">
-              <img wicket:id="icon"/>
-            </a>
-
-            <div id="propagation">
-              <wicket:message key="propresult">[propagation result message]</wicket:message>
-              &nbsp;
-              <span wicket:id="propagation">[propagation result]</span>
-            </div>
-
-            <div wicket:id="failureWindow"></div>
-
-          </div>
-        </div>
-
-        <div id="attrhead">
-          <wicket:message key="before">[before]</wicket:message>
-        </div>
-
-        <div id="attrhead">
-          <wicket:message key="after">[after]</wicket:message>
-        </div>
-      </div>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="emptyAttrHeadFrag">
-      <div class="header alt">
-        <div id="resource">
-          <div>
-            <span wicket:id="resource">[resource name]</span>
-            <a wicket:id="showFailureWindow" href="#">
-              <img wicket:id="icon"/>
-            </a>
-
-            <div id="propagation">
-              <wicket:message key="propresult">[propagation result message]</wicket:message>
-              &nbsp;
-              <span wicket:id="propagation">[propagation result]</span>
-              <div wicket:id="failureWindow"></div>
-
-            </div>
-
-          </div>
-        </div>
-      </div>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="emptyFrag">
-    </wicket:fragment>
-
-    <div wicket:id="container" id="users-contain" class="ui-widget" style="margin:30px; width:inherit">
-
-      <span wicket:id="resultFrag"/>
-
-      <a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="close">
-        <wicket:message key="close"/>
-      </a>
-    </div>
-  </wicket:extend>
-</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.properties
deleted file mode 100644
index 3ee25f8..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal.properties
+++ /dev/null
@@ -1,26 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-operationResult=Operation result for
-close=Close
-selfResult=Your request has been registered: depending on configuration, approval might be required.
-__NAME__=Account Link
-__UID__=Account Id
-__PASSWORD__=Password
-__ENABLE__=Enabled
-propresult=Propagation: 
-before=Before propagation
-after=After propagation

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_it.properties
deleted file mode 100644
index 92ee70e..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_it.properties
+++ /dev/null
@@ -1,26 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-operationResult=Risultato dell'operazione per
-close=Chiudi
-selfResult=La sua richiesta \u00e8 stata presa in carico: se la configurazione lo prevede, sar\u00e0 necessaria l'approvazione.
-__NAME__=Account Link
-__UID__=Account Id
-__PASSWORD__=Password
-__ENABLE__=Abilitato
-propresult=Propagazione: 
-before=Prima della propagazione
-after=Dopo la propagazione

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_pt_BR.properties
deleted file mode 100644
index 319d1c9..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResultStatusModal_pt_BR.properties
+++ /dev/null
@@ -1,26 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-operationResult=Resultado de opera\u00E7\u00E3o para\:
-close=Fechar
-selfResult=Sua requis\u00E7\u00E3o foi registrada e ser\u00E1 encaminhada ao administrador respons\u00E1vel. Obrigado
-__NAME__=Link de conta
-__UID__=Identificador de Conta
-__PASSWORD__=Senha
-__ENABLE__=Habilitado
-propresult=Propaga\u00E7\u00E3o
-before=Antes da Propaga\u00E7\u00E3o
-after=Depois da Propaga\u00E7\u00E3o

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties
index db9e17e..ff21666 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties
@@ -31,4 +31,6 @@ tokenNotValued=Not valued
 
 any.edit=Edit ${anyTO.type} ${anyTO.key}
 any.new=New ${anyTO.type}
+any.finish=Submit ${anyTO.type}
+any.cancel=Cancel ${anyTO.type}
 any.attr.display=Attributes to be displayed

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties
index 70e378a..eb11fe4 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties
@@ -32,3 +32,5 @@ tokenNotValued=Not valued
 any.edit=Modifica ${anyTO.type} ${key}
 any.new=Nuovo ${anyTO.type}
 any.attr.display=Attributes to be displayed
+any.finish=Submit ${anyTO.type}
+any.cancel=Cancel ${anyTO.type}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties
index 889e6f0..21148f2 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties
@@ -32,3 +32,5 @@ tokenNotValued=N\u00e3o Atribu\u00eddo
 any.edit=Alterar ${anyTO.type} ${key}
 any.new=Novo ${anyTO.type}
 any.attr.display=Attributes to be displayed
+any.finish=Submit ${anyTO.type}
+any.cancel=Cancel ${anyTO.type}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
index c2b32de..93ff5ed 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
@@ -45,7 +45,8 @@ under the License.
     <span wicket:id="panelEdit">[plus]</span>
     <span wicket:id="panelExport">[plus]</span>
     <span wicket:id="panelDelete">[plus]</span>
-    <span wicket:id="panelSelect">[plus]</span>
+    <span wicket:id="panelSelect">[select]</span>
+    <span wicket:id="panelClose">[close]</span>
     <span wicket:id="panelSuspend">[plus]</span>
     <span wicket:id="panelReactivate">[plus]</span>
     <span wicket:id="panelReload">[plus]</span>
@@ -134,6 +135,10 @@ under the License.
     <wicket:fragment wicket:id="fragmentSelect">
       <a href="#" wicket:id="selectLink" class="btn"><i class="glyphicon glyphicon-ok"></i></a>
     </wicket:fragment>
+    
+    <wicket:fragment wicket:id="fragmentClose">
+      <a href="#" wicket:id="closeLink" class="btn"><i class="fa fa-sign-out"></i></a>
+    </wicket:fragment>
 
     <wicket:fragment wicket:id="fragmentExport">
       <a href="#" wicket:id="exportLink" class="btn"><img id="actionLink" src="img/actions/export.png" alt="export icon" title="Export"/></a>

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.html
index eed082f..63f511b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.html
@@ -20,7 +20,18 @@ under the License.
   <head><title></title></head>
   <wicket:panel>
     <div class="form-group" wicket:id="propView">
-      <span wicket:id="attribute">[ATTIRIBUTE]</span>
+      <span wicket:id="value">[ATTIRIBUTE]</span>
     </div>
+    <wicket:fragment wicket:id="singleValue">
+      <span wicket:id="attribute">[ATTIRIBUTE]</span>
+    </wicket:fragment>
+    <wicket:fragment wicket:id="doubleValue">
+      <div class="left attribute">
+        <span wicket:id="oldAttribute">[ATTIRIBUTE]</span>
+      </div>
+      <div class="attribute">
+        <span wicket:id="newAttribute">[ATTIRIBUTE]</span>
+      </div>
+    </wicket:fragment>
   </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
index 6918990..829de18 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
@@ -20,9 +20,13 @@ under the License.
   <head><title></title></head>
   <body>
     <wicket:panel>
-      <wicket:child/>
-      <span wicket:id="status">[STATUS]</span>
-      <span wicket:id="generalStatusInformation">[GENERAL STATUS INFORMATION]</span>
+      <div class="details">
+        <wicket:child/>
+        <span wicket:id="status">[STATUS]</span>
+      </div>
+      <div class="details-footer">
+        <span wicket:id="generalStatusInformation">[GENERAL STATUS INFORMATION]</span>
+      </div>
     </wicket:panel>
   </body>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
new file mode 100644
index 0000000..558f3b3
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <head><title></title></head>
+  <body>
+    <wicket:panel>
+      <span wicket:id="customResultBody"/>
+      <div class="modal-footer circular-actions">
+        <span wicket:id="action"/>
+      </div>
+    </wicket:panel>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
new file mode 100644
index 0000000..7e234f7
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
@@ -0,0 +1,17 @@
+# 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.
+listview.caption=Occurred propagations

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_it.properties
new file mode 100644
index 0000000..a48352d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_it.properties
@@ -0,0 +1,17 @@
+# 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.
+listview.caption=Propagazioni effettuate

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_pt_BR.properties
new file mode 100644
index 0000000..eff8cfa
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_pt_BR.properties
@@ -0,0 +1,17 @@
+# 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.
+listview.caption=Propagations feito

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel.html
index 9fac01f..d7c9981 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel.html
@@ -19,9 +19,9 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <head><title></title></head>
   <wicket:panel>
-    <span wicket:id="container">
+    <div wicket:id="container">
       <wicket:container wicket:id="content" />
-    </span>
+    </div>
 
     <wicket:fragment wicket:id="resources">
       <span wicket:id="resources">[RESOURCES]</span>


[2/2] syncope git commit: [SYNCOPE-156] provides any object create/update result page + several refactorings

Posted by fm...@apache.org.
[SYNCOPE-156] provides any object create/update result page + several refactorings


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

Branch: refs/heads/master
Commit: 03d7de338dfee8ba16608f07df4e89995641d76f
Parents: d5296ca
Author: fmartelli <fa...@gmail.com>
Authored: Tue Jan 12 16:31:53 2016 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Tue Jan 12 16:31:53 2016 +0100

----------------------------------------------------------------------
 .../client/console/commons/Constants.java       |  10 +
 .../console/commons/status/StatusUtils.java     |  14 -
 .../console/pages/BulkActionModalPage.java      |   5 +-
 .../client/console/pages/ResultStatusModal.java | 428 -------------------
 .../panels/AbstractSearchResultPanel.java       |   4 +-
 .../console/panels/AjaxDataTablePanel.java      |   8 +-
 .../panels/AnyObjectSearchResultPanel.java      | 169 ++------
 .../console/panels/AnySearchResultPanel.java    | 195 +++++++++
 .../console/panels/AnyTypeClassesPanel.java     |  14 +-
 .../client/console/panels/AnyTypePanel.java     |  11 +-
 .../console/panels/FailureMessageModal.java     |  24 +-
 .../console/panels/GroupSearchResultPanel.java  |  25 +-
 .../syncope/client/console/panels/Realm.java    |   6 +-
 .../console/panels/RelationshipTypePanel.java   |  11 +-
 .../console/panels/RoleSearchResultPanel.java   |   8 +-
 .../client/console/panels/SchemaTypePanel.java  |  14 +-
 .../console/panels/SecurityQuestionsPanel.java  |  11 +-
 .../console/panels/UserSearchResultPanel.java   |  25 +-
 .../AnyObjectSelectionSearchResultPanel.java    |   5 +
 .../search/AnySelectionSearchResultPanel.java   |   9 +-
 .../search/GroupSelectionSearchResultPanel.java |   5 +
 .../search/UserSelectionSearchResultPanel.java  |   5 +
 .../markup/html/bootstrap/dialog/BaseModal.java |   1 +
 .../wicket/markup/html/form/ActionLink.java     |   3 +-
 .../markup/html/form/ActionLinksPanel.java      |  32 +-
 .../wizards/AbstractModalPanelBuilder.java      |   2 +-
 .../client/console/wizards/AjaxWizard.java      |  25 +-
 .../console/wizards/AjaxWizardBuilder.java      |   4 +-
 .../console/wizards/AjaxWizardButtonBar.java    |   6 +
 .../client/console/wizards/WizardMgtPanel.java  |  78 +++-
 .../wizards/any/AnyObjectWizardBuilder.java     | 141 ++----
 .../console/wizards/any/AnyWizardBuilder.java   |  33 +-
 .../console/wizards/any/ConnObjectPanel.java    |  97 ++++-
 .../console/wizards/any/GroupWizardBuilder.java |   7 +-
 .../client/console/wizards/any/ResultPage.java  |  77 ++++
 .../client/console/wizards/any/StatusPanel.java |  98 ++++-
 .../console/wizards/any/UserWizardBuilder.java  |   7 +-
 .../provision/ProvisionWizardBuilder.java       |   3 +-
 .../console/wizards/role/RoleWizardBuilder.java |   4 +-
 .../META-INF/resources/css/syncopeConsole.css   |  26 ++
 .../client/console/pages/ResultStatusModal.html | 226 ----------
 .../console/pages/ResultStatusModal.properties  |  26 --
 .../pages/ResultStatusModal_it.properties       |  26 --
 .../pages/ResultStatusModal_pt_BR.properties    |  26 --
 .../panels/AbstractSearchResultPanel.properties |   2 +
 .../AbstractSearchResultPanel_it.properties     |   2 +
 .../AbstractSearchResultPanel_pt_BR.properties  |   2 +
 .../markup/html/form/ActionLinksPanel.html      |   7 +-
 .../console/wizards/any/ConnObjectPanel.html    |  13 +-
 .../client/console/wizards/any/Details.html     |  10 +-
 .../client/console/wizards/any/ResultPage.html  |  29 ++
 .../console/wizards/any/ResultPage.properties   |  17 +
 .../wizards/any/ResultPage_it.properties        |  17 +
 .../wizards/any/ResultPage_pt_BR.properties     |  17 +
 .../client/console/wizards/any/StatusPanel.html |   4 +-
 55 files changed, 866 insertions(+), 1208 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
index ac38364..e172bd4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
@@ -118,6 +118,16 @@ public final class Constants {
 
     public static final String PREF_ANY_DERIVED_ATTRIBUTES_VIEW = "any.%s.derived.attributes.view";
 
+    public static final String SUSPENDED_ICON = "glyphicon glyphicon-ban-circle";
+
+    public static final String ACTIVE_ICON = "glyphicon glyphicon-ok-circle";
+
+    public static final String UNDEFINED_ICON = "glyphicon glyphicon-question-sign";
+
+    public static final String NOT_FOUND_ICON = "glyphicon glyphicon-remove-circle";
+
+    ;
+
     /**
      * ConnId's GuardedString is not in the classpath.
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
index 0e5c02f..5a25bed 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
@@ -178,20 +178,6 @@ public class StatusUtils implements Serializable {
         return statusPatch;
     }
 
-    public ConnObjectTO getConnObjectTO(
-            final Long anyKey, final String resourceName, final List<ConnObjectWrapper> objects) {
-
-        for (ConnObjectWrapper object : objects) {
-            if (anyKey.equals(object.getAny().getKey())
-                    && resourceName.equalsIgnoreCase(object.getResourceName())) {
-
-                return object.getConnObjectTO();
-            }
-        }
-
-        return null;
-    }
-
     public Image getStatusImage(final String componentId, final Status status) {
         final String alt, title, statusName;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
index da5aac2..a376bf4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
@@ -49,6 +49,8 @@ public class BulkActionModalPage<T extends Serializable, S> extends AbstractModa
 
     private static final long serialVersionUID = 4114026480146090962L;
 
+    private final String pageId = "Any";
+
     public BulkActionModalPage(
             final BaseModal<T> modal,
             final PageReference pageRef,
@@ -56,8 +58,7 @@ public class BulkActionModalPage<T extends Serializable, S> extends AbstractModa
             final List<IColumn<T, S>> columns,
             final Collection<ActionLink.ActionType> actions,
             final BaseRestClient bulkActionExecutor,
-            final String keyFieldName,
-            final String pageId) {
+            final String keyFieldName) {
 
         super(modal, pageRef);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/pages/ResultStatusModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResultStatusModal.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResultStatusModal.java
deleted file mode 100644
index 9507941..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResultStatusModal.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.pages;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.commons.ConnIdSpecialAttributeName;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.Mode;
-import org.apache.syncope.client.console.commons.status.Status;
-import org.apache.syncope.client.console.commons.status.StatusUtils;
-import org.apache.syncope.client.console.panels.AbstractModalPanel;
-import org.apache.syncope.client.console.panels.FailureMessageModal;
-import org.apache.syncope.client.console.rest.UserRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.wicket.Component;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.behavior.Behavior;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.image.Image;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.markup.html.panel.Fragment;
-import org.apache.wicket.model.ResourceModel;
-import org.apache.wicket.request.resource.ContextRelativeResource;
-
-/**
- * Show user or group status after performing a successful operation.
- *
- * @param <T> anyTO
- */
-public final class ResultStatusModal<T extends AnyTO> extends AbstractModalPanel<T> {
-
-    private static final long serialVersionUID = 2646115294319713723L;
-
-    private static final String IMG_PREFIX = "/img/statuses/";
-
-    private final ProvisioningResult<AnyTO> provResult;
-
-    private final Mode mode;
-
-    /**
-     * Status management utilities.
-     */
-    private final StatusUtils statusUtils;
-
-    public static class Builder<T extends AnyTO> implements Serializable {
-
-        private static final long serialVersionUID = 220361441802274899L;
-
-        private Mode mode;
-
-        private ProvisioningResult<AnyTO> provResult;
-
-        private final BaseModal<T> modal;
-
-        private final PageReference pageRef;
-
-        public Builder(
-                final BaseModal<T> modal,
-                final PageReference pageRef,
-                final ProvisioningResult<AnyTO> provResult) {
-            this.provResult = provResult;
-            this.modal = modal;
-            this.pageRef = pageRef;
-        }
-
-        public ResultStatusModal.Builder<T> mode(final Mode mode) {
-            this.mode = mode;
-            return this;
-        }
-
-        public ResultStatusModal<T> build() {
-            return new ResultStatusModal<>(modal, pageRef, this);
-        }
-    }
-
-    private ResultStatusModal(
-            final BaseModal<T> modal,
-            final PageReference pageRef,
-            final Builder<T> builder) {
-
-        super(modal, pageRef);
-
-        this.provResult = builder.provResult;
-        statusUtils = new StatusUtils(new UserRestClient());
-        if (builder.mode == null) {
-            this.mode = Mode.ADMIN;
-        } else {
-            this.mode = builder.mode;
-        }
-
-        final WebMarkupContainer container = new WebMarkupContainer("container");
-        container.setOutputMarkupId(true);
-        add(container);
-
-        final Fragment fragment = new Fragment("resultFrag", mode == Mode.SELF
-                ? "userSelfResultFrag"
-                : "propagationResultFrag", this);
-        fragment.setOutputMarkupId(true);
-        container.add(fragment);
-
-        if (mode == Mode.ADMIN) {
-            // add Syncope propagation status
-            PropagationStatus syncope = new PropagationStatus();
-            syncope.setResource("Syncope");
-            syncope.setStatus(PropagationTaskExecStatus.SUCCESS);
-
-            List<PropagationStatus> propagations = new ArrayList<PropagationStatus>();
-            propagations.add(syncope);
-            propagations.addAll(provResult.getPropagationStatuses());
-
-            AnyTO any = provResult.getAny();
-
-            fragment.add(new Label("info",
-                    ((any instanceof UserTO) && ((UserTO) any).getUsername() != null)
-                            ? ((UserTO) any).getUsername()
-                            : ((any instanceof GroupTO) && ((GroupTO) any).getName() != null)
-                                    ? ((GroupTO) any).getName()
-                                    : String.valueOf(any.getKey())));
-
-            final ListView<PropagationStatus> propRes = new ListView<PropagationStatus>("resources",
-                    propagations) {
-
-                private static final long serialVersionUID = -1020475259727720708L;
-
-                @Override
-                protected void populateItem(final ListItem<PropagationStatus> item) {
-                    final PropagationStatus propTO = (PropagationStatus) item.getDefaultModelObject();
-
-                    final ListView<String> attributes = getConnObjectView(propTO);
-
-                    final Fragment attrhead;
-                    if (attributes.getModelObject() == null || attributes.getModelObject().isEmpty()) {
-                        attrhead = new Fragment("attrhead", "emptyAttrHeadFrag", this);
-                    } else {
-                        attrhead = new Fragment("attrhead", "attrHeadFrag", this);
-                    }
-
-                    item.add(attrhead);
-                    item.add(attributes);
-
-                    attrhead.add(new Label("resource", propTO.getResource()));
-
-                    attrhead.add(new Label("propagation", propTO.getStatus() == null
-                            ? "UNDEFINED" : propTO.getStatus().toString()));
-
-                    final Image image;
-                    final String alt, title;
-
-                    final BaseModal<T> failureWindow = new BaseModal<>("failureWindow");
-
-                    final AjaxLink<?> failureWindowLink = new AjaxLink<Void>("showFailureWindow") {
-
-                        private static final long serialVersionUID = -7978723352517770644L;
-
-                        @Override
-                        public void onClick(final AjaxRequestTarget target) {
-                            failureWindow.show(target);
-                        }
-                    };
-
-                    switch (propTO.getStatus()) {
-
-                        case SUCCESS:
-                        case CREATED:
-                            image = new Image("icon",
-                                    new ContextRelativeResource(IMG_PREFIX + Status.ACTIVE.toString()
-                                            + Constants.PNG_EXT));
-                            alt = "success icon";
-                            title = "success";
-                            failureWindow.setVisible(false);
-                            failureWindowLink.setEnabled(false);
-                            break;
-
-                        default:
-                            image = new Image("icon",
-                                    new ContextRelativeResource(IMG_PREFIX + Status.SUSPENDED.toString()
-                                            + Constants.PNG_EXT));
-                            alt = "failure icon";
-                            title = "failure";
-                    }
-
-                    image.add(new Behavior() {
-
-                        private static final long serialVersionUID = 1469628524240283489L;
-
-                        @Override
-                        public void onComponentTag(final Component component, final ComponentTag tag) {
-                            tag.put("alt", alt);
-                            tag.put("title", title);
-                        }
-                    });
-                    final FailureMessageModal<T> executionFailureMessagePage;
-                    if (propTO.getFailureReason() == null) {
-                        executionFailureMessagePage = new FailureMessageModal<>(
-                                modal, pageRef, StringUtils.EMPTY);
-                    } else {
-                        executionFailureMessagePage = new FailureMessageModal<>(
-                                modal, pageRef, propTO.getFailureReason());
-                    }
-
-                    failureWindow.setContent(executionFailureMessagePage);
-                }
-            };
-            fragment.add(propRes);
-        }
-
-        final AjaxLink<Void> close = new IndicatingAjaxLink<Void>("close") {
-
-            private static final long serialVersionUID = -7978723352517770644L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target) {
-                builder.modal.close(target);
-            }
-        };
-        container.add(close);
-
-        setOutputMarkupId(true);
-    }
-
-    /**
-     * Get remote attributes list view.
-     *
-     * @param propTO propagation TO.
-     * @return list view.
-     */
-    private ListView<String> getConnObjectView(final PropagationStatus propTO) {
-        final ConnObjectTO before = propTO.getBeforeObj();
-        final ConnObjectTO after = propTO.getAfterObj();
-
-        // sorted in reversed presentation order
-        final List<String> head = new ArrayList<String>();
-        if (provResult.getAny() instanceof UserTO) {
-            head.add(ConnIdSpecialAttributeName.PASSWORD);
-            head.add(ConnIdSpecialAttributeName.ENABLE);
-        }
-        head.add(ConnIdSpecialAttributeName.UID);
-        head.add(ConnIdSpecialAttributeName.NAME);
-
-        final Map<String, AttrTO> beforeAttrMap = before == null
-                ? Collections.<String, AttrTO>emptyMap()
-                : before.getPlainAttrMap();
-
-        final Map<String, AttrTO> afterAttrMap = after == null
-                ? Collections.<String, AttrTO>emptyMap()
-                : after.getPlainAttrMap();
-
-        final Set<String> attributes = new HashSet<String>();
-        attributes.addAll(beforeAttrMap.keySet());
-        attributes.addAll(afterAttrMap.keySet());
-
-        if (!(provResult.getAny() instanceof UserTO)) {
-            attributes.remove(ConnIdSpecialAttributeName.PASSWORD);
-            attributes.remove(ConnIdSpecialAttributeName.ENABLE);
-        }
-
-        final List<String> profile = new ArrayList<String>();
-        profile.addAll(attributes);
-        profile.removeAll(head);
-        Collections.sort(profile);
-
-        for (String attr : head) {
-            if (attributes.contains(attr)) {
-                profile.add(0, attr);
-            }
-        }
-
-        return new ListView<String>("attrs", profile) {
-
-            private static final long serialVersionUID = 4949588177564901031L;
-
-            @Override
-            protected void populateItem(final ListItem<String> item) {
-                String name = item.getModelObject();
-
-                final Fragment beforeValue;
-                final Fragment afterValue;
-                if (ConnIdSpecialAttributeName.ENABLE.equals(name)) {
-                    beforeValue = getStatusIcon("beforeValue", propTO.getResource(), before);
-                    afterValue = getStatusIcon("afterValue", propTO.getResource(), after);
-                } else {
-                    beforeValue = getLabelValue("beforeValue", name, beforeAttrMap);
-                    afterValue = getLabelValue("afterValue", name, afterAttrMap);
-                }
-
-                item.add(new Label("attrName", new ResourceModel(name, name)));
-
-                item.add(beforeValue);
-                item.add(afterValue);
-            }
-        };
-    }
-
-    /**
-     * Get fragment for attribute value (not remote status).
-     *
-     * @param id component id to be replaced with the fragment content.
-     * @param attrName remote attribute name
-     * @param attrMap remote attributes map.
-     * @return fragment.
-     */
-    private Fragment getLabelValue(final String id, final String attrName, final Map<String, AttrTO> attrMap) {
-        final String value;
-
-        final AttrTO attr = attrMap.get(attrName);
-
-        if (attr == null || attr.getValues() == null || attr.getValues().isEmpty()) {
-            value = "";
-        } else if (ConnIdSpecialAttributeName.PASSWORD.equals(attrName)) {
-            value = "********";
-        } else {
-            value = attr.getValues().size() > 1
-                    ? attr.getValues().toString()
-                    : attr.getValues().get(0);
-        }
-
-        Component label = new Label("value", value.length() > 50 ? value.substring(0, 50) + "..." : value).
-                add(new Behavior() {
-
-                    private static final long serialVersionUID = 1469628524240283489L;
-
-                    @Override
-                    public void onComponentTag(final Component component, final ComponentTag tag) {
-                        tag.put("title", value);
-                    }
-                });
-
-        final Fragment frag = new Fragment(id, "attrValueFrag", this);
-        frag.add(label);
-
-        return frag;
-    }
-
-    /**
-     * Get fragment for user status icon.
-     *
-     * @param id component id to be replaced with the fragment content
-     * @param resourceName resource name
-     * @param objectTO connector object TO
-     * @return fragment.
-     */
-    private Fragment getStatusIcon(final String id, final String resourceName, final ConnObjectTO objectTO) {
-        final Image image;
-        final String alt, title;
-        switch (statusUtils.getStatusBean(
-                provResult.getAny(), resourceName, objectTO, this.provResult.getAny() instanceof GroupTO).getStatus()) {
-
-            case ACTIVE:
-                image = new Image("status",
-                        new ContextRelativeResource(IMG_PREFIX + Status.ACTIVE.toString() + Constants.PNG_EXT));
-                alt = "active icon";
-                title = "Enabled";
-                break;
-
-            case SUSPENDED:
-                image = new Image("status",
-                        new ContextRelativeResource(IMG_PREFIX + Status.SUSPENDED.toString() + Constants.PNG_EXT));
-                alt = "inactive icon";
-                title = "Disabled";
-                break;
-
-            default:
-                image = null;
-                alt = null;
-                title = null;
-        }
-
-        final Fragment frag;
-        if (image == null) {
-            frag = new Fragment(id, "emptyFrag", this);
-        } else {
-            image.add(new Behavior() {
-
-                private static final long serialVersionUID = 1469628524240283489L;
-
-                @Override
-                public void onComponentTag(final Component component, final ComponentTag tag) {
-                    tag.put("alt", alt);
-                    tag.put("title", title);
-                    tag.put("width", "12px");
-                    tag.put("height", "12px");
-                }
-            });
-
-            frag = new Fragment(id, "remoteStatusFrag", this);
-            frag.add(image);
-        }
-
-        return frag;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
index a744d0a..9da22a5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -170,7 +170,7 @@ public abstract class AbstractSearchResultPanel<
                 ? (create ? (int) resultTable.getPageCount() - 1 : (int) resultTable.getCurrentPage()) : 0;
 
         AjaxDataTablePanel.Builder<T, String> resultTableBuilder = new AjaxDataTablePanel.Builder<>(
-                dataProvider, getPageId(), page.getPageReference()).
+                dataProvider, page.getPageReference()).
                 setColumns(getColumns()).
                 setRowsPerPage(rows).
                 setBulkActions(getBulkActions(), restClient, "key").
@@ -257,8 +257,6 @@ public abstract class AbstractSearchResultPanel<
 
     protected abstract Collection<ActionLink.ActionType> getBulkActions();
 
-    protected abstract String getPageId();
-
     public abstract static class Builder<T extends Serializable, W extends Serializable, E extends BaseRestClient>
             extends WizardMgtPanel.Builder<W> {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
index 6a5b596..3cd283d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -67,15 +67,12 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab
 
         private String itemKeyField;
 
-        private final String pageId;
-
         private final PageReference pageRef;
 
         private WebMarkupContainer container;
 
-        public Builder(final ISortableDataProvider<T, S> provider, final String pageId, final PageReference pageRef) {
+        public Builder(final ISortableDataProvider<T, S> provider, final PageReference pageRef) {
             this.dataProvider = provider;
-            this.pageId = pageId;
             this.pageRef = pageRef;
         }
 
@@ -208,8 +205,7 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab
                         builder.columns,
                         builder.bulkActions,
                         builder.bulkActionExecutor,
-                        builder.itemKeyField,
-                        builder.pageId));
+                        builder.itemKeyField));
 
                 bulkModalWin.show(target);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
index fa0b7d7..a7e5d31 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
@@ -18,21 +18,17 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.client.console.commons.AnyDataProvider;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.AnyDisplayAttributesModalPage;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.client.console.rest.AnyObjectRestClient;
-import org.apache.syncope.client.console.rest.SchemaRestClient;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
@@ -41,7 +37,6 @@ import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.AnyHandler;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.types.AnyEntitlement;
@@ -52,65 +47,16 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.ResourceModel;
 import org.springframework.util.ReflectionUtils;
 
-public class AnyObjectSearchResultPanel<T extends AnyTO>
-        extends AbstractSearchResultPanel<T, AnyHandler<T>, AnyDataProvider<T>, AbstractAnyRestClient<T>> {
+public class AnyObjectSearchResultPanel extends AnySearchResultPanel<AnyObjectTO> {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
-    protected final SchemaRestClient schemaRestClient = new SchemaRestClient();
-
-    protected final List<String> schemaNames;
-
-    protected final List<String> dSchemaNames;
-
-    private final String pageID = "Any";
-
-    /**
-     * Filter used in case of filtered search.
-     */
-    private String fiql;
-
-    /**
-     * Realm related to current panel.
-     */
-    protected final String realm;
-
-    /**
-     * Any type related to current panel.
-     */
-    protected final String type;
-
-    protected AnyObjectSearchResultPanel(final String id, final Builder<T> builder) {
+    protected AnyObjectSearchResultPanel(final String id, final Builder builder) {
         super(id, builder);
-        this.realm = builder.realm;
-        this.type = builder.type;
-        this.fiql = builder.fiql;
-
-        modal.size(Modal.Size.Large);
-
-        add(new Label("name", builder.type));
-
-        this.schemaNames = new ArrayList<>();
-        for (AnyTypeClassTO anyTypeClassTO : AnySearchResultPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) {
-            this.schemaNames.addAll(anyTypeClassTO.getPlainSchemas());
-        }
-        this.dSchemaNames = new ArrayList<>();
-        for (AnyTypeClassTO anyTypeClassTO : AnySearchResultPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) {
-            this.dSchemaNames.addAll(anyTypeClassTO.getDerSchemas());
-        }
-
-        initResultTable();
-    }
-
-    @Override
-    protected AnyDataProvider<T> dataProvider() {
-        final AnyDataProvider<T> dp = new AnyDataProvider<>(restClient, rows, filtered, realm, type);
-        return dp.setFIQL(this.fiql);
     }
 
     @Override
@@ -119,80 +65,81 @@ public class AnyObjectSearchResultPanel<T extends AnyTO>
     }
 
     @Override
-    protected List<IColumn<T, String>> getColumns() {
-        final List<IColumn<T, String>> columns = new ArrayList<>();
+    protected List<IColumn<AnyObjectTO, String>> getColumns() {
+        final List<IColumn<AnyObjectTO, String>> columns = new ArrayList<>();
 
         for (String name : prefMan.getList(getRequest(), String.format(Constants.PREF_ANY_DETAILS_VIEW, type))) {
             final Field field = ReflectionUtils.findField(AnyObjectTO.class, name);
 
             if ("token".equalsIgnoreCase(name)) {
-                columns.add(new PropertyColumn<T, String>(new ResourceModel(name, name), name, name));
+                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
             } else if (field != null && field.getType().equals(Date.class)) {
-                columns.add(new PropertyColumn<T, String>(new ResourceModel(name, name), name, name));
+                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
             } else {
-                columns.add(new PropertyColumn<T, String>(new ResourceModel(name, name), name, name));
+                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
             }
         }
 
         for (String name : prefMan.getList(getRequest(), String.format(Constants.PREF_ANY_ATTRIBUTES_VIEW, type))) {
             if (schemaNames.contains(name)) {
-                columns.add(new AttrColumn<T>(name, SchemaType.PLAIN));
+                columns.add(new AttrColumn<AnyObjectTO>(name, SchemaType.PLAIN));
             }
         }
 
         for (String name
                 : prefMan.getList(getRequest(), String.format(Constants.PREF_ANY_DERIVED_ATTRIBUTES_VIEW, type))) {
             if (dSchemaNames.contains(name)) {
-                columns.add(new AttrColumn<T>(name, SchemaType.DERIVED));
+                columns.add(new AttrColumn<AnyObjectTO>(name, SchemaType.DERIVED));
             }
         }
 
         // Add defaults in case of no selection
         if (columns.isEmpty()) {
             for (String name : AnyDisplayAttributesModalPage.ANY_DEFAULT_SELECTION) {
-                columns.add(new PropertyColumn<T, String>(new ResourceModel(name, name), name, name));
+                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
             }
 
         }
 
-        columns.add(new ActionColumn<T, String>(new ResourceModel("actions", "")) {
+        columns.add(new ActionColumn<AnyObjectTO, String>(new ResourceModel("actions", "")) {
 
             private static final long serialVersionUID = -3503023501954863131L;
 
             @Override
-            public ActionLinksPanel<T> getActions(final String componentId, final IModel<T> model) {
-                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder(page.getPageReference());
+            public ActionLinksPanel<AnyObjectTO> getActions(final String componentId, final IModel<AnyObjectTO> model) {
+                final ActionLinksPanel.Builder<AnyObjectTO> panel = ActionLinksPanel.builder(page.getPageReference());
 
-                panel.add(new ActionLink<T>() {
+                panel.add(new ActionLink<AnyObjectTO>() {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final T ignore) {
+                    public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
                         send(AnyObjectSearchResultPanel.this, Broadcast.EXACT,
-                                new AjaxWizard.EditItemActionEvent<AnyHandler<T>>(
-                                        new AnyHandler<T>(
-                                                new AnyObjectRestClient().<T>read(model.getObject().getKey())),
+                                new AjaxWizard.EditItemActionEvent<AnyHandler<AnyObjectTO>>(
+                                        new AnyHandler<AnyObjectTO>(new AnyObjectRestClient().<AnyObjectTO>read(
+                                                model.getObject().getKey())),
                                         target));
                     }
                 }, ActionLink.ActionType.EDIT, String.format("%s_%s", type, AnyEntitlement.READ)).add(
-                        new ActionLink<T>() {
+                        new ActionLink<AnyObjectTO>() {
 
                     private static final long serialVersionUID = -7978723352517770645L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final T ignore) {
-                        final T clone = SerializationUtils.clone(model.getObject());
+                    public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                        final AnyObjectTO clone = SerializationUtils.clone(model.getObject());
                         clone.setKey(0L);
                         send(AnyObjectSearchResultPanel.this, Broadcast.EXACT,
-                                new AjaxWizard.NewItemActionEvent<AnyHandler<T>>(new AnyHandler<T>(clone), target));
+                                new AjaxWizard.NewItemActionEvent<AnyHandler<AnyObjectTO>>(new AnyHandler<AnyObjectTO>(
+                                        clone), target));
                     }
-                }, ActionLink.ActionType.CLONE, StandardEntitlement.USER_CREATE).add(new ActionLink<T>() {
+                }, ActionLink.ActionType.CLONE, StandardEntitlement.USER_CREATE).add(new ActionLink<AnyObjectTO>() {
 
                             private static final long serialVersionUID = -7978723352517770646L;
 
                             @Override
-                            public void onClick(final AjaxRequestTarget target, final T ignore) {
+                            public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
                                 try {
                                     restClient.delete(model.getObject().getETagValue(), model.getObject().getKey());
                                     info(getString(Constants.OPERATION_SUCCEEDED));
@@ -245,75 +192,23 @@ public class AnyObjectSearchResultPanel<T extends AnyTO>
         return columns;
     }
 
-    public void search(final String fiql, final AjaxRequestTarget target) {
-        this.fiql = fiql;
-        dataProvider.setFIQL(fiql);
-        super.search(target);
-    }
-
-    @Override
-    protected Collection<ActionLink.ActionType> getBulkActions() {
-        final List<ActionLink.ActionType> bulkActions = new ArrayList<>();
+    public static class Builder extends AnySearchResultPanel.Builder<AnyObjectTO> {
 
-        bulkActions.add(ActionLink.ActionType.DELETE);
-        bulkActions.add(ActionLink.ActionType.SUSPEND);
-        bulkActions.add(ActionLink.ActionType.REACTIVATE);
-
-        return bulkActions;
-    }
-
-    @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    public interface AnySearchResultPanelBuilder extends Serializable {
-
-        List<AnyTypeClassTO> getAnyTypeClassTOs();
-    }
-
-    public static class Builder<T extends AnyTO>
-            extends AbstractSearchResultPanel.Builder<T, AnyHandler<T>, AbstractAnyRestClient<T>>
-            implements AnySearchResultPanelBuilder {
-
-        private static final long serialVersionUID = -6828423611982275640L;
-
-        /**
-         * Realm related to current panel.
-         */
-        protected String realm = "/";
-
-        /**
-         * Any type related to current panel.
-         */
-        protected final String type;
-
-        private final List<AnyTypeClassTO> anyTypeClassTOs;
+        private static final long serialVersionUID = -6828423611982275641L;
 
         public Builder(
                 final List<AnyTypeClassTO> anyTypeClassTOs,
-                final AbstractAnyRestClient<T> restClient,
+                final AbstractAnyRestClient<AnyObjectTO> restClient,
                 final String type,
                 final PageReference pageRef) {
 
-            super(restClient, pageRef);
-            this.anyTypeClassTOs = anyTypeClassTOs;
-            this.type = type;
-        }
-
-        @Override
-        protected WizardMgtPanel<AnyHandler<T>> newInstance(final String id) {
-            return new AnyObjectSearchResultPanel<T>(id, this);
-        }
-
-        public Builder<T> setRealm(final String realm) {
-            this.realm = realm;
-            return this;
+            super(anyTypeClassTOs, restClient, type, pageRef);
+            setShowResultPage(true);
         }
 
         @Override
-        public List<AnyTypeClassTO> getAnyTypeClassTOs() {
-            return this.anyTypeClassTOs;
+        protected WizardMgtPanel<AnyHandler<AnyObjectTO>> newInstance(final String id) {
+            return new AnyObjectSearchResultPanel(id, this);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java
new file mode 100644
index 0000000..6021d8e
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.commons.AnyDataProvider;
+import org.apache.syncope.client.console.commons.SerializableTransformer;
+import org.apache.syncope.client.console.commons.status.ConnObjectWrapper;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wizards.any.AnyHandler;
+import org.apache.syncope.client.console.wizards.any.StatusPanel;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.util.ListModel;
+
+public abstract class AnySearchResultPanel<T extends AnyTO>
+        extends AbstractSearchResultPanel<T, AnyHandler<T>, AnyDataProvider<T>, AbstractAnyRestClient<T>> {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected final SchemaRestClient schemaRestClient = new SchemaRestClient();
+
+    protected final List<String> schemaNames;
+
+    protected final List<String> dSchemaNames;
+
+    /**
+     * Filter used in case of filtered search.
+     */
+    protected String fiql;
+
+    /**
+     * Realm related to current panel.
+     */
+    protected final String realm;
+
+    /**
+     * Any type related to current panel.
+     */
+    protected final String type;
+
+    protected AnySearchResultPanel(final String id, final Builder<T> builder) {
+        super(id, builder);
+        this.realm = builder.realm;
+        this.type = builder.type;
+        this.fiql = builder.fiql;
+
+        modal.size(Modal.Size.Large);
+
+        add(new Label("name", builder.type));
+
+        this.schemaNames = new ArrayList<>();
+        for (AnyTypeClassTO anyTypeClassTO : AnySearchResultPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) {
+            this.schemaNames.addAll(anyTypeClassTO.getPlainSchemas());
+        }
+        this.dSchemaNames = new ArrayList<>();
+        for (AnyTypeClassTO anyTypeClassTO : AnySearchResultPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) {
+            this.dSchemaNames.addAll(anyTypeClassTO.getDerSchemas());
+        }
+
+        initResultTable();
+    }
+
+    @Override
+    protected AnyDataProvider<T> dataProvider() {
+        final AnyDataProvider<T> dp = new AnyDataProvider<>(restClient, rows, filtered, realm, type);
+        return dp.setFIQL(this.fiql);
+    }
+
+    public void search(final String fiql, final AjaxRequestTarget target) {
+        this.fiql = fiql;
+        dataProvider.setFIQL(fiql);
+        super.search(target);
+    }
+
+    @Override
+    protected Collection<ActionLink.ActionType> getBulkActions() {
+        final List<ActionLink.ActionType> bulkActions = new ArrayList<>();
+
+        bulkActions.add(ActionLink.ActionType.DELETE);
+        bulkActions.add(ActionLink.ActionType.SUSPEND);
+        bulkActions.add(ActionLink.ActionType.REACTIVATE);
+
+        return bulkActions;
+    }
+
+    public interface AnySearchResultPanelBuilder extends Serializable {
+
+        List<AnyTypeClassTO> getAnyTypeClassTOs();
+    }
+
+    public abstract static class Builder<T extends AnyTO>
+            extends AbstractSearchResultPanel.Builder<T, AnyHandler<T>, AbstractAnyRestClient<T>>
+            implements AnySearchResultPanelBuilder {
+
+        private static final long serialVersionUID = -6828423611982275640L;
+
+        /**
+         * Realm related to current panel.
+         */
+        protected String realm = "/";
+
+        /**
+         * Any type related to current panel.
+         */
+        protected final String type;
+
+        private final List<AnyTypeClassTO> anyTypeClassTOs;
+
+        public Builder(
+                final List<AnyTypeClassTO> anyTypeClassTOs,
+                final AbstractAnyRestClient<T> restClient,
+                final String type,
+                final PageReference pageRef) {
+
+            super(restClient, pageRef);
+            this.anyTypeClassTOs = anyTypeClassTOs;
+            this.type = type;
+        }
+
+        public Builder<T> setRealm(final String realm) {
+            this.realm = realm;
+            return this;
+        }
+
+        @Override
+        public List<AnyTypeClassTO> getAnyTypeClassTOs() {
+            return this.anyTypeClassTOs;
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected Panel customResultBody(
+            final String panelId, final AnyHandler<T> item, final Serializable result) {
+        if (!(result instanceof ProvisioningResult)) {
+            throw new IllegalStateException("Unsupported result type");
+        }
+
+        return new StatusPanel(
+                panelId,
+                ((ProvisioningResult<T>) result).getAny(),
+                new ListModel<StatusBean>(new ArrayList<StatusBean>()),
+                CollectionUtils.collect(
+                        ((ProvisioningResult<T>) result).getPropagationStatuses(),
+                        new SerializableTransformer<PropagationStatus, Pair<ConnObjectTO, ConnObjectWrapper>>() {
+
+                    private static final long serialVersionUID = -4931455531906427515L;
+
+                    @Override
+                    public Pair<ConnObjectTO, ConnObjectWrapper> transform(final PropagationStatus input) {
+                        ConnObjectTO before = input.getBeforeObj();
+                        ConnObjectWrapper afterObjWrapper = new ConnObjectWrapper(
+                                ((ProvisioningResult<T>) result).getAny(),
+                                input.getResource(),
+                                input.getAfterObj());
+                        return Pair.of(before, afterObjWrapper);
+                    }
+
+                }, new ArrayList<Pair<ConnObjectTO, ConnObjectWrapper>>()),
+                pageRef);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 4ece79e..be9d3c0 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
@@ -60,8 +60,6 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
 
     private static final long serialVersionUID = -2356760296223908382L;
 
-    private final String pageID = "AnyTypesClasses";
-
     public AnyTypeClassesPanel(final String id,
             final AbstractSearchResultPanel.Builder<AnyTypeClassTO, AnyTypeClassTO, BaseRestClient> builder) {
         super(id, builder);
@@ -114,7 +112,8 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
             }
 
             @Override
-            protected void onApplyInternal(final AnyTypeClassTO modelObject) {
+            protected Serializable onApplyInternal(final AnyTypeClassTO modelObject) {
+                return null;
             }
         }, true);
 
@@ -138,11 +137,6 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
     }
 
     @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    @Override
     protected List<IColumn<AnyTypeClassTO, String>> getColumns() {
 
         final List<IColumn<AnyTypeClassTO, String>> columns = new ArrayList<>();
@@ -205,8 +199,8 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
             public void populateItem(final Item<ICellPopulator<AnyTypeClassTO>> item, final String componentId,
                     final IModel<AnyTypeClassTO> model) {
 
-                final ActionLinksPanel.Builder<Serializable> actionLinks =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<Serializable> actionLinks = ActionLinksPanel.builder(page.
+                        getPageReference());
                 actionLinks.setDisableIndicator(true);
                 actionLinks.addWithRoles(new ActionLink<Serializable>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypePanel.java
index e445746..3bea20a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypePanel.java
@@ -64,8 +64,6 @@ public class AnyTypePanel extends AbstractTypesPanel<AnyTypeTO, AnyTypeProvider>
 
     private static final long serialVersionUID = 3905038169553185171L;
 
-    private final String pageID = "AnyTypes";
-
     public AnyTypePanel(final String id, final Builder<AnyTypeTO, AnyTypeTO, BaseRestClient> builder) {
         super(id, builder);
     }
@@ -117,7 +115,9 @@ public class AnyTypePanel extends AbstractTypesPanel<AnyTypeTO, AnyTypeProvider>
             }
 
             @Override
-            protected void onApplyInternal(final AnyTypeTO modelObject) {
+            protected Serializable onApplyInternal(final AnyTypeTO modelObject) {
+                // do nothing
+                return null;
             }
         }, true);
 
@@ -141,11 +141,6 @@ public class AnyTypePanel extends AbstractTypesPanel<AnyTypeTO, AnyTypeProvider>
     }
 
     @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    @Override
     protected List<IColumn<AnyTypeTO, String>> getColumns() {
 
         final List<IColumn<AnyTypeTO, String>> columns = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 bee0c05..ecf64c9 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
@@ -21,15 +21,18 @@ 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.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
 
-public class FailureMessageModal<T extends Serializable> extends AbstractModalPanel<T> {
+public class FailureMessageModal<T extends Serializable> extends Panel implements ModalPanel<T> {
 
     private static final long serialVersionUID = 9216117990503199258L;
 
-    public FailureMessageModal(final BaseModal<T> modal, final PageReference pageRef, final String failureMessage) {
-        super(modal, pageRef);
+    public FailureMessageModal(final PageReference pageRef, final String failureMessage) {
+        super(BaseModal.CONTENT_ID);
         final Label executionFailureMessage;
         if (!failureMessage.isEmpty()) {
             executionFailureMessage = new Label("failureMessage", new Model<String>(failureMessage));
@@ -38,4 +41,19 @@ public class FailureMessageModal<T extends Serializable> extends AbstractModalPa
         }
         add(executionFailureMessage.setOutputMarkupId(true));
     }
+
+    @Override
+    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void onError(final AjaxRequestTarget target, final Form<?> form) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public T getItem() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 27d27b6..762878b 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
@@ -22,7 +22,6 @@ import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
@@ -34,7 +33,6 @@ import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
@@ -54,12 +52,10 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.ResourceModel;
 import org.springframework.util.ReflectionUtils;
 
-public class GroupSearchResultPanel extends AnyObjectSearchResultPanel<GroupTO> {
+public class GroupSearchResultPanel extends AnySearchResultPanel<GroupTO> {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
-    private final String pageID = "Groups";
-
     protected GroupSearchResultPanel(final String id, final Builder builder) {
         super(id, builder);
     }
@@ -192,23 +188,7 @@ public class GroupSearchResultPanel extends AnyObjectSearchResultPanel<GroupTO>
         return columns;
     }
 
-    @Override
-    protected Collection<ActionLink.ActionType> getBulkActions() {
-        final List<ActionType> bulkActions = new ArrayList<>();
-
-        bulkActions.add(ActionType.DELETE);
-        bulkActions.add(ActionType.SUSPEND);
-        bulkActions.add(ActionType.REACTIVATE);
-
-        return bulkActions;
-    }
-
-    @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    public static class Builder extends AnyObjectSearchResultPanel.Builder<GroupTO>
+    public static class Builder extends AnySearchResultPanel.Builder<GroupTO>
             implements AnySearchResultPanelBuilder {
 
         private static final long serialVersionUID = 1L;
@@ -220,6 +200,7 @@ public class GroupSearchResultPanel extends AnyObjectSearchResultPanel<GroupTO>
                 final PageReference pageRef) {
 
             super(anyTypeClassTOs, restClient, type, pageRef);
+            setShowResultPage(true);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 1755341..c07789c 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
@@ -30,7 +30,7 @@ import org.apache.syncope.client.console.rest.UserRestClient;
 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.any.AnyWizardBuilder;
+import org.apache.syncope.client.console.wizards.any.AnyObjectWizardBuilder;
 import org.apache.syncope.client.console.wizards.any.GroupWizardBuilder;
 import org.apache.syncope.client.console.wizards.any.UserWizardBuilder;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
@@ -183,12 +183,12 @@ public abstract class Realm extends Panel {
                 final AnyObjectTO anyObjectTO = new AnyObjectTO();
                 anyObjectTO.setRealm(realmTO.getFullPath());
                 anyObjectTO.setType(anyTypeTO.getKey());
-                panel = new AnyObjectSearchResultPanel.Builder<AnyObjectTO>(
+                panel = new AnyObjectSearchResultPanel.Builder(
                         anyTypeRestClient.getAnyTypeClass(anyTypeTO.getClasses().toArray(new String[] {})),
                         anyObjectRestClient,
                         anyTypeTO.getKey(),
                         pageReference).setRealm(realmTO.getFullPath()).
-                        addNewItemPanelBuilder(new AnyWizardBuilder<AnyObjectTO>(
+                        addNewItemPanelBuilder(new AnyObjectWizardBuilder(
                                 BaseModal.CONTENT_ID, anyObjectTO, anyTypeTO.getClasses(), pageRef)).
                         addNotificationPanel(BasePage.class.cast(this.pageRef.getPage()).getNotificationPanel()).
                         build(id);

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 f4c64e4..0bafa60 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
@@ -62,8 +62,6 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
 
     private static final long serialVersionUID = -3731778000138547357L;
 
-    private final String pageID = "RelationshipTypes";
-
     public RelationshipTypePanel(
             final String id, final Builder<RelationshipTypeTO, RelationshipTypeTO, BaseRestClient> builder) {
         super(id, builder);
@@ -119,7 +117,9 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
             }
 
             @Override
-            protected void onApplyInternal(final RelationshipTypeTO modelObject) {
+            protected Serializable onApplyInternal(final RelationshipTypeTO modelObject) {
+                // do nothing
+                return null;
             }
         }, true);
 
@@ -143,11 +143,6 @@ public class RelationshipTypePanel extends AbstractTypesPanel<RelationshipTypeTO
     }
 
     @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    @Override
     protected List<IColumn<RelationshipTypeTO, String>> getColumns() {
 
         final List<IColumn<RelationshipTypeTO, String>> columns = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 6e2492c..b091a4b 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
@@ -51,10 +51,9 @@ public class RoleSearchResultPanel
 
     private static final long serialVersionUID = -1100228004207271270L;
 
-    private final String pageID = "Roles";
-
     protected RoleSearchResultPanel(final String id, final Builder builder) {
         super(id, builder);
+        setShowResultPage(true);
 
         modal.size(Modal.Size.Large);
         initResultTable();
@@ -161,11 +160,6 @@ public class RoleSearchResultPanel
         return bulkActions;
     }
 
-    @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
     public abstract static class Builder
             extends AbstractSearchResultPanel.Builder<RoleTO, RoleHandler, RoleRestClient> {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
index d8809f2..dba3087 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
@@ -86,8 +86,6 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
         }
     };
 
-    private final String pageID = "Schema";
-
     private final SchemaRestClient schemaRestClient = new SchemaRestClient();
 
     private final SchemaType schemaType;
@@ -152,7 +150,8 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
                 }
 
                 @Override
-                protected void onApplyInternal(final AbstractSchemaTO modelObject) {
+                protected Serializable onApplyInternal(final AbstractSchemaTO modelObject) {
+                    return null;
                 }
             }, true);
 
@@ -179,11 +178,6 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
     }
 
     @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    @Override
     protected List<IColumn<AbstractSchemaTO, String>> getColumns() {
 
         final List<IColumn<AbstractSchemaTO, String>> columns = new ArrayList<>();
@@ -255,8 +249,8 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
 
                 final AbstractSchemaTO schemaTO = model.getObject();
 
-                final ActionLinksPanel.Builder<Serializable> actionLinks =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<Serializable> actionLinks = ActionLinksPanel.builder(page.
+                        getPageReference());
                 actionLinks.setDisableIndicator(true);
                 actionLinks.setDisableIndicator(true);
                 actionLinks.addWithRoles(new ActionLink<Serializable>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 bc83d03..e4ec8dd 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
@@ -64,8 +64,6 @@ public class SecurityQuestionsPanel extends AbstractSearchResultPanel<
 
     private static final long serialVersionUID = 3323019773236588850L;
 
-    private final String pageID = "SecurityQuestions";
-
     public SecurityQuestionsPanel(final String id, final PageReference pageRef) {
         super(id, new Builder<SecurityQuestionTO, SecurityQuestionTO, BaseRestClient>(null, pageRef) {
 
@@ -93,7 +91,9 @@ public class SecurityQuestionsPanel extends AbstractSearchResultPanel<
             }
 
             @Override
-            protected void onApplyInternal(final SecurityQuestionTO modelObject) {
+            protected Serializable onApplyInternal(final SecurityQuestionTO modelObject) {
+                // do nothing
+                return null;
             }
         }, true);
 
@@ -126,11 +126,6 @@ public class SecurityQuestionsPanel extends AbstractSearchResultPanel<
     }
 
     @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    @Override
     protected List<IColumn<SecurityQuestionTO, String>> getColumns() {
 
         final List<IColumn<SecurityQuestionTO, String>> columns = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 c7501c6..e1625f5 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
@@ -22,7 +22,6 @@ import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
@@ -35,7 +34,6 @@ import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
@@ -56,12 +54,10 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.model.ResourceModel;
 import org.springframework.util.ReflectionUtils;
 
-public class UserSearchResultPanel extends AnyObjectSearchResultPanel<UserTO> {
+public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
-    private final String pageID = "Users";
-
     protected UserSearchResultPanel(final String id, final Builder builder) {
         super(id, builder);
     }
@@ -234,23 +230,7 @@ public class UserSearchResultPanel extends AnyObjectSearchResultPanel<UserTO> {
         return columns;
     }
 
-    @Override
-    protected Collection<ActionLink.ActionType> getBulkActions() {
-        final List<ActionType> bulkActions = new ArrayList<>();
-
-        bulkActions.add(ActionType.DELETE);
-        bulkActions.add(ActionType.SUSPEND);
-        bulkActions.add(ActionType.REACTIVATE);
-
-        return bulkActions;
-    }
-
-    @Override
-    protected String getPageId() {
-        return pageID;
-    }
-
-    public static class Builder extends AnyObjectSearchResultPanel.Builder<UserTO> {
+    public static class Builder extends AnySearchResultPanel.Builder<UserTO> {
 
         private static final long serialVersionUID = 1L;
 
@@ -261,6 +241,7 @@ public class UserSearchResultPanel extends AnyObjectSearchResultPanel<UserTO> {
                 final PageReference pageRef) {
 
             super(anyTypeClassTOs, restClient, type, pageRef);
+            setShowResultPage(true);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionSearchResultPanel.java
index 5a31adb..2039937 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionSearchResultPanel.java
@@ -39,6 +39,11 @@ public final class AnyObjectSelectionSearchResultPanel extends AnySelectionSearc
     }
 
     @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_ANYOBJECT_PAGINATOR_ROWS;
+    }
+
+    @Override
     protected String[] getDislayAttributes() {
         return USER_DEFAULT_SELECTION;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
index 82b277b..d013179 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
@@ -27,7 +27,7 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import org.apache.syncope.client.console.pages.AnyDisplayAttributesModalPage;
-import org.apache.syncope.client.console.panels.AnyObjectSearchResultPanel;
+import org.apache.syncope.client.console.panels.AnySearchResultPanel;
 import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 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;
@@ -47,12 +47,11 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.ResourceModel;
 import org.springframework.util.ReflectionUtils;
 
-public abstract class AnySelectionSearchResultPanel<T extends AnyTO> extends AnyObjectSearchResultPanel<T> {
+public abstract class AnySelectionSearchResultPanel<T extends AnyTO> extends AnySearchResultPanel<T> {
 
     private static final long serialVersionUID = -1100228004207271272L;
 
-    protected AnySelectionSearchResultPanel(
-            final String id, final AnySelectionSearchResultPanel.Builder<T> builder) {
+    protected AnySelectionSearchResultPanel(final String id, final AnySearchResultPanel.Builder<T> builder) {
         super(id, builder);
     }
 
@@ -168,7 +167,7 @@ public abstract class AnySelectionSearchResultPanel<T extends AnyTO> extends Any
 
     protected abstract String getPrefDerivedAttributesView();
 
-    public static class Builder<T extends AnyTO> extends AnyObjectSearchResultPanel.Builder<T> {
+    public abstract static class Builder<T extends AnyTO> extends AnySearchResultPanel.Builder<T> {
 
         private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionSearchResultPanel.java
index 8ba4593..e3a734c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionSearchResultPanel.java
@@ -38,6 +38,11 @@ public final class GroupSelectionSearchResultPanel extends AnySelectionSearchRes
     }
 
     @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_GROUP_PAGINATOR_ROWS;
+    }
+
+    @Override
     protected String[] getDislayAttributes() {
         return GROUP_DEFAULT_SELECTION;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionSearchResultPanel.java
index e43c737..8ae41f4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionSearchResultPanel.java
@@ -38,6 +38,11 @@ public final class UserSelectionSearchResultPanel extends AnySelectionSearchResu
     }
 
     @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_USERS_PAGINATOR_ROWS;
+    }
+
+    @Override
     protected String[] getDislayAttributes() {
         return USER_DEFAULT_SELECTION;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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 774d143..4437adb 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
@@ -78,6 +78,7 @@ public class BaseModal<T extends Serializable> extends Modal<T> implements Notif
         super(id);
 
         form = new Form<>(FORM);
+        form.setOutputMarkupId(true);
         add(form);
 
         content = new AbstractModalPanel<T>(this, null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index 6508ab3..708fd92 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.console.wicket.markup.html.form;
 import java.io.Serializable;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 
-public abstract class ActionLink<T> implements Serializable {
+public abstract class ActionLink<T extends Serializable> implements Serializable {
 
     private static final long serialVersionUID = 7031329706998320639L;
 
@@ -56,6 +56,7 @@ public abstract class ActionLink<T> implements Serializable {
         DRYRUN("execute"),
         CLAIM("claim"),
         SELECT("read"),
+        CLOSE("read"),
         EXPORT("read"),
         SUSPEND("update"),
         REACTIVATE("update"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
index 2b2dfd3..b3e989d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
@@ -75,6 +75,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
         super.add(new Fragment("panelExecute", "emptyFragment", this));
         super.add(new Fragment("panelDryRun", "emptyFragment", this));
         super.add(new Fragment("panelSelect", "emptyFragment", this));
+        super.add(new Fragment("panelClose", "emptyFragment", this));
         super.add(new Fragment("panelExport", "emptyFragment", this));
         super.add(new Fragment("panelSuspend", "emptyFragment", this));
         super.add(new Fragment("panelReactivate", "emptyFragment", this));
@@ -478,6 +479,25 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                 }).setVisible(link.isEnabled(model.getObject()));
 
                 break;
+            case CLOSE:
+                fragment = new Fragment("panelClose", "fragmentClose", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("closeLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target, model.getObject());
+                    }
+
+                    @Override
+                    public String getAjaxIndicatorMarkupId() {
+                        return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
+                    }
+                }).setVisible(link.isEnabled(model.getObject()));
+
+                break;
 
             case EXPORT:
                 fragment = new Fragment("panelExport", "fragmentExport", this);
@@ -739,7 +759,9 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
 
         if (fragment != null) {
             fragment.setEnabled(enabled);
-            MetaDataRoleAuthorizationStrategy.authorize(fragment, ENABLE, entitlements);
+            if (StringUtils.isNotBlank(entitlements)) {
+                MetaDataRoleAuthorizationStrategy.authorize(fragment, ENABLE, entitlements);
+            }
             super.addOrReplace(fragment);
         }
 
@@ -812,6 +834,10 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                 super.addOrReplace(new Fragment("panelSelect", "emptyFragment", this));
                 break;
 
+            case CLOSE:
+                super.addOrReplace(new Fragment("panelClose", "emptyFragment", this));
+                break;
+
             case EXPORT:
                 super.addOrReplace(new Fragment("panelExport", "emptyFragment", this));
                 break;
@@ -899,6 +925,10 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             return this;
         }
 
+        public Builder<T> add(final ActionLink<T> link, final ActionLink.ActionType type) {
+            return addWithRoles(link, type, null, true);
+        }
+
         public Builder<T> add(
                 final ActionLink<T> link,
                 final ActionLink.ActionType type,

http://git-wip-us.apache.org/repos/asf/syncope/blob/03d7de33/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
index 88b79c5..dc418a7 100644
--- 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
@@ -49,7 +49,7 @@ public abstract class AbstractModalPanelBuilder<T extends Serializable> implemen
 
     protected abstract void onCancelInternal(T modelObject);
 
-    protected abstract void onApplyInternal(T modelObject);
+    protected abstract Serializable onApplyInternal(T modelObject);
 
     protected T getOriginalItem() {
         return item;