You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2016/03/07 16:52:17 UTC

[1/6] syncope git commit: [SYNCOPE-156] Fixing pages title appeareance - now breadcrumb

Repository: syncope
Updated Branches:
  refs/heads/master 3b784c075 -> 72833a003


[SYNCOPE-156] Fixing pages title appeareance - now breadcrumb


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

Branch: refs/heads/master
Commit: 581f5247dfbece310ca4fb3fcdaca6fdc116ca20
Parents: 3b784c0
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Mar 3 10:24:24 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Mar 7 15:08:00 2016 +0100

----------------------------------------------------------------------
 .../console/BookmarkablePageLinkBuilder.java    |  8 ++++-
 .../syncope/client/console/pages/Layouts.java   |  3 ++
 .../syncope/client/console/pages/Logs.java      |  2 ++
 .../client/console/pages/Notifications.java     |  3 ++
 .../client/console/pages/Parameters.java        |  3 ++
 .../syncope/client/console/pages/Policies.java  |  3 ++
 .../syncope/client/console/pages/Realms.java    |  3 ++
 .../syncope/client/console/pages/Reports.java   |  3 ++
 .../syncope/client/console/pages/Roles.java     |  3 ++
 .../client/console/pages/SecurityQuestions.java |  3 ++
 .../syncope/client/console/pages/Types.java     |  3 ++
 .../syncope/client/console/pages/Dashboard.html |  6 ----
 .../syncope/client/console/pages/Layouts.html   |  7 +++-
 .../syncope/client/console/pages/Logs.html      |  9 +++--
 .../client/console/pages/Notifications.html     |  7 +++-
 .../client/console/pages/Parameters.html        |  9 +++--
 .../syncope/client/console/pages/Policies.html  |  7 +++-
 .../syncope/client/console/pages/Realms.html    | 35 ++++++++++----------
 .../syncope/client/console/pages/Reports.html   |  6 +++-
 .../syncope/client/console/pages/Roles.html     |  9 +++--
 .../client/console/pages/SecurityQuestions.html |  9 +++--
 .../syncope/client/console/pages/Types.html     |  9 +++--
 .../syncope/client/console/pages/Workflow.html  |  4 +--
 .../client/console/pages/CamelRoutes.java       |  3 ++
 .../client/console/pages/CamelRoutes.html       |  9 +++--
 25 files changed, 116 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java
index 00a42db..91d753a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/BookmarkablePageLinkBuilder.java
@@ -26,9 +26,15 @@ public final class BookmarkablePageLinkBuilder {
     public static <T> BookmarkablePageLink<T> build(
             final String key, final Class<? extends BasePage> defaultPageClass) {
 
+        return build(key, key, defaultPageClass);
+    }
+
+    public static <T> BookmarkablePageLink<T> build(
+            final String key, final String id, final Class<? extends BasePage> defaultPageClass) {
+
         Class<? extends BasePage> pageClass = SyncopeConsoleApplication.get().getPageClass(key);
         return new BookmarkablePageLink<>(
-                key,
+                id,
                 pageClass == null ? defaultPageClass : pageClass);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Layouts.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Layouts.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Layouts.java
index bb661bc..24464da 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Layouts.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Layouts.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class Layouts extends BasePage {
@@ -26,5 +27,7 @@ public class Layouts extends BasePage {
 
     public Layouts(final PageParameters parameters) {
         super(parameters);
+
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
index c1816b9..74fe69f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.pages;
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.panels.ConsoleLogPanel;
 import org.apache.syncope.client.console.panels.CoreLogPanel;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
@@ -37,6 +38,7 @@ public class Logs extends BasePage {
     public Logs(final PageParameters parameters) {
         super(parameters);
 
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
         content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Notifications.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Notifications.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Notifications.java
index 61e48bb..b1b7ee9 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Notifications.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Notifications.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class Notifications extends BasePage {
@@ -26,5 +27,7 @@ public class Notifications extends BasePage {
 
     public Notifications(final PageParameters parameters) {
         super(parameters);
+
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Parameters.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Parameters.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Parameters.java
index 997c1a8..e03c5b6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Parameters.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Parameters.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.panels.ParametersPanel;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
@@ -31,6 +32,8 @@ public class Parameters extends BasePage {
     public Parameters(final PageParameters parameters) {
         super(parameters);
 
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
         body.add(content);

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Policies.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Policies.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Policies.java
index 915cbd9..59cc25f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Policies.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Policies.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class Policies extends BasePage {
@@ -26,5 +27,7 @@ public class Policies extends BasePage {
 
     public Policies(final PageParameters parameters) {
         super(parameters);
+
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index 58928a0..a5c10e2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.Realm;
@@ -52,6 +53,8 @@ public class Realms extends BasePage {
     public Realms(final PageParameters parameters) {
         super(parameters);
 
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
         content = new WebMarkupContainer("content");
 
         realmChoicePanel = new RealmChoicePanel("realmChoicePanel", getPageReference());

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
index ca37e5a..f089554 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class Reports extends BasePage {
@@ -26,5 +27,7 @@ public class Reports extends BasePage {
 
     public Reports(final PageParameters parameters) {
         super(parameters);
+
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
index f37d5fd..dd993de 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Roles.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.panels.RoleSearchResultPanel;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
@@ -34,6 +35,8 @@ public class Roles extends BasePage {
     public Roles(final PageParameters parameters) {
         super(parameters);
 
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
         body.add(content);

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/SecurityQuestions.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/SecurityQuestions.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/SecurityQuestions.java
index 28ee332..dd34c1b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/SecurityQuestions.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/SecurityQuestions.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.panels.SecurityQuestionsPanel;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
@@ -29,6 +30,8 @@ public class SecurityQuestions extends BasePage {
     public SecurityQuestions(final PageParameters parameters) {
         super(parameters);
 
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
         body.add(content);

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
index 664315b..3b41821 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.pages;
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.panels.AnyTypeClassesPanel;
 import org.apache.syncope.client.console.panels.AnyTypesPanel;
 import org.apache.syncope.client.console.panels.RelationshipTypesPanel;
@@ -47,6 +48,8 @@ public class Types extends BasePage {
     public Types(final PageParameters parameters) {
         super(parameters);
 
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
         content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
index 4455eb7..3c47012 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
@@ -18,12 +18,6 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
-    <section class="content-header">
-      <h1>
-        <wicket:message key="dashboard"/>
-      </h1>
-    </section>
-
     <section class="content" wicket:id="content">
       <div class="box">
         <div class="box-body" wicket:id="tabbedPanel"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Layouts.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Layouts.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Layouts.html
index ba1764b..a5e0c54 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Layouts.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Layouts.html
@@ -21,9 +21,14 @@ under the License.
 
     <section class="content-header">
       <h1>
-        <wicket:message key="layouts"/>
+        &nbsp;
         <small>Work in progress</small>
       </h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="layouts"/></li>
+      </ol>
     </section>
 
     <section class="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Logs.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Logs.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Logs.html
index 24ce9b1..f7f9ce0 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Logs.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Logs.html
@@ -19,9 +19,12 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content-header">
-      <h1>
-        <wicket:message key="logs"/>
-      </h1>
+      <h1>&nbsp;</h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="logs"/></li>
+      </ol>
     </section>
 
     <section class="content" wicket:id="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Notifications.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Notifications.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Notifications.html
index 9d84dfa..a2a9242 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Notifications.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Notifications.html
@@ -21,9 +21,14 @@ under the License.
 
     <section class="content-header">
       <h1>
-        <wicket:message key="notifications"/>
+        &nbsp;
         <small>Work in progress</small>
       </h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="notifications"/></li>
+      </ol>
     </section>
 
     <section class="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Parameters.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Parameters.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Parameters.html
index 22c362f..08fa4ba 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Parameters.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Parameters.html
@@ -19,9 +19,12 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content-header">
-      <h1>
-        <wicket:message key="parameters"/>
-      </h1>
+      <h1>&nbsp;</h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="parameters"/></li>
+      </ol>
     </section>
 
     <section class="content" wicket:id="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Policies.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Policies.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Policies.html
index be6320a..e76ca31 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Policies.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Policies.html
@@ -21,9 +21,14 @@ under the License.
 
     <section class="content-header">
       <h1>
-        <wicket:message key="policies"/>
+        &nbsp;
         <small>Work in progress</small>
       </h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="policies"/></li>
+      </ol>
     </section>
 
     <section class="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
index ab19e43..200d752 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
@@ -17,24 +17,23 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <head><title>Realms</title></head>
-  <body>
-    <wicket:extend>
-      <section class="content-header">
-        <h1>
-          <wicket:message key="realms"/>
-        </h1>
-      </section>
+  <wicket:extend>
+    <section class="content-header">
+      <h1>&nbsp;</h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="realms"/></li>
+      </ol>
+    </section>
 
-      <section class="content" wicket:id="content">
-        <div class="box">
-          <div class="box-body">
-            <span wicket:id="realmChoicePanel">[Realm Sidebar Panel]</span>
-            <wicket:container wicket:id="body"></wicket:container>
-          </div>
+    <section class="content" wicket:id="content">
+      <div class="box">
+        <div class="box-body">
+          <span wicket:id="realmChoicePanel">[Realm Sidebar Panel]</span>
+          <wicket:container wicket:id="body"></wicket:container>
         </div>
-        <div wicket:id="modal"></div>
-      </section>
-    </wicket:extend>
-  </body>
+      </div>
+      <div wicket:id="modal"></div>
+    </section>
+  </wicket:extend>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.html
index f560876..d6895eb 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.html
@@ -21,9 +21,13 @@ under the License.
 
     <section class="content-header">
       <h1>
-        Reports
+        &nbsp;
         <small>Work in progress</small>
       </h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="reports"/></li>
+      </ol>
     </section>
 
     <section class="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Roles.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Roles.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Roles.html
index 37e5ac8..486e33b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Roles.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Roles.html
@@ -19,9 +19,12 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content-header">
-      <h1>
-        <wicket:message key="roles"/>
-      </h1>
+      <h1>&nbsp;</h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="roles"/></li>
+      </ol>
     </section>
 
     <section class="content" wicket:id="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/SecurityQuestions.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/SecurityQuestions.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/SecurityQuestions.html
index 58d050b..14e360d 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/SecurityQuestions.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/SecurityQuestions.html
@@ -19,9 +19,12 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content-header">
-      <h1>
-        <wicket:message key="securityQuestions"/>
-      </h1>
+      <h1>&nbsp;</h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="securityQuestions"/></li>
+      </ol>
     </section>
 
     <section class="content" wicket:id="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Types.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Types.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Types.html
index 41d3c32..48b2616 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Types.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Types.html
@@ -19,9 +19,12 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content-header">
-      <h1>
-        <wicket:message key="types"/>
-      </h1>
+      <h1>&nbsp;</h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="configuration"/></li>
+        <li class="active"><wicket:message key="types"/></li>
+      </ol>
     </section>
 
     <section class="content" wicket:id="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/client/console/src/main/resources/org/apache/syncope/client/console/pages/Workflow.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Workflow.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Workflow.html
index f26791e..b0ed063 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Workflow.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Workflow.html
@@ -19,9 +19,7 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content-header">
-      <h1>
-        <wicket:message key="workflow"/>
-      </h1>
+      <h1>&nbsp;</h1>
     </section>
 
     <section class="content">

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
----------------------------------------------------------------------
diff --git a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
index b2d2274..f6bce47 100644
--- a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
+++ b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.pages;
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.rest.CamelRoutesRestClient;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CamelEntitlement;
@@ -46,6 +47,8 @@ public class CamelRoutes extends BaseExtPage {
     public CamelRoutes(final PageParameters parameters) {
         super(parameters);
 
+        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
         AjaxBootstrapTabbedPanel<ITab> tabbedPanel = new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList());

http://git-wip-us.apache.org/repos/asf/syncope/blob/581f5247/ext/camel/client-console/src/main/resources/org/apache/syncope/client/console/pages/CamelRoutes.html
----------------------------------------------------------------------
diff --git a/ext/camel/client-console/src/main/resources/org/apache/syncope/client/console/pages/CamelRoutes.html b/ext/camel/client-console/src/main/resources/org/apache/syncope/client/console/pages/CamelRoutes.html
index 33e8411..9d45fe0 100644
--- a/ext/camel/client-console/src/main/resources/org/apache/syncope/client/console/pages/CamelRoutes.html
+++ b/ext/camel/client-console/src/main/resources/org/apache/syncope/client/console/pages/CamelRoutes.html
@@ -20,9 +20,12 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content-header">
-      <h1>
-        <wicket:message key="camelRoutes"/>
-      </h1>
+      <h1>&nbsp;</h1>
+      <ol class="breadcrumb">
+        <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
+        <li class="active"><wicket:message key="extensions"/></li>
+        <li class="active"><wicket:message key="camelRoutes"/></li>
+      </ol>
     </section>
 
     <section class="content" wicket:id="content">


[6/6] syncope git commit: Upgrading maven-project-info-reports-plugin

Posted by il...@apache.org.
Upgrading maven-project-info-reports-plugin


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

Branch: refs/heads/master
Commit: 72833a0032a3669b5c6d0ba8e9bcc750f3c65509
Parents: f9f50c5
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Mar 7 16:52:03 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Mar 7 16:52:03 2016 +0100

----------------------------------------------------------------------
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/72833a00/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8d57971..d629c31 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+e?xml version="1.0" encoding="UTF-8"?>
 <!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
@@ -1779,7 +1779,7 @@ under the License.
                 <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-project-info-reports-plugin</artifactId>
-                  <version>2.8.1</version>
+                  <version>2.9</version>
                   <configuration>
                     <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
                     <dependencyLocationsEnabled>false</dependencyLocationsEnabled>


[5/6] syncope git commit: [SYNCOPE-744] Here is the reconciliation status widget

Posted by il...@apache.org.
[SYNCOPE-744] Here is the reconciliation status widget


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

Branch: refs/heads/master
Commit: f9f50c575114043bc558084e6109fefcf7862ea5
Parents: 581f524
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Mar 7 16:51:20 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Mar 7 16:51:20 2016 +0100

----------------------------------------------------------------------
 client/console/pom.xml                          |  10 +-
 .../client/console/SyncopeConsoleSession.java   |   5 +
 .../client/console/bulk/BulkActionModal.java    |   2 +-
 .../client/console/bulk/BulkContent.java        |  19 +-
 .../console/pages/MustChangePassword.java       |   4 +-
 .../syncope/client/console/pages/Realms.java    |   4 +-
 .../console/panels/AbstractLogsPanel.java       |   5 +-
 .../console/panels/ActionDataTablePanel.java    |  10 +-
 .../console/panels/AjaxDataTablePanel.java      |   3 +-
 .../panels/AnyObjectSearchResultPanel.java      |  21 +-
 .../console/panels/AnyTypeClassesPanel.java     |  10 +-
 .../client/console/panels/AnyTypesPanel.java    |  15 +-
 .../client/console/panels/ConnectorModal.java   |   5 +-
 .../console/panels/DashboardControlPanel.java   |   9 +
 .../console/panels/GroupSearchResultPanel.java  |  16 +-
 .../client/console/panels/ListViewPanel.java    |   4 +-
 .../panels/ParametersEditModalPanel.java        |   3 +-
 .../client/console/panels/ParametersPanel.java  |   9 +-
 .../syncope/client/console/panels/Realm.java    |  14 +-
 .../client/console/panels/RealmModalPanel.java  |   3 +-
 .../console/panels/RelationshipTypesPanel.java  |  12 +-
 .../console/panels/ResourceMappingPanel.java    |   4 +-
 .../client/console/panels/ResourceModal.java    |   5 +-
 .../console/panels/RoleSearchResultPanel.java   |   7 +-
 .../client/console/panels/SchemaTypePanel.java  |  14 +-
 .../panels/SecurityQuestionsModalPanel.java     |   5 +-
 .../console/panels/SecurityQuestionsPanel.java  |   8 +-
 .../console/panels/UserSearchResultPanel.java   |  22 +-
 .../panels/XMLWorkflowEditorModalPanel.java     |   2 +-
 .../search/AnySelectionSearchResultPanel.java   |   7 +-
 .../console/rest/AnyObjectRestClient.java       |   3 +-
 .../console/rest/ExecutionRestClient.java       |   8 +-
 .../client/console/rest/GroupRestClient.java    |   1 -
 .../client/console/rest/ReportRestClient.java   |  20 +-
 .../client/console/rest/TaskRestClient.java     |   5 +
 .../tasks/PropagationTaskSearchResultPanel.java |  20 +-
 .../tasks/SchedTaskSearchResultPanel.java       |  13 +-
 .../console/tasks/StartAtTogglePanel.java       |   7 +-
 .../client/console/tasks/TaskExecutions.java    |  10 +-
 .../client/console/topology/Topology.java       |   2 +-
 .../console/topology/TopologyTogglePanel.java   |   5 +-
 .../wicket/ajax/IndicatorAjaxTimerBehavior.java |   2 +-
 .../markup/html/ClearIndicatingAjaxButton.java  |  66 ---
 .../markup/html/ClearIndicatingAjaxLink.java    |  61 ---
 .../ajax/markup/html/IndicatorAjaxLink.java     |  41 ++
 .../data/table/BooleanPropertyColumn.java       |   1 -
 .../wicket/markup/html/form/ActionLink.java     |   4 +-
 .../markup/html/form/ActionLinksPanel.java      | 236 ++++----
 .../markup/html/form/BinaryFieldPanel.java      |   2 +-
 .../client/console/widgets/JobActionPanel.java  |  13 +-
 .../client/console/widgets/JobWidget.java       |  61 ++-
 .../client/console/widgets/ProgressBean.java    |  71 +++
 .../client/console/widgets/ProgressPanel.java   |  45 ++
 .../client/console/widgets/ProgressesPanel.java |  51 ++
 .../ReconciliationDetailsModalPanel.java        | 177 ++++++
 .../console/widgets/ReconciliationWidget.java   | 532 +++++++++++++++++++
 .../console/widgets/reconciliation/Any.java     |  71 +++
 .../console/widgets/reconciliation/Anys.java    |  55 ++
 .../widgets/reconciliation/Misaligned.java      |  51 ++
 .../console/widgets/reconciliation/Missing.java |  44 ++
 .../reconciliation/ReconciliationReport.java    |  66 +++
 .../ReconciliationReportParser.java             | 192 +++++++
 .../client/console/wizards/AjaxWizard.java      |   6 +-
 .../client/console/wizards/WizardMgtPanel.java  |   9 +-
 .../console/wizards/any/Relationships.java      |   9 +-
 .../client/console/wizards/any/ResultPage.java  |   5 +-
 .../client/console/wizards/any/StatusPanel.java |   2 +-
 .../META-INF/resources/css/syncopeConsole.css   |  10 +
 .../syncope/client/console/pages/Realms.html    |  19 +-
 .../console/panels/DashboardControlPanel.html   |   6 +
 .../client/console/panels/ParametersPanel.html  |   2 +-
 .../console/panels/WorkflowTogglePanel.html     |  51 +-
 .../markup/html/form/ActionLinksPanel.html      |  10 +
 .../console/widgets/AnyByRealmWidget.html       |   2 +-
 .../console/widgets/CompletenessWidget.html     |   2 +-
 .../client/console/widgets/JobWidget.html       |  20 +-
 .../client/console/widgets/JobWidget.properties |   3 +
 .../console/widgets/JobWidget_it.properties     |   3 +
 .../console/widgets/JobWidget_pt_BR.properties  |   3 +
 .../client/console/widgets/LoadWidget.html      |   2 +-
 .../client/console/widgets/ProgressPanel.html   |  30 ++
 .../client/console/widgets/ProgressesPanel.html |  24 +
 .../console/widgets/ProgressesPanel.properties  |  17 +
 .../widgets/ProgressesPanel_it.properties       |  17 +
 .../widgets/ProgressesPanel_pt_BR.properties    |  17 +
 .../ReconciliationDetailsModalPanel.html        |  23 +
 .../console/widgets/ReconciliationWidget.html   |  55 ++
 .../widgets/ReconciliationWidget.properties     |  21 +
 .../widgets/ReconciliationWidget_it.properties  |  21 +
 .../ReconciliationWidget_pt_BR.properties       |  21 +
 .../console/widgets/UsersByStatusWidget.html    |   2 +-
 .../ProvisionWizardBuilder$Mapping.properties   |   2 +-
 ...ProvisionWizardBuilder$Mapping_it.properties |   3 +-
 ...visionWizardBuilder$Mapping_pt_BR.properties |   2 +-
 .../rest/api/service/NotificationService.java   |   2 +
 .../common/rest/api/service/ReportService.java  |   2 +-
 .../common/rest/api/service/TaskService.java    |   2 +-
 .../core/logic/report/GroupReportlet.java       |   2 +-
 .../logic/report/ReconciliationReportlet.java   |  93 ++--
 .../core/logic/report/UserReportlet.java        |   2 +-
 .../syncope/core/misc/utils/MappingUtils.java   |   2 +-
 .../test/resources/domains/MasterContent.xml    |  10 +-
 .../java/data/RealmDataBinderImpl.java          |  42 +-
 .../client/console/panels/CamelRoutesPanel.java |   5 +-
 ext/swagger-ui/pom.xml                          |   2 -
 .../fit/console/AbstractConsoleITCase.java      |   1 -
 .../syncope/fit/console/ParametersITCase.java   |   7 +-
 .../apache/syncope/fit/core/SearchITCase.java   |  17 +-
 .../resources/scriptedsql/CreateScript.groovy   |   4 +-
 .../resources/scriptedsql/UpdateScript.groovy   |   4 +-
 pom.xml                                         |  10 +
 111 files changed, 2258 insertions(+), 561 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/pom.xml
----------------------------------------------------------------------
diff --git a/client/console/pom.xml b/client/console/pom.xml
index 6817358..9588709 100644
--- a/client/console/pom.xml
+++ b/client/console/pom.xml
@@ -94,11 +94,6 @@ under the License.
       <groupId>com.pingunaut</groupId>
       <artifactId>wicket-chartjs</artifactId>
     </dependency>	
-      
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-    </dependency>
     
     <dependency>
       <groupId>org.apache.syncope.client</groupId>
@@ -139,6 +134,11 @@ under the License.
       <groupId>org.webjars</groupId>
       <artifactId>jquery-ui</artifactId>
     </dependency>
+    
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
   </dependencies>
   
   <build>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index d383e4c..396752a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -183,6 +183,11 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
         return roles;
     }
 
+    public void refreshAuth() {
+        authenticate(username, password);
+        roles = null;
+    }
+
     @SuppressWarnings("unchecked")
     private <T> T getCachedService(final Class<T> serviceClass) {
         T service;

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkActionModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkActionModal.java b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkActionModal.java
index 9aeb197..033ee0a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkActionModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkActionModal.java
@@ -42,7 +42,7 @@ public class BulkActionModal<T extends Serializable, S> extends AbstractModalPan
             final String keyFieldName) {
 
         super(modal, pageRef);
-        add(new BulkContent<T, S>("content", modal, pageRef, items, columns, actions, bulkActionExecutor, keyFieldName).
+        add(new BulkContent<>("content", modal, items, columns, actions, bulkActionExecutor, keyFieldName).
                 setRenderBodyOnly(true));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
index 2cc2f1f..153c39c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
@@ -38,13 +38,11 @@ import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.Bas
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
@@ -65,20 +63,19 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
 
     public BulkContent(
             final BaseModal<?> modal,
-            final PageReference pageRef,
             final Collection<T> items,
             final List<IColumn<T, S>> columns,
             final Collection<ActionLink.ActionType> actions,
             final BaseRestClient bulkActionExecutor,
             final String keyFieldName) {
+
         this(MultilevelPanel.SECOND_LEVEL_ID,
-                modal, pageRef, items, columns, actions, bulkActionExecutor, keyFieldName);
+                modal, items, columns, actions, bulkActionExecutor, keyFieldName);
     }
 
     public BulkContent(
             final String id,
             final BaseModal<?> modal,
-            final PageReference pageRef,
             final Collection<T> items,
             final List<IColumn<T, S>> columns,
             final Collection<ActionLink.ActionType> actions,
@@ -117,7 +114,7 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                 dataProvider,
                 Integer.MAX_VALUE).setMarkupId("selectedObjects").setVisible(items != null && !items.isEmpty()));
 
-        final ActionLinksPanel<Serializable> actionPanel = ActionLinksPanel.builder(pageRef).build("actions");
+        final ActionLinksPanel<Serializable> actionPanel = ActionLinksPanel.builder().build("actions");
         container.add(actionPanel);
 
         for (ActionLink.ActionType action : actions) {
@@ -149,8 +146,8 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                                 throw new IllegalArgumentException("Invalid bulk action executor");
                             }
 
-                            final AbstractAnyRestClient<?> anyRestClient
-                                    = AbstractAnyRestClient.class.cast(bulkActionExecutor);
+                            final AbstractAnyRestClient<?> anyRestClient =
+                                    AbstractAnyRestClient.class.cast(bulkActionExecutor);
 
                             if (items.isEmpty() || !(items.iterator().next() instanceof StatusBean)) {
                                 throw new IllegalArgumentException("Invalid items");
@@ -227,11 +224,9 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                         target.add(actionPanel);
 
                         info(getString(Constants.OPERATION_SUCCEEDED));
-                    } catch (SyncopeClientException | NoSuchMethodException | SecurityException | IllegalAccessException
-                            | IllegalArgumentException | InvocationTargetException e) {
+                    } catch (Exception e) {
                         LOG.error("Bulk action failure", e);
-                        error(getString(Constants.ERROR)
-                                + ": Operation " + actionToBeAddresed.getActionId() + " not supported");
+                        error("Operation " + actionToBeAddresed.getActionId() + " not supported");
                     }
                     SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
index f127d92..a25636b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.UserSelfRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPasswordFieldPanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -93,7 +93,7 @@ public class MustChangePassword extends WebPage {
                 } catch (Exception e) {
                     LOG.error("While changing password for {}",
                             SyncopeConsoleSession.get().getSelfTO().getUsername(), e);
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                 }
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index a5c10e2..2ee818f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -157,8 +157,8 @@ public class Realms extends BasePage {
                     target.add(content);                  
                 } catch (Exception e) {
                     LOG.error("While deleting realm", e);
-                    // Excape line breaks
-                    error(getString(Constants.ERROR) + ": " + e.getMessage().replace("\n", " "));
+                    // Escape line breaks
+                    error(e.getMessage().replace("\n", " "));
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
index 227d7d4..dbd79a7 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.panels;
 
 import java.util.Arrays;
 import java.util.List;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
@@ -48,7 +49,7 @@ public abstract class AbstractLogsPanel<T extends AbstractBaseBean> extends Pane
             final String id,
             final PageReference pageRef,
             final List<LoggerTO> loggerTOs) {
-        
+
         super(id);
 
         WebMarkupContainer container = new WebMarkupContainer("loggerContainer");
@@ -79,7 +80,7 @@ public abstract class AbstractLogsPanel<T extends AbstractBaseBean> extends Pane
                                 target.add(loggerTOs);
                             } catch (SyncopeClientException e) {
                                 LOG.error("Error updating the logger level", e);
-                                error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                             }
                             SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
index 65e9ca1..8c465f3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
@@ -30,7 +30,6 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
 import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
@@ -50,19 +49,14 @@ public class ActionDataTablePanel<T extends Serializable, S> extends DataTablePa
 
     private final ActionLinksPanel<Serializable> actionPanel;
 
-    private final PageReference pageRef;
-
     public ActionDataTablePanel(
             final String id,
             final List<IColumn<T, S>> columns,
             final ISortableDataProvider<T, S> dataProvider,
-            final int rowsPerPage,
-            final PageReference pageRef) {
+            final int rowsPerPage) {
 
         super(id);
 
-        this.pageRef = pageRef;
-
         bulkActionForm = new Form<>("groupForm");
         add(bulkActionForm);
 
@@ -93,7 +87,7 @@ public class ActionDataTablePanel<T extends Serializable, S> extends DataTablePa
         final WebMarkupContainer actionPanelContainer = new WebMarkupContainer("actionPanelContainer");
         bulkActionForm.add(actionPanelContainer);
 
-        actionPanel = ActionLinksPanel.builder(pageRef).build("actions");
+        actionPanel = ActionLinksPanel.builder().build("actions");
         actionPanelContainer.add(actionPanel);
 
         if (dataTable.getRowCount() == 0) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
index dad7267..d02a784 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -223,9 +223,8 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab
 
                     bulkModal.show(true);
                 } else {
-                    builder.multiLevelPanel.next("bulk.action", new BulkContent<T, S>(
+                    builder.multiLevelPanel.next("bulk.action", new BulkContent<>(
                             builder.baseModal,
-                            builder.pageRef,
                             group.getModelObject(),
                             // serialization problem with sublist only
                             new ArrayList<>(builder.columns.subList(1, builder.columns.size() - 1)),

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
index 6cd7521..8eeb37b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectSearchResultPanel.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.AnyObjectRestClient;
@@ -74,9 +75,7 @@ public class AnyObjectSearchResultPanel extends AnySearchResultPanel<AnyObjectTO
 
             final Field field = ReflectionUtils.findField(AnyObjectTO.class, name);
 
-            if ("token".equalsIgnoreCase(name)) {
-                columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
-            } else if (field != null && field.getType().equals(Date.class)) {
+            if (field != null && field.getType().equals(Date.class)) {
                 columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
             } else {
                 columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
@@ -104,18 +103,17 @@ public class AnyObjectSearchResultPanel extends AnySearchResultPanel<AnyObjectTO
             for (String name : AnyObjectDisplayAttributesModalPage.ANY_OBJECT_DEFAULT_SELECTION) {
                 columns.add(new PropertyColumn<AnyObjectTO, String>(new ResourceModel(name, name), name, name));
             }
-
         }
 
         setWindowClosedReloadCallback(displayAttributeModal);
-        
+
         columns.add(new ActionColumn<AnyObjectTO, String>(new ResourceModel("actions", "")) {
 
             private static final long serialVersionUID = -3503023501954863131L;
 
             @Override
             public ActionLinksPanel<AnyObjectTO> getActions(final String componentId, final IModel<AnyObjectTO> model) {
-                final ActionLinksPanel.Builder<AnyObjectTO> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<AnyObjectTO> panel = ActionLinksPanel.builder();
 
                 panel.add(new ActionLink<AnyObjectTO>() {
 
@@ -123,11 +121,11 @@ public class AnyObjectSearchResultPanel extends AnySearchResultPanel<AnyObjectTO
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                                final IModel<AnyHandler<AnyObjectTO>> formModel
-                                        = new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
+                        final IModel<AnyHandler<AnyObjectTO>> formModel =
+                                new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
                         altDefaultModal.setFormModel(formModel);
 
-                        target.add(altDefaultModal.setContent(new StatusModal<AnyObjectTO>(
+                        target.add(altDefaultModal.setContent(new StatusModal<>(
                                 altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
 
                         altDefaultModal.header(new Model<>(
@@ -173,7 +171,8 @@ public class AnyObjectSearchResultPanel extends AnySearchResultPanel<AnyObjectTO
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
                                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -184,7 +183,7 @@ public class AnyObjectSearchResultPanel extends AnySearchResultPanel<AnyObjectTO
 
             @Override
             public ActionLinksPanel<Serializable> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder();
 
                 panel.add(new ActionLink<Serializable>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
index 1f88ea4..8fa1b5a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
@@ -84,7 +84,7 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
                             modal.close(target);
                         } catch (Exception e) {
                             LOG.error("While creating or updating AnyTypeClassTO", e);
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+                            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                     }
@@ -156,7 +156,7 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
             public ActionLinksPanel<AnyTypeClassTO> getActions(
                     final String componentId, final IModel<AnyTypeClassTO> model) {
 
-                ActionLinksPanel<AnyTypeClassTO> panel = ActionLinksPanel.<AnyTypeClassTO>builder(pageRef).
+                ActionLinksPanel<AnyTypeClassTO> panel = ActionLinksPanel.<AnyTypeClassTO>builder().
                         add(new ActionLink<AnyTypeClassTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -180,7 +180,8 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
                                     target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting {}", model.getObject(), e);
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -192,8 +193,7 @@ public class AnyTypeClassesPanel extends AbstractTypesPanel<AnyTypeClassTO, AnyT
 
             @Override
             public ActionLinksPanel<AnyTypeClassTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<AnyTypeClassTO> panel =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<AnyTypeClassTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<AnyTypeClassTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
index 4365610..978c299 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
@@ -78,14 +78,15 @@ public class AnyTypesPanel extends AbstractTypesPanel<AnyTypeTO, AnyTypeProvider
                         try {
                             if (getOriginalItem() == null || StringUtils.isBlank(getOriginalItem().getKey())) {
                                 SyncopeConsoleSession.get().getService(AnyTypeService.class).create(modelObject);
+                                SyncopeConsoleSession.get().refreshAuth();
                             } else {
                                 SyncopeConsoleSession.get().getService(AnyTypeService.class).update(modelObject);
                             }
                             info(getString(Constants.OPERATION_SUCCEEDED));
                             modal.close(target);
                         } catch (Exception e) {
-                            LOG.error("While creating or updating AnyTypeTO", e);
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+                            LOG.error("While creating or updating {}", modelObject, e);
+                            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                     }
@@ -157,7 +158,7 @@ public class AnyTypesPanel extends AbstractTypesPanel<AnyTypeTO, AnyTypeProvider
             public ActionLinksPanel<AnyTypeTO> getActions(
                     final String componentId, final IModel<AnyTypeTO> model) {
 
-                ActionLinksPanel<AnyTypeTO> panel = ActionLinksPanel.<AnyTypeTO>builder(pageRef).
+                ActionLinksPanel<AnyTypeTO> panel = ActionLinksPanel.<AnyTypeTO>builder().
                         add(new ActionLink<AnyTypeTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -177,11 +178,14 @@ public class AnyTypesPanel extends AbstractTypesPanel<AnyTypeTO, AnyTypeProvider
                                 try {
                                     SyncopeConsoleSession.get().
                                             getService(AnyTypeService.class).delete(model.getObject().getKey());
+                                    SyncopeConsoleSession.get().refreshAuth();
+
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting {}", model.getObject(), e);
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage()) 
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -193,8 +197,7 @@ public class AnyTypesPanel extends AbstractTypesPanel<AnyTypeTO, AnyTypeProvider
 
             @Override
             public ActionLinksPanel<AnyTypeTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<AnyTypeTO> panel =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<AnyTypeTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<AnyTypeTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
index bbb645e..33b04bc 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
@@ -166,8 +167,8 @@ public class ConnectorModal extends AbstractResourceModal<Serializable> {
             modal.close(target);
             info(getString(Constants.OPERATION_SUCCEEDED));
         } catch (Exception e) {
-            LOG.error("Failure managing resource {}", connInstanceTO, e);
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            LOG.error("Failure managing {}", connInstanceTO, e);
+            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
         }
         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java
index 0c993b8..8641aa1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.panels;
 
 import org.apache.syncope.client.console.widgets.JobWidget;
+import org.apache.syncope.client.console.widgets.ReconciliationWidget;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
@@ -39,5 +40,13 @@ public class DashboardControlPanel extends Panel {
                         StandardEntitlement.TASK_LIST,
                         StandardEntitlement.REPORT_LIST));
         add(job);
+
+        ReconciliationWidget reconciliation = new ReconciliationWidget("reconciliation", pageRef);
+        MetaDataRoleAuthorizationStrategy.authorize(job, WebPage.ENABLE,
+                String.format("%s,%s,%s",
+                        StandardEntitlement.REPORT_EXECUTE,
+                        StandardEntitlement.REPORT_READ,
+                        StandardEntitlement.REPORT_LIST));
+        add(reconciliation);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
index 17d2d87..c82b56f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.GroupRestClient;
@@ -105,14 +106,14 @@ public class GroupSearchResultPanel extends AnySearchResultPanel<GroupTO> {
         }
 
         setWindowClosedReloadCallback(displayAttributeModal);
-        
+
         columns.add(new ActionColumn<GroupTO, String>(new ResourceModel("actions", "")) {
 
             private static final long serialVersionUID = -3503023501954863131L;
 
             @Override
             public ActionLinksPanel<GroupTO> getActions(final String componentId, final IModel<GroupTO> model) {
-                final ActionLinksPanel.Builder<GroupTO> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<GroupTO> panel = ActionLinksPanel.builder();
 
                 panel.
                         add(new ActionLink<GroupTO>() {
@@ -121,11 +122,11 @@ public class GroupSearchResultPanel extends AnySearchResultPanel<GroupTO> {
 
                             @Override
                             public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
-                                final IModel<AnyHandler<GroupTO>> formModel
-                                        = new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
+                                final IModel<AnyHandler<GroupTO>> formModel =
+                                        new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
                                 altDefaultModal.setFormModel(formModel);
 
-                                target.add(altDefaultModal.setContent(new StatusModal<GroupTO>(
+                                target.add(altDefaultModal.setContent(new StatusModal<>(
                                         altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
 
                                 altDefaultModal.header(new Model<>(
@@ -169,8 +170,9 @@ public class GroupSearchResultPanel extends AnySearchResultPanel<GroupTO> {
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
                                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -181,7 +183,7 @@ public class GroupSearchResultPanel extends AnySearchResultPanel<GroupTO> {
 
             @Override
             public ActionLinksPanel<Serializable> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<Serializable>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index 0b6205f..ebc0b18 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -154,7 +154,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
 
             @Override
             protected void populateItem(final ListItem<T> beanItem) {
-                beanItem.add(new Check<T>("check", beanItem.getModel(), checkGroup).setOutputMarkupId(true)
+                beanItem.add(new Check<>("check", beanItem.getModel(), checkGroup).setOutputMarkupId(true)
                         .setOutputMarkupPlaceholderTag(true)
                         .setVisible(ListViewPanel.this.check.getObject() == CheckAvailability.AVAILABLE
                                 || ListViewPanel.this.check.getObject() == CheckAvailability.DISABLED)
@@ -234,7 +234,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             super(pageRef);
             this.reference = reference;
             this.items = null;
-            this.actions = ActionLinksPanel.<T>builder(pageRef);
+            this.actions = ActionLinksPanel.<T>builder();
         }
 
         public Builder<T> setModel(final IModel<? extends Collection<T>> model) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersEditModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersEditModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersEditModalPanel.java
index 2074889..4d2795a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersEditModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersEditModalPanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
@@ -58,7 +59,7 @@ public class ParametersEditModalPanel extends AbstractModalPanel<AttrTO> {
             info(getString(Constants.OPERATION_SUCCEEDED));
         } catch (Exception e) {
             LOG.error("While creating or updating AttrTO", e);
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
         }
         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
index a826ede..6ee4ae0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.SearchableDataProvider;
@@ -142,7 +143,7 @@ public class ParametersPanel extends AbstractSearchResultPanel<
 
             @Override
             public ActionLinksPanel<AttrTO> getActions(final String componentId, final IModel<AttrTO> model) {
-                ActionLinksPanel<AttrTO> panel = ActionLinksPanel.<AttrTO>builder(pageRef).
+                ActionLinksPanel<AttrTO> panel = ActionLinksPanel.<AttrTO>builder().
                         add(new ActionLink<AttrTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -172,7 +173,8 @@ public class ParametersPanel extends AbstractSearchResultPanel<
                                     target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting {}", model.getObject(), e);
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -184,8 +186,7 @@ public class ParametersPanel extends AbstractSearchResultPanel<
 
             @Override
             public ActionLinksPanel<AttrTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<AttrTO> panel =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<AttrTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<AttrTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index 183e23e..73118b4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -78,7 +78,7 @@ public abstract class Realm extends Panel {
         return realmTO;
     }
 
-    private List<ITab> buildTabList(final PageReference pageReference) {
+    private List<ITab> buildTabList(final PageReference pageRef) {
 
         final List<ITab> tabs = new ArrayList<>();
 
@@ -88,7 +88,7 @@ public abstract class Realm extends Panel {
 
             @Override
             public Panel getPanel(final String panelId) {
-                final ActionLinksPanel<RealmTO> actionLinksPanel = ActionLinksPanel.<RealmTO>builder(pageRef).
+                final ActionLinksPanel<RealmTO> actionLinksPanel = ActionLinksPanel.<RealmTO>builder().
                         add(new ActionLink<RealmTO>(realmTO) {
 
                             private static final long serialVersionUID = 2802988981431379827L;
@@ -133,14 +133,14 @@ public abstract class Realm extends Panel {
 
                 @Override
                 public Panel getPanel(final String panelId) {
-                    return getAnyPanel(panelId, pageReference, anyTypeTO);
+                    return getAnyPanel(panelId, pageRef, anyTypeTO);
                 }
             });
         }
         return tabs;
     }
 
-    private Panel getAnyPanel(final String id, final PageReference pageReference, final AnyTypeTO anyTypeTO) {
+    private Panel getAnyPanel(final String id, final PageReference pageRef, final AnyTypeTO anyTypeTO) {
         final Panel panel;
         switch (anyTypeTO.getKind()) {
             case USER:
@@ -149,7 +149,7 @@ public abstract class Realm extends Panel {
                 panel = new UserSearchResultPanel.Builder(
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
-                        pageReference).setRealm(realmTO.getFullPath()).
+                        pageRef).setRealm(realmTO.getFullPath()).
                         addNewItemPanelBuilder(new UserWizardBuilder(
                                 BaseModal.CONTENT_ID, userTO, anyTypeTO.getClasses(), pageRef)).build(id);
                 MetaDataRoleAuthorizationStrategy.authorize(panel, WebPage.RENDER, StandardEntitlement.USER_LIST);
@@ -160,7 +160,7 @@ public abstract class Realm extends Panel {
                 panel = new GroupSearchResultPanel.Builder(
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
-                        pageReference).setRealm(realmTO.getFullPath()).
+                        pageRef).setRealm(realmTO.getFullPath()).
                         addNewItemPanelBuilder(new GroupWizardBuilder(
                                 BaseModal.CONTENT_ID, groupTO, anyTypeTO.getClasses(), pageRef)).build(id);
                 // list of group is available to all authenticated users
@@ -172,7 +172,7 @@ public abstract class Realm extends Panel {
                 panel = new AnyObjectSearchResultPanel.Builder(
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
-                        pageReference).setRealm(realmTO.getFullPath()).
+                        pageRef).setRealm(realmTO.getFullPath()).
                         addNewItemPanelBuilder(new AnyObjectWizardBuilder(
                                 BaseModal.CONTENT_ID, anyObjectTO, anyTypeTO.getClasses(), pageRef)).build(id);
                 MetaDataRoleAuthorizationStrategy.authorize(panel, WebPage.RENDER,

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
index af64f81..287e2a6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.RealmRestClient;
@@ -82,7 +83,7 @@ public class RealmModalPanel extends AbstractModalPanel<RealmTO> {
             info(getString(Constants.OPERATION_SUCCEEDED));
         } catch (Exception e) {
             LOG.error("While creating or updating realm", e);
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
         }
         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
index 01b565e..81df00e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
@@ -86,8 +86,8 @@ public class RelationshipTypesPanel extends AbstractTypesPanel<RelationshipTypeT
                             info(getString(Constants.OPERATION_SUCCEEDED));
                             modal.close(target);
                         } catch (Exception e) {
-                            LOG.error("While creating or updating RelationshipTypeTO", e);
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+                            LOG.error("While creating or updating {}", modelObject, e);
+                            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                     }
@@ -160,7 +160,7 @@ public class RelationshipTypesPanel extends AbstractTypesPanel<RelationshipTypeT
             public ActionLinksPanel<RelationshipTypeTO> getActions(
                     final String componentId, final IModel<RelationshipTypeTO> model) {
 
-                ActionLinksPanel<RelationshipTypeTO> panel = ActionLinksPanel.<RelationshipTypeTO>builder(pageRef).
+                ActionLinksPanel<RelationshipTypeTO> panel = ActionLinksPanel.<RelationshipTypeTO>builder().
                         add(new ActionLink<RelationshipTypeTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -184,7 +184,8 @@ public class RelationshipTypesPanel extends AbstractTypesPanel<RelationshipTypeT
                                     target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting {}", model.getObject(), e);
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -196,8 +197,7 @@ public class RelationshipTypesPanel extends AbstractTypesPanel<RelationshipTypeT
 
             @Override
             public ActionLinksPanel<RelationshipTypeTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<RelationshipTypeTO> panel =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<RelationshipTypeTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<RelationshipTypeTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
index 5fb5564..0613296 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
@@ -221,9 +221,7 @@ public class ResourceMappingPanel extends Panel {
                     entity = mapItem.getIntMappingType().getAnyTypeKind();
                 }
 
-                final ActionLinksPanel.Builder<Serializable> actions = ActionLinksPanel.builder(
-                        getPage().getPageReference());
-
+                final ActionLinksPanel.Builder<Serializable> actions = ActionLinksPanel.builder();
                 actions.add(new ActionLink<Serializable>() {
 
                     private static final long serialVersionUID = -3722207913631435501L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
index 8006430..b3405b7 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
@@ -24,6 +24,7 @@ import java.util.Collection;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
@@ -255,8 +256,8 @@ public class ResourceModal<T extends Serializable> extends AbstractResourceModal
                 info(getString(Constants.OPERATION_SUCCEEDED));
                 modal.close(target);
             } catch (Exception e) {
-                LOG.error("Failure managing resource {}", resourceTO, e);
-                error(getString(Constants.ERROR) + ": " + e.getMessage());
+                LOG.error("Failure managing {}", resourceTO, e);
+                error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
             }
         }
         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
index f789ec5..3856375 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleSearchResultPanel.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.RoleDataProvider;
@@ -87,7 +88,7 @@ public class RoleSearchResultPanel
 
             @Override
             public ActionLinksPanel<RoleTO> getActions(final String componentId, final IModel<RoleTO> model) {
-                final ActionLinksPanel.Builder<RoleTO> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<RoleTO> panel = ActionLinksPanel.builder();
 
                 panel.add(new ActionLink<RoleTO>() {
 
@@ -123,7 +124,7 @@ public class RoleSearchResultPanel
                             target.add(container);
                         } catch (SyncopeClientException e) {
                             LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+                            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                     }
@@ -134,7 +135,7 @@ public class RoleSearchResultPanel
 
             @Override
             public ActionLinksPanel<RoleTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<RoleTO> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<RoleTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<RoleTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
index 1370bbe..b06318d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
@@ -115,8 +115,8 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
                                 info(getString(Constants.OPERATION_SUCCEEDED));
                                 modal.close(target);
                             } catch (Exception e) {
-                                LOG.error("While creating or updating schema", e);
-                                error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                LOG.error("While creating or updating {}", modelObject, e);
+                                error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                             }
                             SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                         }
@@ -187,7 +187,7 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
             public ActionLinksPanel<AbstractSchemaTO> getActions(
                     final String componentId, final IModel<AbstractSchemaTO> model) {
 
-                ActionLinksPanel<AbstractSchemaTO> panel = ActionLinksPanel.<AbstractSchemaTO>builder(pageRef).
+                ActionLinksPanel<AbstractSchemaTO> panel = ActionLinksPanel.<AbstractSchemaTO>builder().
                         add(new ActionLink<AbstractSchemaTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -222,8 +222,9 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (Exception e) {
-                                    LOG.error(getString(Constants.ERROR) + ": " + e.getMessage());
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    LOG.error("While deleting {}", model.getObject(), e);
+                                    error(StringUtils.isBlank(e.getMessage()) 
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -235,8 +236,7 @@ public class SchemaTypePanel extends AbstractTypesPanel<AbstractSchemaTO, Schema
 
             @Override
             public ActionLinksPanel<AbstractSchemaTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<AbstractSchemaTO> panel =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<AbstractSchemaTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<AbstractSchemaTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
index 01cd411..0d27f0c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
@@ -59,8 +60,8 @@ public class SecurityQuestionsModalPanel extends AbstractModalPanel<SecurityQues
             info(getString(Constants.OPERATION_SUCCEEDED));
             modal.close(target);
         } catch (Exception e) {
-            LOG.error("While creating or updating SecutiryQuestionTO", e);
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            LOG.error("While creating or updating {}", securityQuestionTO, e);
+            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
         }
         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
index 487ff94..bac8481 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
@@ -154,7 +154,7 @@ public class SecurityQuestionsPanel extends AbstractSearchResultPanel<
             public ActionLinksPanel<SecurityQuestionTO> getActions(
                     final String componentId, final IModel<SecurityQuestionTO> model) {
 
-                ActionLinksPanel<SecurityQuestionTO> panel = ActionLinksPanel.<SecurityQuestionTO>builder(pageRef).
+                ActionLinksPanel<SecurityQuestionTO> panel = ActionLinksPanel.<SecurityQuestionTO>builder().
                         add(new ActionLink<SecurityQuestionTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -178,7 +178,8 @@ public class SecurityQuestionsPanel extends AbstractSearchResultPanel<
                                     target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting {}", model.getObject(), e);
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -190,8 +191,7 @@ public class SecurityQuestionsPanel extends AbstractSearchResultPanel<
 
             @Override
             public ActionLinksPanel<SecurityQuestionTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<SecurityQuestionTO> panel =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<SecurityQuestionTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<SecurityQuestionTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
index 11e3ffa..7cb3bb5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.UserRestClient;
@@ -105,15 +106,14 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> {
         }
 
         setWindowClosedReloadCallback(displayAttributeModal);
-        
+
         columns.add(new ActionColumn<UserTO, String>(new ResourceModel("actions", "")) {
 
             private static final long serialVersionUID = -3503023501954863131L;
 
             @Override
             public ActionLinksPanel<UserTO> getActions(final String componentId, final IModel<UserTO> model) {
-
-                final ActionLinksPanel.Builder<UserTO> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<UserTO> panel = ActionLinksPanel.builder();
 
                 panel.add(new ActionLink<UserTO>() {
 
@@ -122,11 +122,11 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> {
                     @Override
                     public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
 
-                        final IModel<AnyHandler<UserTO>> formModel
-                                = new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
+                        final IModel<AnyHandler<UserTO>> formModel =
+                                new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
                         altDefaultModal.setFormModel(formModel);
 
-                        target.add(altDefaultModal.setContent(new StatusModal<UserTO>(
+                        target.add(altDefaultModal.setContent(new StatusModal<>(
                                 altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
 
                         altDefaultModal.header(new Model<>(
@@ -140,11 +140,11 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
-                        final IModel<AnyHandler<UserTO>> formModel
-                                = new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
+                        final IModel<AnyHandler<UserTO>> formModel =
+                                new CompoundPropertyModel<>(new AnyHandler<>(model.getObject()));
                         altDefaultModal.setFormModel(formModel);
 
-                        target.add(altDefaultModal.setContent(new StatusModal<UserTO>(
+                        target.add(altDefaultModal.setContent(new StatusModal<>(
                                 altDefaultModal, pageRef, formModel.getObject().getInnerObject(), true)));
 
                         altDefaultModal.header(new Model<>(
@@ -186,7 +186,7 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> {
                             target.add(container);
                         } catch (SyncopeClientException e) {
                             LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+                            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                     }
@@ -197,7 +197,7 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> {
 
             @Override
             public ActionLinksPanel<Serializable> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<Serializable>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/XMLWorkflowEditorModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/XMLWorkflowEditorModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/XMLWorkflowEditorModalPanel.java
index f10b05d..5c4138d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/XMLWorkflowEditorModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/XMLWorkflowEditorModalPanel.java
@@ -78,7 +78,7 @@ public class XMLWorkflowEditorModalPanel extends AbstractModalPanel<String> {
             modal.show(false);
             modal.close(target);
         } catch (SyncopeClientException e) {
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
         }
         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
index b194981..b6ddc5a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionSearchResultPanel.java
@@ -100,8 +100,7 @@ public abstract class AnySelectionSearchResultPanel<T extends AnyTO> extends Any
 
             @Override
             public ActionLinksPanel<T> getActions(final String componentId, final IModel<T> model) {
-
-                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder();
 
                 panel.add(new ActionLink<T>() {
 
@@ -110,7 +109,7 @@ public abstract class AnySelectionSearchResultPanel<T extends AnyTO> extends Any
                     @Override
                     public void onClick(final AjaxRequestTarget target, final T ignore) {
                         send(AnySelectionSearchResultPanel.this,
-                                Broadcast.BUBBLE, new ItemSelection<T>(target, model.getObject()));
+                                Broadcast.BUBBLE, new ItemSelection<>(target, model.getObject()));
                     }
                 }, ActionLink.ActionType.SELECT, String.format("%s_%s", type, AnyEntitlement.READ));
 
@@ -119,7 +118,7 @@ public abstract class AnySelectionSearchResultPanel<T extends AnyTO> extends Any
 
             @Override
             public ActionLinksPanel<T> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder();
 
                 return panel.
                         add(new ActionLink<T>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
index 9007011..176ec79 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
@@ -115,7 +115,6 @@ public class AnyObjectRestClient extends AbstractAnyRestClient<AnyObjectTO> {
 
     @Override
     public BulkActionResult bulkAction(final BulkAction action) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return getService(AnyObjectService.class).bulk(action);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java
index e259fdd..7659a5d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java
@@ -19,10 +19,14 @@
 package org.apache.syncope.client.console.rest;
 
 import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.to.ExecTO;
 
 public interface ExecutionRestClient {
 
-    void startExecution(long executionCollectorId, Date start);
+    void startExecution(long executionCollectorKey, Date start);
 
-    void deleteExecution(long executionId);
+    void deleteExecution(long executionKeyI);
+
+    List<ExecTO> listRecentExecutions(final int max);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
index ece8ad7..632f6cf 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
@@ -118,5 +118,4 @@ public class GroupRestClient extends AbstractAnyRestClient<GroupTO> {
     public BulkActionResult bulkAction(final BulkAction action) {
         return getService(GroupService.class).bulk(action);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
index 73e5303..4a9b28e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
@@ -21,6 +21,8 @@ package org.apache.syncope.client.console.rest;
 import java.util.Date;
 import java.util.List;
 import javax.ws.rs.core.Response;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.ReportTO;
 import org.apache.syncope.common.lib.types.ReportExecExportFormat;
 import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
@@ -51,7 +53,7 @@ public class ReportRestClient extends BaseRestClient implements ExecutionRestCli
      *
      * @param reportKey report to delete
      */
-    public void delete(final Long reportKey) {
+    public void delete(final long reportKey) {
         getService(ReportService.class).delete(reportKey);
     }
 
@@ -60,17 +62,17 @@ public class ReportRestClient extends BaseRestClient implements ExecutionRestCli
         getService(ReportService.class).execute(new ExecuteQuery.Builder().key(reportKey).startAt(start).build());
     }
 
-    /**
-     * Delete specified report execution.
-     *
-     * @param reportExecId report execution id
-     */
     @Override
-    public void deleteExecution(final long reportExecId) {
-        getService(ReportService.class).deleteExecution(reportExecId);
+    public void deleteExecution(final long reportExecKey) {
+        getService(ReportService.class).deleteExecution(reportExecKey);
+    }
+
+    @Override
+    public List<ExecTO> listRecentExecutions(final int max) {
+        return SyncopeConsoleSession.get().getService(ReportService.class).listRecentExecutions(max);
     }
 
-    public Response exportExecutionResult(final Long executionId, final ReportExecExportFormat fmt) {
+    public Response exportExecutionResult(final long executionId, final ReportExecExportFormat fmt) {
         return getService(ReportService.class).exportExecutionResult(executionId, fmt);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
index 92ff15a..2338911 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
@@ -165,6 +165,11 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
         getService(TaskService.class).deleteExecution(taskExecId);
     }
 
+    @Override
+    public List<ExecTO> listRecentExecutions(final int max) {
+        return SyncopeConsoleSession.get().getService(TaskService.class).listRecentExecutions(max);
+    }
+
     public void create(final SchedTaskTO taskTO) {
         getService(TaskService.class).create(taskTO);
     }


[2/6] syncope git commit: [SYNCOPE-744] Here is the reconciliation status widget

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.html
new file mode 100644
index 0000000..30a980a
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.html
@@ -0,0 +1,55 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:panel>
+    <div class="box box-default box-solid">
+      <div class="box-header with-border">
+        <h3 class="box-title"><wicket:message key="reconciliationStatus"/></h3>
+        <div class="box-tools pull-right">
+          <div class="btn-group">
+            <button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown">
+              <i class="fa fa-wrench"></i>
+            </button>
+            <ul class="dropdown-menu" role="menu">
+              <li><a wicket:id="refresh"><wicket:message key="refresh"/></a></li>
+            </ul>
+          </div>
+          <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
+        </div>
+      </div>
+      <div class="box-body">
+        <div wicket:id="reportResult"/>
+
+        <wicket:fragment wicket:id="noExecFragment">
+          <wicket:message key="nothingToShow"/>
+        </wicket:fragment>
+
+        <wicket:fragment wicket:id="execFragment">
+          <div wicket:id="execResult"/>
+        </wicket:fragment>
+
+      </div>
+      <div wicket:id="overlay" class="overlay">
+        <i class="fa fa-refresh fa-spin"></i>
+      </div>
+    </div>
+
+    <div wicket:id="detailsModal"/>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.properties
new file mode 100644
index 0000000..562c79c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget.properties
@@ -0,0 +1,21 @@
+# 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.
+reconciliationStatus=Reconciliation Status
+refresh=Refresh
+nothingToShow=Nothing to show yet. Please refresh.
+summary=Summary
+reference=Reference

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_it.properties
new file mode 100644
index 0000000..59918ab
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_it.properties
@@ -0,0 +1,21 @@
+# 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.
+reconciliationStatus=Stato della Riconciliazione
+refresh=Ricarica
+nothingToShow=Nessun risultato disponibile. Ricaricare per favore.
+summary=Sommario
+reference=Riferimento

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_pt_BR.properties
new file mode 100644
index 0000000..9d4cc1c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationWidget_pt_BR.properties
@@ -0,0 +1,21 @@
+# 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.
+reconciliationStatus=Estado Reconcilia\u00e7\u00e3o
+refresh=Atualize
+nothingToShow=Nada para mostrar ainda. Por favor, atualize.
+summary=Resumo
+reference=Refer\u00eancia

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
index ce24a16..d5cf2fc 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
-    <div class="box">
+    <div class="box box-default box-solid">
       <div class="box-header with-border">
         <h3 class="box-title"><wicket:message key="userStatus"/></h3>
         <div class="box-tools pull-right">

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping.properties
index 632a45b..8dc0c10 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping.properties
@@ -15,6 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-mapping.title=Specify the maping about the provisioning  object
+mapping.title=Specify the mapping for this provisioning object
 mapping.summary=
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_it.properties
index 632a45b..63e44ce 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_it.properties
@@ -15,6 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 
-mapping.title=Specify the maping about the provisioning  object
+mapping.title=Specify the mapping for this provisioning object
 mapping.summary=
-

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_pt_BR.properties
index 632a45b..8dc0c10 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/provision/ProvisionWizardBuilder$Mapping_pt_BR.properties
@@ -15,6 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-mapping.title=Specify the maping about the provisioning  object
+mapping.title=Specify the mapping for this provisioning object
 mapping.summary=
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
index 2529ec6..7200ed8 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
@@ -105,5 +105,7 @@ public interface NotificationService extends JAXRSService {
      *
      * @param action action to execute
      */
+    @POST
+    @Path("job")
     void actionJob(@QueryParam("action") JobAction action);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
index df8fab1..235cfcb 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
@@ -171,6 +171,6 @@ public interface ReportService extends JAXRSService {
      * @param action action to execute
      */
     @POST
-    @Path("/job/{key}")
+    @Path("jobs/{key}")
     void actionJob(@NotNull @PathParam("key") Long key, @QueryParam("action") JobAction action);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
index 4ad482c..2e34de6 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
@@ -190,6 +190,6 @@ public interface TaskService extends JAXRSService {
      * @param action action to execute
      */
     @POST
-    @Path("/job/{key}")
+    @Path("jobs/{key}")
     void actionJob(@NotNull @PathParam("key") Long key, @QueryParam("action") JobAction action);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
index 7460205..413a665 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
@@ -280,7 +280,7 @@ public class GroupReportlet extends AbstractReportlet {
 
     private int count() {
         return StringUtils.isBlank(conf.getMatchingCond())
-                ? groupDAO.count(SyncopeConstants.FULL_ADMIN_REALMS)
+                ? groupDAO.count()
                 : searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
                         SearchCondConverter.convert(conf.getMatchingCond()), AnyTypeKind.GROUP);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
index 42f6e2f..9fcd7bb 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
@@ -24,12 +24,14 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import org.apache.commons.collections4.Closure;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.report.ReconciliationReportletConf;
 import org.apache.syncope.common.lib.report.ReconciliationReportletConf.Feature;
@@ -61,6 +63,7 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.OperationalAttributes;
 import org.identityconnectors.framework.common.objects.Uid;
@@ -232,22 +235,26 @@ public class ReconciliationReportlet extends AbstractReportlet {
             handler.startElement("", "", "misaligned", atts);
 
             handler.startElement("", "", "onSyncope", null);
-            for (Object value : item.getOnSyncope()) {
-                char[] asChars = value.toString().toCharArray();
+            if (item.getOnSyncope() != null) {
+                for (Object value : item.getOnSyncope()) {
+                    char[] asChars = value.toString().toCharArray();
 
-                handler.startElement("", "", "value", null);
-                handler.characters(asChars, 0, asChars.length);
-                handler.endElement("", "", "value");
+                    handler.startElement("", "", "value", null);
+                    handler.characters(asChars, 0, asChars.length);
+                    handler.endElement("", "", "value");
+                }
             }
             handler.endElement("", "", "onSyncope");
 
             handler.startElement("", "", "onResource", null);
-            for (Object value : item.getOnResource()) {
-                char[] asChars = value.toString().toCharArray();
+            if (item.getOnResource() != null) {
+                for (Object value : item.getOnResource()) {
+                    char[] asChars = value.toString().toCharArray();
 
-                handler.startElement("", "", "value", null);
-                handler.characters(asChars, 0, asChars.length);
-                handler.endElement("", "", "value");
+                    handler.startElement("", "", "value", null);
+                    handler.characters(asChars, 0, asChars.length);
+                    handler.endElement("", "", "value");
+                }
             }
             handler.endElement("", "", "onResource");
 
@@ -299,10 +306,18 @@ public class ReconciliationReportlet extends AbstractReportlet {
                         missing.add(new Missing(resource.getKey(), connObjectKeyValue));
                     } else {
                         // 5. found but misaligned?
+                        Pair<String, Set<Attribute>> preparedAttrs =
+                                mappingUtils.prepareAttrs(any, null, false, null, provision);
+                        preparedAttrs.getRight().add(AttributeBuilder.build(
+                                Uid.NAME, preparedAttrs.getLeft()));
+                        preparedAttrs.getRight().add(AttributeBuilder.build(
+                                connObjectKeyItem.getExtAttrName(), preparedAttrs.getLeft()));
 
                         final Map<String, Set<Object>> syncopeAttrs = new HashMap<>();
-                        for (Attribute attr : mappingUtils.prepareAttrs(any, null, false, null, provision).getRight()) {
-                            syncopeAttrs.put(attr.getName(), new HashSet<>(attr.getValue()));
+                        for (Attribute attr : preparedAttrs.getRight()) {
+                            syncopeAttrs.put(
+                                    attr.getName(),
+                                    attr.getValue() == null ? null : new HashSet<>(attr.getValue()));
                         }
 
                         final Map<String, Set<Object>> resourceAttrs = new HashMap<>();
@@ -310,7 +325,9 @@ public class ReconciliationReportlet extends AbstractReportlet {
                             if (!OperationalAttributes.PASSWORD_NAME.equals(attr.getName())
                                     && !OperationalAttributes.ENABLE_NAME.equals(attr.getName())) {
 
-                                resourceAttrs.put(attr.getName(), new HashSet<>(attr.getValue()));
+                                resourceAttrs.put(
+                                        attr.getName(),
+                                        attr.getValue() == null ? null : new HashSet<>(attr.getValue()));
                             }
                         }
 
@@ -330,7 +347,7 @@ public class ReconciliationReportlet extends AbstractReportlet {
 
                         for (Map.Entry<String, Set<Object>> entry : resourceAttrs.entrySet()) {
                             if (syncopeAttrs.containsKey(entry.getKey())) {
-                                if (!syncopeAttrs.get(entry.getKey()).equals(entry.getValue())) {
+                                if (!Objects.equals(syncopeAttrs.get(entry.getKey()), entry.getValue())) {
                                     misaligned.add(new Misaligned(
                                             resource.getKey(),
                                             connObjectKeyValue,
@@ -357,14 +374,10 @@ public class ReconciliationReportlet extends AbstractReportlet {
         }
     }
 
-    private void doExtract(final ContentHandler handler, final SearchCond cond, final AnyTypeKind anyTypeKind)
+    private void doExtract(
+            final ContentHandler handler, final int count, final SearchCond cond, final AnyTypeKind anyTypeKind)
             throws SAXException {
 
-        int count = searchDAO.count(
-                SyncopeConstants.FULL_ADMIN_REALMS,
-                cond,
-                anyTypeKind);
-
         for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
             List<AnyObject> anys = searchDAO.search(
                     SyncopeConstants.FULL_ADMIN_REALMS,
@@ -386,32 +399,43 @@ public class ReconciliationReportlet extends AbstractReportlet {
             throw new ReportException(new IllegalArgumentException("Invalid configuration provided"));
         }
 
-        handler.startElement("", "", getAnyElementName(AnyTypeKind.USER) + "s", null);
+        AttributesImpl atts = new AttributesImpl();
+
         if (StringUtils.isBlank(this.conf.getUserMatchingCond())) {
+            atts.addAttribute("", "", "total", ReportXMLConst.XSD_INT, String.valueOf(userDAO.count()));
+            handler.startElement("", "", getAnyElementName(AnyTypeKind.USER) + "s", atts);
+
             doExtract(handler, userDAO.findAll());
         } else {
             SearchCond cond = SearchCondConverter.convert(this.conf.getUserMatchingCond());
-            doExtract(handler, cond, AnyTypeKind.USER);
+
+            int count = searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.USER);
+            atts.addAttribute("", "", "total", ReportXMLConst.XSD_INT, String.valueOf(count));
+            handler.startElement("", "", getAnyElementName(AnyTypeKind.USER) + "s", atts);
+
+            doExtract(handler, count, cond, AnyTypeKind.USER);
         }
         handler.endElement("", "", getAnyElementName(AnyTypeKind.USER) + "s");
 
-        handler.startElement("", "", getAnyElementName(AnyTypeKind.GROUP) + "s", null);
+        atts.clear();
         if (StringUtils.isBlank(this.conf.getGroupMatchingCond())) {
+            atts.addAttribute("", "", "total", ReportXMLConst.XSD_INT, String.valueOf(groupDAO.count()));
+            handler.startElement("", "", getAnyElementName(AnyTypeKind.GROUP) + "s", atts);
+
             doExtract(handler, groupDAO.findAll());
         } else {
             SearchCond cond = SearchCondConverter.convert(this.conf.getUserMatchingCond());
-            doExtract(handler, cond, AnyTypeKind.GROUP);
+
+            int count = searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.GROUP);
+            atts.addAttribute("", "", "total", ReportXMLConst.XSD_INT, String.valueOf(count));
+            handler.startElement("", "", getAnyElementName(AnyTypeKind.GROUP) + "s", atts);
+
+            doExtract(handler, count, cond, AnyTypeKind.GROUP);
         }
         handler.endElement("", "", getAnyElementName(AnyTypeKind.GROUP) + "s");
 
-        AttributesImpl atts = new AttributesImpl();
-
         for (AnyType anyType : anyTypeDAO.findAll()) {
             if (!anyType.equals(anyTypeDAO.findUser()) && !anyType.equals(anyTypeDAO.findGroup())) {
-                atts.clear();
-                atts.addAttribute("", "", "type", ReportXMLConst.XSD_STRING, anyType.getKey());
-                handler.startElement("", "", getAnyElementName(AnyTypeKind.ANY_OBJECT) + "s", atts);
-
                 AnyTypeCond anyTypeCond = new AnyTypeCond();
                 anyTypeCond.setAnyTypeName(anyType.getKey());
                 SearchCond cond = StringUtils.isBlank(this.conf.getAnyObjectMatchingCond())
@@ -420,7 +444,14 @@ public class ReconciliationReportlet extends AbstractReportlet {
                                 SearchCond.getLeafCond(anyTypeCond),
                                 SearchCondConverter.convert(this.conf.getAnyObjectMatchingCond()));
 
-                doExtract(handler, cond, AnyTypeKind.ANY_OBJECT);
+                int count = searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.ANY_OBJECT);
+
+                atts.clear();
+                atts.addAttribute("", "", "type", ReportXMLConst.XSD_STRING, anyType.getKey());
+                atts.addAttribute("", "", "total", ReportXMLConst.XSD_INT, String.valueOf(count));
+                handler.startElement("", "", getAnyElementName(AnyTypeKind.ANY_OBJECT) + "s", atts);
+
+                doExtract(handler, count, cond, AnyTypeKind.ANY_OBJECT);
 
                 handler.endElement("", "", getAnyElementName(AnyTypeKind.ANY_OBJECT) + "s");
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
index 71cc9b3..1a447d8 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
@@ -349,7 +349,7 @@ public class UserReportlet extends AbstractReportlet {
 
     private int count() {
         return StringUtils.isBlank(conf.getMatchingCond())
-                ? userDAO.count(SyncopeConstants.FULL_ADMIN_REALMS)
+                ? userDAO.count()
                 : searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
                         SearchCondConverter.convert(conf.getMatchingCond()), AnyTypeKind.USER);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
index 6fde3ea..9d2fc07 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
@@ -376,7 +376,7 @@ public class MappingUtils {
      * @param mapItem mapping item for the given attribute
      * @param any any object
      * @param password clear-text password
-     * @return connObjectLink + prepared attribute
+     * @return connObjectKey + prepared attribute
      */
     private Pair<String, Attribute> prepareAttr(
             final Provision provision, final MappingItem mapItem, final Any<?> any, final String password) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 84ad5eb..0787b63 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -810,7 +810,7 @@ under the License.
   <Provision id="7" resource_name="resource-testdb" anyType_name="USER" objectClass="__ACCOUNT__"/>
   <Mapping id="7" provision_id="7"/>
   <MappingItem id="119" mapping_id="7"
-               extAttrName="id" intMappingType="Username" mandatoryCondition="true"
+               extAttrName="ID" intMappingType="Username" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="BOTH"/>
   <MappingItem id="120" mapping_id="7"
                extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
@@ -818,7 +818,7 @@ under the License.
                      
   <Provision id="8" resource_name="resource-testdb2" anyType_name="USER" objectClass="__ACCOUNT__"/>
   <Mapping id="8" provision_id="8"/>
-  <MappingItem id="121" mapping_id="8" extAttrName="id" 
+  <MappingItem id="121" mapping_id="8" extAttrName="ID" 
                intMappingType="Username" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="PROPAGATION"/>
   <MappingItem id="122" mapping_id="8" extAttrName="__PASSWORD__" 
@@ -944,7 +944,7 @@ under the License.
   <Provision id="17" resource_name="resource-db-virattr" anyType_name="USER" objectClass="__ACCOUNT__"/>
   <Mapping id="17" provision_id="17"/>
   <MappingItem id="331" mapping_id="17" connObjectKey="1" password="0"
-               extAttrName="id" intMappingType="UserKey" 
+               extAttrName="ID" intMappingType="UserKey" 
                mandatoryCondition="true" purpose="BOTH"/>
                 
   <VirSchema name="virtualdata" anyTypeClass_name="minimal user" provision_id="17" extAttrName="USERNAME"/>
@@ -963,10 +963,10 @@ under the License.
 
   <Provision id="21" resource_name="resource-db-scripted" anyType_name="PRINTER" objectClass="__PRINTER__"/>
   <Mapping id="21" provision_id="21"/>
-  <MappingItem id="405" mapping_id="21" extAttrName="id" 
+  <MappingItem id="405" mapping_id="21" extAttrName="ID" 
                intMappingType="AnyObjectKey" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="406" mapping_id="21" extAttrName="location" 
+  <MappingItem id="406" mapping_id="21" extAttrName="LOCATION" 
                intAttrName="location" intMappingType="AnyObjectPlainSchema"
                mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/>
     

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
index 3bb1ed6..c1c3254 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java.data;
 import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -33,6 +34,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.provisioning.api.data.RealmDataBinder;
@@ -98,10 +100,26 @@ public class RealmDataBinderImpl implements RealmDataBinder {
         realm.setParent(realmDAO.find(parentPath));
 
         if (realmTO.getPasswordPolicy() != null) {
-            realm.setPasswordPolicy((PasswordPolicy) policyDAO.find(realmTO.getPasswordPolicy()));
+            Policy policy = policyDAO.find(realmTO.getPasswordPolicy());
+            if (policy instanceof PasswordPolicy) {
+                realm.setPasswordPolicy((PasswordPolicy) policy);
+            } else {
+                SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+                sce.getElements().add("Expected " + PasswordPolicy.class.getSimpleName()
+                        + ", found " + policy.getClass().getSimpleName());
+                throw sce;
+            }
         }
         if (realmTO.getAccountPolicy() != null) {
-            realm.setAccountPolicy((AccountPolicy) policyDAO.find(realmTO.getAccountPolicy()));
+            Policy policy = policyDAO.find(realmTO.getAccountPolicy());
+            if (policy instanceof AccountPolicy) {
+                realm.setAccountPolicy((AccountPolicy) policy);
+            } else {
+                SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+                sce.getElements().add("Expected " + AccountPolicy.class.getSimpleName()
+                        + ", found " + policy.getClass().getSimpleName());
+                throw sce;
+            }
         }
 
         realm.getActionsClassNames().addAll(realmTO.getActionsClassNames());
@@ -117,10 +135,26 @@ public class RealmDataBinderImpl implements RealmDataBinder {
         realm.setParent(realmTO.getParent() == 0 ? null : realmDAO.find(realmTO.getParent()));
 
         if (realmTO.getPasswordPolicy() != null) {
-            realm.setPasswordPolicy((PasswordPolicy) policyDAO.find(realmTO.getPasswordPolicy()));
+            Policy policy = policyDAO.find(realmTO.getPasswordPolicy());
+            if (policy instanceof PasswordPolicy) {
+                realm.setPasswordPolicy((PasswordPolicy) policy);
+            } else {
+                SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+                sce.getElements().add("Expected " + PasswordPolicy.class.getSimpleName()
+                        + ", found " + policy.getClass().getSimpleName());
+                throw sce;
+            }
         }
         if (realmTO.getAccountPolicy() != null) {
-            realm.setAccountPolicy((AccountPolicy) policyDAO.find(realmTO.getAccountPolicy()));
+            Policy policy = policyDAO.find(realmTO.getAccountPolicy());
+            if (policy instanceof AccountPolicy) {
+                realm.setAccountPolicy((AccountPolicy) policy);
+            } else {
+                SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+                sce.getElements().add("Expected " + AccountPolicy.class.getSimpleName()
+                        + ", found " + policy.getClass().getSimpleName());
+                throw sce;
+            }
         }
 
         realm.getActionsClassNames().clear();

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutesPanel.java
----------------------------------------------------------------------
diff --git a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutesPanel.java b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutesPanel.java
index 86fa45d..2d1afa4 100644
--- a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutesPanel.java
+++ b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutesPanel.java
@@ -154,7 +154,7 @@ public class CamelRoutesPanel extends AbstractSearchResultPanel<
             public ActionLinksPanel<CamelRouteTO> getActions(
                     final String componentId, final IModel<CamelRouteTO> model) {
 
-                ActionLinksPanel<CamelRouteTO> panel = ActionLinksPanel.<CamelRouteTO>builder(pageRef).
+                ActionLinksPanel<CamelRouteTO> panel = ActionLinksPanel.<CamelRouteTO>builder().
                         add(new ActionLink<CamelRouteTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -172,8 +172,7 @@ public class CamelRoutesPanel extends AbstractSearchResultPanel<
 
             @Override
             public ActionLinksPanel<CamelRouteTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<CamelRouteTO> panel =
-                        ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<CamelRouteTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<CamelRouteTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/ext/swagger-ui/pom.xml
----------------------------------------------------------------------
diff --git a/ext/swagger-ui/pom.xml b/ext/swagger-ui/pom.xml
index 09ae106..01ec468 100644
--- a/ext/swagger-ui/pom.xml
+++ b/ext/swagger-ui/pom.xml
@@ -45,12 +45,10 @@ under the License.
     <dependency>
       <groupId>com.fasterxml.jackson.dataformat</groupId>
       <artifactId>jackson-dataformat-yaml</artifactId>
-      <version>${jackson.version}</version>
     </dependency>
     <dependency>
       <groupId>com.fasterxml.jackson.dataformat</groupId>
       <artifactId>jackson-dataformat-xml</artifactId>
-      <version>${jackson.version}</version>
     </dependency>
     <dependency>
       <groupId>com.fasterxml.jackson.datatype</groupId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
index eb2acbc..3f9d841 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
@@ -48,7 +48,6 @@ public abstract class AbstractConsoleITCase extends AbstractITCase {
 
     @Before
     public void setUp() {
-
         testApplicaton = new SyncopeConsoleApplication() {
 
             @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
index 389a7be..5173a68 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
@@ -61,8 +61,13 @@ public class ParametersITCase extends AbstractConsoleITCase {
 
         formTester.submit("content:parametersCreateWizardPanel:form:buttons:finish");
 
+        try {
         wicketTester.assertInfoMessages("Operation executed successfully");
-
+        } catch(Throwable t) {
+            System.err.println("EEEEEEEEEEEEEE " + wicketTester.getLastResponseAsString());
+            t.printStackTrace();
+        }
+        
         wicketTester.cleanupFeedbackMessages();
         wicketTester.assertRenderedPage(Parameters.class);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index 6f15786..d18c94b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -236,6 +236,21 @@ public class SearchITCase extends AbstractITCase {
     }
 
     @Test
+    public void searchByDate() {
+        clientFactory.create("bellini", "password").self();
+
+        PagedResult<UserTO> users = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        is("lastLoginDate").lexicalNotBefore("2016-03-02 15:21:22").
+                        and("username").equalTo("bellini").query()).
+                build());
+        assertNotNull(users);
+        assertEquals(1, users.getTotalCount());
+        assertEquals(1, users.getResult().size());
+    }
+
+    @Test
     public void searchByRelationshipAnyCond() {
         PagedResult<GroupTO> groups = groupService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
@@ -405,7 +420,7 @@ public class SearchITCase extends AbstractITCase {
                 getResult();
 
         assertFalse(usersWithType.isEmpty());
-        
+
         final PagedResult<UserTO> matchedUsers = userService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").notNullValue().query()).

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/fit/core-reference/src/test/resources/scriptedsql/CreateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/scriptedsql/CreateScript.groovy b/fit/core-reference/src/test/resources/scriptedsql/CreateScript.groovy
index 52c10f9..5ee8d55 100644
--- a/fit/core-reference/src/test/resources/scriptedsql/CreateScript.groovy
+++ b/fit/core-reference/src/test/resources/scriptedsql/CreateScript.groovy
@@ -35,12 +35,12 @@ log.info("Entering " + action + " Script");
 
 def sql = new Sql(connection);
 
-switch ( objectClass ) {
+switch ( objectClass ) {  
 case "__PRINTER__":
   sql.execute("INSERT INTO TESTPRINTER (id, location, lastmodification) values (?,?,?)",
     [
       id,
-      attributes.get("location").get(0),
+      attributes.get("LOCATION").get(0),
       new Date()
     ])
   break

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/fit/core-reference/src/test/resources/scriptedsql/UpdateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/scriptedsql/UpdateScript.groovy b/fit/core-reference/src/test/resources/scriptedsql/UpdateScript.groovy
index f3155cb..4d1ce5e 100644
--- a/fit/core-reference/src/test/resources/scriptedsql/UpdateScript.groovy
+++ b/fit/core-reference/src/test/resources/scriptedsql/UpdateScript.groovy
@@ -50,9 +50,9 @@ def sql = new Sql(connection);
 
 switch (action) {
 case "UPDATE":
-  if (attributes.get("location").get(0) != null) {
+  if (attributes.get("LOCATION").get(0) != null) {
     sql.executeUpdate("UPDATE TESTPRINTER SET location = ?, lastmodification = ? where id = ?", 
-      [attributes.get("location").get(0), new Date(), attributes.get("__NAME__").get(0)])
+      [attributes.get("LOCATION").get(0), new Date(), attributes.get("__NAME__").get(0)])
     
     return attributes.get("__NAME__").get(0);
   }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2a2683c..8d57971 100644
--- a/pom.xml
+++ b/pom.xml
@@ -633,6 +633,16 @@ under the License.
         <artifactId>jackson-module-afterburner</artifactId>
         <version>${jackson.version}</version>
       </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-yaml</artifactId>
+        <version>${jackson.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-xml</artifactId>
+        <version>${jackson.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>org.springframework</groupId>


[4/6] syncope git commit: [SYNCOPE-744] Here is the reconciliation status widget

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
index ca7f5ea..2f572d5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.TaskDataProvider;
@@ -69,7 +70,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
 
     @Override
     protected List<IColumn<PropagationTaskTO, String>> getColumns() {
-        final List<IColumn<PropagationTaskTO, String>> columns = new ArrayList<IColumn<PropagationTaskTO, String>>();
+        final List<IColumn<PropagationTaskTO, String>> columns = new ArrayList<>();
 
         columns.add(new PropertyColumn<PropagationTaskTO, String>(
                 new StringResourceModel("key", this, null), "key", "key"));
@@ -110,7 +111,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
 
                 final PropagationTaskTO taskTO = model.getObject();
 
-                final ActionLinksPanel<PropagationTaskTO> panel = ActionLinksPanel.<PropagationTaskTO>builder(pageRef).
+                final ActionLinksPanel<PropagationTaskTO> panel = ActionLinksPanel.<PropagationTaskTO>builder().
                         add(new ActionLink<PropagationTaskTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -119,7 +120,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
                             public void onClick(final AjaxRequestTarget target, final PropagationTaskTO modelObject) {
                                 viewTask(taskTO, target);
                             }
-                        }, ActionLink.ActionType.SEARCH, StandardEntitlement.TASK_READ).
+                        }, ActionLink.ActionType.VIEW, StandardEntitlement.TASK_READ).
                         add(new ActionLink<PropagationTaskTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -131,8 +132,9 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                                    LOG.error("While running propagation task {}", taskTO.getKey(), e);
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
+                                    LOG.error("While running {}", taskTO.getKey(), e);
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -148,8 +150,9 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                                    LOG.error("While deleting propagation task {}", taskTO.getKey(), e);
+                                    LOG.error("While deleting {}", taskTO.getKey(), e);
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -160,8 +163,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
 
             @Override
             public ActionLinksPanel<PropagationTaskTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<PropagationTaskTO> panel = ActionLinksPanel.builder(page.
-                        getPageReference());
+                final ActionLinksPanel.Builder<PropagationTaskTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<PropagationTaskTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
index 899a624..8345fb4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.TaskDataProvider;
@@ -165,7 +166,7 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
 
                 final T taskTO = model.getObject();
 
-                final ActionLinksPanel<T> panel = ActionLinksPanel.<T>builder(pageRef).
+                final ActionLinksPanel<T> panel = ActionLinksPanel.<T>builder().
                         add(new ActionLink<T>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -174,7 +175,7 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
                             public void onClick(final AjaxRequestTarget target, final T ignore) {
                                 viewTask(taskTO, target);
                             }
-                        }, ActionLink.ActionType.SEARCH, StandardEntitlement.TASK_READ).
+                        }, ActionLink.ActionType.VIEW, StandardEntitlement.TASK_READ).
                         add(new ActionLink<T>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -220,7 +221,8 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                     LOG.error("While running propagation task {}", taskTO.getKey(), e);
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -237,7 +239,8 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                     LOG.error("While deleting propagation task {}", taskTO.getKey(), e);
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -249,7 +252,7 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
 
             @Override
             public ActionLinksPanel<T> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<T>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
index e03f56e..7219c4c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.tasks;
 
 import java.io.Serializable;
 import java.util.Date;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.TogglePanel;
@@ -48,7 +49,7 @@ public class StartAtTogglePanel extends TogglePanel<Serializable> {
         final Form<?> form = new Form<>("startAtForm");
         addInnerObject(form);
 
-        final Model<Date> startAtDateModel = new Model<Date>();
+        final Model<Date> startAtDateModel = new Model<>();
 
         final AjaxDateFieldPanel startAtDate = new AjaxDateFieldPanel(
                 "startAtDate", "startAtDate", startAtDateModel, SyncopeConstants.DATE_PATTERNS[3]);
@@ -57,7 +58,7 @@ public class StartAtTogglePanel extends TogglePanel<Serializable> {
         form.add(startAtDate);
 
         final AjaxCheckBoxPanel startAtCheck = new AjaxCheckBoxPanel(
-                "startAtCheck", "startAtCheck", new Model<Boolean>(false), false);
+                "startAtCheck", "startAtCheck", new Model<>(false), false);
 
         form.add(startAtCheck);
 
@@ -83,7 +84,7 @@ public class StartAtTogglePanel extends TogglePanel<Serializable> {
                     toggle(target, false);
                     target.add(container);
                 } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     LOG.error("While running propagation task {}", taskTO.getKey(), e);
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
index 1d08460..43de894 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
@@ -103,12 +103,10 @@ public abstract class TaskExecutions
             private static final long serialVersionUID = -3503023501954863131L;
 
             @Override
-            public ActionLinksPanel<ExecTO> getActions(
-                    final String componentId, final IModel<ExecTO> model) {
-
+            public ActionLinksPanel<ExecTO> getActions(final String componentId, final IModel<ExecTO> model) {
                 final ExecTO taskExecutionTO = model.getObject();
 
-                final ActionLinksPanel.Builder<ExecTO> panel = ActionLinksPanel.builder(pageRef);
+                final ActionLinksPanel.Builder<ExecTO> panel = ActionLinksPanel.builder();
 
                 panel.
                         add(new ActionLink<ExecTO>() {
@@ -120,7 +118,7 @@ public abstract class TaskExecutions
                                 next(new StringResourceModel("execution.view", TaskExecutions.this, model).getObject(),
                                         new ExecMessage(model.getObject().getMessage()), target);
                             }
-                        }, ActionLink.ActionType.SEARCH, StandardEntitlement.TASK_READ).
+                        }, ActionLink.ActionType.VIEW, StandardEntitlement.TASK_READ).
                         add(new ActionLink<ExecTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -144,7 +142,7 @@ public abstract class TaskExecutions
 
             @Override
             public ActionLinksPanel<Serializable> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder(pageRef);
+                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<Serializable>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index 8017238..2b90e96 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -167,7 +167,7 @@ public class Topology extends BasePage {
         // -----------------------------------------
         // Add Zoom panel
         // -----------------------------------------
-        final ActionLinksPanel.Builder<Serializable> zoomActionPanel = ActionLinksPanel.builder(getPageReference());
+        final ActionLinksPanel.Builder<Serializable> zoomActionPanel = ActionLinksPanel.builder();
         zoomActionPanel.setDisableIndicator(true);
 
         zoomActionPanel.add(new ActionLink<Serializable>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index 40a4942..48f2588 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.topology;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.text.MessageFormat;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.ConnectorModal;
@@ -185,7 +186,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     target.appendJavaScript(String.format("jsPlumb.remove('%s');", node.getKey()));
                     info(getString(Constants.OPERATION_SUCCEEDED));
                 } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     LOG.error("While deleting resource {}", node.getKey(), e);
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -266,7 +267,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     target.appendJavaScript(String.format("jsPlumb.remove('%s');", node.getKey()));
                     info(getString(Constants.OPERATION_SUCCEEDED));
                 } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     LOG.error("While deleting resource {}", node.getKey(), e);
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
index 5efc5a9..6026ecf 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
@@ -24,7 +24,7 @@ import org.apache.wicket.ajax.IAjaxIndicatorAware;
 import org.apache.wicket.util.time.Duration;
 
 /**
- * An {@link AbstractAjaxTimerBehavior} not showin veil.
+ * An {@link AbstractAjaxTimerBehavior} not showing veil.
  */
 public abstract class IndicatorAjaxTimerBehavior extends AbstractAjaxTimerBehavior implements IAjaxIndicatorAware {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java
deleted file mode 100644
index 449bcd3..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.wicket.ajax.markup.html;
-
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.model.IModel;
-
-public abstract class ClearIndicatingAjaxButton extends IndicatingAjaxButton {
-
-    private static final long serialVersionUID = 7206379812788748287L;
-
-    private final PageReference pageRef;
-
-    public ClearIndicatingAjaxButton(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-    }
-
-    public ClearIndicatingAjaxButton(final String id, final Form<?> form, final PageReference pageRef) {
-        super(id, form);
-        this.pageRef = pageRef;
-    }
-
-    public ClearIndicatingAjaxButton(final String id, final IModel<String> model, final PageReference pageRef) {
-        super(id, model);
-        this.pageRef = pageRef;
-    }
-
-    public ClearIndicatingAjaxButton(final String id, final IModel<String> model, final Form<?> form,
-            final PageReference pageRef) {
-
-        super(id, model, form);
-        this.pageRef = pageRef;
-    }
-
-    protected abstract void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form);
-
-    public ClearIndicatingAjaxButton feedbackPanelAutomaticReload(final boolean reloadFeedbackPanel) {
-        return this;
-    }
-
-    @Override
-    protected final void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-        super.onSubmit(target, form);
-        onSubmitInternal(target, form);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java
deleted file mode 100644
index adab320..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.wicket.ajax.markup.html;
-
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.model.IModel;
-
-public abstract class ClearIndicatingAjaxLink<T> extends IndicatingAjaxLink<T> {
-
-    private static final long serialVersionUID = 7913625094362339643L;
-
-    private final PageReference pageRef;
-
-    private boolean reloadFeedbackPanel = true;
-
-    public ClearIndicatingAjaxLink(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-        setOutputMarkupId(true);
-    }
-
-    public ClearIndicatingAjaxLink(final String id, final IModel<T> model, final PageReference pageRef) {
-        super(id, model);
-        this.pageRef = pageRef;
-        setOutputMarkupId(true);
-    }
-
-    public ClearIndicatingAjaxLink<T> feedbackPanelAutomaticReload(final boolean reloadFeedbackPanel) {
-        this.reloadFeedbackPanel = reloadFeedbackPanel;
-        return this;
-    }
-
-    protected abstract void onClickInternal(final AjaxRequestTarget target);
-
-    @Override
-    public final void onClick(final AjaxRequestTarget target) {
-//        final Page page = pageRef.getPage();
-//        if (reloadFeedbackPanel && page instanceof NotificationAwareComponent) {
-//            ((NotificationAwareComponent) page).getNotification().refresh(target);
-//        }
-        onClickInternal(target);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java
new file mode 100644
index 0000000..d894954
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wicket.ajax.markup.html;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.wicket.ajax.IAjaxIndicatorAware;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+
+/**
+ * An {@link AjaxLink} not showing veil.
+ */
+public abstract class IndicatorAjaxLink<T> extends AjaxLink<T> implements IAjaxIndicatorAware {
+
+    private static final long serialVersionUID = -1390762132437554937L;
+
+    public IndicatorAjaxLink(final String id) {
+        super(id);
+    }
+
+    @Override
+    public String getAjaxIndicatorMarkupId() {
+        return StringUtils.EMPTY;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
index 843fd3a..c069470 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
@@ -43,7 +43,6 @@ public class BooleanPropertyColumn<T> extends PropertyColumn<T, String> {
 
     @Override
     public void populateItem(final Item<ICellPopulator<T>> item, final String componentId, final IModel<T> rowModel) {
-
         BeanWrapper bwi = new BeanWrapperImpl(rowModel.getObject());
         Object obj = bwi.getPropertyValue(getPropertyExpression());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index 708fd92..93fda56 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -50,7 +50,9 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
         GROUP_TEMPLATE("read"),
         RESET("update"),
         ENABLE("update"),
-        SEARCH("read"),
+        NOT_FOND("read"),
+        VIEW("view"),
+        SEARCH("search"),
         DELETE("delete"),
         EXECUTE("execute"),
         DRYRUN("execute"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
index de7baf5..b56da38 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
@@ -24,8 +24,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Triple;
-import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
-import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
@@ -43,16 +41,13 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
 
     private static final long serialVersionUID = 322966537010107771L;
 
-    private final PageReference pageRef;
-
     private final IModel<T> model;
 
     private boolean disableIndicator = false;
 
-    private ActionLinksPanel(final String componentId, final IModel<T> model, final PageReference pageRef) {
+    private ActionLinksPanel(final String componentId, final IModel<T> model) {
         super(componentId, model);
         this.model = model;
-        this.pageRef = pageRef;
 
         setOutputMarkupId(true);
 
@@ -70,6 +65,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
         super.add(new Fragment("panelUserTemplate", "emptyFragment", this));
         super.add(new Fragment("panelGroupTemplate", "emptyFragment", this));
         super.add(new Fragment("panelEnable", "emptyFragment", this));
+        super.add(new Fragment("panelNotFound", "emptyFragment", this));
+        super.add(new Fragment("panelView", "emptyFragment", this));
         super.add(new Fragment("panelSearch", "emptyFragment", this));
         super.add(new Fragment("panelDelete", "emptyFragment", this));
         super.add(new Fragment("panelExecute", "emptyFragment", this));
@@ -104,12 +101,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case CLAIM:
                 fragment = new Fragment("panelClaim", "fragmentClaim", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("claimLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("claimLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -117,19 +114,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MANAGE_RESOURCES:
                 fragment = new Fragment("panelManageResources", "fragmentManageResources", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageResourcesLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("manageResourcesLink") {
 
                     private static final long serialVersionUID = -6957616042924610291L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -137,19 +133,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MANAGE_USERS:
                 fragment = new Fragment("panelManageUsers", "fragmentManageUsers", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageUsersLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("manageUsersLink") {
 
                     private static final long serialVersionUID = -6957616042924610292L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -157,19 +152,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MANAGE_GROUPS:
                 fragment = new Fragment("panelManageGroups", "fragmentManageGroups", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageGroupsLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("manageGroupsLink") {
 
                     private static final long serialVersionUID = -6957616042924610293L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -177,19 +171,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MAPPING:
                 fragment = new Fragment("panelMapping", "fragmentMapping", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("mappingLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("mappingLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -197,19 +190,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case ACCOUNT_LINK:
                 fragment = new Fragment("panelAccountLink", "fragmentAccountLink", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("accountLinkLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("accountLinkLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -217,19 +209,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case RESET_TIME:
                 fragment = new Fragment("panelResetTime", "fragmentResetTime", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("resetTimeLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("resetTimeLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -237,19 +228,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case CLONE:
                 fragment = new Fragment("panelClone", "fragmentClone", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("cloneLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("cloneLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -257,19 +247,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case CREATE:
                 fragment = new Fragment("panelCreate", "fragmentCreate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("createLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("createLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -277,19 +266,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case RESET:
                 fragment = new Fragment("panelReset", "fragmentReset", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("resetLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("resetLink") {
 
                     private static final long serialVersionUID = -6957616042924610290L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -303,12 +291,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case EDIT:
                 fragment = new Fragment("panelEdit", "fragmentEdit", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("editLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("editLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -316,19 +304,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case USER_TEMPLATE:
                 fragment = new Fragment("panelUserTemplate", "fragmentUserTemplate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("userTemplateLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("userTemplateLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -336,19 +323,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case GROUP_TEMPLATE:
                 fragment = new Fragment("panelGroupTemplate", "fragmentGroupTemplate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("groupTemplateLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("groupTemplateLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -356,19 +342,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case ENABLE:
                 fragment = new Fragment("panelEnable", "fragmentEnable", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("enableLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("enableLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -376,19 +361,40 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
+                break;
+
+            case NOT_FOND:
+                fragment = new Fragment("panelNotFound", "fragmentNotFound", this);
+                break;
+
+            case VIEW:
+                fragment = new Fragment("panelView", "fragmentView", this);
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("viewLink") {
+
+                    private static final long serialVersionUID = -1876519166660008562L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        link.onClick(target, model.getObject());
+                    }
+
+                    @Override
+                    public String getAjaxIndicatorMarkupId() {
+                        return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
+                    }
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case SEARCH:
                 fragment = new Fragment("panelSearch", "fragmentSearch", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("searchLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("searchLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -396,19 +402,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case EXECUTE:
                 fragment = new Fragment("panelExecute", "fragmentExecute", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("executeLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("executeLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -416,19 +421,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case DRYRUN:
                 fragment = new Fragment("panelDryRun", "fragmentDryRun", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("dryRunLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("dryRunLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -436,8 +440,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case DELETE:
@@ -463,12 +466,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case SELECT:
                 fragment = new Fragment("panelSelect", "fragmentSelect", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("selectLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("selectLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -482,12 +485,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case CLOSE:
                 fragment = new Fragment("panelClose", "fragmentClose", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("closeLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("closeLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -502,12 +505,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case EXPORT:
                 fragment = new Fragment("panelExport", "fragmentExport", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("exportLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("exportLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -521,12 +524,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case SUSPEND:
                 fragment = new Fragment("panelSuspend", "fragmentSuspend", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("suspendLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("suspendLink") {
 
                     private static final long serialVersionUID = -6957616042924610291L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -534,19 +537,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case REACTIVATE:
                 fragment = new Fragment("panelReactivate", "fragmentReactivate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("reactivateLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("reactivateLink") {
 
                     private static final long serialVersionUID = -6957616042924610292L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -554,19 +556,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case RELOAD:
                 fragment = new Fragment("panelReload", "fragmentReload", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("reloadLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("reloadLink") {
 
                     private static final long serialVersionUID = -6957616042924610293L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -574,19 +575,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case CHANGE_VIEW:
                 fragment = new Fragment("panelChangeView", "fragmentChangeView", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("changeViewLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("changeViewLink") {
 
                     private static final long serialVersionUID = -6957616042924610292L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -594,8 +594,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case UNLINK:
@@ -659,12 +658,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case ASSIGN:
                 fragment = new Fragment("panelAssign", "fragmentAssign", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("assignLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("assignLink") {
 
                     private static final long serialVersionUID = -6957616042924610304L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -672,8 +671,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case DEPROVISION:
@@ -699,12 +697,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case PROVISION:
                 fragment = new Fragment("panelProvision", "fragmentProvision", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("provisionLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("provisionLink") {
 
                     private static final long serialVersionUID = -6957616042924610305L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -712,18 +710,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
+
             case ZOOM_IN:
                 fragment = new Fragment("panelZoomIn", "fragmentZoomIn", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("zoomInLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("zoomInLink") {
 
                     private static final long serialVersionUID = -6957616042924610305L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -731,18 +729,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
+
             case ZOOM_OUT:
                 fragment = new Fragment("panelZoomOut", "fragmentZoomOut", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("zoomOutLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("zoomOutLink") {
 
                     private static final long serialVersionUID = -6957616042924610305L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -750,9 +748,9 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
+
             default:
             // do nothing
         }
@@ -814,6 +812,10 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                 super.addOrReplace(new Fragment("panelUserTemplate", "emptyFragment", this));
                 break;
 
+            case VIEW:
+                super.addOrReplace(new Fragment("panelView", "emptyFragment", this));
+                break;
+
             case SEARCH:
                 super.addOrReplace(new Fragment("panelSearch", "emptyFragment", this));
                 break;
@@ -897,8 +899,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
         return this;
     }
 
-    public static <T extends Serializable> Builder<T> builder(final PageReference pageRef) {
-        return new Builder<T>(pageRef);
+    public static <T extends Serializable> Builder<T> builder() {
+        return new Builder<>();
     }
 
     /**
@@ -912,14 +914,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
 
         private final Map<ActionLink.ActionType, Triple<ActionLink<T>, String, Boolean>> actions = new HashMap<>();
 
-        private final PageReference pageRef;
-
         private boolean disableIndicator = false;
 
-        private Builder(final PageReference pageRef) {
-            this.pageRef = pageRef;
-        }
-
         public Builder<T> setDisableIndicator(final boolean disableIndicator) {
             this.disableIndicator = disableIndicator;
             return this;
@@ -982,8 +978,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
          */
         public ActionLinksPanel<T> build(final String id, final T modelObject) {
             final ActionLinksPanel<T> panel = modelObject == null
-                    ? new ActionLinksPanel<>(id, new Model<T>(), this.pageRef)
-                    : new ActionLinksPanel<>(id, new Model<>(modelObject), this.pageRef);
+                    ? new ActionLinksPanel<>(id, new Model<T>())
+                    : new ActionLinksPanel<>(id, new Model<>(modelObject));
 
             panel.setDisableIndicator(disableIndicator);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
index cae2e9a..6ef9a94 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
@@ -139,7 +139,7 @@ public class BinaryFieldPanel extends FieldPanel<String> {
 
                     getRequestCycle().scheduleRequestHandlerAfterCurrent(rsrh);
                 } catch (Exception e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                 }
             }
         };

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
index bd55689..9c20635 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
@@ -19,15 +19,16 @@
 package org.apache.syncope.client.console.widgets;
 
 import java.io.Serializable;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.IndicatorAjaxLink;
 import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.rest.api.service.NotificationService;
 import org.apache.syncope.common.rest.api.service.ReportService;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.markup.html.panel.Panel;
@@ -47,7 +48,7 @@ public class JobActionPanel extends Panel {
         Fragment controls;
         if (jobTO.isRunning()) {
             controls = new Fragment("controls", "runningFragment", this);
-            controls.add(new AjaxLink<Void>("stop") {
+            controls.add(new IndicatorAjaxLink<Void>("stop") {
 
                 private static final long serialVersionUID = -7978723352517770644L;
 
@@ -76,14 +77,14 @@ public class JobActionPanel extends Panel {
                         send(widget, Broadcast.EXACT, new JobActionPayload(target));
                     } catch (Exception e) {
                         LOG.error("While stopping {}", jobTO.getRefDesc(), e);
-                        error(getString(Constants.ERROR) + ": " + e.getMessage());
+                        error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     }
                     SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                 }
             });
         } else {
             controls = new Fragment("controls", "notRunningFragment", this);
-            controls.add(new AjaxLink<Void>("start") {
+            controls.add(new IndicatorAjaxLink<Void>("start") {
 
                 private static final long serialVersionUID = -7978723352517770644L;
 
@@ -111,8 +112,8 @@ public class JobActionPanel extends Panel {
                         info(getString(Constants.OPERATION_SUCCEEDED));
                         send(widget, Broadcast.EXACT, new JobActionPayload(target));
                     } catch (Exception e) {
-                        LOG.error("While stopping {}", jobTO.getRefDesc(), e);
-                        error(getString(Constants.ERROR) + ": " + e.getMessage());
+                        LOG.error("While starting {}", jobTO.getRefDesc(), e);
+                        error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     }
                     SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
index 89f1964..9fd5186 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.widgets;
 
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -51,7 +52,10 @@ import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
@@ -97,26 +101,20 @@ public class JobWidget extends AbstractWidget {
 
     private final List<JobTO> available;
 
-    private final AvailableJobsPanel availableJobsPanel;
+    private AvailableJobsPanel availableJobsPanel;
 
     private final List<ExecTO> recent;
 
-    private final RecentExecPanel recentExecPanel;
+    private RecentExecPanel recentExecPanel;
 
     public JobWidget(final String id, final PageReference pageRef) {
         super(id);
-
         setOutputMarkupId(true);
 
         available = getAvailable(SyncopeConsoleSession.get());
-        availableJobsPanel = new AvailableJobsPanel("available", pageRef);
-        availableJobsPanel.setOutputMarkupId(true);
-        add(availableJobsPanel);
-
         recent = getRecent(SyncopeConsoleSession.get());
-        recentExecPanel = new RecentExecPanel("recent", pageRef);
-        recentExecPanel.setOutputMarkupId(true);
-        add(recentExecPanel);
+
+        add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(pageRef)));
 
         add(new WebSocketBehavior() {
 
@@ -130,6 +128,36 @@ public class JobWidget extends AbstractWidget {
         });
     }
 
+    private List<ITab> buildTabList(final PageReference pageRef) {
+        final List<ITab> tabs = new ArrayList<>();
+
+        tabs.add(new AbstractTab(new ResourceModel("available")) {
+
+            private static final long serialVersionUID = -6815067322125799251L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                availableJobsPanel = new AvailableJobsPanel(panelId, pageRef);
+                availableJobsPanel.setOutputMarkupId(true);
+                return availableJobsPanel;
+            }
+        });
+
+        tabs.add(new AbstractTab(new ResourceModel("recent")) {
+
+            private static final long serialVersionUID = -6815067322125799251L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                recentExecPanel = new RecentExecPanel(panelId, pageRef);
+                recentExecPanel.setOutputMarkupId(true);
+                return recentExecPanel;
+            }
+        });
+
+        return tabs;
+    }
+
     @Override
     public void onEvent(final IEvent<?> event) {
         if (event.getPayload() instanceof WebSocketPushPayload) {
@@ -141,10 +169,14 @@ public class JobWidget extends AbstractWidget {
                 recent.clear();
                 recent.addAll(((JobWidgetMessage) wsEvent.getMessage()).getUpdatedRecent());
 
-                availableJobsPanel.modelChanged();
-                wsEvent.getHandler().add(availableJobsPanel);
-                recentExecPanel.modelChanged();
-                wsEvent.getHandler().add(recentExecPanel);
+                if (availableJobsPanel != null) {
+                    availableJobsPanel.modelChanged();
+                    wsEvent.getHandler().add(availableJobsPanel);
+                }
+                if (recentExecPanel != null) {
+                    recentExecPanel.modelChanged();
+                    wsEvent.getHandler().add(recentExecPanel);
+                }
             }
         } else if (event.getPayload() instanceof JobActionPanel.JobActionPayload) {
             available.clear();
@@ -402,6 +434,5 @@ public class JobWidget extends AbstractWidget {
         public List<ExecTO> getUpdatedRecent() {
             return updatedRecent;
         }
-
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java
new file mode 100644
index 0000000..3882471
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import java.io.Serializable;
+
+public class ProgressBean implements Serializable {
+
+    private static final long serialVersionUID = 7135463859007124458L;
+
+    private String text;
+
+    private int fraction;
+
+    private int total;
+
+    private String cssClass;
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(final String text) {
+        this.text = text;
+    }
+
+    public int getFraction() {
+        return fraction;
+    }
+
+    public void setFraction(final int fraction) {
+        this.fraction = fraction;
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public void setTotal(final int total) {
+        this.total = total;
+    }
+
+    public float getPercent() {
+        return getTotal() == 0 ? 0 : 100 * getFraction() / getTotal();
+    }
+
+    public String getCssClass() {
+        return cssClass;
+    }
+
+    public void setCssClass(final String cssClass) {
+        this.cssClass = cssClass;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java
new file mode 100644
index 0000000..f82aedd
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class ProgressPanel extends Panel {
+
+    private static final long serialVersionUID = -8854916811656228816L;
+
+    public ProgressPanel(final String id, final ProgressBean progressBean) {
+        super(id);
+        setOutputMarkupId(true);
+
+        add(new Label("text", progressBean.getText()));
+        add(new Label("fraction", progressBean.getFraction()));
+        add(new Label("total", progressBean.getTotal()));
+
+        WebMarkupContainer progress = new WebMarkupContainer("progress");
+        progress.add(new AttributeModifier("style", "width: " + progressBean.getPercent() + "%"));
+        progress.add(new AttributeAppender("class", " " + progressBean.getCssClass()));
+        add(progress);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java
new file mode 100644
index 0000000..923a653
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+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;
+
+public class ProgressesPanel extends Panel {
+
+    private static final long serialVersionUID = 7837262802315339565L;
+
+    public ProgressesPanel(final String id, final Date lastUpdate, final List<ProgressBean> progressBeans) {
+        super(id);
+
+        add(new Label("lastUpdate", SyncopeConsoleSession.get().getDateFormat().format(lastUpdate)));
+
+        ListView<ProgressBean> progresses = new ListView<ProgressBean>("progresses", progressBeans) {
+
+            private static final long serialVersionUID = -9180479401817023838L;
+
+            @Override
+            protected void populateItem(final ListItem<ProgressBean> item) {
+                item.add(new ProgressPanel("progress", item.getModelObject()));
+            }
+        };
+        progresses.setOutputMarkupId(true);
+        add(progresses);
+    }
+
+}


[3/6] syncope git commit: [SYNCOPE-744] Here is the reconciliation status widget

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java
new file mode 100644
index 0000000..0e5addc
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.SearchableDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.AbstractModalPanel;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.widgets.reconciliation.Any;
+import org.apache.syncope.client.console.widgets.reconciliation.Misaligned;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class ReconciliationDetailsModalPanel extends AbstractModalPanel<Any> {
+
+    private static final long serialVersionUID = 1469396040405535283L;
+
+    private static final int ROWS = 10;
+
+    private final String resource;
+
+    private final List<Misaligned> misaligned;
+
+    public ReconciliationDetailsModalPanel(
+            final BaseModal<Any> modal,
+            final String resource,
+            final List<Misaligned> misaligned,
+            final PageReference pageRef) {
+
+        super(modal, pageRef);
+        this.resource = resource;
+        this.misaligned = misaligned;
+
+        add(new DiffPanel("diff", pageRef));
+    }
+
+    private class DiffPanel extends AbstractSearchResultPanel<
+        Misaligned, Misaligned, DetailsProvider, BaseRestClient> {
+
+        private static final long serialVersionUID = -8214546246301342868L;
+
+        DiffPanel(final String id, final PageReference pageRef) {
+            super(id, new Builder<Misaligned, Misaligned, BaseRestClient>(null, pageRef) {
+
+                private static final long serialVersionUID = 8769126634538601689L;
+
+                @Override
+                protected WizardMgtPanel<Misaligned> newInstance(final String id) {
+                    return new DiffPanel(id, pageRef);
+                }
+            }.disableCheckBoxes().hidePaginator());
+
+            rows = 10;
+            initResultTable();
+        }
+
+        @Override
+        protected DetailsProvider dataProvider() {
+            return new DetailsProvider();
+        }
+
+        @Override
+        protected String paginatorRowsKey() {
+            return StringUtils.EMPTY;
+        }
+
+        @Override
+        protected Collection<ActionLink.ActionType> getBulkActions() {
+            return Collections.<ActionLink.ActionType>emptyList();
+        }
+
+        @Override
+        protected List<IColumn<Misaligned, String>> getColumns() {
+            List<IColumn<Misaligned, String>> columns = new ArrayList<>();
+
+            columns.add(new PropertyColumn<Misaligned, String>(new ResourceModel("key"), "name", "name"));
+
+            columns.add(new AbstractColumn<Misaligned, String>(Model.of("Syncope")) {
+
+                private static final long serialVersionUID = 2054811145491901166L;
+
+                @Override
+                public void populateItem(
+                        final Item<ICellPopulator<Misaligned>> cellItem,
+                        final String componentId,
+                        final IModel<Misaligned> rowModel) {
+
+                    cellItem.add(new Label(componentId, rowModel.getObject().getOnSyncope().toString()));
+                    cellItem.add(new AttributeModifier("class", "code-deletion"));
+                }
+            });
+
+            columns.add(new AbstractColumn<Misaligned, String>(Model.of(resource)) {
+
+                private static final long serialVersionUID = 2054811145491901166L;
+
+                @Override
+                public void populateItem(
+                        final Item<ICellPopulator<Misaligned>> cellItem,
+                        final String componentId,
+                        final IModel<Misaligned> rowModel) {
+
+                    cellItem.add(new Label(componentId, rowModel.getObject().getOnResource().toString()));
+                    cellItem.add(new AttributeModifier("class", "code-addition"));
+                }
+            });
+
+            return columns;
+        }
+    }
+
+    protected final class DetailsProvider extends SearchableDataProvider<Misaligned> {
+
+        private static final long serialVersionUID = -1500081449932597854L;
+
+        private final SortableDataProviderComparator<Misaligned> comparator;
+
+        private DetailsProvider() {
+            super(ROWS);
+            setSort("name", SortOrder.ASCENDING);
+            comparator = new SortableDataProviderComparator<>(this);
+        }
+
+        @Override
+        public Iterator<Misaligned> iterator(final long first, final long count) {
+            Collections.sort(misaligned, comparator);
+            return misaligned.subList((int) first, (int) first + (int) count).iterator();
+        }
+
+        @Override
+        public long size() {
+            return misaligned.size();
+        }
+
+        @Override
+        public IModel<Misaligned> model(final Misaligned object) {
+            return new CompoundPropertyModel<>(object);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
new file mode 100644
index 0000000..1ac8c9a
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
@@ -0,0 +1,532 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SearchableDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.rest.ReportRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.IndicatorAjaxLink;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.client.console.widgets.reconciliation.Any;
+import org.apache.syncope.client.console.widgets.reconciliation.Anys;
+import org.apache.syncope.client.console.widgets.reconciliation.Misaligned;
+import org.apache.syncope.client.console.widgets.reconciliation.Missing;
+import org.apache.syncope.client.console.widgets.reconciliation.ReconciliationReport;
+import org.apache.syncope.client.console.widgets.reconciliation.ReconciliationReportParser;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.common.lib.to.ExecTO;
+import org.apache.syncope.common.lib.to.JobTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.wicket.Application;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.Component;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Fragment;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.WebSocketPushBroadcaster;
+import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
+import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
+import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
+import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReconciliationWidget extends AbstractWidget {
+
+    private static final long serialVersionUID = -816175678514035085L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(ReconciliationWidget.class);
+
+    private static final long RECONCILIATION_REPORT_KEY = 2L;
+
+    private static final int ROWS = 10;
+
+    private final BaseModal<Any> detailsModal = new BaseModal<>("detailsModal");
+
+    private final PageReference pageRef;
+
+    private final ReportRestClient restClient = new ReportRestClient();
+
+    private final WebMarkupContainer overlay;
+
+    private boolean checkReconciliationJob = false;
+
+    public ReconciliationWidget(final String id, final PageReference pageRef) {
+        super(id);
+        this.pageRef = pageRef;
+        setOutputMarkupId(true);
+        add(detailsModal);
+
+        overlay = new WebMarkupContainer("overlay");
+        overlay.setOutputMarkupPlaceholderTag(true);
+        overlay.setVisible(false);
+        add(overlay);
+
+        ReportTO reconciliationReport = restClient.read(RECONCILIATION_REPORT_KEY);
+
+        Fragment reportResult = reconciliationReport.getExecutions().isEmpty()
+                ? new Fragment("reportResult", "noExecFragment", this)
+                : buildExecFragment();
+        reportResult.setOutputMarkupId(true);
+        add(reportResult);
+
+        add(new WebSocketBehavior() {
+
+            private static final long serialVersionUID = 3507933905864454312L;
+
+            @Override
+            protected void onConnect(final ConnectedMessage message) {
+                super.onConnect(message);
+
+                SyncopeConsoleSession.get().scheduleAtFixedRate(
+                        new ReconciliationJobInfoUpdater(message), 0, 10, TimeUnit.SECONDS);
+            }
+        });
+
+        add(new IndicatorAjaxLink<Void>("refresh") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    restClient.startExecution(RECONCILIATION_REPORT_KEY, null);
+
+                    overlay.setVisible(true);
+                    target.add(ReconciliationWidget.this);
+
+                    synchronized (this) {
+                        checkReconciliationJob = true;
+                    }
+
+                    info(getString(Constants.OPERATION_SUCCEEDED));
+                } catch (Exception e) {
+                    LOG.error("While starting reconciliation report", e);
+                    error("Could not start reconciliation report");
+                }
+                SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+            }
+        });
+    }
+
+    private Fragment buildExecFragment() {
+        Fragment execFragment = new Fragment("reportResult", "execFragment", this);
+        execFragment.setOutputMarkupId(true);
+
+        Pair<List<ProgressBean>, ReconciliationReport> execResult;
+        try {
+            execResult = parseReconciliationReportExec();
+        } catch (Exception e) {
+            LOG.error("Could not parse the reconciliation report result", e);
+            execResult = Pair.of(Collections.<ProgressBean>emptyList(), null);
+        }
+        final List<ProgressBean> progressBeans = execResult.getLeft();
+        final ReconciliationReport report = execResult.getRight();
+
+        List<ITab> tabs = new ArrayList<>();
+        tabs.add(new AbstractTab(new ResourceModel("summary")) {
+
+            private static final long serialVersionUID = -6815067322125799251L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                return new ProgressesPanel(panelId, report.getRun(), progressBeans);
+            }
+        });
+        tabs.add(new AbstractTab(new ResourceModel("users")) {
+
+            private static final long serialVersionUID = -6815067322125799251L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                return new AnysReconciliationPanel(panelId, report.getUsers(), pageRef);
+            }
+        });
+        tabs.add(new AbstractTab(new ResourceModel("groups")) {
+
+            private static final long serialVersionUID = -6815067322125799251L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                return new AnysReconciliationPanel(panelId, report.getGroups(), pageRef);
+            }
+        });
+        for (final Anys anys : report.getAnyObjects()) {
+            tabs.add(new AbstractTab(Model.of(anys.getAnyType())) {
+
+                private static final long serialVersionUID = -6815067322125799251L;
+
+                @Override
+                public Panel getPanel(final String panelId) {
+                    return new AnysReconciliationPanel(panelId, anys, pageRef);
+                }
+            });
+        }
+
+        execFragment.add(new AjaxBootstrapTabbedPanel<>("execResult", tabs));
+
+        return execFragment;
+    }
+
+    private Pair<List<ProgressBean>, ReconciliationReport> parseReconciliationReportExec() throws IOException {
+        List<ProgressBean> beans = Collections.emptyList();
+        ReconciliationReport report = null;
+
+        ExecTO exec = IterableUtils.find(restClient.listRecentExecutions(ROWS), new Predicate<ExecTO>() {
+
+            @Override
+            public boolean evaluate(final ExecTO exec) {
+                return exec.getRefKey() == RECONCILIATION_REPORT_KEY;
+            }
+        });
+        if (exec == null) {
+            LOG.error("Could not find the last execution of reconciliation report");
+        } else {
+            Object entity = restClient.exportExecutionResult(exec.getKey(), ReportExecExportFormat.XML).getEntity();
+            if (entity instanceof InputStream) {
+                try {
+                    report = ReconciliationReportParser.parse(exec.getEnd(), (InputStream) entity);
+
+                    beans = new ArrayList<>();
+
+                    ProgressBean progressBean = new ProgressBean();
+                    progressBean.setText(getString("users"));
+                    progressBean.setTotal(report.getUsers().getTotal());
+                    progressBean.setFraction(report.getUsers().getTotal() - report.getUsers().getAnys().size());
+                    progressBean.setCssClass("progress-bar-yellow");
+                    beans.add(progressBean);
+
+                    progressBean = new ProgressBean();
+                    progressBean.setText(getString("groups"));
+                    progressBean.setTotal(report.getGroups().getTotal());
+                    progressBean.setFraction(report.getGroups().getTotal() - report.getGroups().getAnys().size());
+                    progressBean.setCssClass("progress-bar-red");
+                    beans.add(progressBean);
+
+                    int i = 0;
+                    for (Anys anys : report.getAnyObjects()) {
+                        progressBean = new ProgressBean();
+                        progressBean.setText(anys.getAnyType());
+                        progressBean.setTotal(anys.getTotal());
+                        progressBean.setFraction(anys.getTotal() - anys.getAnys().size());
+                        progressBean.setCssClass("progress-bar-" + (i % 2 == 0 ? "green" : "aqua"));
+                        beans.add(progressBean);
+
+                        i++;
+                    }
+                } catch (Exception e) {
+                    LOG.error("Could not parse the last execution available of reconciliation report", e);
+                }
+            }
+        }
+
+        return Pair.of(beans, report);
+    }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if (event.getPayload() instanceof WebSocketPushPayload) {
+            WebSocketPushPayload wsEvent = (WebSocketPushPayload) event.getPayload();
+            if (wsEvent.getMessage() instanceof ReconciliationJobNotRunningMessage) {
+                overlay.setVisible(false);
+
+                addOrReplace(buildExecFragment());
+
+                wsEvent.getHandler().add(ReconciliationWidget.this);
+
+                synchronized (this) {
+                    checkReconciliationJob = false;
+                }
+            }
+        }
+    }
+
+    private class AnysReconciliationPanel extends AbstractSearchResultPanel<
+        Any, Any, AnysReconciliationProvider, BaseRestClient> {
+
+        private static final long serialVersionUID = -8214546246301342868L;
+
+        private final Anys anys;
+
+        AnysReconciliationPanel(final String id, final Anys anys, final PageReference pageRef) {
+            super(id, new Builder<Any, Any, BaseRestClient>(null, pageRef) {
+
+                private static final long serialVersionUID = 8769126634538601689L;
+
+                @Override
+                protected WizardMgtPanel<Any> newInstance(final String id) {
+                    return new AnysReconciliationPanel(id, anys, pageRef);
+                }
+            }.disableCheckBoxes().hidePaginator());
+
+            this.anys = anys;
+            this.rows = ROWS;
+            initResultTable();
+        }
+
+        @Override
+        protected AnysReconciliationProvider dataProvider() {
+            return new AnysReconciliationProvider(anys);
+        }
+
+        @Override
+        protected String paginatorRowsKey() {
+            return StringUtils.EMPTY;
+        }
+
+        @Override
+        protected Collection<ActionLink.ActionType> getBulkActions() {
+            return Collections.<ActionLink.ActionType>emptyList();
+        }
+
+        @Override
+        protected List<IColumn<Any, String>> getColumns() {
+            List<IColumn<Any, String>> columns = new ArrayList<>();
+
+            columns.add(new AbstractColumn<Any, String>(new ResourceModel("reference"), "key") {
+
+                private static final long serialVersionUID = -1822504503325964706L;
+
+                @Override
+                public void populateItem(
+                        final Item<ICellPopulator<Any>> cellItem,
+                        final String componentId,
+                        final IModel<Any> rowModel) {
+
+                    cellItem.add(new Label(componentId,
+                            rowModel.getObject().getKey()
+                            + (StringUtils.isBlank(rowModel.getObject().getName())
+                            ? StringUtils.EMPTY
+                            : " " + rowModel.getObject().getName())));
+                }
+            });
+
+            final Set<String> resources = new HashSet<>();
+            for (Any any : anys.getAnys()) {
+                resources.addAll(CollectionUtils.collect(any.getMissing(), new Transformer<Missing, String>() {
+
+                    @Override
+                    public String transform(final Missing input) {
+                        return input.getResource();
+                    }
+                }));
+                resources.addAll(CollectionUtils.collect(any.getMisaligned(), new Transformer<Misaligned, String>() {
+
+                    @Override
+                    public String transform(final Misaligned input) {
+                        return input.getResource();
+                    }
+                }));
+            }
+            for (final String resource : resources) {
+                columns.add(new AbstractColumn<Any, String>(Model.of(resource)) {
+
+                    private static final long serialVersionUID = -1822504503325964706L;
+
+                    @Override
+                    public void populateItem(
+                            final Item<ICellPopulator<Any>> cellItem,
+                            final String componentId,
+                            final IModel<Any> rowModel) {
+
+                        final Any any = rowModel.getObject();
+
+                        Missing missing = IterableUtils.find(any.getMissing(), new Predicate<Missing>() {
+
+                            @Override
+                            public boolean evaluate(final Missing object) {
+                                return resource.equals(object.getResource());
+                            }
+                        });
+                        final List<Misaligned> misaligned = CollectionUtils.select(
+                                any.getMisaligned(), new Predicate<Misaligned>() {
+
+                            @Override
+                            public boolean evaluate(final Misaligned object) {
+                                return resource.equals(object.getResource());
+                            }
+                        }, new ArrayList<Misaligned>());
+                        Component content = missing == null
+                                ? misaligned == null || misaligned.isEmpty()
+                                        ? new Label(componentId, StringUtils.EMPTY)
+                                        : ActionLinksPanel.<Any>builder().add(new ActionLink<Any>() {
+
+                                            private static final long serialVersionUID = -3722207913631435501L;
+
+                                            @Override
+                                            public void onClick(final AjaxRequestTarget target, final Any ignore) {
+                                                modal.header(Model.of(
+                                                        rowModel.getObject().getType()
+                                                        + " " + rowModel.getObject().getKey()
+                                                        + " " + rowModel.getObject().getName()));
+                                                modal.setContent(new ReconciliationDetailsModalPanel(
+                                                        modal,
+                                                        resource,
+                                                        misaligned,
+                                                        ReconciliationWidget.this.pageRef));
+                                                modal.show(true);
+                                                target.add(modal);
+                                            }
+                                        }, ActionLink.ActionType.VIEW).
+                                        build(componentId)
+                                : ActionLinksPanel.<Any>builder().add(null, ActionLink.ActionType.NOT_FOND).
+                                build(componentId);
+                        cellItem.add(content);
+                        cellItem.add(new AttributeModifier("class", "text-center"));
+                    }
+                });
+            }
+
+            return columns;
+        }
+    }
+
+    protected final class AnysReconciliationProvider extends SearchableDataProvider<Any> {
+
+        private static final long serialVersionUID = -1500081449932597854L;
+
+        private final Anys anys;
+
+        private final SortableDataProviderComparator<Any> comparator;
+
+        private AnysReconciliationProvider(final Anys anys) {
+            super(ROWS);
+            this.anys = anys;
+            setSort("key", SortOrder.ASCENDING);
+            comparator = new SortableDataProviderComparator<>(this);
+        }
+
+        @Override
+        public Iterator<Any> iterator(final long first, final long count) {
+            Collections.sort(anys.getAnys(), comparator);
+            return anys.getAnys().subList((int) first, (int) first + (int) count).iterator();
+        }
+
+        @Override
+        public long size() {
+            return anys.getAnys().size();
+        }
+
+        @Override
+        public IModel<Any> model(final Any object) {
+            return new CompoundPropertyModel<>(object);
+        }
+    }
+
+    protected final class ReconciliationJobInfoUpdater implements Runnable {
+
+        private final String applicationName;
+
+        private final SyncopeConsoleSession session;
+
+        private final IKey key;
+
+        public ReconciliationJobInfoUpdater(final ConnectedMessage message) {
+            this.applicationName = message.getApplication().getName();
+            this.session = SyncopeConsoleSession.get();
+            this.key = message.getKey();
+        }
+
+        @Override
+        public void run() {
+            synchronized (ReconciliationWidget.this) {
+                if (ReconciliationWidget.this.checkReconciliationJob) {
+                    try {
+                        Application application = Application.get(applicationName);
+                        ThreadContext.setApplication(application);
+                        ThreadContext.setSession(session);
+
+                        JobTO reportJobTO = IterableUtils.find(session.getService(ReportService.class).listJobs(),
+                                new Predicate<JobTO>() {
+
+                            @Override
+                            public boolean evaluate(final JobTO jobTO) {
+                                return RECONCILIATION_REPORT_KEY == jobTO.getRefKey();
+                            }
+                        });
+                        if (reportJobTO != null && !reportJobTO.isRunning()) {
+                            LOG.debug("Report {} is not running", RECONCILIATION_REPORT_KEY);
+
+                            WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
+                            WebSocketPushBroadcaster broadcaster =
+                                    new WebSocketPushBroadcaster(webSocketSettings.getConnectionRegistry());
+                            broadcaster.broadcast(
+                                    new ConnectedMessage(application, session.getId(), key),
+                                    new ReconciliationJobNotRunningMessage());
+                        }
+                    } catch (Throwable t) {
+                        LOG.error("Unexpected error while checking for updated reconciliation job info", t);
+                    } finally {
+                        ThreadContext.detach();
+                    }
+                }
+            }
+        }
+    }
+
+    private static class ReconciliationJobNotRunningMessage implements IWebSocketPushMessage, Serializable {
+
+        private static final long serialVersionUID = -824793424112532838L;
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java
new file mode 100644
index 0000000..5e915b4
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets.reconciliation;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class Any extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 2421645848049271898L;
+
+    private String type;
+
+    private long key;
+
+    private String name;
+
+    private final List<Missing> missing = new ArrayList<>();
+
+    private final List<Misaligned> misaligned = new ArrayList<>();
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(final String type) {
+        this.type = type;
+    }
+
+    public long getKey() {
+        return key;
+    }
+
+    public void setKey(final long key) {
+        this.key = key;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public List<Missing> getMissing() {
+        return missing;
+    }
+
+    public List<Misaligned> getMisaligned() {
+        return misaligned;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java
new file mode 100644
index 0000000..fecdfee
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets.reconciliation;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class Anys extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -2482591351364634179L;
+
+    private int total = 0;
+
+    private String anyType;
+
+    private final List<Any> anys = new ArrayList<>();
+
+    public int getTotal() {
+        return total;
+    }
+
+    public void setTotal(final int total) {
+        this.total = total;
+    }
+
+    public String getAnyType() {
+        return anyType;
+    }
+
+    public void setAnyType(final String anyType) {
+        this.anyType = anyType;
+    }
+
+    public List<Any> getAnys() {
+        return anys;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java
new file mode 100644
index 0000000..bd189e6
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets.reconciliation;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class Misaligned extends Missing {
+
+    private static final long serialVersionUID = -2287634884015557714L;
+
+    private final String name;
+
+    private final Set<String> onSyncope = new HashSet<>();
+
+    private final Set<String> onResource = new HashSet<>();
+
+    public Misaligned(final String resource, final String connObjectKeyValue, final String name) {
+        super(resource, connObjectKeyValue);
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Set<String> getOnSyncope() {
+        return onSyncope;
+    }
+
+    public Set<String> getOnResource() {
+        return onResource;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java
new file mode 100644
index 0000000..2d0254a
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets.reconciliation;
+
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class Missing extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -4779715117027316991L;
+
+    private final String resource;
+
+    private final String connObjectKeyValue;
+
+    public Missing(final String resource, final String connObjectKeyValue) {
+        this.resource = resource;
+        this.connObjectKeyValue = connObjectKeyValue;
+    }
+
+    public String getResource() {
+        return resource;
+    }
+
+    public String getConnObjectKeyValue() {
+        return connObjectKeyValue;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java
new file mode 100644
index 0000000..b107426
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets.reconciliation;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class ReconciliationReport extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 931063230006747313L;
+
+    private final Date run;
+
+    private Anys users;
+
+    private Anys groups;
+
+    private final List<Anys> anyObjects = new ArrayList<>();
+
+    public ReconciliationReport(final Date run) {
+        this.run = run;
+    }
+
+    public Date getRun() {
+        return run == null ? null : new Date(run.getTime());
+    }
+
+    public Anys getUsers() {
+        return users;
+    }
+
+    public void setUsers(final Anys users) {
+        this.users = users;
+    }
+
+    public Anys getGroups() {
+        return groups;
+    }
+
+    public void setGroups(final Anys groups) {
+        this.groups = groups;
+    }
+
+    public List<Anys> getAnyObjects() {
+        return anyObjects;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java
new file mode 100644
index 0000000..c99b7e3
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets.reconciliation;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+public final class ReconciliationReportParser {
+
+    private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance();
+
+    public static ReconciliationReport parse(final Date run, final InputStream in) throws XMLStreamException {
+        XMLStreamReader streamReader = INPUT_FACTORY.createXMLStreamReader(in);
+        streamReader.nextTag(); // root
+        streamReader.nextTag(); // report
+        streamReader.nextTag(); // reportlet
+
+        ReconciliationReport report = new ReconciliationReport(run);
+
+        List<Missing> missing = new ArrayList<>();
+        List<Misaligned> misaligned = new ArrayList<>();
+        Set<String> onSyncope = null;
+        Set<String> onResource = null;
+
+        Any user = null;
+        Any group = null;
+        Any anyObject = null;
+        String lastAnyType = null;
+        while (streamReader.hasNext()) {
+            if (streamReader.isStartElement()) {
+                switch (streamReader.getLocalName()) {
+                    case "users":
+                        Anys users = new Anys();
+                        users.setTotal(Integer.valueOf(streamReader.getAttributeValue("", "total")));
+                        report.setUsers(users);
+                        break;
+
+                    case "user":
+                        user = new Any();
+                        user.setType(AnyTypeKind.USER.name());
+                        user.setKey(Long.valueOf(streamReader.getAttributeValue("", "key")));
+                        user.setName(streamReader.getAttributeValue("", "username"));
+                        report.getUsers().getAnys().add(user);
+                        break;
+
+                    case "groups":
+                        Anys groups = new Anys();
+                        groups.setTotal(Integer.valueOf(streamReader.getAttributeValue("", "total")));
+                        report.setGroups(groups);
+                        break;
+
+                    case "group":
+                        group = new Any();
+                        group.setType(AnyTypeKind.GROUP.name());
+                        group.setKey(Long.valueOf(streamReader.getAttributeValue("", "key")));
+                        group.setName(streamReader.getAttributeValue("", "groupName"));
+                        report.getGroups().getAnys().add(group);
+                        break;
+
+                    case "anyObjects":
+                        lastAnyType = streamReader.getAttributeValue("", "type");
+                        Anys anyObjects = new Anys();
+                        anyObjects.setAnyType(lastAnyType);
+                        anyObjects.setTotal(Integer.valueOf(streamReader.getAttributeValue("", "total")));
+                        report.getAnyObjects().add(anyObjects);
+                        break;
+
+                    case "anyObject":
+                        anyObject = new Any();
+                        anyObject.setType(lastAnyType);
+                        anyObject.setKey(Long.valueOf(streamReader.getAttributeValue("", "key")));
+                        final String anyType = lastAnyType;
+                        IterableUtils.find(report.getAnyObjects(), new Predicate<Anys>() {
+
+                            @Override
+                            public boolean evaluate(final Anys anys) {
+                                return anyType.equals(anys.getAnyType());
+                            }
+                        }).getAnys().add(anyObject);
+                        break;
+
+                    case "missing":
+                        missing.add(new Missing(
+                                streamReader.getAttributeValue("", "resource"),
+                                streamReader.getAttributeValue("", "connObjectKeyValue")));
+                        break;
+
+                    case "misaligned":
+                        misaligned.add(new Misaligned(
+                                streamReader.getAttributeValue("", "resource"),
+                                streamReader.getAttributeValue("", "connObjectKeyValue"),
+                                streamReader.getAttributeValue("", "name")));
+                        break;
+
+                    case "onSyncope":
+                        onSyncope = new HashSet<>();
+                        break;
+
+                    case "onResource":
+                        onResource = new HashSet<>();
+                        break;
+
+                    case "value":
+                        Set<String> set = onSyncope == null ? onResource : onSyncope;
+                        set.add(streamReader.getElementText());
+                        break;
+
+                    default:
+                }
+            } else if (streamReader.isEndElement()) {
+                switch (streamReader.getLocalName()) {
+                    case "user":
+                        user.getMissing().addAll(missing);
+                        user.getMisaligned().addAll(misaligned);
+                        missing.clear();
+                        misaligned.clear();
+                        break;
+
+                    case "group":
+                        group.getMissing().addAll(missing);
+                        group.getMisaligned().addAll(misaligned);
+                        missing.clear();
+                        misaligned.clear();
+                        break;
+
+                    case "anyObject":
+                        anyObject.getMissing().addAll(missing);
+                        anyObject.getMisaligned().addAll(misaligned);
+                        missing.clear();
+                        misaligned.clear();
+                        break;
+
+                    case "onSyncope":
+                        misaligned.get(misaligned.size() - 1).getOnSyncope().addAll(onSyncope);
+                        onSyncope = null;
+                        break;
+
+                    case "onResource":
+                        misaligned.get(misaligned.size() - 1).getOnResource().addAll(onResource);
+                        onResource = null;
+                        break;
+
+                    default:
+                }
+
+            }
+
+            streamReader.next();
+        }
+
+        try {
+            System.out.println("QQQQQQQQQ\n" + new ObjectMapper().writeValueAsString(report));
+        } catch (JsonProcessingException ex) {
+            System.err.println("nuuuuuuuuuuuuuuuuuuuuuuuu");
+            ex.printStackTrace();
+        }
+
+        return report;
+    }
+
+    private ReconciliationReportParser() {
+        // private constructor for static utility class
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
index dc883bf..59bb335 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.client.console.wizards;
 
 import java.io.Serializable;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.ModalPanel;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -87,7 +87,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
             send(AjaxWizard.this, Broadcast.BUBBLE, new NewItemCancelEvent<>(item, target));
         } catch (Exception e) {
             LOG.warn("Wizard error on cancel", e);
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
             SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
         }
     }
@@ -103,7 +103,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
             send(AjaxWizard.this, Broadcast.BUBBLE, new NewItemFinishEvent<>(item, target).setResult(res));
         } catch (Exception e) {
             LOG.error("Wizard error on finish", e);
-            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
             SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
index 6d295f7..34dc4a3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
@@ -82,9 +82,9 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
     /**
      * Modal window.
      */
-    protected final BaseModal<T> altDefaultModal = new BaseModal<T>("alternativeDefaultModal");
+    protected final BaseModal<T> altDefaultModal = new BaseModal<>("alternativeDefaultModal");
     
-    protected final BaseModal<T> displayAttributeModal = new BaseModal<T>("displayAttributeModal");
+    protected final BaseModal<T> displayAttributeModal = new BaseModal<>("displayAttributeModal");
 
     protected WizardMgtPanel(final String id) {
         this(id, false);
@@ -166,10 +166,9 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
                 if (wizardInModal && showResultPage) {
                     modal.setContent(new ResultPage<T>(
                             item,
-                            AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult(),
-                            pageRef) {
+                            AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult()) {
 
-                        private static final long serialVersionUID = 1L;
+                        private static final long serialVersionUID = -2630573849050255233L;
 
                         @Override
                         protected void closeAction(final AjaxRequestTarget target) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index fafdfb0..fc2a941 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.wizards.any;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -153,7 +154,7 @@ public class Relationships extends WizardStep {
             }
         });
 
-        viewFragment.add(ActionLinksPanel.<RelationshipTO>builder(pageRef).add(new ActionLink<RelationshipTO>() {
+        viewFragment.add(ActionLinksPanel.<RelationshipTO>builder().add(new ActionLink<RelationshipTO>() {
 
             private static final long serialVersionUID = 3257738274365467945L;
 
@@ -192,9 +193,7 @@ public class Relationships extends WizardStep {
     }
 
     private void addNewRelationships(final RelationshipTO... rels) {
-        for (RelationshipTO relationship : rels) {
-            getCurrentRelationships().add(relationship);
-        }
+        getCurrentRelationships().addAll(Arrays.asList(rels));
     }
 
     private void removeRelationships(
@@ -330,7 +329,7 @@ public class Relationships extends WizardStep {
 
                         anyObjectSearchPanel = new AnyObjectSearchPanel.Builder(
                                 anyType.getKey(),
-                                new ListModel<SearchClause>(new ArrayList<SearchClause>())).
+                                new ListModel<>(new ArrayList<SearchClause>())).
                                 enableSearch().
                                 build("searchPanel");
                         fragment.add(anyObjectSearchPanel.setRenderBodyOnly(true));

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
index 060a027..45b4aa3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
@@ -23,7 +23,6 @@ import org.apache.syncope.client.console.panels.ModalPanel;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.panel.Panel;
@@ -38,14 +37,14 @@ public abstract class ResultPage<T extends Serializable> extends Panel implement
 
     private final T item;
 
-    public ResultPage(final T item, final Serializable result, final PageReference pageRef) {
+    public ResultPage(final T item, final Serializable result) {
         super(BaseModal.CONTENT_ID);
         setOutputMarkupId(true);
         this.item = item;
 
         add(customResultBody("customResultBody", item, result));
 
-        add(ActionLinksPanel.<T>builder(pageRef).add(new ActionLink<T>() {
+        add(ActionLinksPanel.<T>builder().add(new ActionLink<T>() {
 
             private static final long serialVersionUID = 3257738274365467945L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index bfb194b..14d1d24 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -177,7 +177,7 @@ public class StatusPanel extends Panel {
             public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
                 mlp.next(bean.getResourceName(), new RemoteObjectPanel(bean, connObjects), target);
             }
-        }, ActionLink.ActionType.SEARCH, StandardEntitlement.RESOURCE_GET_CONNOBJECT);
+        }, ActionLink.ActionType.VIEW, StandardEntitlement.RESOURCE_GET_CONNOBJECT);
 
         listViewPanel = ListViewPanel.class.cast(builder.build(MultilevelPanel.FIRST_LEVEL_ID));
         mlp.setFirstLevel(listViewPanel);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 0f71eeb..c3940eb 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -531,3 +531,13 @@ END - Result page
 .nav-tabs-custom > .nav-tabs > li.active {
   border-top-color: #d2d6de !important;
 }
+
+.code-deletion {
+  background-color: #ffdddd;
+  border-color: #f1c0c0;
+}
+
+.code-addition {
+  background-color: #dbffdb;
+  border-color: #c1e9c1;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
index 200d752..e2c5948 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
@@ -17,23 +17,34 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <script type="text/javascript">
+      $(document).ready(function () {
+        $("#pageTitleInBradcrumb").append($("#pageTitle").text());
+      });
+    </script>
+  </wicket:head>
   <wicket:extend>
+    <script lang="text/javascript">
+
+    </script>
     <section class="content-header">
       <h1>&nbsp;</h1>
       <ol class="breadcrumb">
         <li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
-        <li class="active"><wicket:message key="realms"/></li>
+        <li class="active" id="pageTitleInBradcrumb"/>
       </ol>
+      <div id="pageTitle" style="visibility: hidden;"><wicket:message key='realms'/></div>
     </section>
 
     <section class="content" wicket:id="content">
       <div class="box">
         <div class="box-body">
-          <span wicket:id="realmChoicePanel">[Realm Sidebar Panel]</span>
-          <wicket:container wicket:id="body"></wicket:container>
+          <span wicket:id="realmChoicePanel"/>
+          <wicket:container wicket:id="body"/>
         </div>
       </div>
-      <div wicket:id="modal"></div>
+      <div wicket:id="modal"/>
     </section>
   </wicket:extend>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
index ae731af..bc6f762 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
@@ -23,5 +23,11 @@ under the License.
         <span wicket:id="job"/>
       </div>
     </div>
+
+    <div class="row">
+      <div class="col-md-12">
+        <span wicket:id="reconciliation"/>
+      </div>
+    </div>
   </wicket:panel>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
index 4b6bc36..3550ace 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
@@ -18,6 +18,6 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
-    <div wicket:id="modalDetails" />
+    <div wicket:id="modalDetails"/>
   </wicket:extend>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
index 9cbe6ba..cb02567 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
@@ -17,33 +17,30 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <head><title>toggle menu</title></head>
-  <body>
-    <wicket:head>
-      <script type="text/javascript">
-        $(document).ready(function () {
-          $("div.inactive-topology-menu").toggle("slow");
-          $("div.inactive-topology-menu").attr("class", "topology-menu active-topology-menu");
-        });
-      </script>
+  <wicket:head>
+    <script type="text/javascript">
+      $(document).ready(function () {
+        $("div.inactive-topology-menu").toggle("slow");
+        $("div.inactive-topology-menu").attr("class", "topology-menu active-topology-menu");
+      });
+    </script>
 
-      <style type="text/css">
-        div.topology-menu {
-          top: 65px !important;
-        }
+    <style type="text/css">
+      div.topology-menu {
+        top: 65px !important;
+      }
 
-        div.topology-menu div.header {
-          display: none !important;
-        }
-      </style>
-    </wicket:head>
-    <wicket:extend>
-      <div wicket:id="container">
-        <ul class="menu">
-          <li><i class="fa fa-file-image-o"></i><a href="#" wicket:id="activitiModeler">Activiti Modeler</a></li>
-          <li><i class="fa fa-file-text-o"></i><a href="#" wicket:id="xmlEditor">XML editor</a></li>
-        </ul>
-      </div>
-    </wicket:extend>
-  </body>
+      div.topology-menu div.header {
+        display: none !important;
+      }
+    </style>
+  </wicket:head>
+  <wicket:extend>
+    <div wicket:id="container">
+      <ul class="menu">
+        <li><i class="fa fa-file-image-o"></i><a href="#" wicket:id="activitiModeler">Activiti Modeler</a></li>
+        <li><i class="fa fa-file-text-o"></i><a href="#" wicket:id="xmlEditor">XML editor</a></li>
+      </ul>
+    </div>
+  </wicket:extend>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
index 8829644..78d0927 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
@@ -34,6 +34,8 @@ under the License.
     <span wicket:id="panelExecute">[plus]</span>
     <span wicket:id="panelEnable">[plus]</span>
     <span wicket:id="panelSearch">[plus]</span>
+    <span wicket:id="panelNotFound">[plus]</span>
+    <span wicket:id="panelView">[plus]</span>
     <span wicket:id="panelMapping">[plus]</span>
     <span wicket:id="panelAccountLink">[plus]</span>
     <span wicket:id="panelResetTime">[plus]</span>
@@ -96,6 +98,14 @@ under the License.
       <a href="#" wicket:id="createLink" class="btn"><i class="glyphicon glyphicon-plus" alt="create icon" title="Create"></i></a>
     </wicket:fragment>
 
+    <wicket:fragment wicket:id="fragmentNotFound">
+      <i class="fa fa-eye-slash" alt="notFound icon" title="Not Found"></i>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentView">
+      <a href="#" wicket:id="viewLink" class="btn"><i class="fa fa-eye" alt="view icon" title="View"></i></a>
+    </wicket:fragment>
+
     <wicket:fragment wicket:id="fragmentSearch">
       <a href="#" wicket:id="searchLink" class="btn"><i class="glyphicon glyphicon-search" alt="search icon" title="Search"></i></a>
     </wicket:fragment>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
index c2f9ce3..a476bc2 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
-    <div class="box">
+    <div class="box box-default box-solid">
       <div class="box-header with-border">
         <h3 class="box-title"><wicket:message key="usersGroupsAndAnyObjectsDistribution"/></h3>
         <div class="box-tools pull-right">

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
index acc12b3..2e48d08 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
-    <div class="box">
+    <div class="box box-default box-solid">
       <div class="box-header with-border">
         <h3 class="box-title"><wicket:message key="configurationStatus"/></h3>
         <div class="box-tools pull-right">

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
index bc19be2..fdf5373 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
@@ -18,20 +18,16 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
-    <div class="nav-tabs-custom">
-      <ul class="nav nav-tabs pull-right ui-sortable-handle">
-        <li class="active"><a data-toggle="tab" href="#running">Available</a></li>
-        <li><a data-toggle="tab" href="#recent">Recent</a></li>
-        <li class="pull-left header"><i class="fa fa-gears"></i> Jobs</li>
-      </ul>
-      <div class="tab-content no-padding">
-        <div style="position: relative;" id="running" class="chart tab-pane active">
-          <span wicket:id="available"/>
-        </div>
-        <div style="position: relative;" id="recent" class="chart tab-pane">
-          <span wicket:id="recent"/>
+    <div class="box box-default box-solid">
+      <div class="box-header with-border">
+        <h3 class="box-title"><wicket:message key="jobs"/></h3>
+        <div class="box-tools pull-right">
+          <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
         </div>
       </div>
+      <div class="box-body">
+        <div class="box-body" wicket:id="tabbedPanel"/>
+      </div>
     </div>
   </wicket:panel>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
index 35dbb2e..273253a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
@@ -20,3 +20,6 @@ scheduled=Scheduled
 start=Start
 message=Message
 end=End
+available=Available
+recent=Recent
+jobs=Jobs

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
index 3738c3c..19a26b9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
@@ -20,3 +20,6 @@ scheduled=Programmato
 start=Inizio
 message=Messaggio
 end=Fine
+available=Disponibili
+recent=Recenti
+jobs=Job

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
index 02411ab..e300f11 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
@@ -20,3 +20,6 @@ scheduled=Programado
 start=Come\u00e7o
 message=Mensagem
 end=Final
+available=Dispon\u00edvel
+recent=Recente
+jobs=Job

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
index d6a4260..8ce2e9f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
-    <div class="box">
+    <div class="box box-default box-solid">
       <div class="box-header with-border">
         <h3 class="box-title"><wicket:message key="systemLoad"/></h3>
         <div class="box-tools pull-right">

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html
new file mode 100644
index 0000000..98550e5
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:panel>
+    <div class="progress-group">
+      <span class="progress-text" wicket:id="text"></span>
+      <span class="progress-number"><b><span wicket:id="fraction"/></b>/<span wicket:id="total"/></span>
+
+      <div class="progress sm">
+        <div wicket:id="progress" class="progress-bar progress-bar-striped"></div>
+      </div>
+    </div>
+  </wicket:panel>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html
new file mode 100644
index 0000000..7aba758
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html
@@ -0,0 +1,24 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:panel>
+    <div class="text-right"><em><wicket:message key="lastUpdateMsg"/>: <span wicket:id="lastUpdate"/></em></div><br/>
+    <span wicket:id="progresses"><span wicket:id="progress"/></span>
+  </wicket:panel>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties
new file mode 100644
index 0000000..41f94c6
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+lastUpdateMsg=Last Update

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties
new file mode 100644
index 0000000..c32f22c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+lastUpdateMsg=Ultimo Aggiornamento

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties
new file mode 100644
index 0000000..878c519
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+lastUpdateMsg=\u00daltima Atualiza\u00e7\u00e3o

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html
new file mode 100644
index 0000000..645039d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html
@@ -0,0 +1,23 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:extend>
+    <div wicket:id="diff"/>
+  </wicket:extend>
+</html>