You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by an...@apache.org on 2022/09/12 08:02:49 UTC

[syncope] branch master updated: [SYNCOPE-1665] show error on propagation failure, made some refactoring (#363)

This is an automated email from the ASF dual-hosted git repository.

andreapatricelli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new f6735a8389 [SYNCOPE-1665] show error on propagation failure, made some refactoring (#363)
f6735a8389 is described below

commit f6735a83898d6a0d64ff8308e52534cb51d1976c
Author: Andrea Patricelli <an...@apache.org>
AuthorDate: Mon Sep 12 10:02:43 2022 +0200

    [SYNCOPE-1665] show error on propagation failure, made some refactoring (#363)
    
    * [SYNCOPE-1665] show error in enduser on propagation failure if enabled by
    configuration
---
 ...AnyDirectoryPanelAdditionalActionsProvider.java |   8 +-
 .../console/panels/ConnectorDirectoryPanel.java    |   2 +-
 .../client/console/panels/ConnidLocations.java     |   2 +-
 .../console/panels/ResourceDirectoryPanel.java     |   2 +-
 .../syncope/client/ui/commons/Constants.java       |   4 +
 .../ui/commons/panels/SimpleListViewPanel.java     | 250 +++++++++++++++++++++
 .../client/ui/commons/status/StatusUtils.java      |   5 +
 .../commons/wizards/any/AbstractResultPanel.java   |  54 +++++
 .../ui/commons/panels/SimpleListViewPanel.html}    |  25 ++-
 .../commons/panels/SimpleListViewPanel.properties} |   4 +-
 .../panels/SimpleListViewPanel_fr_CA.properties}   |   4 +-
 .../panels/SimpleListViewPanel_it.properties}      |   4 +-
 .../panels/SimpleListViewPanel_ja.properties}      |   4 +-
 .../panels/SimpleListViewPanel_pt_BR.properties}   |   4 +-
 .../panels/SimpleListViewPanel_ru.properties}      |   7 +-
 .../commons/wizards/any/AbstractResultPanel.html}  |   9 +-
 .../syncope/client/console/pages/Realms.java       |   6 +-
 .../console/panels/AccessTokenDirectoryPanel.java  |   2 +-
 .../console/panels/ApplicationDirectoryPanel.java  |   2 +-
 .../console/panels/DelegationDirectoryPanel.java   |   2 +-
 .../console/panels/DynRealmDirectoryPanel.java     |   2 +-
 .../syncope/client/console/panels/Realm.java       |   2 +-
 .../client/console/panels/RoleDirectoryPanel.java  |   2 +-
 .../panels/TypeExtensionDirectoryPanel.java        |   2 +-
 .../client/console/tasks/TaskDirectoryPanel.java   |   6 +-
 .../client/console/wizards/WizardMgtPanel.java     |  19 +-
 .../any/{ResultPage.java => ResultPanel.java}      |  30 +--
 .../any/{ResultPage.html => ResultPanel.html}      |   4 +-
 ...esultPage.properties => ResultPanel.properties} |   0
 ..._CA.properties => ResultPanel_fr_CA.properties} |   0
 ...age_it.properties => ResultPanel_it.properties} |   0
 ...age_ja.properties => ResultPanel_ja.properties} |   0
 ..._BR.properties => ResultPanel_pt_BR.properties} |   0
 ...age_ru.properties => ResultPanel_ru.properties} |   0
 .../console/wizards/any/StatusPanel_ru.properties  |   6 +-
 .../syncope/client/enduser/EnduserProperties.java  |  21 +-
 .../client/enduser/SyncopeWebApplication.java      |   8 +
 .../client/enduser/commons/EnduserConstants.java   |   4 +-
 .../client/enduser/commons/ProvisioningUtils.java  |  67 ++++++
 .../client/enduser/pages/EditChangePassword.java   |  39 ++--
 .../client/enduser/pages/EditSecurityQuestion.java |  67 +++---
 .../syncope/client/enduser/pages/SelfResult.java   |  36 ++-
 .../syncope/client/enduser/panels/ResultPanel.java |  65 ++++++
 .../client/enduser/panels/UserFormPanel.java       |  43 ++--
 .../client/enduser/panels/UserSelfFormPanel.java   |  48 ++--
 .../enduser/src/main/resources/enduser.properties  |   2 +
 .../enduser/SyncopeEnduserApplication.properties   |   1 +
 .../SyncopeEnduserApplication_fr_CA.properties     |   1 +
 .../SyncopeEnduserApplication_it.properties        |   1 +
 .../SyncopeEnduserApplication_ja.properties        | 116 +++++-----
 .../SyncopeEnduserApplication_pt_BR.properties     |   2 +
 .../SyncopeEnduserApplication_ru.properties        | 100 +++++----
 .../enduser/pages/EditChangePassword.properties    |   4 +-
 .../enduser/pages/EditChangePassword_it.properties |   2 +-
 .../pages/EditSecurityQuestion_it.properties       |   2 +-
 .../enduser/pages/MustChangePassword_it.properties |   2 +-
 .../pages/SelfConfirmPasswordReset.properties      |   4 +-
 .../pages/SelfConfirmPasswordReset_it.properties   |   4 +-
 .../syncope/client/enduser/pages/SelfResult.html   |  77 ++++---
 .../client/enduser/pages/SelfResult.properties     |   2 +
 .../enduser/pages/SelfResult_fr_CA.properties      |   4 +-
 .../client/enduser/pages/SelfResult_it.properties  |   2 +
 .../client/enduser/pages/SelfResult_ja.properties  |   4 +-
 .../enduser/pages/SelfResult_pt_BR.properties      |   4 +-
 .../client/enduser/pages/SelfResult_ru.properties  |   4 +-
 .../client/enduser/panels/ResultPanel.html}        |   7 +-
 .../client/enduser/panels/UserFormPanel.properties |   4 +-
 .../enduser/panels/UserFormPanel_it.properties     |   2 +-
 .../enduser/panels/UserFormPanel_ja.properties     |   8 +-
 .../enduser/panels/UserFormPanel_pt_BR.properties  |   4 +-
 .../enduser/panels/UserFormPanel_ru.properties     |   8 +-
 .../console/panels/BpmnProcessDirectoryPanel.java  |   2 +-
 .../syncope/client/console/pages/SCIMConfPage.java |   6 +-
 .../client/console/panels/SCIMConfPanel.java       |   2 +-
 74 files changed, 861 insertions(+), 391 deletions(-)

diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
index 32d2ebfef0..02f6c48cf7 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
@@ -34,7 +34,7 @@ import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.Bas
 import org.apache.syncope.client.console.wizards.CSVPullWizardBuilder;
 import org.apache.syncope.client.console.wizards.CSVPushWizardBuilder;
 import org.apache.syncope.client.console.wizards.any.ProvisioningReportsPanel;
-import org.apache.syncope.client.console.wizards.any.ResultPage;
+import org.apache.syncope.client.console.wizards.any.ResultPanel;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.to.ProvisioningReport;
@@ -90,7 +90,7 @@ public class IdMAnyDirectoryPanelAdditionalActionsProvider implements AnyDirecto
                     Optional<AjaxRequestTarget> target = payload.getTarget();
 
                     if (payload.getResult() instanceof ArrayList) {
-                        modal.setContent(new ResultPage<>(
+                        modal.setContent(new ResultPanel<>(
                             null,
                             payload.getResult()) {
 
@@ -103,11 +103,11 @@ public class IdMAnyDirectoryPanelAdditionalActionsProvider implements AnyDirecto
 
                             @Override
                             protected Panel customResultBody(
-                                final String id, final Serializable item, final Serializable result) {
+                                final String panelId, final Serializable item, final Serializable result) {
 
                                 @SuppressWarnings("unchecked")
                                 ArrayList<ProvisioningReport> reports = (ArrayList<ProvisioningReport>) result;
-                                return new ProvisioningReportsPanel(id, reports, pageRef);
+                                return new ProvisioningReportsPanel(panelId, reports, pageRef);
                             }
                         });
                         target.ifPresent(t -> t.add(modal.getForm()));
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.java
index 445083e4a2..69035c0e6a 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDirectoryPanel.java
@@ -73,7 +73,7 @@ public class ConnectorDirectoryPanel extends
             MetaDataRoleAuthorizationStrategy.unauthorizeAll(addAjaxLink, RENDER);
         }
 
-        setShowResultPage(false);
+        setShowResultPanel(false);
         modal.size(Modal.Size.Large);
         initResultTable();
 
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnidLocations.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnidLocations.java
index 1a9de82da6..0f755ccbb1 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnidLocations.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnidLocations.java
@@ -60,7 +60,7 @@ public class ConnidLocations extends
         super(id, builder);
 
         disableCheckBoxes();
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
         initResultTable();
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
index f7f1a1829b..b5654d7d91 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
@@ -87,7 +87,7 @@ public class ResourceDirectoryPanel extends
             MetaDataRoleAuthorizationStrategy.unauthorizeAll(addAjaxLink, RENDER);
         }
 
-        setShowResultPage(false);
+        setShowResultPanel(false);
         modal.size(Modal.Size.Large);
         initResultTable();
 
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java
index 2efdb0bb38..789fa41872 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/Constants.java
@@ -108,6 +108,8 @@ public final class Constants {
     public static final String UNDEFINED_ICON = "fas fa-question-circle";
 
     public static final String NOT_FOUND_ICON = "fas fa-minus-circle";
+    
+    public static final String WARNING_ICON = "fas fa-exclamation-circle";
 
     public static final int MAX_GROUP_LIST_SIZE = 30;
 
@@ -120,6 +122,8 @@ public final class Constants {
     public static final String NOTIFICATION_LEVEL_PARAM = "notificationLevel";
 
     public static final String ENDUSER_ANYLAYOUT = "enduser.anylayout";
+    
+    public static final String CONTENT_ID = "content";
 
     public static Component getJEXLPopover(final Component caller, final TooltipConfig.Placement placement) {
         return getJEXLPopover(caller, placement, caller.getString("jexl_ex1"), caller.getString("jexl_ex2"));
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.java
new file mode 100644
index 0000000000..0b1f028287
--- /dev/null
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.java
@@ -0,0 +1,250 @@
+/*
+ * 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.ui.commons.panels;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.wicket.Component;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.core.util.lang.PropertyResolver;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.ResourceModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class SimpleListViewPanel<T extends Serializable> extends Panel {
+
+    private static final long serialVersionUID = -7982691107029848579L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(SimpleListViewPanel.class);
+
+    private final ListView<T> beans;
+
+    private final List<T> listOfItems;
+
+    /**
+     * Table view of a list of beans.
+     *
+     * @param id        id.
+     * @param list      list of item.
+     * @param reference list item reference class.
+     * @param includes  Used to sort and restrict the set of bean's fields to be shown.
+     */
+    private SimpleListViewPanel(
+            final String id,
+            final List<T> list,
+            final Class<T> reference,
+            final List<String> includes) {
+
+        super(id);
+        setOutputMarkupId(true);
+
+        final List<String> toBeIncluded;
+        if (includes == null || includes.isEmpty()) {
+            toBeIncluded = new ArrayList<>();
+            for (Field field : reference.getDeclaredFields()) {
+                toBeIncluded.add(field.getName());
+            }
+        } else {
+            toBeIncluded = includes;
+        }
+
+        if (toBeIncluded.isEmpty()) {
+            LOG.warn("No field has been retrieved from {}", reference.getName());
+            listOfItems = new ArrayList<>();
+        } else if (list == null || list.isEmpty()) {
+            LOG.info("No item to be shown");
+            listOfItems = new ArrayList<>();
+        } else {
+            listOfItems = list;
+            LOG.debug("Show fields {}", toBeIncluded);
+        }
+
+        add(header(toBeIncluded));
+
+        beans = new ListView<>("beans", listOfItems) {
+
+            private static final long serialVersionUID = -9112553137618363167L;
+
+            @Override
+            protected void populateItem(final ListItem<T> beanItem) {
+                final T bean = beanItem.getModelObject();
+
+                final ListView<String> fields = new ListView<>("fields", toBeIncluded) {
+
+                    private static final long serialVersionUID = -9112553137618363167L;
+
+                    @Override
+                    protected void populateItem(final ListItem<String> fieldItem) {
+                        fieldItem.add(getValueComponent(fieldItem.getModelObject(), bean));
+                    }
+                };
+
+                beanItem.add(fields);
+            }
+        };
+        add(beans.setOutputMarkupId(true).setRenderBodyOnly(true));
+    }
+
+    protected ListView<String> header(final List<String> labels) {
+        return new ListView<>("names", labels) {
+
+            private static final long serialVersionUID = -9112553137618363167L;
+
+            @Override
+            protected void populateItem(final ListItem<String> item) {
+                item.add(new Label(Constants.NAME_FIELD_NAME,
+                        new ResourceModel(item.getModelObject(), item.getModelObject())));
+            }
+        };
+    }
+
+    /**
+     * SimpleListViewPanel builder.
+     *
+     * @param <T> list item reference type.
+     */
+    public static class Builder<T extends Serializable> implements Serializable {
+
+        private static final long serialVersionUID = -3643771352897992172L;
+
+        private final List<String> includes = new ArrayList<>();
+
+        private List<T> items;
+
+        private final Class<T> reference;
+
+        private final PageReference pageReference;
+
+        public Builder(final Class<T> reference, final PageReference pageRef) {
+            this.pageReference = pageRef;
+            this.reference = reference;
+            this.items = null;
+        }
+
+        /**
+         * Sets list of items.
+         *
+         * @param items list of items.
+         * @return current builder object.
+         */
+        public Builder<T> setItems(final List<T> items) {
+            this.items = items;
+            return this;
+        }
+
+        /**
+         * Adds item.
+         *
+         * @param item item.
+         * @return current builder object.
+         */
+        public Builder<T> addItem(final T item) {
+            if (item == null) {
+                return this;
+            }
+
+            if (this.items == null) {
+                this.items = new ArrayList<>();
+            }
+
+            this.items.add(item);
+            return this;
+        }
+
+        /**
+         * Gives fields to be shown. It could be used to give an order as well.
+         *
+         * @param includes field names to be shown.
+         * @return current builder object.
+         */
+        public Builder<T> includes(final String... includes) {
+            for (String include : includes) {
+                if (include != null && !this.includes.contains(include)) {
+                    this.includes.add(include);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Overridable method to generate field value rendering component.
+         *
+         * @param key  field key.
+         * @param bean source bean.
+         * @return field rendering component.
+         */
+        protected Component getValueComponent(final String key, final T bean) {
+            LOG.debug("Processing field {}", key);
+
+            Object value;
+            try {
+                value = includes.contains(key)
+                        ? PropertyResolver.getPropertyGetter(key, bean).invoke(bean)
+                        : StringUtils.EMPTY;
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                LOG.error("Error retrieving value for field {}", key, e);
+                value = StringUtils.EMPTY;
+            }
+
+            LOG.debug("Field value {}", value);
+
+            return Optional.ofNullable(value)
+                    .map(o -> new Label("field", new ResourceModel(o.toString(), o.toString())))
+                    .orElseGet(() -> new Label("field", StringUtils.EMPTY));
+        }
+
+        protected T getActualItem(final T item, final List<T> list) {
+            return item == null
+                    ? null
+                    : list.stream().filter(item::equals).findAny().orElse(null);
+        }
+
+        public SimpleListViewPanel<T> build(final String id) {
+            return new SimpleListViewPanel<T>(id, items, reference, includes) {
+
+                @Override
+                protected Component getValueComponent(final String key, final T bean) {
+                    return Builder.this.getValueComponent(key, bean);
+                }
+
+                @Override
+                protected T getActualItem(final T item, final List<T> list) {
+                    return Builder.this.getActualItem(item, list);
+                }
+
+            };
+        }
+
+    }
+
+    protected abstract T getActualItem(T item, List<T> list);
+
+    protected abstract Component getValueComponent(String key, T bean);
+
+}
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java
index 787f8eb744..e6e73fab0d 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java
@@ -203,6 +203,11 @@ public final class StatusUtils implements Serializable {
         return getLabel(componentId, alt, title, clazz);
     }
 
+    public static Panel getWarningStatusPanel(final String componentId) {
+        return new LabelPanel(componentId,
+                getLabel("label", "warning icon", "Propagation failed", Constants.WARNING_ICON));
+    }
+    
     public static Label getLabel(final String componentId, final String alt, final String title, final String clazz) {
         return new Label(componentId, StringUtils.EMPTY) {
 
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AbstractResultPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AbstractResultPanel.java
new file mode 100644
index 0000000000..f529ea2869
--- /dev/null
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AbstractResultPanel.java
@@ -0,0 +1,54 @@
+/*
+ * 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.ui.commons.wizards.any;
+
+import java.io.Serializable;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public abstract class AbstractResultPanel<T extends Serializable, R extends Serializable> extends Panel
+        implements WizardModalPanel<T> {
+
+    private static final long serialVersionUID = -1619945285130369086L;
+
+    protected final T item;
+
+    protected final R result;
+
+    public AbstractResultPanel(final T item, final R result) {
+        super(Constants.CONTENT_ID);
+        setOutputMarkupId(true);
+        this.item = item;
+        this.result = result;
+
+        add(customResultBody("customResultBody", item, result).setOutputMarkupId(true));
+    }
+
+    protected abstract Panel customResultBody(String panelId, T item, R result);
+
+    @Override
+    public T getItem() {
+        return this.item;
+    }
+
+    public R getResult() {
+        return result;
+    }
+}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.html
similarity index 58%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.html
index bca1667d43..918acbd5b0 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.html
@@ -17,10 +17,25 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:panel>
-    <span wicket:id="customResultBody"/>
-    <div id="inline-actions" class="modal-footer circular-actions">
-      <span wicket:id="action"/>
+<head>
+    <title>List view panel</title>
+</head>
+<body>
+<wicket:panel>
+    <div class="col-xs-12">
+        <div class="card-body table-responsive no-padding">
+            <table class="table table-hover">
+                <tbody>
+                <tr>
+                    <th wicket:id="names"><span wicket:id="name"/></th>
+                </tr>
+                <tr wicket:id="beans">
+                    <td wicket:id="fields" class="col_width list_view_panel_labels"><span wicket:id="field"/></td>
+                </tr>
+                </tbody>
+            </table>
+        </div><!-- /.card-body -->
     </div>
-  </wicket:panel>
+</wicket:panel>
+</body>
 </html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.properties
similarity index 93%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.properties
index 7e234f7e8e..a198c987ca 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-listview.caption=Occurred propagations
+resource=Resource
+connObjectLink=Remote ID
+status=Status
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_fr_CA.properties
similarity index 92%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_fr_CA.properties
index 7e234f7e8e..13c045c041 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_fr_CA.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-listview.caption=Occurred propagations
+resource=Ressource
+connObjectLink=ID \uFFFD distance
+status=Statut
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_it.properties
similarity index 93%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_it.properties
index 7e234f7e8e..7d47cb150b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_it.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-listview.caption=Occurred propagations
+resource=Risorsa
+connObjectLink=ID Remoto
+status=Stato
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_ja.properties
similarity index 87%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_ja.properties
index 7e234f7e8e..4dee2f1533 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_ja.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-listview.caption=Occurred propagations
+resource=\u30EA\u30BD\u30FC\u30B9
+connObjectLink=\u30EA\u30E2\u30FC\u30C8 ID
+status=\u30B9\u30C6\u30FC\u30BF\u30B9
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_pt_BR.properties
similarity index 93%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_pt_BR.properties
index 7e234f7e8e..a330519d49 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_pt_BR.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-listview.caption=Occurred propagations
+resource=Recurso
+connObjectLink=ID Remoto
+status=Estado
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel_ru.properties b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_ru.properties
similarity index 82%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel_ru.properties
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_ru.properties
index 6d01c515ce..2b63e3d2f9 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel_ru.properties
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/SimpleListViewPanel_ru.properties
@@ -14,10 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-
-# resource=Ресурс
 resource=\u0420\u0435\u0441\u0443\u0440\u0441
-# connObjectLink=Учетная запись
-connObjectLink=\u0423\u0447\u0435\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c
-# status=Статус
+connObjectLink=\u0423\u0447\u0435\u0442\u043D\u0430\u044F \u0437\u0430\u043F\u0438\u0441\u044C
 status=\u0421\u0442\u0430\u0442\u0443\u0441
+
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/wizards/any/AbstractResultPanel.html
similarity index 81%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
copy to client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/wizards/any/AbstractResultPanel.html
index bca1667d43..1f36abf6ee 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
+++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/wizards/any/AbstractResultPanel.html
@@ -17,10 +17,7 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:panel>
-    <span wicket:id="customResultBody"/>
-    <div id="inline-actions" class="modal-footer circular-actions">
-      <span wicket:id="action"/>
-    </div>
-  </wicket:panel>
+<wicket:panel>
+    <wicket:child/>
+</wicket:panel>
 </html>
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index b191865fc7..ac51e04040 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -30,7 +30,7 @@ import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.RealmRestClient;
 import org.apache.syncope.client.console.tasks.TemplatesTogglePanel;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wizards.any.ResultPage;
+import org.apache.syncope.client.console.wizards.any.ResultPanel;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
 import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
@@ -197,8 +197,8 @@ public class Realms extends BasePage {
         @Override
         protected void setWindowClosedReloadCallback(final BaseModal<?> modal) {
             modal.setWindowClosedCallback(target -> {
-                if (modal.getContent() instanceof ResultPage) {
-                    Serializable result = ResultPage.class.cast(modal.getContent()).getResult();
+                if (modal.getContent() instanceof ResultPanel) {
+                    Object result = ResultPanel.class.cast(modal.getContent()).getResult();
 
                     RealmTO newRealmTO = RealmTO.class.cast(ProvisioningResult.class.cast(result).getEntity());
                     // reload realmChoicePanel label too - SYNCOPE-1151
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
index 96d8c5037d..22a7bd7ff7 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
@@ -63,7 +63,7 @@ public class AccessTokenDirectoryPanel
     protected AccessTokenDirectoryPanel(final String id, final Builder builder) {
         super(id, builder);
 
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
         initResultTable();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java
index eaad62752c..f710a6a423 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java
@@ -79,7 +79,7 @@ public class ApplicationDirectoryPanel extends
         setReadOnly(!SyncopeConsoleSession.get().owns(IdRepoEntitlement.APPLICATION_UPDATE));
 
         disableCheckBoxes();
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Default);
         modal.addSubmitButton();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationDirectoryPanel.java
index fab7e51f38..a17421d6db 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationDirectoryPanel.java
@@ -67,7 +67,7 @@ public class DelegationDirectoryPanel extends
         super(id, builder);
 
         disableCheckBoxes();
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
         initResultTable();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java
index 8b26080648..fe7696196f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java
@@ -61,7 +61,7 @@ public class DynRealmDirectoryPanel extends
         setReadOnly(!SyncopeConsoleSession.get().owns(IdRepoEntitlement.DYNREALM_UPDATE));
 
         disableCheckBoxes();
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
         modal.addSubmitButton();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index 7e1ad12c4e..0471be4260 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -91,7 +91,7 @@ public abstract class Realm extends WizardMgtPanel<RealmTO> {
         this.wizardBuilder = buildNewItemPanelBuilder(pageRef);
         addNewItemPanelBuilder(this.wizardBuilder, false);
 
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
         setWindowClosedReloadCallback(modal);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
index cf7a1b2482..a4b383aa91 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
@@ -82,7 +82,7 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
         setReadOnly(!SyncopeConsoleSession.get().owns(IdRepoEntitlement.ROLE_UPDATE));
 
         disableCheckBoxes();
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
         initResultTable();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
index fdead33b25..3d21b39a5f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
@@ -80,7 +80,7 @@ public class TypeExtensionDirectoryPanel
                 pageRef);
         this.addNewItemPanelBuilder(builder, true);
 
-        setShowResultPage(false);
+        setShowResultPanel(false);
         initResultTable();
     }
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
index bf9d181204..03cc5d6147 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
@@ -56,7 +56,7 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
         this.baseModal = baseModal;
         this.multiLevelPanelRef = multiLevelPanelRef;
         restClient = new TaskRestClient();
-        setShowResultPage(false);
+        setShowResultPanel(false);
     }
 
     protected TaskDirectoryPanel(
@@ -66,7 +66,7 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
         this.baseModal = baseModal;
         this.multiLevelPanelRef = multiLevelPanelRef;
         restClient = new TaskRestClient();
-        setShowResultPage(false);
+        setShowResultPanel(false);
     }
 
     protected TaskDirectoryPanel(
@@ -76,7 +76,7 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
         this.baseModal = baseModal;
         this.multiLevelPanelRef = multiLevelPanelRef;
         restClient = new TaskRestClient();
-        setShowResultPage(false);
+        setShowResultPanel(false);
     }
 
     @Override
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
index 86c5e6eabc..20b36d2f6c 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
@@ -26,7 +26,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
-import org.apache.syncope.client.console.wizards.any.ResultPage;
+import org.apache.syncope.client.console.wizards.any.ResultPanel;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
 import org.apache.syncope.client.ui.commons.panels.NotificationPanel;
@@ -82,7 +82,7 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
 
     protected boolean footerVisibility = false;
 
-    protected boolean showResultPage = false;
+    protected boolean showResultPanel = false;
 
     private final List<Component> outerObjects = new ArrayList<>();
 
@@ -230,8 +230,8 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
                 target.ifPresent(ajaxRequestTarget ->
                     ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(ajaxRequestTarget));
 
-                if (wizardInModal && showResultPage) {
-                    modal.setContent(new ResultPage<>(
+                if (wizardInModal && showResultPanel) {
+                    modal.setContent(new ResultPanel<>(
                         item,
                         AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult()) {
 
@@ -243,8 +243,9 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
                         }
 
                         @Override
-                        protected Panel customResultBody(final String id, final T item, final Serializable result) {
-                            return WizardMgtPanel.this.customResultBody(id, item, result);
+                        protected Panel customResultBody(final String panelId, final T item, 
+                                final Serializable result) {
+                            return WizardMgtPanel.this.customResultBody(panelId, item, result);
                         }
                     });
                     target.ifPresent(t -> t.add(modal.getForm()));
@@ -328,8 +329,8 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
         return this;
     }
 
-    public <B extends ModalPanelBuilder<T>> WizardMgtPanel<T> setShowResultPage(final boolean showResultPage) {
-        this.showResultPage = showResultPage;
+    public <B extends ModalPanelBuilder<T>> WizardMgtPanel<T> setShowResultPanel(final boolean showResultPanel) {
+        this.showResultPanel = showResultPanel;
         return this;
     }
 
@@ -426,7 +427,7 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
         public WizardMgtPanel<T> build(final String id) {
             return newInstance(id, wizardInModal).
                     setPageRef(this.pageRef).
-                    setShowResultPage(this.showResultPage).
+                    setShowResultPanel(this.showResultPage).
                     addNewItemPanelBuilder(this.newItemPanelBuilder, this.newItemDefaultButtonEnabled).
                     addNotificationPanel(this.notificationPanel);
         }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPanel.java
similarity index 67%
rename from client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
rename to client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPanel.java
index c200e49652..f4f4bc291e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPanel.java
@@ -20,30 +20,18 @@ package org.apache.syncope.client.console.wizards.any;
 
 import java.io.Serializable;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.ui.commons.Constants;
-import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
+import org.apache.syncope.client.ui.commons.wizards.any.AbstractResultPanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.markup.html.panel.Panel;
 
-public abstract class ResultPage<T extends Serializable> extends Panel implements WizardModalPanel<T> {
+public abstract class ResultPanel<T extends Serializable, R extends Serializable> extends AbstractResultPanel<T, R> {
 
     private static final long serialVersionUID = -1619945285130369086L;
 
-    private final T item;
-
-    private final Serializable result;
-
-    public ResultPage(final T item, final Serializable result) {
-        super(BaseModal.CONTENT_ID);
-        setOutputMarkupId(true);
-        this.item = item;
-        this.result = result;
-
-        add(customResultBody("customResultBody", item, result));
-
+    public ResultPanel(final T item, final R result) {
+        super(item, result);
         ActionsPanel<T> panel = new ActionsPanel<>(Constants.ACTION, null);
         panel.add(new ActionLink<>() {
 
@@ -59,14 +47,4 @@ public abstract class ResultPage<T extends Serializable> extends Panel implement
 
     protected abstract void closeAction(AjaxRequestTarget target);
 
-    protected abstract Panel customResultBody(String panleId, T item, Serializable result);
-
-    @Override
-    public T getItem() {
-        return this.item;
-    }
-
-    public Serializable getResult() {
-        return result;
-    }
 }
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel.html
similarity index 96%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel.html
index bca1667d43..7d70c57e21 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel.html
@@ -17,10 +17,10 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:panel>
+<wicket:extend>
     <span wicket:id="customResultBody"/>
     <div id="inline-actions" class="modal-footer circular-actions">
       <span wicket:id="action"/>
     </div>
-  </wicket:panel>
+</wicket:extend>
 </html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_fr_CA.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_fr_CA.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_fr_CA.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_it.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_it.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_it.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_ja.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_ja.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_ja.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_pt_BR.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_pt_BR.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_pt_BR.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_ru.properties
similarity index 100%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage_ru.properties
rename to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPanel_ru.properties
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel_ru.properties
index 6d01c515ce..603b7738dd 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/StatusPanel_ru.properties
@@ -14,10 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-
-# resource=Ресурс
 resource=\u0420\u0435\u0441\u0443\u0440\u0441
-# connObjectLink=Учетная запись
-connObjectLink=\u0423\u0447\u0435\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c
-# status=Статус
+connObjectLink=\u0423\u0447\u0435\u0442\u043D\u0430\u044F \u0437\u0430\u043F\u0438\u0441\u044C
 status=\u0421\u0442\u0430\u0442\u0443\u0441
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java
index e2d75919a3..0cc4a8d18d 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java
@@ -24,7 +24,6 @@ import org.apache.syncope.client.enduser.pages.BasePage;
 import org.apache.syncope.client.enduser.panels.Sidebar;
 import org.apache.syncope.client.ui.commons.CommonUIProperties;
 import org.springframework.boot.context.properties.ConfigurationProperties;
-
 @ConfigurationProperties("enduser")
 public class EnduserProperties extends CommonUIProperties {
 
@@ -34,6 +33,10 @@ public class EnduserProperties extends CommonUIProperties {
 
     private boolean captcha;
 
+    private boolean reportPropagationErrors;
+
+    private boolean reportPropagationErrorDetails;
+
     private final Map<String, Class<? extends BasePage>> page = new HashMap<>();
 
     public Class<? extends Sidebar> getSidebar() {
@@ -60,6 +63,22 @@ public class EnduserProperties extends CommonUIProperties {
         this.captcha = captcha;
     }
 
+    public boolean isReportPropagationErrors() {
+        return reportPropagationErrors;
+    }
+
+    public void setReportPropagationErrors(final boolean reportPropagationErrors) {
+        this.reportPropagationErrors = reportPropagationErrors;
+    }
+
+    public boolean isReportPropagationErrorDetails() {
+        return reportPropagationErrorDetails;
+    }
+
+    public void setReportPropagationErrorDetails(final boolean reportPropagationErrorDetails) {
+        this.reportPropagationErrorDetails = reportPropagationErrorDetails;
+    }
+
     public Map<String, Class<? extends BasePage>> getPage() {
         return page;
     }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
index d11f1fce13..205b440b65 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
@@ -261,6 +261,14 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
     public boolean isCaptchaEnabled() {
         return props.isCaptcha();
     }
+    
+    public boolean isReportPropagationErrors() {
+        return props.isReportPropagationErrors();
+    }
+    
+    public boolean isReportPropagationErrorDetails() {
+        return props.isReportPropagationErrorDetails();
+    }
 
     public long getMaxWaitTimeInSeconds() {
         return props.getMaxWaitTimeOnApplyChanges();
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java
index abdf65211a..07719f91b4 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java
@@ -21,8 +21,10 @@ package org.apache.syncope.client.enduser.commons;
 public final class EnduserConstants {
 
     public static final String STATUS = "status";
-
+    
     public static final String SUCCESS = "success";
+    
+    public static final String FAILING_RESOURCES = "failing_resources";
 
     public static final String LANDING_PAGE = "landingPage";
 
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/ProvisioningUtils.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/ProvisioningUtils.java
new file mode 100644
index 0000000000..5adb023888
--- /dev/null
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/ProvisioningUtils.java
@@ -0,0 +1,67 @@
+/*
+ * 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.enduser.commons;
+
+import org.apache.syncope.client.enduser.SyncopeWebApplication;
+import org.apache.syncope.client.enduser.pages.Dashboard;
+import org.apache.syncope.client.enduser.rest.UserSelfRestClient;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.common.lib.request.UserCR;
+import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.Component;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+public final class ProvisioningUtils {
+
+    public static final UserSelfRestClient USER_SELF_REST_CLIENT = new UserSelfRestClient();
+
+    private ProvisioningUtils() {
+    }
+
+    public static ProvisioningResult<UserTO> createUser(final UserCR userCR) {
+        return userCR == null ? new ProvisioningResult<>() : USER_SELF_REST_CLIENT.create(userCR);
+    }
+
+    public static ProvisioningResult<UserTO> updateUser(final UserUR userUR, final String etag) {
+        return userUR.isEmpty() ? new ProvisioningResult<>() : USER_SELF_REST_CLIENT.update(etag, userUR);
+    }
+
+    public static PageParameters managePageParams(final Component component, final String section,
+            final boolean isSuccess) {
+        PageParameters parameters = new PageParameters();
+        parameters.add(EnduserConstants.STATUS,
+                isSuccess
+                        ? Constants.OPERATION_SUCCEEDED
+                        : Constants.OPERATION_ERROR);
+        parameters.add(Constants.NOTIFICATION_TITLE_PARAM,
+                isSuccess
+                        ? component.getString("self." + section + ".success.msg")
+                        : component.getString("self." + section + ".error.msg"));
+        parameters.add(Constants.NOTIFICATION_MSG_PARAM,
+                isSuccess
+                        ? component.getString("self." + section + ".success")
+                        : component.getString("self." + section + ".error"));
+        parameters.add(EnduserConstants.LANDING_PAGE,
+                SyncopeWebApplication.get().getPageClass("profile", Dashboard.class).getName());
+        return parameters;
+    }
+}
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java
index fe781a29d3..d4df1da270 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java
@@ -20,13 +20,14 @@ package org.apache.syncope.client.enduser.pages;
 
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.commons.EnduserConstants;
+import org.apache.syncope.client.enduser.commons.ProvisioningUtils;
 import org.apache.syncope.client.enduser.rest.UserSelfRestClient;
-import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPasswordFieldPanel;
 import org.apache.syncope.common.lib.request.PasswordPatch;
 import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ExecStatus;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
@@ -44,27 +45,21 @@ public class EditChangePassword extends AbstractChangePassword {
     protected void doPwdSubmit(final AjaxRequestTarget target, final AjaxPasswordFieldPanel passwordField) {
         try {
             UserTO userTO = getPwdLoggedUser();
-
-            UserUR req = new UserUR.Builder(userTO.getKey()).
-                    password(new PasswordPatch.Builder().
-                            value(passwordField.getModelObject()).onSyncope(true).resources(userTO.getResources()).
-                            build()).
-                    build();
-            userSelfRestClient.update(userTO.getETagValue(), req);
-
-            SyncopeEnduserSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
-
-            PageParameters parameters = new PageParameters();
-            parameters.add(EnduserConstants.STATUS, Constants.OPERATION_SUCCEEDED);
-            parameters.add(Constants.NOTIFICATION_TITLE_PARAM, getString("self.pwd.change.success.msg"));
-            parameters.add(Constants.NOTIFICATION_MSG_PARAM, getString("self.pwd.change.success"));
-            parameters.add(
-                    EnduserConstants.LANDING_PAGE,
-                    SyncopeWebApplication.get().getPageClass("profile", Dashboard.class).getName());
-            setResponsePage(SelfResult.class, parameters);
+            // update and set page paramters according to provisioning result
+            ProvisioningResult<UserTO> provisioningResult =
+                    ProvisioningUtils.updateUser(new UserUR.Builder(userTO.getKey()).
+                            password(new PasswordPatch.Builder().
+                                    value(passwordField.getModelObject()).onSyncope(true)
+                                    .resources(userTO.getResources()).
+                                    build()).
+                            build(), userTO.getETagValue());
+            setResponsePage(new SelfResult(provisioningResult,
+                    ProvisioningUtils.managePageParams(EditChangePassword.this, "pwd.change",
+                            !SyncopeWebApplication.get().isReportPropagationErrors()
+                                    || provisioningResult.getPropagationStatuses().stream()
+                                    .allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus()))));
         } catch (Exception e) {
-            LOG.error("While changing password for {}",
-                    SyncopeEnduserSession.get().getSelfTO().getUsername(), e);
+            LOG.error("While changing password for {}", SyncopeEnduserSession.get().getSelfTO().getUsername(), e);
             SyncopeEnduserSession.get().onException(e);
             notificationPanel.refresh(target);
         }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java
index e2398f05df..a4c9080756 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java
@@ -24,6 +24,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.SyncopeWebApplication;
 import org.apache.syncope.client.enduser.commons.EnduserConstants;
+import org.apache.syncope.client.enduser.commons.ProvisioningUtils;
 import org.apache.syncope.client.enduser.panels.captcha.CaptchaPanel;
 import org.apache.syncope.client.enduser.rest.SecurityQuestionRestClient;
 import org.apache.syncope.client.enduser.rest.UserSelfRestClient;
@@ -34,8 +35,10 @@ import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
 import org.apache.syncope.client.ui.commons.panels.CardPanel;
 import org.apache.syncope.common.lib.request.StringReplacePatchItem;
 import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.SecurityQuestionTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ExecStatus;
 import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
@@ -78,6 +81,7 @@ public class EditSecurityQuestion extends BasePage {
         securityQuestion = new AjaxDropDownChoicePanel<>("securityQuestion",
                 "securityQuestion", new PropertyModel<>(userTO, "securityQuestion"));
         securityQuestion.setNullValid(true);
+        securityQuestion.setRequired(true);
 
         List<SecurityQuestionTO> securityQuestions = SecurityQuestionRestClient.list();
         securityQuestion.setChoices(securityQuestions.stream().
@@ -89,7 +93,7 @@ public class EditSecurityQuestion extends BasePage {
             @Override
             public Object getDisplayValue(final String value) {
                 return securityQuestions.stream().filter(sq -> value.equals(sq.getKey())).
-                    map(SecurityQuestionTO::getContent).findFirst().orElse(null);
+                        map(SecurityQuestionTO::getContent).findFirst().orElse(null);
             }
 
             @Override
@@ -120,6 +124,7 @@ public class EditSecurityQuestion extends BasePage {
                 new PropertyModel<>(userTO, "securityAnswer"), false);
         form.add(securityAnswer.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true).
                 setEnabled(StringUtils.isNotBlank(securityQuestion.getModelObject())));
+        securityAnswer.setRequired(true);
 
         CaptchaPanel<Void> captcha = new CaptchaPanel<>(EnduserConstants.CONTENT_PANEL);
         captcha.setOutputMarkupPlaceholderTag(true);
@@ -135,51 +140,29 @@ public class EditSecurityQuestion extends BasePage {
 
             @Override
             protected void onSubmit(final AjaxRequestTarget target) {
-                if (StringUtils.isBlank(securityQuestion.getModelObject())
-                        || StringUtils.isBlank(securityAnswer.getModelObject())) {
-
+                if (SyncopeWebApplication.get().isCaptchaEnabled() && !captcha.check()) {
                     SyncopeEnduserSession.get().error(getString(Constants.CAPTCHA_ERROR));
                     ((BasePage) getPageReference().getPage()).getNotificationPanel().refresh(target);
                 } else {
-                    boolean checked = true;
-                    if (SyncopeWebApplication.get().isCaptchaEnabled()) {
-                        checked = captcha.check();
-                    }
-                    if (!checked) {
-                        SyncopeEnduserSession.get().error(getString(Constants.CAPTCHA_ERROR));
+                    try {
+                        ProvisioningResult<UserTO> provisioningResult =
+                                ProvisioningUtils.updateUser(new UserUR.Builder(userTO.getKey())
+                                                .securityQuestion(new StringReplacePatchItem.Builder().
+                                                        value(securityQuestion.getModelObject()).build())
+                                                .securityAnswer(new StringReplacePatchItem.Builder().
+                                                        value(securityAnswer.getModelObject()).build()).build(),
+                                        userTO.getETagValue());
+                        setResponsePage(new SelfResult(provisioningResult,
+                                ProvisioningUtils.managePageParams(EditSecurityQuestion.this,
+                                        "securityquestion.change",
+                                        !SyncopeWebApplication.get().isReportPropagationErrors()
+                                                || provisioningResult.getPropagationStatuses().stream()
+                                                        .allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus()))));
+                    } catch (Exception e) {
+                        LOG.error("While updating security question for {}",
+                                SyncopeEnduserSession.get().getSelfTO().getUsername(), e);
+                        SyncopeEnduserSession.get().onException(e);
                         ((BasePage) getPageReference().getPage()).getNotificationPanel().refresh(target);
-                    } else {
-                        PageParameters parameters = new PageParameters();
-                        try {
-                            UserUR req = new UserUR();
-                            req.setKey(userTO.getKey());
-                            req.setSecurityQuestion(new StringReplacePatchItem.Builder().
-                                    value(securityQuestion.getModelObject()).build());
-                            req.setSecurityAnswer(new StringReplacePatchItem.Builder().
-                                    value(securityAnswer.getModelObject()).build());
-                            userSelfRestClient.update(userTO.getETagValue(), req);
-
-                            parameters.add(EnduserConstants.STATUS, Constants.OPERATION_SUCCEEDED);
-                            parameters.add(Constants.NOTIFICATION_TITLE_PARAM,
-                                    getString("self.securityquestion.change.success"));
-                            parameters.add(Constants.NOTIFICATION_MSG_PARAM,
-                                    getString("self.securityquestion.change.success.msg"));
-                            SyncopeEnduserSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (Exception e) {
-                            LOG.error("While changing password for {}",
-                                    SyncopeEnduserSession.get().getSelfTO().getUsername(), e);
-                            parameters.add(EnduserConstants.STATUS, Constants.OPERATION_ERROR);
-                            parameters.add(Constants.NOTIFICATION_TITLE_PARAM,
-                                    getString("self.securityquestion.change.error"));
-                            parameters.add(Constants.NOTIFICATION_MSG_PARAM,
-                                    getString("self.securityquestion.change.error.msg"));
-                            SyncopeEnduserSession.get().onException(e);
-                            notificationPanel.refresh(target);
-                        }
-                        parameters.add(
-                                EnduserConstants.LANDING_PAGE,
-                                SyncopeWebApplication.get().getPageClass("profile", Dashboard.class).getName());
-                        setResponsePage(SelfResult.class, parameters);
                     }
                 }
             }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfResult.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfResult.java
index 4d415c4b97..cfce8be6e3 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfResult.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfResult.java
@@ -18,9 +18,17 @@
  */
 package org.apache.syncope.client.enduser.pages;
 
+import java.io.Serializable;
+import java.util.stream.Collectors;
 import org.apache.syncope.client.enduser.BookmarkablePageLinkBuilder;
+import org.apache.syncope.client.enduser.SyncopeWebApplication;
 import org.apache.syncope.client.enduser.commons.EnduserConstants;
+import org.apache.syncope.client.enduser.panels.ResultPanel;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.status.StatusUtils;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ExecStatus;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.basic.Label;
@@ -34,8 +42,12 @@ public class SelfResult extends BasePage {
 
     private static final String RESULT_PAGE = "page.resultPage";
 
-    @SuppressWarnings("unchecked")
     public SelfResult(final PageParameters parameters) {
+        this(null, parameters);
+    }
+
+    @SuppressWarnings("unchecked")
+    public SelfResult(final ProvisioningResult<UserTO> provisioningResult, final PageParameters parameters) {
         super(parameters, RESULT_PAGE);
 
         WebMarkupContainer content = new WebMarkupContainer("content");
@@ -60,8 +72,24 @@ public class SelfResult extends BasePage {
 
         content.add(new Label("resultTitle", parameters.get(Constants.NOTIFICATION_TITLE_PARAM).toString()));
         content.add(new Label("resultMessage", parameters.get(Constants.NOTIFICATION_MSG_PARAM).toString()));
-        content.add(new Fragment("statusIcon",
-                Constants.OPERATION_SUCCEEDED.equals(parameters.get(EnduserConstants.STATUS).toString())
-                ? "successIcon" : "errorIcon", content));
+        Fragment statusFragment = new Fragment("statusIcon",
+                provisioningResult != null
+                        && SyncopeWebApplication.get().isReportPropagationErrors()
+                        && provisioningResult.getPropagationStatuses().stream()
+                        .anyMatch(ps -> ExecStatus.SUCCESS != ps.getStatus())
+                        ? "errorIcon" : "successIcon", content);
+        // add also details about failed propagations, if enbaled by property enduser.showPropErrors
+        if (provisioningResult != null
+                && provisioningResult.getPropagationStatuses().stream()
+                .anyMatch(ps -> ExecStatus.SUCCESS != ps.getStatus())) {
+            statusFragment.add(new ResultPanel("propagationErrors",
+                    (Serializable) provisioningResult.getPropagationStatuses().stream()
+                            .filter(ps -> ExecStatus.SUCCESS != ps.getStatus())
+                            .map(ps -> StatusUtils.getStatusBean(provisioningResult.getEntity(), ps.getResource(),
+                                    ps.getAfterObj(), false)).collect(Collectors.toList()), getPageReference())
+                    .setOutputMarkupId(true)
+                    .setVisible(SyncopeWebApplication.get().isReportPropagationErrorDetails()));
+        }
+        content.add(statusFragment);
     }
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ResultPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ResultPanel.java
new file mode 100644
index 0000000000..88fb13d724
--- /dev/null
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ResultPanel.java
@@ -0,0 +1,65 @@
+/*
+ * 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.enduser.panels;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import org.apache.syncope.client.ui.commons.panels.SimpleListViewPanel;
+import org.apache.syncope.client.ui.commons.status.StatusBean;
+import org.apache.syncope.client.ui.commons.status.StatusUtils;
+import org.apache.syncope.client.ui.commons.wizards.any.AbstractResultPanel;
+import org.apache.wicket.Component;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResultPanel extends AbstractResultPanel<String, Serializable> {
+
+    private static final long serialVersionUID = -8995647450549098844L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(ResultPanel.class);
+
+    private final PageReference pageRef;
+
+    public ResultPanel(final String item, final Serializable errors, final PageReference pageRef) {
+        super(item, errors);
+        this.pageRef = pageRef;
+    }
+
+    @Override
+    protected Panel customResultBody(final String panelId, final String item, final Serializable errorBeans) {
+        return new SimpleListViewPanel.Builder<>(StatusBean.class, pageRef) {
+
+            private static final long serialVersionUID = -6809736686861678498L;
+
+            @Override
+            protected Component getValueComponent(final String key, final StatusBean bean) {
+                if ("status".equalsIgnoreCase(key)) {
+                    return StatusUtils.getWarningStatusPanel("field");
+                } else {
+                    return super.getValueComponent(key, bean);
+                }
+            }
+        }.setItems((ArrayList<StatusBean>) errorBeans)
+                .includes("resource", "status")
+                .build(panelId);
+    }
+
+}
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java
index 0b5bb37c08..16ffafd941 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java
@@ -22,9 +22,9 @@ import java.util.List;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.SyncopeWebApplication;
 import org.apache.syncope.client.enduser.commons.EnduserConstants;
+import org.apache.syncope.client.enduser.commons.ProvisioningUtils;
 import org.apache.syncope.client.enduser.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.enduser.pages.BasePage;
-import org.apache.syncope.client.enduser.pages.Dashboard;
 import org.apache.syncope.client.enduser.pages.SelfResult;
 import org.apache.syncope.client.enduser.panels.any.Details;
 import org.apache.syncope.client.enduser.panels.any.UserDetails;
@@ -38,13 +38,12 @@ import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
 import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper;
 import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.request.UserUR;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ExecStatus;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.event.IEventSink;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class UserFormPanel extends AnyFormPanel implements UserForm {
 
@@ -98,37 +97,27 @@ public class UserFormPanel extends AnyFormPanel implements UserForm {
             SyncopeEnduserSession.get().error(getString(Constants.CAPTCHA_ERROR));
             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
         } else {
-            ProvisioningResult<UserTO> result;
-            PageParameters parameters = new PageParameters();
             try {
                 AnyWrapper<UserTO> updatedWrapper = form.getModelObject();
                 UserTO userTO = updatedWrapper.getInnerObject();
 
                 fixPlainAndVirAttrs(userTO, getOriginalItem().getInnerObject());
-                UserUR req = AnyOperations.diff(userTO, getOriginalItem().getInnerObject(), false);
-
-                // update just if it is changed
-                if (req.isEmpty()) {
-                    result = new ProvisioningResult<>();
-                    result.setEntity(userTO);
-                } else {
-                    result = userSelfRestClient.update(getOriginalItem().getInnerObject().getETagValue(), req);
-                    LOG.debug("User {} has been modified", result.getEntity().getUsername());
-                }
-                parameters.add(EnduserConstants.STATUS, Constants.OPERATION_SUCCEEDED);
-                parameters.add(Constants.NOTIFICATION_TITLE_PARAM, getString("self.profile.change.success"));
-                parameters.add(Constants.NOTIFICATION_MSG_PARAM, getString("self.profile.change.success.msg"));
-            } catch (SyncopeClientException sce) {
-                parameters.add(EnduserConstants.STATUS, Constants.ERROR);
-                parameters.add(Constants.NOTIFICATION_TITLE_PARAM, getString("self.profile.change.error"));
-                parameters.add(Constants.NOTIFICATION_MSG_PARAM, getString("self.profile.change.error.msg"));
-                SyncopeEnduserSession.get().onException(sce);
+                // update and set page paramters according to provisioning result
+                ProvisioningResult<UserTO> provisioningResult =
+                        ProvisioningUtils.updateUser(
+                                AnyOperations.diff(userTO, getOriginalItem().getInnerObject(), false),
+                                getOriginalItem().getInnerObject().getETagValue());
+                setResponsePage(new SelfResult(provisioningResult,
+                        ProvisioningUtils.managePageParams(UserFormPanel.this, "profile.change",
+                                !SyncopeWebApplication.get().isReportPropagationErrors()
+                                        || provisioningResult.getPropagationStatuses().stream()
+                                                .allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus()))));
+            } catch (SyncopeClientException e) {
+                LOG.error("While changing password for {}",
+                        SyncopeEnduserSession.get().getSelfTO().getUsername(), e);
+                SyncopeEnduserSession.get().onException(e);
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
-            parameters.add(
-                    EnduserConstants.LANDING_PAGE,
-                    SyncopeWebApplication.get().getPageClass("profile", Dashboard.class).getName());
-            setResponsePage(SelfResult.class, parameters);
         }
     }
 
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserSelfFormPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserSelfFormPanel.java
index 6bd20417e1..3fac4ac8e9 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserSelfFormPanel.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserSelfFormPanel.java
@@ -23,16 +23,15 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.SyncopeWebApplication;
 import org.apache.syncope.client.enduser.commons.EnduserConstants;
+import org.apache.syncope.client.enduser.commons.ProvisioningUtils;
 import org.apache.syncope.client.enduser.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.enduser.pages.BasePage;
-import org.apache.syncope.client.enduser.pages.Login;
 import org.apache.syncope.client.enduser.pages.SelfResult;
 import org.apache.syncope.client.enduser.panels.any.Details;
 import org.apache.syncope.client.enduser.panels.any.SelfUserDetails;
 import org.apache.syncope.client.enduser.rest.UserSelfRestClient;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
-import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
 import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper;
 import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -40,12 +39,12 @@ import org.apache.syncope.common.lib.request.UserCR;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.SecurityQuestionTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ExecStatus;
 import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.Model;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class UserSelfFormPanel extends UserFormPanel {
 
@@ -78,42 +77,31 @@ public class UserSelfFormPanel extends UserFormPanel {
 
     @Override
     protected void onFormSubmit(final AjaxRequestTarget target) {
-        // captcha check
-        boolean checked = true;
-        if (SyncopeWebApplication.get().isCaptchaEnabled()) {
-            checked = captcha.check();
-        }
-        if (!checked) {
+        // first check captcha
+        if (SyncopeWebApplication.get().isCaptchaEnabled() && !captcha.check()) {
             SyncopeEnduserSession.get().error(getString(Constants.CAPTCHA_ERROR));
             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
         } else {
-            ProvisioningResult<UserTO> result;
-            PageParameters parameters = new PageParameters();
+            UserTO userTO = form.getModelObject().getInnerObject();
             try {
-                AnyWrapper<UserTO> updatedWarapper = form.getModelObject();
-                UserTO userTO = updatedWarapper.getInnerObject();
-
+                // create and set page paramters according to provisioning result
                 UserCR req = new UserCR();
                 EntityTOUtils.toAnyCR(userTO, req);
-                req.setStorePassword(updatedWarapper instanceof UserWrapper
-                        ? UserWrapper.class.cast(updatedWarapper).isStorePasswordInSyncope()
+                req.setStorePassword(form.getModelObject() instanceof UserWrapper
+                        ? UserWrapper.class.cast(form.getModelObject()).isStorePasswordInSyncope()
                         : StringUtils.isNotBlank(userTO.getPassword()));
-
-                result = userSelfRestClient.create(req);
-                LOG.debug("User {} has been created", result.getEntity().getUsername());
-
-                parameters.add(EnduserConstants.STATUS, Constants.OPERATION_SUCCEEDED);
-                parameters.add(Constants.NOTIFICATION_TITLE_PARAM, getString("self.profile.change.success"));
-                parameters.add(Constants.NOTIFICATION_MSG_PARAM, getString("self.profile.change.success.msg"));
-            } catch (SyncopeClientException sce) {
-                parameters.add(EnduserConstants.STATUS, Constants.ERROR);
-                parameters.add(Constants.NOTIFICATION_TITLE_PARAM, getString("self.profile.change.error"));
-                parameters.add(Constants.NOTIFICATION_MSG_PARAM, getString("self.profile.change.error.msg"));
-                SyncopeEnduserSession.get().onException(sce);
+                // perform request and pass propagation statuses to SelfResult page
+                ProvisioningResult<UserTO> provisioningResult = ProvisioningUtils.createUser(req);
+                setResponsePage(new SelfResult(provisioningResult,
+                        ProvisioningUtils.managePageParams(UserSelfFormPanel.this, "profile.change",
+                                !SyncopeWebApplication.get().isReportPropagationErrors()
+                                || provisioningResult.getPropagationStatuses().stream()
+                                        .allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus()))));
+            } catch (SyncopeClientException e) {
+                LOG.error("While creating user {}", userTO.getUsername(), e);
+                SyncopeEnduserSession.get().onException(e);
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
-            parameters.add(EnduserConstants.LANDING_PAGE, Login.class);
-            setResponsePage(SelfResult.class, parameters);
         }
     }
 
diff --git a/client/idrepo/enduser/src/main/resources/enduser.properties b/client/idrepo/enduser/src/main/resources/enduser.properties
index ff0bd6aa20..fd8e1d6a0b 100644
--- a/client/idrepo/enduser/src/main/resources/enduser.properties
+++ b/client/idrepo/enduser/src/main/resources/enduser.properties
@@ -45,6 +45,8 @@ enduser.maxUploadFileSizeMB=5
 
 enduser.x-forward=true
 enduser.captcha=true
+enduser.reportPropagationErrors=true
+enduser.reportPropagationErrorDetails=true
 enduser.csrf=true
 
 # Sidebar
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties
index 4a13869431..51a1bdc99e 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties
@@ -78,6 +78,7 @@ before=Before
 after=After
 
 captcha_error=Captcha entered does not match
+blank_security_info=Security question and/or answer is/are blank
 
 invalid.security.answer=Invalid security answer
 tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB). 
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties
index 59104f0c72..f621b43ff1 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties
@@ -77,6 +77,7 @@ before=Avant
 after=Apr\u00e8s
 
 captcha_error=Le captcha saisi ne correspond pas
+blank_security_info=La question et/ou la r�ponse de s�curit� est/sont vide(s)
 
 invalid.security.answer=R\u00e9ponse de s\u00e9curit\u00e9 non valide
 tooLargeFile=Le fichier est trop grand, la taille du fichier de t\u00e9l\u00e9chargement max est ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB). 
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties
index 7330ec8538..371ab4ba84 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties
@@ -75,6 +75,7 @@ before=Prima
 after=Dopo
 
 captcha_error=Il Captcha inserito non \u00e8 corretto
+blank_security_info=La domanda e/o la risposta di sicurezza �/sono vuote
 
 invalid.security.answer=Risposta di sicurezza non valida
 tooLargeFile=File troppo grande, la dimensione massima ammessa \\u00e8 ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties
index 10e8d0933a..dd6cb62415 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties
@@ -14,71 +14,73 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-users=\u30e6\u30fc\u30b6\u30fc
-groups=\u30b0\u30eb\u30fc\u30d7
-configuration=\u8a2d\u5b9a
-resources=\u30ea\u30bd\u30fc\u30b9
-connectors=\u30b3\u30cd\u30af\u30bf\u30fc
-reports=\u30ec\u30dd\u30fc\u30c8
-tasks=\u30bf\u30b9\u30af
-logout=\u30ed\u30b0\u30a2\u30a6\u30c8
-schema=\u30b9\u30ad\u30fc\u30de
-operation_succeeded=\u64cd\u4f5c\u3092\u6b63\u5e38\u306b\u5b9f\u884c\u3057\u307e\u3057\u305f
-operation_error=\u8981\u6c42\u3057\u305f\u64cd\u4f5c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
-alert=\u30a2\u30e9\u30fc\u30c8\:
-confirmDelete=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
-confirmUnlink=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3068\u30ea\u30bd\u30fc\u30b9\u306e\u9593\u306e\u30ea\u30f3\u30af\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
-confirmUnassign=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3068\u30ea\u30bd\u30fc\u30b9\u306e\u9593\u306e\u5272\u308a\u5f53\u3066\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
-confirmDeprovision=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u30c7\u30d7\u30ed\u30d3\u30b8\u30e7\u30f3\uff08\u524a\u9664\uff09\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
-confirmProvision=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u30d7\u30ed\u30d3\u30b8\u30e7\u30f3\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
-confirmClone=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u8907\u88fd\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
-dropDownChoiceField.nullValid=\uff11\u3064\u9078\u629e
-DateTimeField$HoursValidator=\u6642\u9593\u306e\u5024\u306f 1\uff5e12 \u306e\u7bc4\u56f2
-error=\u30a8\u30e9\u30fc
-generic_error=\u64cd\u4f5c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
-id=\u30ad\u30fc
-name=\u540d\u524d
-palette.available=\u5229\u7528\u53ef\u80fd
-palette.selected=\u9078\u629e\u6e08
-jexl_info=\u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u306f JEXL \u8868\u73fe\u3092\u671f\u5f85\u3057\u3066\u3044\u307e\u3059\u3002\u4f8b\:
-jexl_ex1=\u59d3 + ',' + \u540d
-jexl_ex2='\u65b0\u3057\u3044.' + \u59d3
-jexl_syntax_url=\u5b8c\u5168 JEXL \u53c2\u7167
-create=\u4f5c\u6210
-key=\u30ad\u30fc
-types=\u30bf\u30a4\u30d7
-realms=\u30ec\u30eb\u30e0
-roles=\u30ed\u30fc\u30eb
-policies=\u30dd\u30ea\u30b7\u30fc
-workflow=\u30ef\u30fc\u30af\u30d5\u30ed\u30fc
-logs=\u30ed\u30b0
-layouts=\u30ec\u30a4\u30a2\u30a6\u30c8
-notifications=\u901a\u77e5
-parameters=\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc
-extensions=\u62e1\u5f35
-NavigatorLabel=${from} \uff5e ${to} \uff0f ${of} \u884c\u3092\u8868\u793a\u4e2d
-displayRows=\u8868\u793a\u3059\u308b\u884c\u6570\:
+users=\u30E6\u30FC\u30B6\u30FC
+groups=\u30B0\u30EB\u30FC\u30D7
+configuration=\u8A2D\u5B9A
+resources=\u30EA\u30BD\u30FC\u30B9
+connectors=\u30B3\u30CD\u30AF\u30BF\u30FC
+reports=\u30EC\u30DD\u30FC\u30C8
+tasks=\u30BF\u30B9\u30AF
+logout=\u30ED\u30B0\u30A2\u30A6\u30C8
+schema=\u30B9\u30AD\u30FC\u30DE
+operation_succeeded=\u64CD\u4F5C\u3092\u6B63\u5E38\u306B\u5B9F\u884C\u3057\u307E\u3057\u305F
+operation_error=\u8981\u6C42\u3057\u305F\u64CD\u4F5C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
+alert=\u30A2\u30E9\u30FC\u30C8\:
+confirmDelete=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u524A\u9664\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
+confirmUnlink=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u9593\u306E\u30EA\u30F3\u30AF\u3092\u524A\u9664\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
+confirmUnassign=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u9593\u306E\u5272\u308A\u5F53\u3066\u3092\u524A\u9664\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
+confirmDeprovision=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u30C7\u30D7\u30ED\u30D3\u30B8\u30E7\u30F3\uFF08\u524A\u9664\uFF09\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
+confirmProvision=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u30D7\u30ED\u30D3\u30B8\u30E7\u30F3\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
+confirmClone=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u8907\u88FD\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
+dropDownChoiceField.nullValid=\uFF11\u3064\u9078\u629E
+DateTimeField$HoursValidator=\u6642\u9593\u306E\u5024\u306F 1\uFF5E12 \u306E\u7BC4\u56F2
+error=\u30A8\u30E9\u30FC
+generic_error=\u64CD\u4F5C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
+id=\u30AD\u30FC
+name=\u540D\u524D
+palette.available=\u5229\u7528\u53EF\u80FD
+palette.selected=\u9078\u629E\u6E08
+jexl_info=\u3053\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306F JEXL \u8868\u73FE\u3092\u671F\u5F85\u3057\u3066\u3044\u307E\u3059\u3002\u4F8B\:
+jexl_ex1=\u59D3 + ',' + \u540D
+jexl_ex2='\u65B0\u3057\u3044.' + \u59D3
+jexl_syntax_url=\u5B8C\u5168 JEXL \u53C2\u7167
+create=\u4F5C\u6210
+key=\u30AD\u30FC
+types=\u30BF\u30A4\u30D7
+realms=\u30EC\u30EB\u30E0
+roles=\u30ED\u30FC\u30EB
+policies=\u30DD\u30EA\u30B7\u30FC
+workflow=\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC
+logs=\u30ED\u30B0
+layouts=\u30EC\u30A4\u30A2\u30A6\u30C8
+notifications=\u901A\u77E5
+parameters=\u30D1\u30E9\u30E1\u30FC\u30BF\u30FC
+extensions=\u62E1\u5F35
+NavigatorLabel=${from} \uFF5E ${to} \uFF0F ${of} \u884C\u3092\u8868\u793A\u4E2D
+displayRows=\u8868\u793A\u3059\u308B\u884C\u6570\:
 OrderByLink.CSS.ascending=sorting_asc
 OrderByLink.CSS.descending=sorting_desc
 OrderByLink.CSS.none=sorting
-entitlements=\u4ed8\u4e0e
-audit=\u76e3\u67fb
-connectors.confirm.reload=\u3053\u306e\u8981\u6c42\u306f\u3001\u5b9f\u884c\u4e2d\u306e\u64cd\u4f5c\u306b\u5bfe\u3057\u3066\u5371\u967a\u306a\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u7d9a\u884c\u3057\u307e\u3059\u304b?
-intAttrNameInfo.help=\u30aa\u30fc\u30c8\u30b3\u30f3\u30d7\u30ea\u30fc\u30c8\u306e\u5c5e\u6027\u4ee5\u5916\u306b\u3001\u30b0\u30eb\u30fc\u30d7\u3001\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3001\u30e1\u30f3\u30d0\u30fc\u30b7\u30c3\u30d7\u3082\u53c2\u7167\u53ef\u80fd\u3067\u3059 (\u8a72\u5f53\u3059\u308b\u5834\u5408)\u3002\u4f8b\:
-confirmGlobalLogout=\u30b0\u30ed\u30fc\u30d0\u30eb\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?
-implementations=\u5c0e\u5165
-timeout=\u64cd\u4f5c\u306b\u9577\u6642\u9593\u304b\u304b\u3063\u3066\u3044\u307e\u3059\: \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u5b9f\u884c\u3055\u308c\u307e\u3059\u3002 \u7d50\u679c\u3092\u5f8c\u3067\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044 (\u30a8\u30e9\u30fc\u306f\u5f15\u304d\u8d77\u3053\u3057\u307e\u305b\u3093)\u3002
-editsecurityquestion=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3
-before=\u524d
-after=\u5f8c
+entitlements=\u4ED8\u4E0E
+audit=\u76E3\u67FB
+connectors.confirm.reload=\u3053\u306E\u8981\u6C42\u306F\u3001\u5B9F\u884C\u4E2D\u306E\u64CD\u4F5C\u306B\u5BFE\u3057\u3066\u5371\u967A\u306A\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u7D9A\u884C\u3057\u307E\u3059\u304B?
+intAttrNameInfo.help=\u30AA\u30FC\u30C8\u30B3\u30F3\u30D7\u30EA\u30FC\u30C8\u306E\u5C5E\u6027\u4EE5\u5916\u306B\u3001\u30B0\u30EB\u30FC\u30D7\u3001\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3001\u30E1\u30F3\u30D0\u30FC\u30B7\u30C3\u30D7\u3082\u53C2\u7167\u53EF\u80FD\u3067\u3059 (\u8A72\u5F53\u3059\u308B\u5834\u5408)\u3002\u4F8B\:
+confirmGlobalLogout=\u30B0\u30ED\u30FC\u30D0\u30EB\u30ED\u30B0\u30A2\u30A6\u30C8\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
+implementations=\u5C0E\u5165
+timeout=\u64CD\u4F5C\u306B\u9577\u6642\u9593\u304B\u304B\u3063\u3066\u3044\u307E\u3059\: \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u3067\u5B9F\u884C\u3055\u308C\u307E\u3059\u3002 \u7D50\u679C\u3092\u5F8C\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044 (\u30A8\u30E9\u30FC\u306F\u5F15\u304D\u8D77\u3053\u3057\u307E\u305B\u3093)\u3002
+editsecurityquestion=\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3
+before=\u524D
+after=\u5F8C
+
+captcha_error=\u5165\u529B\u3055\u308C\u305F\u30AD\u30E3\u30D7\u30C1\u30E3\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093
+blank_security_info=\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u8CEA\u554F\u304A\u3088\u3073/\u307E\u305F\u306F\u56DE\u7B54\u304C\u7A7A\u767D\u3067\u3042\u308B
 
-captcha_error=\u5165\u529b\u3055\u308c\u305f\u30ad\u30e3\u30d7\u30c1\u30e3\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093
 invalid.security.answer=Invalid security answer
 tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB). 
 home=Home
 profile=Personal Information
 requests=User Requests
-edituser=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u7de8\u96c6
+edituser=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u7DE8\u96C6
 submit=Submit
 cancel=Cancel
 editchangepassword=Change password
@@ -90,7 +92,7 @@ details=Details
 user-requests-link=User Requests
 self-pwd-reset-link=Self Password Reset
 self-registration-link=Self Registration
-user_request_error=\u30e6\u30fc\u30b6\u30fc\u30ea\u30af\u30a8\u30b9\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 \u7ba1\u7406\u8005\u306b\u9023\u7d61\u3057\u3066\u304f\u3060\u3055\u3044
+user_request_error=\u30E6\u30FC\u30B6\u30FC\u30EA\u30AF\u30A8\u30B9\u30C8\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 \u7BA1\u7406\u8005\u306B\u9023\u7D61\u3057\u3066\u304F\u3060\u3055\u3044
 
 page.home=Home
 page.changePassword=Change Password
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties
index 9223e0bdfd..128d00a373 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties
@@ -75,6 +75,8 @@ before=Before
 after=After
 
 captcha_error=Captcha entered does not match
+blank_security_info=A pergunta e/ou resposta de seguran�a est�/est�o em branco
+
 invalid.security.answer=Invalid security answer
 tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
 home=Home
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties
index ecf3ec7898..2ecc5877c9 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties
@@ -14,59 +14,59 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-users=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438
-groups=\u0413\u0440\u0443\u043f\u043f\u044b
-configuration=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f
-resources=\u0420\u0435\u0441\u0443\u0440\u0441\u044b
-connectors=\u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b
-reports=\u041e\u0442\u0447\u0435\u0442\u044b
+users=\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438
+groups=\u0413\u0440\u0443\u043F\u043F\u044B
+configuration=\u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F
+resources=\u0420\u0435\u0441\u0443\u0440\u0441\u044B
+connectors=\u041A\u043E\u043D\u043D\u0435\u043A\u0442\u043E\u0440\u044B
+reports=\u041E\u0442\u0447\u0435\u0442\u044B
 tasks=\u0417\u0430\u0434\u0430\u0447\u0438
-logout=\u0412\u044b\u0439\u0442\u0438
+logout=\u0412\u044B\u0439\u0442\u0438
 schema=\u0410\u0442\u0440\u0438\u0431\u0443\u0442
-operation_succeeded=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e
-operation_error=\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430
-alert=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435:
-confirmDelete=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b?
-confirmUnlink=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u043c?
-confirmUnassign=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432?
-confirmDeprovision=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043e\u0437\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b?
-confirmProvision=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b?
-confirmClone=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b?
-dropDownChoiceField.nullValid=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435
-DateTimeField$HoursValidator=\u0427\u0430\u0441\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 (1, 12)
-error=\u041e\u0448\u0438\u0431\u043a\u0430
-generic_error=\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430
-id=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440
-name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
-palette.available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e
-palette.selected=\u0412\u044b\u0431\u0440\u0430\u043d\u043e
-jexl_info=\u042d\u0442\u043e \u043f\u043e\u043b\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c JEXL \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:
+operation_succeeded=\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u043E
+operation_error=\u0412\u043E \u0432\u0440\u0435\u043C\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u043F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430
+alert=\u041F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u0435:
+confirmDelete=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B?
+confirmUnlink=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0432\u044F\u0437\u044C \u043C\u0435\u0436\u0434\u0443 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u043C\u0438 \u043E\u0431\u044A\u0435\u043A\u0442\u0430\u043C\u0438 \u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043E\u043C?
+confirmUnassign=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0434\u043B\u044F \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0445 \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432?
+confirmDeprovision=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u043E\u0442\u043E\u0437\u0432\u0430\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B?
+confirmProvision=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u043F\u0440\u0435\u0434\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B?
+confirmClone=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u043A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B?
+dropDownChoiceField.nullValid=\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435
+DateTimeField$HoursValidator=\u0427\u0430\u0441\u044B \u0434\u043E\u043B\u0436\u043D\u044B \u0431\u044B\u0442\u044C \u0443\u043A\u0430\u0437\u0430\u043D\u044B \u0432 \u0434\u0438\u0430\u043F\u0430\u0437\u043E\u043D\u0435 (1, 12)
+error=\u041E\u0448\u0438\u0431\u043A\u0430
+generic_error=\u0412\u043E \u0432\u0440\u0435\u043C\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u043F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430
+id=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440
+name=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435
+palette.available=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u043E
+palette.selected=\u0412\u044B\u0431\u0440\u0430\u043D\u043E
+jexl_info=\u042D\u0442\u043E \u043F\u043E\u043B\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C JEXL \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440:
 jexl_ex1=surname + ',' + firstname
 jexl_ex2='new.' + surname
-jexl_syntax_url=\u0421\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e JEXL
-create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c
-key=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440
-types=\u0422\u0438\u043f\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432
-realms=\u041e\u0431\u043b\u0430\u0441\u0442\u0438
-roles=\u0420\u043e\u043b\u0438
-policies=\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0438
-workflow=\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f
-logs=\u041b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
-layouts=\u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0430
-notifications=\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f
-parameters=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b
-extensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f
-NavigatorLabel=\u0421\u0442\u0440\u043e\u043a\u0438 ${from}-${to} \u0438\u0437 ${of}
-displayRows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e:
-OrderByLink.CSS.ascending=\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430_\u043f\u043e_\u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u043d\u0438\u044e
-OrderByLink.CSS.descending=\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430_\u043f\u043e_\u0443\u0431\u044b\u0432\u0430\u043d\u0438\u044e
-OrderByLink.CSS.none=\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430
-entitlements=\u041f\u043e\u043b\u043d\u043e\u043c\u043e\u0447\u0438\u044f
+jexl_syntax_url=\u0421\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E JEXL
+create=\u0421\u043E\u0437\u0434\u0430\u0442\u044C
+key=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440
+types=\u0422\u0438\u043F\u044B \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432
+realms=\u041E\u0431\u043B\u0430\u0441\u0442\u0438
+roles=\u0420\u043E\u043B\u0438
+policies=\u041F\u043E\u043B\u0438\u0442\u0438\u043A\u0438
+workflow=\u041F\u0440\u043E\u0446\u0435\u0441\u0441 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u0438\u044F
+logs=\u041B\u043E\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435
+layouts=\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430
+notifications=\u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F
+parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B
+extensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F
+NavigatorLabel=\u0421\u0442\u0440\u043E\u043A\u0438 ${from}-${to} \u0438\u0437 ${of}
+displayRows=\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E:
+OrderByLink.CSS.ascending=\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430_\u043F\u043E_\u0432\u043E\u0437\u0440\u0430\u0441\u0442\u0430\u043D\u0438\u044E
+OrderByLink.CSS.descending=\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430_\u043F\u043E_\u0443\u0431\u044B\u0432\u0430\u043D\u0438\u044E
+OrderByLink.CSS.none=\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430
+entitlements=\u041F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u044F
 audit=\u0410\u0443\u0434\u0438\u0442
-connectors.confirm.reload=\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u043f\u0430\u0441\u043d\u043e \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?
-intAttrNameInfo.help=\u041f\u043e\u043c\u0438\u043c\u043e \u0430\u0432\u0442\u043e\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b, \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0 [...]
+connectors.confirm.reload=\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u044D\u0442\u043E\u0433\u043E \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u043F\u043E\u0442\u0435\u043D\u0446\u0438\u0430\u043B\u044C\u043D\u043E \u043E\u043F\u0430\u0441\u043D\u043E \u0434\u043B\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u0435\u043C\u044B\u0445 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0439. \u041F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C?
+intAttrNameInfo.help=\u041F\u043E\u043C\u0438\u043C\u043E \u0430\u0432\u0442\u043E\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043E\u0432, \u0432\u044B \u0442\u0430\u043A\u0436\u0435 \u043C\u043E\u0436\u0435\u0442\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0433\u0440\u0443\u043F\u043F\u044B, \u0440\u0430\u0437\u043B\u0438\u0447\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B \u0 [...]
 confirmGlobalLogout=Do you really want to perform global logout?
-implementations=\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438
+implementations=\u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438
 
 timeout=Operation is taking too long: it will be executed in background. Please check later for the result (errors won't be triggered).
 editsecurityquestion=Security question
@@ -74,12 +74,14 @@ before=Before
 after=After
 
 captcha_error=Captcha entered does not match
+blank_security_info=\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u044B\u0439 \u0432\u043E\u043F\u0440\u043E\u0441 \u0438/\u0438\u043B\u0438 \u043E\u0442\u0432\u0435\u0442 \u043F\u0443\u0441\u0442\u044B
+
 invalid.security.answer=Invalid security answer
 tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB). 
 home=Home
 profile=Personal Information
 requests=User Requests
-edituser=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c
+edituser=\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u0440\u043E\u0444\u0438\u043B\u044C
 submit=Submit
 cancel=Cancel
 editchangepassword=Change password
@@ -91,7 +93,7 @@ details=Details
 user-requests-link=User Requests
 self-pwd-reset-link=Self Password Reset
 self-registration-link=Self Registration
-user_request_error=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443
+user_request_error=\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u0437\u0430\u043F\u0440\u043E\u0441\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F. \u041E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043A \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0443
 
 page.home=Home
 page.changePassword=Change Password
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties
index 2be69393ba..451aab8071 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties
@@ -20,6 +20,6 @@ cancel=Cancel
 confirmPassword=Password (confirm)
 passwordNeedsToBeUpdated=Password needs to be updated
 self.pwd.change.success.msg=Password successfully changed
-self.pwd.change.error=Unable to complete the change password
-self.pwd.change.error.msg=Please contact an administrator
+self.pwd.change.error=An error occured while propagating to related resources, please contact the system administrator.
+self.pwd.change.error.msg=Error while changing password.
 self.pwd.change.success=Successfully changed
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties
index 0044ab10ca..0b6cc61778 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties
@@ -21,5 +21,5 @@ confirmPassword=Password (conferma)
 passwordNeedsToBeUpdated=La password deve essere aggiornata
 self.pwd.change.success.msg=Password aggiornata con successo
 self.pwd.change.error=Errore durante il cambio password
-self.pwd.change.error.msg=Si prega di contattare 
+self.pwd.change.error.msg=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema.
 self.pwd.change.success=Aggiornamento avvenuto con successo
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties
index deec62007d..6920aca5de 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties
@@ -19,5 +19,5 @@ submit=Cambia
 cancel=Annulla
 self.securityquestion.change.success=Aggiornamento avvenuto con successo
 self.securityquestion.change.error=Errore durante il cambio della domanda di sicurezza
-self.securityquestion.change.error.msg=Si prega di contattare 
+self.securityquestion.change.error.msg=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema. 
 self.securityquestion.change.success.msg=Aggiornamento della domanda di sicurezza avvenuto con successo
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties
index caa926bd7a..bfc6873603 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties
@@ -24,4 +24,4 @@ self.pwd.change.success=Password aggiornata con successo
 
 Cancel=Annulla
 self.pwd.change.error=Errore durante il cambio password
-self.pwd.change.error.msg=Si prega di contattare 
+self.pwd.change.error.msg=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema. 
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
index 05f050b642..c5da696e65 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
@@ -24,5 +24,5 @@ self.confirm.pwd.reset.success=Password Changed!
 self.confirm.pwd.reset.success.msg=Password successfully changed
 self.confirm.pwd.reset.error.empty=No token was specified in the url, cannot access to the requested page
 
-self.confirm.pwd.reset.error=Unable to complete the Password Reset
-self.confirm.pwd.reset.error.msg=Please contact an administrator
+self.confirm.pwd.reset.error=Error while performing password reset
+self.confirm.pwd.reset.error.msg=Please contact the system administrator.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
index d621ebdce6..9500f0c356 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
@@ -23,5 +23,5 @@ submit=Invia
 self.confirm.pwd.reset.success=Password \u00e8 stata modificata
 self.confirm.pwd.reset.success.msg=Cambio password eseguito con successo
 self.confirm.pwd.reset.error.empty=Nessun token \u00e8 specificato nell'url, non \u00e8 possibile accedere alla pagina richiesta
-self.confirm.pwd.reset.error=Errore durante il processo di reset password
-self.confirm.pwd.reset.error.msg=Si prega di contattare 
+self.confirm.pwd.reset.error=Si prega di contattare l'amministratore di sistema.
+self.confirm.pwd.reset.error.msg=Errore durante la richiesta.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.html
index 19e5d56e6f..7fe0b82dda 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.html
@@ -18,57 +18,56 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:extend>
+<wicket:extend>
     <div class="brand-link bg-red brand-custom">
       <span class="logo-mini">
         <img aria-label="Apache Syncope Enduser" alt="Apache Syncope Enduser" src="ui-commons/img/logo-mini.png"/>
       </span>
-      <span class="brand-text font-weight-light">Apache Syncope</span>
+        <span class="brand-text font-weight-light">Apache Syncope</span>
     </div>
     <section class="content" wicket:id="content">
-      <div class="box">
-        <div id="password_reset" class="container-fluid password_reset_wrapper">
+        <div class="box">
+            <div id="password_reset" class="container-fluid password_reset_wrapper">
 
-          <div class="row ">
-            <div class="col-md-6 mx-auto">
+                <div class="row ">
+                    <div class="col-md-6 mx-auto">
 
-              <div class="page-header">
-                <h1>
-                  <span wicket:id="resultTitle">[LABEL]</span>
-                </h1>
+                        <div class="page-header">
+                            <h1>
+                                <span wicket:id="resultTitle">[LABEL]</span>
+                            </h1>
 
-              </div>
-              <fieldset class="enduser_fieldset">
+                        </div>
+                        <fieldset class="enduser_fieldset">
 
-                <div class="form-group input-md">
-                  <span wicket:id="resultMessage">[LABEL]</span>
-                  <a wicket:id="login">
-                    <wicket:message key="login">[login]</wicket:message>
-                  </a>
-                </div>
+                            <div class="form-group input-md">
+                                <span wicket:id="resultMessage">[LABEL]</span>
+                                <a wicket:id="login">
+                                    <wicket:message key="login">[login]</wicket:message>
+                                </a>
+                            </div>
 
-              </fieldset>
+                        </fieldset>
 
-              <span wicket:id="statusIcon"></span>
-              <wicket:fragment wicket:id="successIcon">
-                <svg class="checkmark_ok" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
-                  <circle class="checkmark_circle_ok" cx="26" cy="26" r="25" fill="none"/>
-                  <path class="checkmark_check_ok" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
-                </svg>
-              </wicket:fragment>
-              <wicket:fragment wicket:id="errorIcon">
-                <svg class="checkmark_error" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
-                  <circle class="checkmark_circle_error" cx="26" cy="26" r="25" fill="none"/>
-                  <path class="checkmark_check_error" fill="none" d="M16 16 36 36 M36 16 16 36"/>
-                </svg>
-              </wicket:fragment>
-
-
-            </div>
-          </div> <!-- col -->
-        </div> <!-- row -->
-      </div>
+                        <span wicket:id="statusIcon"></span>
+                        <wicket:fragment wicket:id="successIcon">
+                            <svg class="checkmark_ok" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
+                                <circle class="checkmark_circle_ok" cx="26" cy="26" r="25" fill="none"/>
+                                <path class="checkmark_check_ok" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
+                            </svg>
+                        </wicket:fragment>
+                        <wicket:fragment wicket:id="errorIcon">
+                            <svg class="checkmark_error" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
+                                <circle class="checkmark_circle_error" cx="26" cy="26" r="25" fill="none"/>
+                                <path class="checkmark_check_error" fill="none" d="M16 16 36 36 M36 16 16 36"/>
+                            </svg>
+                            <span wicket:id="content"/>
+                        </wicket:fragment>
+                    </div>
+                </div> <!-- col -->
+            </div> <!-- row -->
+        </div>
     </section>
 
-  </wicket:extend>
+</wicket:extend>
 </html>
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.properties
index bcdb339109..beca61fc18 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult.properties
@@ -15,3 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 login=Back to Home
+
+failing.propagations.title=Error Details
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties
index 3d4c66feed..0a78c8a6dd 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-login=Retour \u00e0 la page d'accueil
+login=Retour \u00E0 la page d'accueil
+
+failing.propagations.title=D\u00E9tails de l'erreur
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_it.properties
index 709cc6ff9e..502e57d3fd 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_it.properties
@@ -15,3 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 login=Torna alla Home
+
+failing.propagations.title=Dettagli Errore
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ja.properties
index bcdb339109..46baa23c94 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ja.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-login=Back to Home
+login=\u30DB\u30FC\u30E0\u30DA\u30FC\u30B8
+
+failing.propagations.title=\u30A8\u30E9\u30FC\u306E\u8A73\u7D30
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_pt_BR.properties
index bcdb339109..93e8720806 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_pt_BR.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-login=Back to Home
+login=Voltar para a p�gina inicial
+
+failing.propagations.title=Detalhes do erro
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ru.properties
index bcdb339109..c6b6922fb0 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_ru.properties
@@ -14,4 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-login=Back to Home
+login=\u0414\u043E\u043C\u0430\u0448\u043D\u044F\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430
+
+failing.propagations.title=\u0421\u0432\u0435\u0434\u0435\u043D\u0438\u044F \u043E\u0431 \u043E\u0448\u0438\u0431\u043A\u0435
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ResultPanel.html
similarity index 85%
rename from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
rename to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ResultPanel.html
index bca1667d43..9eb657815a 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ResultPage.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ResultPanel.html
@@ -17,10 +17,7 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:panel>
+<wicket:extend>
     <span wicket:id="customResultBody"/>
-    <div id="inline-actions" class="modal-footer circular-actions">
-      <span wicket:id="action"/>
-    </div>
-  </wicket:panel>
+</wicket:extend>
 </html>
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.properties
index 0a7e6bb5b2..14f32bcedc 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.properties
@@ -17,5 +17,5 @@
 self.profile.change.success.msg=Your profile has been successfully changed
 
 self.profile.change.success=Operation completed successfully
-self.profile.change.error.msg=Error updating profile
-self.profile.change.error=Error
+self.profile.change.error.msg=Error while updating profile
+self.profile.change.error=An error occured while propagating information to related resources, please contact the system administrator.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_it.properties
index 94cf2b2bb7..f03f41de3e 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_it.properties
@@ -17,4 +17,4 @@
 self.profile.change.success.msg=Il tuo profilo \u00e8 stato modificato correttamente
 self.profile.change.success=Operazione completata con successo
 self.profile.change.error.msg=Errore durante l'aggiornamento del profilo
-self.profile.change.error=Errore
+self.profile.change.error=Si � verificato un errore durante la propagazione delle informazioni sulle risorse. Si prega di contattare l'amministratore sistema.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ja.properties
index 6bfaa279a9..5674740c81 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ja.properties
@@ -14,7 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-self.profile.change.success.msg=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u304c\u6b63\u5e38\u306b\u7de8\u96c6\u3055\u308c\u307e\u3057\u305f
-self.profile.change.success=\u64cd\u4f5c\u306f\u6b63\u5e38\u306b\u5b8c\u4e86\u3057\u307e\u3057\u305f
-self.profile.change.error.msg=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
-self.profile.change.error=\u30a8\u30e9\u30fc
+self.profile.change.success.msg=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u304C\u6B63\u5E38\u306B\u7DE8\u96C6\u3055\u308C\u307E\u3057\u305F
+self.profile.change.success=\u64CD\u4F5C\u306F\u6B63\u5E38\u306B\u5B8C\u4E86\u3057\u307E\u3057\u305F
+self.profile.change.error.msg=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u66F4\u65B0\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
+self.profile.change.error=\u95A2\u9023\u3059\u308B\u30EA\u30BD\u30FC\u30B9\u306B\u60C5\u5831\u3092\u4F1D\u9054\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30B7\u30B9\u30C6\u30E0\u7BA1\u7406\u8005\u306B\u9023\u7D61\u3057\u3066\u304F\u3060\u3055\u3044\u3002
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_pt_BR.properties
index fda623b068..bff470ef12 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_pt_BR.properties
@@ -15,6 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 self.profile.change.success.msg=Seu perfil foi editado com sucesso
-self.profile.change.success=Opera\u00e7\u00e3o conclu\u00edda com sucesso
+self.profile.change.success=Opera\u00E7\u00E3o conclu\u00EDda com sucesso
 self.profile.change.error.msg=Erro ao atualizar perfil
-self.profile.change.error=Erro
+self.profile.change.error=Ocorreu um erro ao propagar informa\u00E7\u00F5es para recursos relacionados, entre em contato com o administrador do sistema.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ru.properties
index adc4bf8072..0b40f763ac 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel_ru.properties
@@ -14,7 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-self.profile.change.success.msg=\u0412\u0430\u0448 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d
-self.profile.change.success=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
-self.profile.change.error.msg=\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0444\u0438\u043b\u044f
-self.profile.change.error=\u043e\u0448\u0438\u0431\u043a\u0430
+self.profile.change.success.msg=\u0412\u0430\u0448 \u043F\u0440\u043E\u0444\u0438\u043B\u044C \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u043E\u0442\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D
+self.profile.change.success=\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430
+self.profile.change.error.msg=\u041E\u0448\u0438\u0431\u043A\u0430 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u043F\u0440\u043E\u0444\u0438\u043B\u044F
+self.profile.change.error=\u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u0440\u0430\u0441\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u0438 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438 \u043D\u0430 \u0441\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044B, \u043E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043A \u0441\u0438\u0441\u044 [...]
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
index 2755144025..d71c33ee15 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
@@ -125,7 +125,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
         };
         ((WebMarkupContainer) get("container:content")).addOrReplace(newBpmnProcessLink);
 
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
 
diff --git a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java
index 19ae259500..a217d7bfba 100644
--- a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java
+++ b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java
@@ -25,7 +25,7 @@ import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.panels.SCIMConfPanel;
 import org.apache.syncope.client.console.rest.SCIMConfRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wizards.any.ResultPage;
+import org.apache.syncope.client.console.wizards.any.ResultPanel;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.annotations.ExtPage;
 import org.apache.syncope.common.lib.scim.SCIMConf;
@@ -68,8 +68,8 @@ public class SCIMConfPage extends BaseExtPage {
             @Override
             protected void setWindowClosedReloadCallback(final BaseModal<?> modal) {
                 modal.setWindowClosedCallback(target -> {
-                    if (modal.getContent() instanceof ResultPage) {
-                        Serializable result = ResultPage.class.cast(modal.getContent()).getResult();
+                    if (modal.getContent() instanceof ResultPanel) {
+                        Serializable result = (Serializable) ResultPanel.class.cast(modal.getContent()).getResult();
                         try {
                             SCIMConfRestClient.set(MAPPER.readValue(result.toString(), SCIMConf.class));
 
diff --git a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/SCIMConfPanel.java b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/SCIMConfPanel.java
index c1b76cbcbe..ddc86bb26d 100644
--- a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/SCIMConfPanel.java
+++ b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/SCIMConfPanel.java
@@ -72,7 +72,7 @@ public abstract class SCIMConfPanel extends WizardMgtPanel<SCIMConf> {
         };
         addInnerObject(saveButton);
 
-        setShowResultPage(true);
+        setShowResultPanel(true);
 
         modal.size(Modal.Size.Large);
         setWindowClosedReloadCallback(modal);