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 2015/06/10 14:34:36 UTC

[01/27] syncope git commit: [SYNCOPE-156] providing basic layout for realms and administration pages

Repository: syncope
Updated Branches:
  refs/heads/SYNCOPE-666 fbfe9447f -> a45a46bba


http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/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 2fc4487..12af172 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
@@ -56,4 +56,51 @@ pre {
   left:50%;
   margin-left:-75px;
   width:150px;
+}
+
+.block-sidebar {
+  max-height: 100%; 
+  overflow: auto; 
+  padding-top: 90px; 
+  padding-bottom: 50px; 
+  position: fixed;
+}
+
+.inner-control-sidebar {
+  position: fixed; 
+  height: auto;
+}
+
+.content-margin-layout {
+  margin: 0px 230px 0px 0px !important;
+  padding: 20px !important;
+}
+
+.admin-content-page {
+  padding: 20px;
+  background: #ecf0f5
+}
+
+.realms {
+  min-height: 554px
+}
+
+.actions > li > a {
+  padding-top: 5px !important;
+  padding-bottom: 5px !important;
+}
+
+.block-header {
+  position: fixed;
+}
+
+.logo-pos {
+  padding-top: 4px !important;
+  overflow: visible !important;
+}
+
+@media (min-width: 768px) {
+  .main-header .logo {
+    height: 54px;
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/js/AdminLTE-app.min.js
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/js/AdminLTE-app.min.js b/client/console/src/main/resources/META-INF/resources/js/AdminLTE-app.min.js
index 173d6d9..e61cc0f 100644
--- a/client/console/src/main/resources/META-INF/resources/js/AdminLTE-app.min.js
+++ b/client/console/src/main/resources/META-INF/resources/js/AdminLTE-app.min.js
@@ -7,7 +7,7 @@
  * @Author  Almsaeed Studio
  * @Support <http://www.almsaeedstudio.com>
  * @Email   <su...@almsaeedstudio.com>
- * @version 2.0.4
+ * @version 2.1.0
  * @license MIT <http://opensource.org/licenses/MIT>
  */
-"use strict";if("undefined"==typeof jQuery)throw new Error("AdminLTE requires jQuery");$.AdminLTE={},$.AdminLTE.options={navbarMenuSlimscroll:!0,navbarMenuSlimscrollWidth:"3px",navbarMenuHeight:"200px",sidebarToggleSelector:"[data-toggle='offcanvas']",sidebarPushMenu:!0,sidebarSlimScroll:!0,enableBoxRefresh:!0,enableBSToppltip:!0,BSTooltipSelector:"[data-toggle='tooltip']",enableFastclick:!0,enableBoxWidget:!0,boxWidgetOptions:{boxWidgetIcons:{collapse:"fa fa-minus",open:"fa fa-plus",remove:"fa fa-times"},boxWidgetSelectors:{remove:'[data-widget="remove"]',collapse:'[data-widget="collapse"]'}},directChat:{enable:!0,contactToggleSelector:'[data-widget="chat-pane-toggle"]'},colors:{lightBlue:"#3c8dbc",red:"#f56954",green:"#00a65a",aqua:"#00c0ef",yellow:"#f39c12",blue:"#0073b7",navy:"#001F3F",teal:"#39CCCC",olive:"#3D9970",lime:"#01FF70",orange:"#FF851B",fuchsia:"#F012BE",purple:"#8E24AA",maroon:"#D81B60",black:"#222222",gray:"#d2d6de"},screenSizes:{xs:480,sm:768,md:992,lg:1200}},$(fun
 ction(){var a=$.AdminLTE.options;$.AdminLTE.layout.activate(),$.AdminLTE.tree(".sidebar"),a.navbarMenuSlimscroll&&"undefined"!=typeof $.fn.slimscroll&&$(".navbar .menu").slimscroll({height:"200px",alwaysVisible:!1,size:"3px"}).css("width","100%"),a.sidebarPushMenu&&$.AdminLTE.pushMenu(a.sidebarToggleSelector),a.enableBSToppltip&&$(a.BSTooltipSelector).tooltip(),a.enableBoxWidget&&$.AdminLTE.boxWidget.activate(),a.enableFastclick&&"undefined"!=typeof FastClick&&FastClick.attach(document.body),a.directChat.enable&&$(a.directChat.contactToggleSelector).click(function(){var a=$(this).parents(".direct-chat").first();a.toggleClass("direct-chat-contacts-open")}),$('.btn-group[data-toggle="btn-toggle"]').each(function(){var a=$(this);$(this).find(".btn").click(function(b){a.find(".btn.active").removeClass("active"),$(this).addClass("active"),b.preventDefault()})})}),$.AdminLTE.layout={activate:function(){var a=this;a.fix(),a.fixSidebar(),$(window,".wrapper").resize(function(){a.fix(),a.fixS
 idebar()})},fix:function(){var a=$(".main-header").outerHeight()+$(".main-footer").outerHeight(),b=$(window).height(),c=$(".sidebar").height();$("body").hasClass("fixed")?$(".content-wrapper, .right-side").css("min-height",b-$(".main-footer").outerHeight()):b>=c?$(".content-wrapper, .right-side").css("min-height",b-a):$(".content-wrapper, .right-side").css("min-height",c)},fixSidebar:function(){return $("body").hasClass("fixed")?("undefined"==typeof $.fn.slimScroll&&console&&console.error("Error: the fixed layout requires the slimscroll plugin!"),void($.AdminLTE.options.sidebarSlimScroll&&"undefined"!=typeof $.fn.slimScroll&&($(".sidebar").slimScroll({destroy:!0}).height("auto"),$(".sidebar").slimscroll({height:$(window).height()-$(".main-header").height()+"px",color:"rgba(0,0,0,0.2)",size:"3px"})))):void("undefined"!=typeof $.fn.slimScroll&&$(".sidebar").slimScroll({destroy:!0}).height("auto"))}},$.AdminLTE.pushMenu=function(a){var b=this.options.screenSizes;$(a).click(function(a){
 a.preventDefault(),$(window).width()>b.sm-1?$("body").toggleClass("sidebar-collapse"):$("body").hasClass("sidebar-open")?($("body").removeClass("sidebar-open"),$("body").removeClass("sidebar-collapse")):$("body").addClass("sidebar-open")}),$(".content-wrapper").click(function(){$(window).width()<=b.sm-1&&$("body").hasClass("sidebar-open")&&$("body").removeClass("sidebar-open")})},$.AdminLTE.tree=function(a){var b=this;$("li a",$(a)).click(function(a){var c=$(this),d=c.next();if(d.is(".treeview-menu")&&d.is(":visible"))d.slideUp("normal",function(){d.removeClass("menu-open")}),d.parent("li").removeClass("active");else if(d.is(".treeview-menu")&&!d.is(":visible")){var e=c.parents("ul").first(),f=e.find("ul:visible").slideUp("normal");f.removeClass("menu-open");var g=c.parent("li");d.slideDown("normal",function(){d.addClass("menu-open"),e.find("li.active").removeClass("active"),g.addClass("active"),b.layout.fix()})}d.is(".treeview-menu")&&a.preventDefault()})},$.AdminLTE.boxWidget={act
 ivate:function(){var a=$.AdminLTE.options,b=this;$(a.boxWidgetOptions.boxWidgetSelectors.collapse).click(function(a){a.preventDefault(),b.collapse($(this))}),$(a.boxWidgetOptions.boxWidgetSelectors.remove).click(function(a){a.preventDefault(),b.remove($(this))})},collapse:function(a){var b=a.parents(".box").first(),c=b.find(".box-body, .box-footer");b.hasClass("collapsed-box")?(a.children(".fa-plus").removeClass("fa-plus").addClass("fa-minus"),c.slideDown(300,function(){b.removeClass("collapsed-box")})):(a.children(".fa-minus").removeClass("fa-minus").addClass("fa-plus"),c.slideUp(300,function(){b.addClass("collapsed-box")}))},remove:function(a){var b=a.parents(".box").first();b.slideUp()},options:$.AdminLTE.options.boxWidgetOptions},function(a){a.fn.boxRefresh=function(b){function c(a){a.append(f),e.onLoadStart.call(a)}function d(a){a.find(f).remove(),e.onLoadDone.call(a)}var e=a.extend({trigger:".refresh-btn",source:"",onLoadStart:function(){},onLoadDone:function(){}},b),f=a('<div
  class="overlay"><div class="fa fa-refresh fa-spin"></div></div>');return this.each(function(){if(""===e.source)return void(console&&console.log("Please specify a source first - boxRefresh()"));var b=a(this),f=b.find(e.trigger).first();f.click(function(a){a.preventDefault(),c(b),b.find(".box-body").load(e.source,function(){d(b)})})})}}(jQuery),function(a){a.fn.todolist=function(b){var c=a.extend({onCheck:function(){},onUncheck:function(){}},b);return this.each(function(){"undefined"!=typeof a.fn.iCheck?(a("input",this).on("ifChecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onCheck.call(b)}),a("input",this).on("ifUnchecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onUncheck.call(b)})):a("input",this).on("change",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onCheck.call(b)})})}}(jQuery);
\ No newline at end of file
+"use strict";function _init(){$.AdminLTE.layout={activate:function(){var a=this;a.fix(),a.fixSidebar(),$(window,".wrapper").resize(function(){a.fix(),a.fixSidebar()})},fix:function(){var a=$(".main-header").outerHeight()+$(".main-footer").outerHeight(),b=$(window).height(),c=$(".sidebar").height();if($("body").hasClass("fixed"))$(".content-wrapper, .right-side").css("min-height",b-$(".main-footer").outerHeight());else{var d;b>=c?($(".content-wrapper, .right-side").css("min-height",b-a),d=b-a):($(".content-wrapper, .right-side").css("min-height",c),d=c);var e=$($.AdminLTE.options.controlSidebarOptions.selector);"undefined"!=typeof e&&e.height()>d&&$(".content-wrapper, .right-side").css("min-height",e.height())}},fixSidebar:function(){return $("body").hasClass("fixed")?("undefined"==typeof $.fn.slimScroll&&console&&console.error("Error: the fixed layout requires the slimscroll plugin!"),void($.AdminLTE.options.sidebarSlimScroll&&"undefined"!=typeof $.fn.slimScroll&&($(".sidebar").slim
 Scroll({destroy:!0}).height("auto"),$(".sidebar").slimscroll({height:$(window).height()-$(".main-header").height()+"px",color:"rgba(0,0,0,0.2)",size:"3px"})))):void("undefined"!=typeof $.fn.slimScroll&&$(".sidebar").slimScroll({destroy:!0}).height("auto"))}},$.AdminLTE.pushMenu={activate:function(a){var b=$.AdminLTE.options.screenSizes;$(a).on("click",function(a){a.preventDefault(),$(window).width()>b.sm-1?$("body").toggleClass("sidebar-collapse"):$("body").hasClass("sidebar-open")?($("body").removeClass("sidebar-open"),$("body").removeClass("sidebar-collapse")):$("body").addClass("sidebar-open")}),$(".content-wrapper").click(function(){$(window).width()<=b.sm-1&&$("body").hasClass("sidebar-open")&&$("body").removeClass("sidebar-open")}),($.AdminLTE.options.sidebarExpandOnHover||$("body").hasClass("fixed")&&$("body").hasClass("sidebar-mini"))&&this.expandOnHover()},expandOnHover:function(){var a=this,b=$.AdminLTE.options.screenSizes.sm-1;$(".main-sidebar").hover(function(){$("body")
 .hasClass("sidebar-mini")&&$("body").hasClass("sidebar-collapse")&&$(window).width()>b&&a.expand()},function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-expanded-on-hover")&&$(window).width()>b&&a.collapse()})},expand:function(){$("body").removeClass("sidebar-collapse").addClass("sidebar-expanded-on-hover")},collapse:function(){$("body").hasClass("sidebar-expanded-on-hover")&&$("body").removeClass("sidebar-expanded-on-hover").addClass("sidebar-collapse")}},$.AdminLTE.tree=function(a){var b=this;$("li a",$(a)).on("click",function(a){var c=$(this),d=c.next();if(d.is(".treeview-menu")&&d.is(":visible"))d.slideUp("normal",function(){d.removeClass("menu-open")}),d.parent("li").removeClass("active");else if(d.is(".treeview-menu")&&!d.is(":visible")){var e=c.parents("ul").first(),f=e.find("ul:visible").slideUp("normal");f.removeClass("menu-open");var g=c.parent("li");d.slideDown("normal",function(){d.addClass("menu-open"),e.find("li.active").removeClass("active"),g.ad
 dClass("active"),b.layout.fix()})}d.is(".treeview-menu")&&a.preventDefault()})},$.AdminLTE.controlSidebar={activate:function(){var a=this,b=$.AdminLTE.options.controlSidebarOptions,c=$(b.selector),d=$(b.toggleBtnSelector);d.on("click",function(d){d.preventDefault(),c.hasClass("control-sidebar-open")||$("body").hasClass("control-sidebar-open")?a.close(c,b.slide):a.open(c,b.slide)});var e=$(".control-sidebar-bg");a._fix(e),$("body").hasClass("fixed")?a._fixForFixed(c):$(".content-wrapper, .right-side").height()<c.height()&&a._fixForContent(c)},open:function(a,b){b?a.addClass("control-sidebar-open"):$("body").addClass("control-sidebar-open")},close:function(a,b){b?a.removeClass("control-sidebar-open"):$("body").removeClass("control-sidebar-open")},_fix:function(a){var b=this;$("body").hasClass("layout-boxed")?(a.css("position","absolute"),a.height($(".wrapper").height()),$(window).resize(function(){b._fix(a)})):a.css({position:"fixed",height:"auto"})},_fixForFixed:function(a){a.css({po
 sition:"fixed","max-height":"100%",overflow:"auto","padding-bottom":"50px"})},_fixForContent:function(a){$(".content-wrapper, .right-side").css("min-height",a.height())}},$.AdminLTE.boxWidget={selectors:$.AdminLTE.options.boxWidgetOptions.boxWidgetSelectors,icons:$.AdminLTE.options.boxWidgetOptions.boxWidgetIcons,activate:function(){var a=this;$(a.selectors.collapse).on("click",function(b){b.preventDefault(),a.collapse($(this))}),$(a.selectors.remove).on("click",function(b){b.preventDefault(),a.remove($(this))})},collapse:function(a){var b=this,c=a.parents(".box").first(),d=c.find("> .box-body, > .box-footer");c.hasClass("collapsed-box")?(a.children(":first").removeClass(b.icons.open).addClass(b.icons.collapse),d.slideDown(300,function(){c.removeClass("collapsed-box")})):(a.children(":first").removeClass(b.icons.collapse).addClass(b.icons.open),d.slideUp(300,function(){c.addClass("collapsed-box")}))},remove:function(a){var b=a.parents(".box").first();b.slideUp()}}}if("undefined"==ty
 peof jQuery)throw new Error("AdminLTE requires jQuery");$.AdminLTE={},$.AdminLTE.options={navbarMenuSlimscroll:!0,navbarMenuSlimscrollWidth:"3px",navbarMenuHeight:"200px",sidebarToggleSelector:"[data-toggle='offcanvas']",sidebarPushMenu:!0,sidebarSlimScroll:!0,sidebarExpandOnHover:!1,enableBoxRefresh:!0,enableBSToppltip:!0,BSTooltipSelector:"[data-toggle='tooltip']",enableFastclick:!0,enableControlSidebar:!0,controlSidebarOptions:{toggleBtnSelector:"[data-toggle='control-sidebar']",selector:".control-sidebar",slide:!0},enableBoxWidget:!0,boxWidgetOptions:{boxWidgetIcons:{collapse:"fa-minus",open:"fa-plus",remove:"fa-times"},boxWidgetSelectors:{remove:'[data-widget="remove"]',collapse:'[data-widget="collapse"]'}},directChat:{enable:!0,contactToggleSelector:'[data-widget="chat-pane-toggle"]'},colors:{lightBlue:"#3c8dbc",red:"#f56954",green:"#00a65a",aqua:"#00c0ef",yellow:"#f39c12",blue:"#0073b7",navy:"#001F3F",teal:"#39CCCC",olive:"#3D9970",lime:"#01FF70",orange:"#FF851B",fuchsia:"#F0
 12BE",purple:"#8E24AA",maroon:"#D81B60",black:"#222222",gray:"#d2d6de"},screenSizes:{xs:480,sm:768,md:992,lg:1200}},$(function(){"undefined"!=typeof AdminLTEOptions&&$.extend(!0,$.AdminLTE.options,AdminLTEOptions);var a=$.AdminLTE.options;_init(),$.AdminLTE.layout.activate(),$.AdminLTE.tree(".sidebar"),a.enableControlSidebar&&$.AdminLTE.controlSidebar.activate(),a.navbarMenuSlimscroll&&"undefined"!=typeof $.fn.slimscroll&&$(".navbar .menu").slimscroll({height:a.navbarMenuHeight,alwaysVisible:!1,size:a.navbarMenuSlimscrollWidth}).css("width","100%"),a.sidebarPushMenu&&$.AdminLTE.pushMenu.activate(a.sidebarToggleSelector),a.enableBSToppltip&&$("body").tooltip({selector:a.BSTooltipSelector}),a.enableBoxWidget&&$.AdminLTE.boxWidget.activate(),a.enableFastclick&&"undefined"!=typeof FastClick&&FastClick.attach(document.body),a.directChat.enable&&$(a.directChat.contactToggleSelector).on("click",function(){var a=$(this).parents(".direct-chat").first();a.toggleClass("direct-chat-contacts-ope
 n")}),$('.btn-group[data-toggle="btn-toggle"]').each(function(){var a=$(this);$(this).find(".btn").on("click",function(b){a.find(".btn.active").removeClass("active"),$(this).addClass("active"),b.preventDefault()})})}),function(a){a.fn.boxRefresh=function(b){function c(a){a.append(f),e.onLoadStart.call(a)}function d(a){a.find(f).remove(),e.onLoadDone.call(a)}var e=a.extend({trigger:".refresh-btn",source:"",onLoadStart:function(a){},onLoadDone:function(a){}},b),f=a('<div class="overlay"><div class="fa fa-refresh fa-spin"></div></div>');return this.each(function(){if(""===e.source)return void(console&&console.log("Please specify a source first - boxRefresh()"));var b=a(this),f=b.find(e.trigger).first();f.on("click",function(a){a.preventDefault(),c(b),b.find(".box-body").load(e.source,function(){d(b)})})})}}(jQuery),function(a){a.fn.todolist=function(b){var c=a.extend({onCheck:function(a){},onUncheck:function(a){}},b);return this.each(function(){"undefined"!=typeof a.fn.iCheck?(a("input
 ",this).on("ifChecked",function(b){var d=a(this).parents("li").first();d.toggleClass("done"),c.onCheck.call(d)}),a("input",this).on("ifUnchecked",function(b){var d=a(this).parents("li").first();d.toggleClass("done"),c.onUncheck.call(d)})):a("input",this).on("change",function(b){var d=a(this).parents("li").first();d.toggleClass("done"),c.onCheck.call(d)})})}}(jQuery);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
index f640006..66fcc75 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
@@ -51,8 +51,8 @@ under the License.
 
     <div class="wrapper">
 
-      <header class="main-header">
-        <div class="logo">
+      <header class="main-header block-pos">
+        <div class="logo logo-pos">
           <img src="img/logo.png"/>
         </div>
 
@@ -96,12 +96,11 @@ under the License.
         </nav>
       </header>
 
-      <aside class="main-sidebar">
+      <aside class="main-sidebar block-sidebar">
         <section class="sidebar">
           <ul class="sidebar-menu">
-            <li class="header">&nbsp;</li>
             <li wicket:id="dashboardLI"><a href="#" wicket:id="dashboard"><i class="fa fa-dashboard"></i><span>Dashboard</span></a></li>
-            <li><a href="#"><i class="fa fa-users"></i><span>Realms</span></a></li>
+            <li wicket:id="realmsLI"><a href="#" wicket:id="realms"><i class="fa fa-users"></i><span>Realms</span></a></li>
             <li><a href="#"><i class="fa fa-th"></i><span>Resources</span></a></li>
             <li><a href="#"><i class="fa fa-pie-chart"></i><span>Reports</span></a></li>
             <li wicket:id="configurationLI" class="treeview">

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/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
new file mode 100644
index 0000000..ab26a9e
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<!--
+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://xmlns.jcp.org/jsf/composite">
+  <wicket:extend>
+
+    <div class="wrapper">
+      <div class="admin-content-page content-margin-layout">
+        <div class="box box-solid box-primary">
+          <div class="box-header with-border">
+            <h3 class="box-title">Realm 5</h3>
+            <div class="box-tools pull-right">
+              <ul class="nav navbar-nav actions">
+                <li><a href="#"><i class="fa fa-plus"></i></a></li>
+                <li><a href="#"><i class="fa fa-minus"></i></a></li>
+                <li><a href="#"><i class="fa fa-pencil-square-o"></i></a></li>
+              </ul>
+            </div><!-- /.box-tools -->
+          </div><!-- /.box-header -->
+          <div class="box-body">
+            <div class="realms">body</div>
+          </div>
+        </div>
+      </div>
+
+      <!-- The Right Sidebar -->
+      <aside class="control-sidebar control-sidebar-dark control-sidebar-open block-sidebar">
+        <section class="sidebar">
+          <ul class="sidebar-menu">
+            <li><a href="#"><i class="fa fa-dashboard"></i><span>Realm 1</span></a></li>
+            <li><a href="#"><i class="fa fa-users"></i><span>Realm 2</span></a></li>
+            <li><a href="#"><i class="fa fa-th"></i><span>Realm 3</span></a></li>
+            <li><a href="#"><i class="fa fa-pie-chart"></i><span>Realm 4</span></a></li>
+            <li class="treeview">
+              <a href="#"><i class="fa fa-edit"></i><span>Realm 5</span> <i class="fa fa-angle-left pull-right"></i></a>
+              <ul class="treeview-menu">
+                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.1</a></li>
+                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.2</a></li>
+                <li class="treeview">
+                  <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3</span> <i class="fa fa-angle-left pull-right"></i></a>
+                  <ul class="treeview-menu">
+                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.1</a></li>
+                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2</a></li>
+                    <li class="treeview">
+                      <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2</span> <i class="fa fa-angle-left pull-right"></i></a>
+                      <ul class="treeview-menu">
+                        <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.1</a></li>
+                        <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.2</a></li>
+                        <li class="treeview">
+                          <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2.3</span> <i class="fa fa-angle-left pull-right"></i></a>
+                          <ul class="treeview-menu">
+                            <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.1</a></li>
+                            <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.2</a></li>
+                            <li class="treeview">
+                              <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2.3.3</span> <i class="fa fa-angle-left pull-right"></i></a>
+                              <ul class="treeview-menu">
+                                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.1</a></li>
+                                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.2</a></li>
+                                <li class="treeview">
+                                  <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2.3.3.3</span> <i class="fa fa-angle-left pull-right"></i></a>
+                                  <ul class="treeview-menu">
+                                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.3.1</a></li>
+                                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.3.2</a></li>
+                                  </ul>
+                                </li>
+                              </ul>
+                            </li>
+                          </ul>
+                        </li>
+                      </ul>
+                    </li>
+                  </ul>
+                </li>
+                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.4</a></li>
+                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.5</a></li>
+                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.6</a></li>
+                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.7</a></li>
+              </ul>
+            </li>
+            <li class="treeview">
+              <a href="#"><i class="fa fa-laptop"></i><span>Realm 6</span> <i class="fa fa-angle-left pull-right"></i></a>
+              <ul class="treeview-menu">
+                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 6.1</a></li>
+              </ul>
+            </li>
+          </ul>
+        </section>
+      </aside>
+      <!-- The sidebar's background -->
+      <!-- This div must placed right after the sidebar for it to work-->
+      <div class="control-sidebar-bg inner-control-sidebar"></div>
+    </div>
+
+  </wicket:extend>
+</html>
\ No newline at end of file


[12/27] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/SYNCOPE-666
Commit: eb5915fac91b9b448dc3bfff47f52af9b43e5c56
Parents: 6edda65 a6bcbd4
Author: fmartelli <fa...@gmail.com>
Authored: Mon Jun 8 22:21:14 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Jun 8 22:21:14 2015 +0200

----------------------------------------------------------------------
 .../provisioning/api/notification/NotificationManager.java   | 4 +++-
 .../java/notification/NotificationManagerImpl.java           | 8 ++++++--
 pom.xml                                                      | 6 +++---
 3 files changed, 12 insertions(+), 6 deletions(-)
----------------------------------------------------------------------



[09/27] syncope git commit: Upgrading AspectJ

Posted by il...@apache.org.
Upgrading AspectJ


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

Branch: refs/heads/SYNCOPE-666
Commit: bcf3b4335a06967abcc2cc8db63d787decb66fad
Parents: 37a4bcc
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jun 8 14:46:43 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jun 8 14:46:43 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/bcf3b433/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7b5b361..a32149c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -341,7 +341,7 @@ under the License.
 
     <activiti.version>5.16.4</activiti.version>
 
-    <aspectj.version>1.8.5</aspectj.version>
+    <aspectj.version>1.8.6</aspectj.version>
 
     <cxf.version>3.0.5</cxf.version>	
     <spring.version>4.0.9.RELEASE</spring.version>


[11/27] syncope git commit: Merge branch 'master' into SYNCOPE-666

Posted by il...@apache.org.
Merge branch 'master' into SYNCOPE-666


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

Branch: refs/heads/SYNCOPE-666
Commit: a8a40639d59ca79fccc321f514aaab5a8ec9973b
Parents: fbfe944 a6bcbd4
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jun 8 15:19:10 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jun 8 15:19:10 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a8a40639/pom.xml
----------------------------------------------------------------------


[27/27] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
[SYNCOPE-666] Any* tests added


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

Branch: refs/heads/SYNCOPE-666
Commit: a45a46bba7186ef43b4877482d636901bc40cbc5
Parents: 46aaa9e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jun 10 14:33:59 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jun 10 14:33:59 2015 +0200

----------------------------------------------------------------------
 .../client/console/commons/AnyDataProvider.java | 101 ++++
 .../commons/AttributableDataProvider.java       | 103 ----
 .../console/pages/BulkActionModalPage.java      |   8 +-
 .../pages/BulkActionResultModalPage.java        |   8 +-
 .../console/pages/ProvisioningModalPage.java    |  38 +-
 .../client/console/pages/ResourceModalPage.java |  52 +-
 .../panels/AbstractSearchResultPanel.java       |  22 +-
 .../console/panels/AjaxDataTablePanel.java      |   4 +-
 .../console/panels/AnnotatedBeanPanel.java      |   4 +-
 .../console/panels/ResourceConnConfPanel.java   |  18 +-
 .../console/panels/ResourceDetailsPanel.java    |  10 +-
 .../console/panels/ResourceMappingPanel.java    | 228 +++++----
 .../client/console/panels/Resources.java        | 485 -------------------
 .../console/rest/ConnectorRestClient.java       |   6 +-
 .../client/console/rest/GroupRestClient.java    |  47 +-
 .../client/console/rest/UserRestClient.java     |  48 +-
 .../repeater/data/table/ActionResultColumn.java |  17 +-
 .../console/pages/ResourceModalPage.properties  |   6 +-
 .../pages/ResourceModalPage_it.properties       |   6 +-
 .../pages/ResourceModalPage_pt_BR.properties    |   6 +-
 .../console/panels/ResourceMappingPanel.html    |  14 +-
 .../client/console/panels/Resources.html        |  52 --
 .../client/console/panels/Resources.properties  |  34 --
 .../console/panels/Resources_it.properties      |  34 --
 .../console/panels/Resources_pt_BR.properties   |  32 --
 .../syncope/client/lib/SyncopeClient.java       |  13 +-
 .../lib/builders/AnyListQueryBuilder.java       |   1 +
 .../apache/syncope/common/lib/mod/AnyMod.java   |   2 +
 .../AbstractFiqlSearchConditionBuilder.java     |   1 +
 .../AnyObjectFiqlSearchConditionBuilder.java    |  71 +++
 .../common/lib/search/AnyObjectProperty.java    |  23 +
 .../syncope/common/lib/search/SpecialAttr.java  |   1 +
 .../common/lib/to/ConnIdObjectClassTO.java      |  74 ---
 .../apache/syncope/common/lib/to/MappingTO.java |   2 +-
 .../common/lib/types/IntMappingType.java        |  18 +-
 .../common/lib/wrap/ConnIdObjectClass.java      |  30 ++
 .../rest/api/service/AnyObjectService.java      |  49 ++
 .../common/rest/api/service/AnyService.java     | 191 ++++++++
 .../rest/api/service/ConnectorService.java      |   4 +-
 .../common/rest/api/service/GroupService.java   | 158 +-----
 .../common/rest/api/service/UserService.java    | 160 +-----
 .../syncope/core/logic/AbstractAnyLogic.java    |  16 +-
 .../syncope/core/logic/AnyObjectLogic.java      |  27 +-
 .../apache/syncope/core/logic/AnyTypeLogic.java |  10 +-
 .../apache/syncope/core/logic/GroupLogic.java   |   1 +
 .../apache/syncope/core/logic/UserLogic.java    |   6 +
 .../syncope/core/misc/ConnObjectUtils.java      |   5 +
 .../apache/syncope/core/misc/MappingUtils.java  |  14 +-
 .../core/misc/search/SearchCondVisitor.java     |   7 +
 .../misc/search/SearchCondConverterTest.java    |  14 +
 .../core/persistence/api/dao/AnyObjectDAO.java  |   8 +-
 .../persistence/api/dao/search/AnyTypeCond.java |  40 ++
 .../persistence/api/dao/search/SearchCond.java  |  22 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |  24 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |  22 +
 .../persistence/jpa/entity/JPAAnyUtils.java     |   6 +-
 .../jpa/entity/resource/JPAMapping.java         |   2 +-
 .../jpa/entity/resource/JPAMappingItem.java     |   2 +-
 .../persistence/jpa/entity/AnyObjectTest.java   |  10 +
 .../persistence/jpa/entity/AnySearchTest.java   |  24 +-
 .../persistence/jpa/entity/AnyTypeTest.java     |   8 +-
 .../persistence/jpa/entity/PlainSchemaTest.java |   2 +-
 .../persistence/jpa/entity/ResourceTest.java    |   4 +-
 .../core/persistence/jpa/entity/TaskTest.java   |   2 +-
 .../persistence/jpa/relationship/GroupTest.java |  16 +-
 .../jpa/relationship/PlainSchemaTest.java       |  12 +-
 .../persistence/jpa/relationship/RoleTest.java  |   2 +-
 .../src/test/resources/content.xml              |  70 ++-
 .../provisioning/java/ConnectorFacadeProxy.java |  35 +-
 .../provisioning/java/VirAttrHandlerImpl.java   |   2 +-
 .../java/data/AbstractAnyDataBinder.java        |   2 +-
 .../java/data/AnyObjectDataBinderImpl.java      |  16 +
 .../propagation/PropagationManagerImpl.java     |   1 +
 .../provisioning/java/sync/SyncJobImpl.java     |  39 +-
 .../core/provisioning/java/sync/SyncUtils.java  |   6 +-
 .../rest/cxf/service/AbstractAnyService.java    | 290 +++++++++++
 .../rest/cxf/service/AnyObjectServiceImpl.java  |  71 +++
 .../rest/cxf/service/ConnectorServiceImpl.java  |  12 +-
 .../core/rest/cxf/service/GroupServiceImpl.java | 205 +-------
 .../core/rest/cxf/service/UserServiceImpl.java  | 259 +---------
 .../core/logic/init/CamelRouteLoader.java       |   4 +
 .../CamelAnyObjectProvisioningManager.java      | 163 +++++++
 .../processor/AnyObjectCreateProcessor.java     |  71 +++
 .../processor/AnyObjectDeleteProcessor.java     |  83 ++++
 .../AnyObjectDeprovisionProcessor.java          |  78 +++
 .../processor/AnyObjectUpdateProcessor.java     |  90 ++++
 .../src/main/resources/anyObjectRoutes.xml      | 121 +++++
 .../src/main/resources/provisioning.properties  |   2 +-
 .../main/resources/provisioningCamelContext.xml |   6 +-
 fit/build-tools/pom.xml                         |  10 +-
 .../fit/buildtools/ConnIdStartStopListener.java |   3 +-
 .../src/main/resources/buildToolsContext.xml    |   7 +-
 fit/build-tools/src/main/resources/testdb.sql   |   8 +-
 .../src/main/resources/connid.properties        |   2 +-
 .../resources/scriptedsql/CreateScript.groovy   |  52 ++
 .../resources/scriptedsql/DeleteScript.groovy   |  43 ++
 .../resources/scriptedsql/SchemaScript.groovy   |  50 ++
 .../resources/scriptedsql/SearchScript.groovy   |  94 ++++
 .../resources/scriptedsql/SyncScript.groovy     |  98 ++++
 .../resources/scriptedsql/TestScript.groovy     |  31 ++
 .../resources/scriptedsql/UpdateScript.groovy   |  67 +++
 .../fit/core/reference/AbstractITCase.java      |  35 +-
 .../fit/core/reference/AnyObjectITCase.java     | 126 +++++
 .../fit/core/reference/AnyTypeClassITCase.java  | 117 +++++
 .../fit/core/reference/AnyTypeITCase.java       | 169 +++++++
 .../fit/core/reference/ConnectorITCase.java     |  15 +-
 .../syncope/fit/core/reference/GroupITCase.java |  24 +-
 .../fit/core/reference/SearchITCase.java        |  93 ++--
 .../fit/core/reference/SyncTaskITCase.java      |  45 ++
 .../syncope/fit/core/reference/UserITCase.java  |   4 +-
 pom.xml                                         |  11 +-
 111 files changed, 3166 insertions(+), 2051 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
new file mode 100644
index 0000000..bd4183b
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
@@ -0,0 +1,101 @@
+/*
+ * 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.commons;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+
+public class AnyDataProvider extends SortableDataProvider<AnyTO, String> {
+
+    private static final long serialVersionUID = 6267494272884913376L;
+
+    private final SortableAnyProviderComparator comparator;
+
+    private String fiql = null;
+
+    private final int paginatorRows;
+
+    private final boolean filtered;
+
+    private final AbstractAnyRestClient restClient;
+
+    private final String realm = "/";
+
+    public AnyDataProvider(final AbstractAnyRestClient restClient, final int paginatorRows, final boolean filtered) {
+        super();
+
+        this.restClient = restClient;
+        this.filtered = filtered;
+        this.paginatorRows = paginatorRows;
+
+        // default sorting
+        setSort("key", SortOrder.ASCENDING);
+
+        this.comparator = new SortableAnyProviderComparator(this);
+    }
+
+    public void setFIQL(final String fiql) {
+        this.fiql = fiql;
+    }
+
+    @Override
+    public Iterator<? extends AnyTO> iterator(final long first, final long count) {
+        List<? extends AnyTO> result;
+
+        final int page = ((int) first / paginatorRows);
+
+        if (filtered) {
+            result = fiql == null
+                    ? Collections.<AnyTO>emptyList()
+                    : restClient.search(realm, fiql, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
+        } else {
+            result = restClient.list(realm, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
+        }
+
+        Collections.sort(result, comparator);
+        return result.iterator();
+    }
+
+    @Override
+    public long size() {
+        long result;
+
+        if (filtered) {
+            result = fiql == null
+                    ? 0
+                    : restClient.searchCount(realm, fiql);
+        } else {
+            result = restClient.count(realm);
+        }
+
+        return result;
+    }
+
+    @Override
+    public IModel<AnyTO> model(final AnyTO object) {
+        return new CompoundPropertyModel<>(object);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
deleted file mode 100644
index 1890a80..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
+++ /dev/null
@@ -1,103 +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.commons;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.IModel;
-
-public class AttributableDataProvider extends SortableDataProvider<AbstractAttributableTO, String> {
-
-    private static final long serialVersionUID = 6267494272884913376L;
-
-    private final SortableAttributableProviderComparator comparator;
-
-    private String fiql = null;
-
-    private final int paginatorRows;
-
-    private final boolean filtered;
-
-    private final AbstractSubjectRestClient restClient;
-
-    private final String realm = "/";
-
-    public AttributableDataProvider(final AbstractSubjectRestClient restClient,
-            final int paginatorRows, final boolean filtered) {
-
-        super();
-
-        this.restClient = restClient;
-        this.filtered = filtered;
-        this.paginatorRows = paginatorRows;
-
-        // default sorting
-        setSort("key", SortOrder.ASCENDING);
-
-        this.comparator = new SortableAttributableProviderComparator(this);
-    }
-
-    public void setFIQL(final String fiql) {
-        this.fiql = fiql;
-    }
-
-    @Override
-    public Iterator<? extends AbstractAttributableTO> iterator(final long first, final long count) {
-        List<? extends AbstractAttributableTO> result;
-
-        final int page = ((int) first / paginatorRows);
-
-        if (filtered) {
-            result = fiql == null
-                    ? Collections.<AbstractAttributableTO>emptyList()
-                    : restClient.search(realm, fiql, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
-        } else {
-            result = restClient.list(realm, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
-        }
-
-        Collections.sort(result, comparator);
-        return result.iterator();
-    }
-
-    @Override
-    public long size() {
-        long result;
-
-        if (filtered) {
-            result = fiql == null
-                    ? 0
-                    : restClient.searchCount(realm, fiql);
-        } else {
-            result = restClient.count(realm);
-        }
-
-        return result;
-    }
-
-    @Override
-    public IModel<AbstractAttributableTO> model(final AbstractAttributableTO object) {
-        return new CompoundPropertyModel<>(object);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
index 65dfa58..5567094 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
@@ -53,7 +53,7 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
             final List<IColumn<T, S>> columns,
             final Collection<ActionLink.ActionType> actions,
             final BaseRestClient bulkActionExecutor,
-            final String idFieldName,
+            final String keyFieldName,
             final String pageId) {
 
         super();
@@ -92,9 +92,9 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
             final BulkAction bulkAction = new BulkAction();
             for (T item : items) {
                 try {
-                    bulkAction.getTargets().add(getTargetId(item, idFieldName).toString());
+                    bulkAction.getTargets().add(getTargetId(item, keyFieldName).toString());
                 } catch (IllegalAccessException | InvocationTargetException e) {
-                    LOG.error("Error retrieving item id {}", idFieldName, e);
+                    LOG.error("Error retrieving item id {}", keyFieldName, e);
                 }
             }
 
@@ -128,7 +128,7 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
                         final BulkActionResult res = (BulkActionResult) bulkActionExecutor.getClass().
                                 getMethod("bulkAction", BulkAction.class).invoke(bulkActionExecutor, bulkAction);
 
-                        setResponsePage(new BulkActionResultModalPage<>(window, items, columns, res, idFieldName));
+                        setResponsePage(new BulkActionResultModalPage<>(window, items, columns, res, keyFieldName));
                     } catch (NoSuchMethodException | SecurityException | IllegalAccessException 
                             | IllegalArgumentException | InvocationTargetException e) {
                         error(getString(Constants.ERROR)

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
index 72a789f..98ac15c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
@@ -36,14 +36,12 @@ import org.apache.wicket.model.IModel;
 
 /**
  * Show user or group status after performing a successful operation.
+ *
  * @param <T>
  * @param <S>
  */
 public class BulkActionResultModalPage<T, S> extends BaseModalPage {
 
-    /**
-     * Serial version id.
-     */
     private static final long serialVersionUID = 2646115294319713724L;
 
     public BulkActionResultModalPage(
@@ -51,12 +49,12 @@ public class BulkActionResultModalPage<T, S> extends BaseModalPage {
             final Collection<T> items,
             final List<IColumn<T, S>> columns,
             final BulkActionResult results,
-            final String idFieldName) {
+            final String keyFieldName) {
 
         super();
 
         final List<IColumn<T, S>> newColumnList = new ArrayList<>(columns.subList(1, columns.size() - 1));
-        newColumnList.add(newColumnList.size(), new ActionResultColumn<T, S>(results, idFieldName));
+        newColumnList.add(newColumnList.size(), new ActionResultColumn<T, S>(results, keyFieldName));
 
         final SortableDataProvider<T, S> dataProvider = new SortableDataProvider<T, S>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
index af1d0b5..6f56bbb 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
@@ -31,15 +31,13 @@ import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.console.panels.ActionDataTablePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.AbstractWrappable;
-import org.apache.syncope.common.lib.wrap.SubjectKey;
+import org.apache.syncope.common.lib.wrap.AnyKey;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
@@ -54,7 +52,7 @@ import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.StringResourceModel;
 
-public class ProvisioningModalPage<T extends AbstractAttributableTO> extends AbstractStatusModalPage {
+public class ProvisioningModalPage<T extends AnyTO> extends AbstractStatusModalPage {
 
     private static final long serialVersionUID = -4285220460543213901L;
 
@@ -62,7 +60,7 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
 
     private final ResourceTO resourceTO;
 
-    private final Class<? extends AbstractAttributableTO> typeRef;
+    private final AnyTypeKind anyTypeKind;
 
     private final PageReference pageRef;
 
@@ -76,16 +74,16 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             final PageReference pageRef,
             final ModalWindow window,
             final ResourceTO resourceTO,
-            final Class<T> typeRef) {
+            final AnyTypeKind anyTypeKind) {
 
         super();
 
         this.pageRef = pageRef;
         this.window = window;
         this.resourceTO = resourceTO;
-        this.typeRef = typeRef;
+        this.anyTypeKind = anyTypeKind;
 
-        statusUtils = new StatusUtils((UserTO.class.isAssignableFrom(typeRef) ? userRestClient : groupRestClient));
+        statusUtils = new StatusUtils(anyTypeKind == AnyTypeKind.USER ? userRestClient : groupRestClient);
 
         add(new Label("displayName", StringUtils.EMPTY));
 
@@ -100,8 +98,8 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
                 new StringResourceModel("resourceName", this, null, "Resource name"),
                 "resourceName", "resourceName"));
         columns.add(new PropertyColumn<StatusBean, String>(
-                new StringResourceModel("accountLink", this, null, "Account link"),
-                "accountLink", "accountLink"));
+                new StringResourceModel("connObjectLink", this, null, "ConnObjectLink"),
+                "connObjectLink", "connObjectLink"));
         columns.add(new AbstractColumn<StatusBean, String>(
                 new StringResourceModel("status", this, null, "")) {
 
@@ -198,7 +196,7 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             final String fiql = SyncopeClient.getUserSearchConditionBuilder().hasResources(resourceTO.getKey()).query();
 
             final List<T> subjects = new ArrayList<>();
-            if (UserTO.class.isAssignableFrom(typeRef)) {
+            if (anyTypeKind == AnyTypeKind.USER) {
                 subjects.addAll((List<T>) userRestClient.search(
                         realm, fiql, 1, ROWS_PER_PAGE, new SortParam<>("key", true)));
             } else {
@@ -207,16 +205,16 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             }
 
             final List<ConnObjectWrapper> connObjects = statusUtils.getConnectorObjects(
-                    (List<AbstractSubjectTO>) subjects, Collections.<String>singleton(resourceTO.getKey()));
+                    (List<AnyTO>) subjects, Collections.<String>singleton(resourceTO.getKey()));
 
             final List<StatusBean> statusBeans = new ArrayList<>(connObjects.size() + 1);
             final LinkedHashMap<String, StatusBean> initialStatusBeanMap = new LinkedHashMap<>(connObjects.size());
 
             for (ConnObjectWrapper entry : connObjects) {
-                final StatusBean statusBean = statusUtils.getStatusBean(entry.getAttributable(),
+                StatusBean statusBean = statusUtils.getStatusBean(entry.getAny(),
                         entry.getResourceName(),
                         entry.getConnObjectTO(),
-                        GroupTO.class.isAssignableFrom(typeRef));
+                        anyTypeKind == AnyTypeKind.GROUP);
 
                 initialStatusBeanMap.put(entry.getResourceName(), statusBean);
                 statusBeans.add(statusBean);
@@ -233,21 +231,21 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             final List<IColumn<StatusBean, String>> columns) {
 
         final List<StatusBean> beans = new ArrayList<>(table.getModelObject());
-        List<SubjectKey> subjectKeys = new ArrayList<>();
+        List<AnyKey> subjectKeys = new ArrayList<>();
         for (StatusBean bean : beans) {
             LOG.debug("Selected bean {}", bean);
-            subjectKeys.add(AbstractWrappable.getInstance(SubjectKey.class, bean.getAttributableId()));
+            subjectKeys.add(AbstractWrappable.getInstance(AnyKey.class, bean.getAnyKey()));
         }
 
         if (beans.isEmpty()) {
             window.close(target);
         } else {
             final BulkActionResult res = resourceRestClient.bulkAssociationAction(
-                    resourceTO.getKey(), typeRef, type, subjectKeys);
+                    resourceTO.getKey(), anyTypeKind.name(), type, subjectKeys);
 
             ((BasePage) pageRef.getPage()).setModalResult(true);
 
-            setResponsePage(new BulkActionResultModalPage<>(window, beans, columns, res, "attributableKey"));
+            setResponsePage(new BulkActionResultModalPage<>(window, beans, columns, res, "anyKey"));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
index aa9dbfc..e578255 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.AnnotatedBeanPanel;
 import org.apache.syncope.client.console.panels.ResourceConnConfPanel;
@@ -25,8 +27,9 @@ import org.apache.syncope.client.console.panels.ResourceDetailsPanel;
 import org.apache.syncope.client.console.panels.ResourceMappingPanel;
 import org.apache.syncope.client.console.panels.ResourceSecurityPanel;
 import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -66,8 +69,8 @@ public class ResourceModalPage extends BaseModalPage {
         //--------------------------------
         // Resource mapping panels
         //--------------------------------
-        form.add(new ResourceMappingPanel("umapping", resourceTO, AttributableType.USER));
-        form.add(new ResourceMappingPanel("gmapping", resourceTO, AttributableType.GROUP));
+        form.add(new ResourceMappingPanel("umapping", resourceTO, AnyTypeKind.USER));
+        form.add(new ResourceMappingPanel("gmapping", resourceTO, AnyTypeKind.GROUP));
         //--------------------------------
 
         //--------------------------------
@@ -84,7 +87,7 @@ public class ResourceModalPage extends BaseModalPage {
         form.add(new ResourceSecurityPanel("security", resourceTO));
         //--------------------------------
 
-        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
+        AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
 
             private static final long serialVersionUID = -958724007591692537L;
 
@@ -92,34 +95,29 @@ public class ResourceModalPage extends BaseModalPage {
             protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
                 final ResourceTO resourceTO = (ResourceTO) form.getDefaultModelObject();
 
-                boolean accountIdError = false;
+                boolean connObjectKeyError = false;
 
-                if (resourceTO.getUmapping() == null || resourceTO.getUmapping().getItems().isEmpty()) {
-                    resourceTO.setUmapping(null);
-                } else {
-                    int uAccountIdCount = 0;
-                    for (MappingItemTO item : resourceTO.getUmapping().getItems()) {
-                        if (item.isAccountid()) {
-                            uAccountIdCount++;
-                        }
-                    }
-                    accountIdError = uAccountIdCount != 1;
-                }
+                for (ProvisionTO provision : resourceTO.getProvisions()) {
+                    if (provision != null) {
+                        if (provision.getMapping() == null || provision.getMapping().getItems().isEmpty()) {
+                            resourceTO.getProvisions().remove(provision);
+                        } else {
+                            int uConnObjectKeyCount = CollectionUtils.countMatches(
+                                    provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
 
-                if (resourceTO.getGmapping() == null || resourceTO.getGmapping().getItems().isEmpty()) {
-                    resourceTO.setGmapping(null);
-                } else {
-                    int rAccountIdCount = 0;
-                    for (MappingItemTO item : resourceTO.getGmapping().getItems()) {
-                        if (item.isAccountid()) {
-                            rAccountIdCount++;
+                                        @Override
+                                        public boolean evaluate(final MappingItemTO item) {
+                                            return item.isConnObjectKey();
+                                        }
+                                    });
+
+                            connObjectKeyError = uConnObjectKeyCount != 1;
                         }
                     }
-                    accountIdError |= rAccountIdCount != 1;
                 }
 
-                if (accountIdError) {
-                    error(getString("accountIdValidation"));
+                if (connObjectKeyError) {
+                    error(getString("connObjectKeyValidation"));
                     feedbackPanel.refresh(target);
                 } else {
                     try {
@@ -142,6 +140,7 @@ public class ResourceModalPage extends BaseModalPage {
             }
 
             @Override
+
             protected void onError(final AjaxRequestTarget target, final Form<?> form) {
                 feedbackPanel.refresh(target);
             }
@@ -171,6 +170,7 @@ public class ResourceModalPage extends BaseModalPage {
 
         MetaDataRoleAuthorizationStrategy.authorize(
                 submit, ENABLE, createFlag ? Entitlement.RESOURCE_CREATE : Entitlement.RESOURCE_UPDATE);
+
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
index 0af8a0b..20f62d5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -21,12 +21,12 @@ package org.apache.syncope.client.console.panels;
 import java.util.Collection;
 import java.util.List;
 import org.apache.syncope.client.console.PreferenceManager;
-import org.apache.syncope.client.console.commons.AttributableDataProvider;
+import org.apache.syncope.client.console.commons.AnyDataProvider;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.AbstractBasePage;
-import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
@@ -89,7 +89,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
     @SpringBean
     protected PreferenceManager prefMan;
 
-    protected final AbstractSubjectRestClient restClient;
+    protected final AbstractAnyRestClient restClient;
 
     /**
      * Number of rows per page.
@@ -120,12 +120,12 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
     /**
      * Result table.
      */
-    private AjaxDataTablePanel<AbstractAttributableTO, String> resultTable;
+    private AjaxDataTablePanel<AnyTO, String> resultTable;
 
     /**
      * Data provider used to search for users.
      */
-    private AttributableDataProvider dataProvider;
+    private AnyDataProvider dataProvider;
 
     /**
      * Modal window to be used for user profile editing. Global visibility is required ...
@@ -147,8 +147,8 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
      */
     protected final AbstractBasePage page;
 
-    protected <T extends AbstractAttributableTO> AbstractSearchResultPanel(final String id, final boolean filtered,
-            final String fiql, final PageReference pageRef, final AbstractSubjectRestClient restClient) {
+    protected <T extends AnyTO> AbstractSearchResultPanel(final String id, final boolean filtered,
+            final String fiql, final PageReference pageRef, final AbstractAnyRestClient restClient) {
 
         super(id);
 
@@ -238,7 +238,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
     }
 
     private void updateResultTable(final boolean create, final int rows) {
-        dataProvider = new AttributableDataProvider(restClient, rows, filtered);
+        dataProvider = new AnyDataProvider(restClient, rows, filtered);
         dataProvider.setFIQL(fiql);
 
         final int currentPage = resultTable != null
@@ -265,7 +265,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
         container.addOrReplace(resultTable);
     }
 
-    protected abstract List<IColumn<AbstractAttributableTO, String>> getColumns();
+    protected abstract List<IColumn<AnyTO, String>> getColumns();
 
     @Override
     public void onEvent(final IEvent<?> event) {
@@ -340,7 +340,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
         }
     }
 
-    protected abstract <T extends AbstractAttributableTO> Collection<ActionLink.ActionType> getBulkActions();
+    protected abstract <T extends AnyTO> Collection<ActionLink.ActionType> getBulkActions();
 
     protected abstract String getPageId();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 563bd17..daaaa23 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
@@ -52,7 +52,7 @@ public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
             final int rowsPerPage,
             final Collection<ActionLink.ActionType> actions,
             final BaseRestClient bulkActionExecutor,
-            final String itemIdField,
+            final String itemKeyField,
             final String pageId,
             final PageReference pageRef) {
 
@@ -130,7 +130,7 @@ public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
                                 columns,
                                 actions,
                                 bulkActionExecutor,
-                                itemIdField,
+                                itemKeyField,
                                 pageId);
                     }
                 });

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
index e809263..ab1e7e0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
@@ -20,7 +20,7 @@ package org.apache.syncope.client.console.panels;
 
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
@@ -29,7 +29,7 @@ public class AnnotatedBeanPanel extends Panel {
 
     private static final long serialVersionUID = 4228064224811390809L;
 
-    public <T extends AbstractAttributableTO> AnnotatedBeanPanel(
+    public <T extends AnyTO> AnnotatedBeanPanel(
             final String id, final AbstractAnnotatedBean sysInfoTO) {
 
         super(id);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
index c1d01e0..6f2a17b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
@@ -57,9 +57,9 @@ public class ResourceConnConfPanel extends Panel {
 
     private List<ConnConfProperty> connConfProperties;
 
-    private WebMarkupContainer connConfPropContainer;
+    private final WebMarkupContainer connConfPropContainer;
 
-    private AjaxButton check;
+    private final AjaxButton check;
 
     public ResourceConnConfPanel(final String id, final ResourceTO resourceTO, final boolean createFlag) {
         super(id);
@@ -103,7 +103,7 @@ public class ResourceConnConfPanel extends Panel {
 
         check.setEnabled(!connConfProperties.isEmpty());
         check.setVisible(!connConfProperties.isEmpty());
-        
+
         connConfPropContainer.add(check);
     }
 
@@ -113,10 +113,10 @@ public class ResourceConnConfPanel extends Panel {
      * @return overridable properties.
      */
     private List<ConnConfProperty> getConnConfProperties() {
-        final List<ConnConfProperty> props = new ArrayList<ConnConfProperty>();
-        final Long connectorId = resourceTO.getConnectorId();
-        if (connectorId != null && connectorId > 0) {
-            for (ConnConfProperty property : restClient.getConnectorProperties(connectorId)) {
+        List<ConnConfProperty> props = new ArrayList<>();
+        Long connectorKey = resourceTO.getConnector();
+        if (connectorKey != null && connectorKey > 0) {
+            for (ConnConfProperty property : restClient.getConnectorProperties(connectorKey)) {
                 if (property.isOverridable()) {
                     props.add(property);
                 }
@@ -125,7 +125,7 @@ public class ResourceConnConfPanel extends Panel {
         if (createFlag || resourceTO.getConnConfProperties().isEmpty()) {
             resourceTO.getConnConfProperties().clear();
         } else {
-            Map<String, ConnConfProperty> valuedProps = new HashMap<String, ConnConfProperty>();
+            Map<String, ConnConfProperty> valuedProps = new HashMap<>();
             for (ConnConfProperty prop : resourceTO.getConnConfProperties()) {
                 valuedProps.put(prop.getSchema().getName(), prop);
             }
@@ -169,7 +169,7 @@ public class ResourceConnConfPanel extends Panel {
      */
     public static class ConnConfModEvent extends ResourceEvent {
 
-        private List<ConnConfProperty> configuration;
+        private final List<ConnConfProperty> configuration;
 
         /**
          * Constructor.

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
index 3bff23f..3095b4e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
@@ -222,7 +222,7 @@ public class ResourceDetailsPanel extends Panel {
                 new ResourceModel("connector", "connector").getObject(),
                 new PropertyModel<ConnInstanceTO>(this, "connInstanceTO"));
         conn.setChoices(connectors.getObject());
-        conn.setChoiceRenderer(new ChoiceRenderer("displayName", "key"));
+        conn.setChoiceRenderer(new ChoiceRenderer<String>("displayName", "key"));
 
         conn.getField().setModel(new IModel<ConnInstanceTO>() {
 
@@ -235,7 +235,7 @@ public class ResourceDetailsPanel extends Panel {
 
             @Override
             public void setObject(final ConnInstanceTO connector) {
-                resourceTO.setConnectorId(connector.getKey());
+                resourceTO.setConnector(connector.getKey());
                 connInstanceTO = connector;
             }
 
@@ -270,20 +270,20 @@ public class ResourceDetailsPanel extends Panel {
      */
     private ConnInstanceTO getConectorInstanceTO(final List<ConnInstanceTO> connectorTOs, final ResourceTO resourceTO) {
         if (connectorTOs.isEmpty()) {
-            resourceTO.setConnectorId(null);
+            resourceTO.setConnector(null);
             return null;
         } else {
             // use the first element as default
             ConnInstanceTO res = connectorTOs.get(0);
 
             for (ConnInstanceTO to : connectorTOs) {
-                if (Long.valueOf(to.getKey()).equals(resourceTO.getConnectorId())) {
+                if (Long.valueOf(to.getKey()).equals(resourceTO.getConnector())) {
                     res = to;
                 }
             }
 
             // in case of no match
-            resourceTO.setConnectorId(res.getKey());
+            resourceTO.setConnector(res.getKey());
 
             return res;
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 b00bc1b..17ae3bf 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
@@ -36,12 +36,12 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MappingPurposePanel;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.MappingItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -122,37 +122,28 @@ public class ResourceMappingPanel extends Panel {
     /**
      * User / group.
      */
-    private final AttributableType attrType;
+    private final AnyTypeKind anyTypeKind;
 
     /**
      * Mapping container.
      */
     private final WebMarkupContainer mappingContainer;
 
-    /**
-     * AccountLink container.
-     */
-    private final WebMarkupContainer accountLinkContainer;
+    private final WebMarkupContainer connObjectLinkContainer;
 
-    private final AjaxCheckBoxPanel accountLinkCheckbox;
+    private final AjaxCheckBoxPanel connObjectLinkCheckbox;
 
     private MappingTO getMapping() {
-        MappingTO result = null;
-
-        if (AttributableType.USER == this.attrType) {
-            if (this.resourceTO.getUmapping() == null) {
-                this.resourceTO.setUmapping(new MappingTO());
-            }
-            result = this.resourceTO.getUmapping();
+        ProvisionTO provision = resourceTO.getProvision(this.anyTypeKind.name());
+        if (provision == null) {
+            provision = new ProvisionTO();
+            resourceTO.getProvisions().add(provision);
         }
-        if (AttributableType.GROUP == this.attrType) {
-            if (this.resourceTO.getGmapping() == null) {
-                this.resourceTO.setGmapping(new MappingTO());
-            }
-            result = this.resourceTO.getGmapping();
+        if (provision.getMapping() == null) {
+            provision.setMapping(new MappingTO());
         }
 
-        return result;
+        return provision.getMapping();
     }
 
     /**
@@ -160,25 +151,25 @@ public class ResourceMappingPanel extends Panel {
      *
      * @param id panel id
      * @param resourceTO external resource
-     * @param attrType USER / GROUP
+     * @param anyTypeKind USER / GROUP
      */
-    public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AttributableType attrType) {
+    public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AnyTypeKind anyTypeKind) {
         super(id);
         setOutputMarkupId(true);
 
         this.resourceTO = resourceTO;
-        this.attrType = attrType;
+        this.anyTypeKind = anyTypeKind;
 
         this.mappingContainer = new WebMarkupContainer("mappingContainer");
         this.mappingContainer.setOutputMarkupId(true);
         add(this.mappingContainer);
 
-        this.accountLinkContainer = new WebMarkupContainer("accountLinkContainer");
-        this.accountLinkContainer.setOutputMarkupId(true);
-        add(this.accountLinkContainer);
+        this.connObjectLinkContainer = new WebMarkupContainer("connObjectLinkContainer");
+        this.connObjectLinkContainer.setOutputMarkupId(true);
+        add(this.connObjectLinkContainer);
 
-        if (this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0) {
-            schemaNames = getSchemaNames(this.resourceTO.getConnectorId(), this.resourceTO.getConnConfProperties());
+        if (this.resourceTO.getConnector() != null && this.resourceTO.getConnector() > 0) {
+            schemaNames = getSchemaNames(this.resourceTO.getConnector(), this.resourceTO.getConnConfProperties());
 
             setEnabled();
         } else {
@@ -193,7 +184,7 @@ public class ResourceMappingPanel extends Panel {
 
         final Label passwordLabel = new Label("passwordLabel", new ResourceModel("password"));
         mappingContainer.add(passwordLabel);
-        if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
+        if (AnyTypeKind.USER != ResourceMappingPanel.this.anyTypeKind) {
             passwordLabel.setVisible(false);
         }
 
@@ -213,8 +204,8 @@ public class ResourceMappingPanel extends Panel {
                 } else if (left.getPurpose() != MappingPurpose.BOTH && right.getPurpose() == MappingPurpose.BOTH) {
                     compared = 1;
                 } else if (left.getPurpose() == MappingPurpose.PROPAGATION
-                        && (right.getPurpose() == MappingPurpose.SYNCHRONIZATION || right.getPurpose()
-                        == MappingPurpose.NONE)) {
+                        && (right.getPurpose() == MappingPurpose.SYNCHRONIZATION
+                        || right.getPurpose() == MappingPurpose.NONE)) {
                     compared = -1;
                 } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION
                         && right.getPurpose() == MappingPurpose.PROPAGATION) {
@@ -225,9 +216,9 @@ public class ResourceMappingPanel extends Panel {
                 } else if (left.getPurpose() == MappingPurpose.NONE
                         && right.getPurpose() != MappingPurpose.NONE) {
                     compared = 1;
-                } else if (left.isAccountid()) {
+                } else if (left.isConnObjectKey()) {
                     compared = -1;
-                } else if (right.isAccountid()) {
+                } else if (right.isConnObjectKey()) {
                     compared = 1;
                 } else if (left.isPassword()) {
                     compared = -1;
@@ -251,14 +242,12 @@ public class ResourceMappingPanel extends Panel {
                     mapItem.setPurpose(MappingPurpose.BOTH);
                 }
 
-                AttributableType entity = null;
+                AnyTypeKind entity = null;
                 if (mapItem.getIntMappingType() != null) {
-                    entity = mapItem.getIntMappingType().getAttributableType();
+                    entity = mapItem.getIntMappingType().getAnyTypeKind();
                 }
 
-                final List<IntMappingType> attrTypes = new ArrayList<IntMappingType>(getAttributeTypes(entity));
-
-                item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) {
+                item.add(new AjaxDecoratedCheckbox("toRemove", new Model<>(Boolean.FALSE)) {
 
                     private static final long serialVersionUID = 7170946748485726506L;
 
@@ -282,7 +271,7 @@ public class ResourceMappingPanel extends Panel {
                     protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
                         super.updateAjaxAttributes(attributes);
 
-                        final AjaxCallListener ajaxCallListener = new AjaxCallListener() {
+                        AjaxCallListener ajaxCallListener = new AjaxCallListener() {
 
                             private static final long serialVersionUID = 7160235486520935153L;
 
@@ -296,7 +285,7 @@ public class ResourceMappingPanel extends Panel {
                 });
 
                 final AjaxDropDownChoicePanel<String> intAttrNames =
-                        new AjaxDropDownChoicePanel<String>("intAttrNames", getString("intAttrNames"),
+                        new AjaxDropDownChoicePanel<>("intAttrNames", getString("intAttrNames"),
                                 new PropertyModel<String>(mapItem, "intAttrName"), false);
                 intAttrNames.setChoices(schemaNames);
                 intAttrNames.setRequired(true);
@@ -311,8 +300,9 @@ public class ResourceMappingPanel extends Panel {
                 });
                 item.add(intAttrNames);
 
+                final List<IntMappingType> attrTypes = new ArrayList<>(getAttributeTypes(entity));
                 final AjaxDropDownChoicePanel<IntMappingType> intMappingTypes =
-                        new AjaxDropDownChoicePanel<IntMappingType>("intMappingTypes",
+                        new AjaxDropDownChoicePanel<>("intMappingTypes",
                                 new ResourceModel("intMappingTypes", "intMappingTypes").getObject(),
                                 new PropertyModel<IntMappingType>(mapItem, "intMappingType"));
                 intMappingTypes.setRequired(true);
@@ -320,13 +310,13 @@ public class ResourceMappingPanel extends Panel {
                 intMappingTypes.setStyleSheet(FIELD_STYLE);
                 item.add(intMappingTypes);
 
-                final AjaxDropDownChoicePanel<AttributableType> entitiesPanel =
-                        new AjaxDropDownChoicePanel<AttributableType>("entities",
-                                new ResourceModel("entities", "entities").getObject(), new Model<AttributableType>(
-                                        entity));
-                entitiesPanel.setChoices(attrType == AttributableType.GROUP
-                        ? Collections.<AttributableType>singletonList(AttributableType.GROUP)
-                        : Arrays.asList(AttributableType.values()));
+                final AjaxDropDownChoicePanel<AnyTypeKind> entitiesPanel =
+                        new AjaxDropDownChoicePanel<>("entities",
+                                new ResourceModel("entities", "entities").getObject(),
+                                new Model<>(entity));
+                entitiesPanel.setChoices(anyTypeKind == AnyTypeKind.GROUP
+                        ? Collections.<AnyTypeKind>singletonList(AnyTypeKind.GROUP)
+                        : Arrays.asList(AnyTypeKind.values()));
                 entitiesPanel.setStyleSheet(DEF_FIELD_STYLE);
                 entitiesPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
@@ -369,16 +359,16 @@ public class ResourceMappingPanel extends Panel {
                 mandatory.setStyleSheet(SHORT_FIELD_STYLE);
                 item.add(mandatory);
 
-                final AjaxCheckBoxPanel accountId = new AjaxCheckBoxPanel("accountId",
-                        new ResourceModel("accountId", "accountId").getObject(),
-                        new PropertyModel<Boolean>(mapItem, "accountid"));
-                accountId.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+                final AjaxCheckBoxPanel connObjectKey = new AjaxCheckBoxPanel("connObjectKey",
+                        new ResourceModel("connObjectKey", "connObjectKey").getObject(),
+                        new PropertyModel<Boolean>(mapItem, "connObjectKey"));
+                connObjectKey.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
                     private static final long serialVersionUID = -1107858522700306810L;
 
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
-                        if (accountId.getModelObject()) {
+                        if (connObjectKey.getModelObject()) {
                             mapItem.setMandatoryCondition("true");
                             mandatory.setEnabled(false);
                         } else {
@@ -388,7 +378,7 @@ public class ResourceMappingPanel extends Panel {
                         target.add(mandatory);
                     }
                 });
-                item.add(accountId);
+                item.add(connObjectKey);
 
                 final AjaxCheckBoxPanel password = new AjaxCheckBoxPanel("password",
                         new ResourceModel("password", "password").getObject(),
@@ -399,17 +389,17 @@ public class ResourceMappingPanel extends Panel {
 
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
-                        extAttrNames.setEnabled(!mapItem.isAccountid() && !password.getModelObject());
+                        extAttrNames.setEnabled(!mapItem.isConnObjectKey() && !password.getModelObject());
                         extAttrNames.setModelObject(null);
                         extAttrNames.setRequired(!password.getModelObject());
                         target.add(extAttrNames);
 
-                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
-                        target.add(accountId);
+                        setConnObjectKey(intMappingTypes.getModelObject(), connObjectKey, password);
+                        target.add(connObjectKey);
                     }
                 });
                 item.add(password);
-                if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
+                if (AnyTypeKind.USER != ResourceMappingPanel.this.anyTypeKind) {
                     password.setVisible(false);
                 }
 
@@ -432,13 +422,13 @@ public class ResourceMappingPanel extends Panel {
                         setAttrNames(intMappingTypes.getModelObject(), intAttrNames);
                         target.add(intAttrNames);
 
-                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
-                        target.add(accountId);
+                        setConnObjectKey(intMappingTypes.getModelObject(), connObjectKey, password);
+                        target.add(connObjectKey);
                     }
                 });
 
                 setAttrNames(mapItem.getIntMappingType(), intAttrNames);
-                setAccountId(mapItem.getIntMappingType(), accountId, password);
+                setConnObjectKey(mapItem.getIntMappingType(), connObjectKey, password);
             }
         };
 
@@ -456,41 +446,41 @@ public class ResourceMappingPanel extends Panel {
             }
         };
         addMappingBtn.setDefaultFormProcessing(false);
-        addMappingBtn.setEnabled(this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0);
+        addMappingBtn.setEnabled(this.resourceTO.getConnector() != null && this.resourceTO.getConnector() > 0);
         mappingContainer.add(addMappingBtn);
 
-        boolean accountLinkEnabled = false;
-        if (getMapping().getAccountLink() != null) {
-            accountLinkEnabled = true;
+        boolean connObjectLinkEnabled = false;
+        if (getMapping().getConnObjectLink() != null) {
+            connObjectLinkEnabled = true;
         }
-        accountLinkCheckbox = new AjaxCheckBoxPanel("accountLinkCheckbox",
-                new ResourceModel("accountLinkCheckbox", "accountLinkCheckbox").getObject(),
-                new Model<Boolean>(Boolean.valueOf(accountLinkEnabled)));
-        accountLinkCheckbox.setEnabled(true);
+        connObjectLinkCheckbox = new AjaxCheckBoxPanel("connObjectLinkCheckbox",
+                new ResourceModel("connObjectLinkCheckbox", "connObjectLinkCheckbox").getObject(),
+                new Model<>(connObjectLinkEnabled));
+        connObjectLinkCheckbox.setEnabled(true);
 
-        accountLinkContainer.add(accountLinkCheckbox);
+        connObjectLinkContainer.add(connObjectLinkCheckbox);
 
-        final AjaxTextFieldPanel accountLink = new AjaxTextFieldPanel("accountLink",
-                new ResourceModel("accountLink", "accountLink").getObject(),
-                new PropertyModel<String>(getMapping(), "accountLink"));
-        accountLink.setEnabled(accountLinkEnabled);
-        accountLinkContainer.add(accountLink);
+        final AjaxTextFieldPanel connObjectLink = new AjaxTextFieldPanel("connObjectLink",
+                new ResourceModel("connObjectLink", "connObjectLink").getObject(),
+                new PropertyModel<String>(getMapping(), "connObjectLink"));
+        connObjectLink.setEnabled(connObjectLinkEnabled);
+        connObjectLinkContainer.add(connObjectLink);
 
-        accountLinkCheckbox.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+        connObjectLinkCheckbox.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
             private static final long serialVersionUID = -1107858522700306810L;
 
             @Override
             protected void onUpdate(final AjaxRequestTarget target) {
-                if (accountLinkCheckbox.getModelObject()) {
-                    accountLink.setEnabled(Boolean.TRUE);
-                    accountLink.setModelObject("");
+                if (connObjectLinkCheckbox.getModelObject()) {
+                    connObjectLink.setEnabled(Boolean.TRUE);
+                    connObjectLink.setModelObject("");
                 } else {
-                    accountLink.setEnabled(Boolean.FALSE);
-                    accountLink.setModelObject("");
+                    connObjectLink.setEnabled(Boolean.FALSE);
+                    connObjectLink.setModelObject("");
                 }
 
-                target.add(accountLink);
+                target.add(connObjectLink);
             }
         });
     }
@@ -504,25 +494,22 @@ public class ResourceMappingPanel extends Panel {
     }
 
     private void setEnabled() {
-        final ConnInstanceTO connInstanceTO = new ConnInstanceTO();
-        connInstanceTO.setKey(this.resourceTO.getConnectorId());
+        ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+        connInstanceTO.setKey(this.resourceTO.getConnector());
         connInstanceTO.getConfiguration().addAll(this.resourceTO.getConnConfProperties());
 
-        List<ConnIdObjectClassTO> objectClasses = connRestClient.getSupportedObjectClasses(connInstanceTO);
+        boolean enabled = resourceTO.getProvision(anyTypeKind.name()) != null;
 
-        boolean enabled = objectClasses.isEmpty()
-                || (AttributableType.USER == attrType && objectClasses.contains(ConnIdObjectClassTO.ACCOUNT))
-                || (AttributableType.GROUP == attrType && objectClasses.contains(ConnIdObjectClassTO.GROUP));
         this.mappingContainer.setEnabled(enabled);
         this.mappingContainer.setVisible(enabled);
-        this.accountLinkContainer.setEnabled(enabled);
-        this.accountLinkContainer.setVisible(enabled);
+        this.connObjectLinkContainer.setEnabled(enabled);
+        this.connObjectLinkContainer.setVisible(enabled);
 
         if (!enabled) {
             getMapping().getItems().clear();
-            getMapping().setAccountLink(null);
-            if (this.accountLinkCheckbox != null) {
-                this.accountLinkCheckbox.setModelObject(null);
+            getMapping().setConnObjectLink(null);
+            if (this.connObjectLinkCheckbox != null) {
+                this.connObjectLinkCheckbox.setModelObject(null);
             }
         }
     }
@@ -536,10 +523,10 @@ public class ResourceMappingPanel extends Panel {
 
             mappings.removeAll();
 
-            addMappingBtn.setEnabled(resourceTO.getConnectorId() != null && resourceTO.getConnectorId() > 0);
+            addMappingBtn.setEnabled(resourceTO.getConnector() != null && resourceTO.getConnector() > 0);
 
             schemaNames.clear();
-            schemaNames.addAll(getSchemaNames(resourceTO.getConnectorId(), new HashSet<ConnConfProperty>(conf)));
+            schemaNames.addAll(getSchemaNames(resourceTO.getConnector(), new HashSet<ConnConfProperty>(conf)));
 
             setEnabled();
 
@@ -557,34 +544,35 @@ public class ResourceMappingPanel extends Panel {
         toBeUpdated.setRequired(true);
         toBeUpdated.setEnabled(true);
 
-        if (type == null || type.getAttributableType() == null) {
+        if (type == null || type.getAnyTypeKind() == null) {
             toBeUpdated.setChoices(Collections.<String>emptyList());
         } else {
             switch (type) {
                 // user attribute names
                 case UserPlainSchema:
                 case GroupPlainSchema:
-                case MembershipPlainSchema:
-                    toBeUpdated.setChoices(schemaRestClient.getPlainSchemaNames(type.getAttributableType()));
+                case AnyObjectPlainSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getPlainSchemaNames());
                     break;
 
                 case UserDerivedSchema:
                 case GroupDerivedSchema:
-                case MembershipDerivedSchema:
-                    toBeUpdated.setChoices(schemaRestClient.getDerSchemaNames(type.getAttributableType()));
+                case AnyObjectDerivedSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getDerSchemaNames());
                     break;
 
                 case UserVirtualSchema:
                 case GroupVirtualSchema:
-                case MembershipVirtualSchema:
-                    toBeUpdated.setChoices(schemaRestClient.getVirSchemaNames(type.getAttributableType()));
+                case AnyObjectVirtualSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getVirSchemaNames());
                     break;
 
-                case UserId:
+                case UserKey:
                 case Password:
                 case Username:
-                case GroupId:
+                case GroupKey:
                 case GroupName:
+                case AnyObjectKey:
                 default:
                     toBeUpdated.setRequired(false);
                     toBeUpdated.setEnabled(false);
@@ -594,33 +582,33 @@ public class ResourceMappingPanel extends Panel {
     }
 
     /**
-     * Enable/Disable accountId checkbox.
+     * Enable/Disable connObjectKey checkbox.
      *
      * @param type attribute type.
-     * @param accountId accountId checkbox.
+     * @param connObjectKey connObjectKey checkbox.
      * @param password password checkbox.
      */
-    private void setAccountId(final IntMappingType type, final AjaxCheckBoxPanel accountId,
-            final AjaxCheckBoxPanel password) {
+    private void setConnObjectKey(
+            final IntMappingType type, final AjaxCheckBoxPanel connObjectKey, final AjaxCheckBoxPanel password) {
 
-        if (type != null && type.getAttributableType() != null) {
+        if (type != null && type.getAnyTypeKind() != null) {
             switch (type) {
                 case UserVirtualSchema:
                 case GroupVirtualSchema:
-                case MembershipVirtualSchema:
-                // Virtual accountId is not permitted
+                case AnyObjectVirtualSchema:
+                // Virtual connObjectKey is not permitted
                 case Password:
-                    // AccountId cannot be derived from password.
-                    accountId.setReadOnly(true);
-                    accountId.setModelObject(false);
+                    // connObjectKey cannot be derived from password.
+                    connObjectKey.setReadOnly(true);
+                    connObjectKey.setModelObject(false);
                     break;
 
                 default:
                     if (password.getModelObject()) {
-                        accountId.setReadOnly(true);
-                        accountId.setModelObject(false);
+                        connObjectKey.setReadOnly(true);
+                        connObjectKey.setModelObject(false);
                     } else {
-                        accountId.setReadOnly(false);
+                        connObjectKey.setReadOnly(false);
                     }
             }
         }
@@ -632,11 +620,11 @@ public class ResourceMappingPanel extends Panel {
      * @param entity entity.
      * @return all attribute types.
      */
-    private List<IntMappingType> getAttributeTypes(final AttributableType entity) {
+    private List<IntMappingType> getAttributeTypes(final AnyTypeKind entity) {
         final List<IntMappingType> res = new ArrayList<>();
 
         if (entity != null) {
-            res.addAll(IntMappingType.getAttributeTypes(AttributableType.valueOf(entity.name())));
+            res.addAll(IntMappingType.getAttributeTypes(entity));
         }
 
         return res;


[06/27] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/SYNCOPE-666
Commit: 84c2d7bc836c0f3419ce204169e9dfc98ca8407f
Parents: e3e57df 4cd6f5d
Author: fmartelli <fa...@gmail.com>
Authored: Mon May 25 14:10:24 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Mon May 25 14:10:24 2015 +0200

----------------------------------------------------------------------
 .../syncope/common/lib/types/JobAction.java     |  29 ++++
 .../syncope/common/lib/types/JobStatusType.java |  30 ++++
 .../common/rest/api/service/ReportService.java  |  24 +++
 .../common/rest/api/service/TaskService.java    |  24 +++
 .../syncope/core/logic/AbstractJobLogic.java    | 174 +++++++++++++++++++
 .../apache/syncope/core/logic/ReportLogic.java  |  30 +++-
 .../apache/syncope/core/logic/TaskLogic.java    |  26 ++-
 .../apache/syncope/core/logic/UserLogic.java    |   2 +-
 .../core/provisioning/api/job/JobNamer.java     |   4 +-
 .../core/provisioning/api/job/TaskJob.java      |   4 +-
 .../java/DefaultUserProvisioningManager.java    |   9 +-
 .../core/provisioning/java/VirAttrHandler.java  |   2 +-
 .../provisioning/java/job/AbstractTaskJob.java  |  23 +++
 .../notification/NotificationManagerImpl.java   |   7 +-
 .../propagation/PropagationManagerImpl.java     |  31 ++--
 .../rest/cxf/service/ReportServiceImpl.java     |  12 ++
 .../core/rest/cxf/service/TaskServiceImpl.java  |  13 ++
 .../activiti/ActivitiUserWorkflowAdapter.java   |   6 +-
 .../core/workflow/activiti/task/Update.java     |  11 +-
 .../processor/UserConfirmPwdResetProcessor.java |  13 +-
 .../fit/core/reference/TestSampleJob.java       |  64 +++++++
 .../fit/core/reference/SchedTaskITCase.java     |  60 +++++++
 .../fit/core/reference/UserSelfITCase.java      |  15 ++
 23 files changed, 574 insertions(+), 39 deletions(-)
----------------------------------------------------------------------



[03/27] syncope git commit: [SYNCOPE-156] providing basic layout for realms and administration pages

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-yellow.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-yellow.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-yellow.css
index 650c40a..a852689 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-yellow.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-yellow.css
@@ -17,9 +17,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-yellow .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-yellow .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -49,11 +46,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-yellow .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-yellow .main-header .logo:hover {
-  background: #db8b0b;
+  background-color: #db8b0b;
 }
 .skin-yellow .main-header li.user-header {
   background-color: #f39c12;
@@ -61,6 +55,11 @@
 .skin-yellow .content-header {
   background: transparent;
 }
+.skin-yellow .wrapper,
+.skin-yellow .main-sidebar,
+.skin-yellow .left-side {
+  background-color: #222d32;
+}
 .skin-yellow .user-panel > .info,
 .skin-yellow .user-panel > .info > a {
   color: #fff;
@@ -71,9 +70,8 @@
 }
 .skin-yellow .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-yellow .sidebar-menu > li > a:hover,
+.skin-yellow .sidebar-menu > li:hover > a,
 .skin-yellow .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -83,11 +81,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-yellow .wrapper,
-.skin-yellow .main-sidebar,
-.skin-yellow .left-side {
-  background: #222d32;
-}
 .skin-yellow .sidebar a {
   color: #b8c7ce;
 }
@@ -112,9 +105,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-yellow .sidebar-form input[type="text"] {
   color: #666;


[16/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/META-INF/resources/css/console.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/console.css b/client/console/src/main/resources/META-INF/resources/css/console.css
deleted file mode 100644
index 06c5bc5..0000000
--- a/client/console/src/main/resources/META-INF/resources/css/console.css
+++ /dev/null
@@ -1,4066 +0,0 @@
-@import url(//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);
-/*!
- *   AdminLTE v2.0.4
- *   Author: Almsaeed Studio
- *	 Website: Almsaeed Studio <http://almsaeedstudio.com>
- *   License: Open source - MIT
- *           Please visit http://opensource.org/licenses/MIT for more information
-!*/
-/*
- * Core: Genral Layout Style
- * -------------------------
- */
-html,
-body {
-  min-height: 100%;
-}
-.layout-boxed html,
-.layout-boxed body {
-  height: 100%;
-}
-body {
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;
-  font-weight: 400;
-  overflow-x: hidden;
-  overflow-y: auto;
-}
-/* Layout */
-.wrapper {
-  min-height: 100%;
-  position: static;
-  overflow: hidden;
-}
-.wrapper:before,
-.wrapper:after {
-  content: " ";
-  display: table;
-}
-.wrapper:after {
-  clear: both;
-}
-.layout-boxed .wrapper {
-  max-width: 1250px;
-  margin: 0 auto;
-  min-height: 100%;
-  box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
-  position: relative;
-}
-.layout-boxed {
-  background: url('../img/boxed-bg.jpg') repeat fixed;
-}
-/*
- * Content Wrapper - contins main content
- * ```.right-side has been deprecated as of v2.0.0 in favor of .content-wrapper  ```
- */
-.content-wrapper,
-.right-side,
-.main-footer {
-  -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -moz-transition: -moz-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: -o-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -webkit-transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  margin-left: 230px;
-  z-index: 820;
-}
-.layout-top-nav .content-wrapper,
-.layout-top-nav .right-side,
-.layout-top-nav .main-footer {
-  margin-left: 0;
-}
-@media (max-width: 767px) {
-  .content-wrapper,
-  .right-side,
-  .main-footer {
-    margin-left: 0;
-  }
-}
-@media (min-width: 768px) {
-  .sidebar-collapse .content-wrapper,
-  .sidebar-collapse .right-side,
-  .sidebar-collapse .main-footer {
-    margin-left: 0;
-  }
-}
-@media (max-width: 767px) {
-  .sidebar-open .content-wrapper,
-  .sidebar-open .right-side,
-  .sidebar-open .main-footer {
-    -webkit-transform: translate(230px, 0);
-    -ms-transform: translate(230px, 0);
-    -o-transform: translate(230px, 0);
-    transform: translate(230px, 0);
-  }
-}
-.content-wrapper,
-.right-side {
-  min-height: 100%;
-  background-color: #ecf0f5;
-  z-index: 800;
-}
-.main-footer {
-  background: #fff;
-  padding: 15px;
-  color: #444;
-  border-top: 1px solid #eee;
-}
-/* Fixed layout */
-.fixed .main-header,
-.fixed .main-sidebar,
-.fixed .left-side {
-  position: fixed;
-}
-.fixed .main-header {
-  top: 0;
-  right: 0;
-  left: 0;
-}
-.fixed .content-wrapper,
-.fixed .right-side {
-  padding-top: 50px;
-}
-@media (max-width: 767px) {
-  .fixed .content-wrapper,
-  .fixed .right-side {
-    padding-top: 100px;
-  }
-}
-.fixed.layout-boxed .wrapper {
-  max-width: 100%;
-}
-/* Content */
-.content {
-  min-height: 250px;
-  padding: 15px;
-  margin-right: auto;
-  margin-left: auto;
-  padding-left: 15px;
-  padding-right: 15px;
-}
-/* H1 - H6 font */
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-.h1,
-.h2,
-.h3,
-.h4,
-.h5,
-.h6 {
-  font-family: 'Source Sans Pro', sans-serif;
-}
-/* General Links */
-a {
-  color: #3c8dbc;
-}
-a:hover,
-a:active,
-a:focus {
-  outline: none;
-  text-decoration: none;
-  color: #72afd2;
-}
-/* Page Header */
-.page-header {
-  margin: 10px 0 20px 0;
-  font-size: 22px;
-}
-.page-header > small {
-  color: #666;
-  display: block;
-  margin-top: 5px;
-}
-/*
- * Component: Main Header
- * ----------------------
- */
-.main-header {
-  position: relative;
-  max-height: 100px;
-  z-index: 1030;
-}
-.main-header > .navbar {
-  margin-bottom: 0;
-  margin-left: 230px;
-  border: none;
-  min-height: 50px;
-  border-radius: 0;
-}
-.layout-top-nav .main-header > .navbar {
-  margin-left: 0!important;
-}
-.main-header #navbar-search-input {
-  background: rgba(255, 255, 255, 0.2);
-  border-color: transparent;
-}
-.main-header #navbar-search-input:focus,
-.main-header #navbar-search-input:active {
-  border-color: rgba(0, 0, 0, 0.1) !important;
-  background: rgba(255, 255, 255, 0.9);
-}
-.main-header #navbar-search-input::-moz-placeholder {
-  color: #ccc;
-  opacity: 1;
-}
-.main-header #navbar-search-input:-ms-input-placeholder {
-  color: #ccc;
-}
-.main-header #navbar-search-input::-webkit-input-placeholder {
-  color: #ccc;
-}
-.main-header .navbar-custom-menu,
-.main-header .navbar-right {
-  margin-right: 5px;
-  float: right;
-}
-@media (max-width: 991px) {
-  .main-header .navbar-custom-menu a,
-  .main-header .navbar-right a {
-    color: inherit;
-    background: transparent;
-  }
-}
-@media (max-width: 767px) {
-  .main-header .navbar-right {
-    float: none;
-  }
-  .navbar-collapse .main-header .navbar-right {
-    margin: 7.5px -15px;
-  }
-  .main-header .navbar-right > li {
-    color: inherit;
-    border: 0;
-  }
-}
-.main-header .sidebar-toggle {
-  float: left;
-  background-color: transparent;
-  background-image: none;
-  padding: 15px 15px;
-  font-family: fontAwesome;
-}
-.main-header .sidebar-toggle:before {
-  content: "\f0c9";
-}
-.main-header .sidebar-toggle:hover {
-  color: #fff;
-}
-.main-header .sidebar-toggle .icon-bar {
-  display: none;
-}
-.main-header .navbar .nav > li.user > a > .fa,
-.main-header .navbar .nav > li.user > a > .glyphicon,
-.main-header .navbar .nav > li.user > a > .ion {
-  margin-right: 5px;
-}
-.main-header .navbar .nav > li > a > .label {
-  position: absolute;
-  top: 9px;
-  right: 7px;
-  text-align: center;
-  font-size: 9px;
-  padding: 2px 3px;
-  line-height: .9;
-}
-.main-header .logo {
-  display: block;
-  float: left;
-  height: 50px;
-  font-size: 20px;
-  line-height: 50px;
-  text-align: center;
-  width: 230px;
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  padding: 0 15px;
-  font-weight: 300;
-}
-.main-header .navbar-brand {
-  color: #fff;
-}
-.content-header {
-  position: relative;
-  padding: 15px 15px 0 15px;
-}
-.content-header > h1 {
-  margin: 0;
-  font-size: 24px;
-}
-.content-header > h1 > small {
-  font-size: 15px;
-  display: inline-block;
-  padding-left: 4px;
-  font-weight: 300;
-}
-.content-header > .breadcrumb {
-  float: right;
-  background: transparent;
-  margin-top: 0px;
-  margin-bottom: 0;
-  font-size: 12px;
-  padding: 7px 5px;
-  position: absolute;
-  top: 15px;
-  right: 10px;
-  border-radius: 2px;
-}
-.content-header > .breadcrumb > li > a {
-  color: #444;
-  text-decoration: none;
-  display: inline-block;
-}
-.content-header > .breadcrumb > li > a > .fa,
-.content-header > .breadcrumb > li > a > .glyphicon,
-.content-header > .breadcrumb > li > a > .ion {
-  margin-right: 5px;
-}
-.content-header > .breadcrumb > li + li:before {
-  content: '>\00a0';
-}
-@media (max-width: 991px) {
-  .content-header > .breadcrumb {
-    position: relative;
-    margin-top: 5px;
-    top: 0;
-    right: 0;
-    float: none;
-    background: #d2d6de;
-    padding-left: 10px;
-  }
-  .content-header > .breadcrumb li:before {
-    color: #97a0b3;
-  }
-}
-.navbar-toggle {
-  color: #fff;
-  border: 0;
-  margin: 0;
-  padding: 15px 15px;
-}
-@media (max-width: 991px) {
-  .navbar-custom-menu .navbar-nav > li {
-    float: left;
-  }
-  .navbar-custom-menu .navbar-nav {
-    margin: 0;
-    float: left;
-  }
-  .navbar-custom-menu .navbar-nav > li > a {
-    padding-top: 15px;
-    padding-bottom: 15px;
-    line-height: 20px;
-  }
-}
-@media (max-width: 767px) {
-  .main-header {
-    position: relative;
-  }
-  .main-header .logo,
-  .main-header .navbar {
-    width: 100%;
-    float: none;
-    position: relative!important;
-  }
-  .main-header .navbar {
-    margin: 0;
-  }
-  .main-header .navbar-custom-menu {
-    float: right;
-  }
-  .main-sidebar,
-  .left-side {
-    padding-top: 100px!important;
-  }
-}
-/*
- * Component: Sidebar
- * ------------------
- */
-.main-sidebar,
-.left-side {
-  position: absolute;
-  top: 0;
-  left: 0;
-  padding-top: 50px;
-  min-height: 100%;
-  width: 230px;
-  z-index: 810;
-  -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -moz-transition: -moz-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: -o-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-}
-@media (max-width: 767px) {
-  .main-sidebar,
-  .left-side {
-    -webkit-transform: translate(-230px, 0);
-    -ms-transform: translate(-230px, 0);
-    -o-transform: translate(-230px, 0);
-    transform: translate(-230px, 0);
-  }
-}
-@media (min-width: 768px) {
-  .sidebar-collapse .main-sidebar,
-  .sidebar-collapse .left-side {
-    -webkit-transform: translate(-230px, 0);
-    -ms-transform: translate(-230px, 0);
-    -o-transform: translate(-230px, 0);
-    transform: translate(-230px, 0);
-  }
-}
-@media (max-width: 767px) {
-  .sidebar-open .main-sidebar,
-  .sidebar-open .left-side {
-    -webkit-transform: translate(0, 0);
-    -ms-transform: translate(0, 0);
-    -o-transform: translate(0, 0);
-    transform: translate(0, 0);
-  }
-}
-.sidebar {
-  padding-bottom: 10px;
-}
-.fixed .sidebar {
-  overflow: auto;
-  height: 100%;
-}
-.sidebar-form input:focus {
-  border-color: transparent!important;
-}
-.user-panel {
-  padding: 10px;
-}
-.user-panel:before,
-.user-panel:after {
-  content: " ";
-  display: table;
-}
-.user-panel:after {
-  clear: both;
-}
-.user-panel > .image > img {
-  width: 45px;
-  height: 45px;
-}
-.user-panel > .info {
-  font-weight: 600;
-  padding: 5px 5px 5px 15px;
-  font-size: 14px;
-  line-height: 1;
-}
-.user-panel > .info > p {
-  margin-bottom: 9px;
-}
-.user-panel > .info > a {
-  text-decoration: none;
-  padding-right: 5px;
-  margin-top: 3px;
-  font-size: 11px;
-  font-weight: normal;
-}
-.user-panel > .info > a > .fa,
-.user-panel > .info > a > .ion,
-.user-panel > .info > a > .glyphicon {
-  margin-right: 3px;
-}
-.sidebar-menu {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-.sidebar-menu > li {
-  position: relative;
-  margin: 0;
-  padding: 0;
-}
-.sidebar-menu > li > a {
-  padding: 12px 5px 12px 15px;
-  display: block;
-}
-.sidebar-menu > li > a > .fa,
-.sidebar-menu > li > a > .glyphicon,
-.sidebar-menu > li > a > .ion {
-  width: 20px;
-}
-.sidebar-menu > li .label,
-.sidebar-menu > li .badge {
-  margin-top: 3px;
-  margin-right: 5px;
-}
-.sidebar-menu li.header {
-  padding: 10px 25px 10px 15px;
-  font-size: 12px;
-}
-.sidebar-menu li > a > .fa-angle-left {
-  width: auto;
-  height: auto;
-  padding: 0;
-  margin-right: 10px;
-  margin-top: 3px;
-}
-.sidebar-menu li.active > a > .fa-angle-left {
-  -webkit-transform: rotate(-90deg);
-  -ms-transform: rotate(-90deg);
-  -o-transform: rotate(-90deg);
-  transform: rotate(-90deg);
-}
-.sidebar-menu li.active > .treeview-menu {
-  display: block;
-}
-.sidebar-menu .treeview-menu {
-  display: none;
-  list-style: none;
-  padding: 0;
-  margin: 0;
-  padding-left: 5px;
-}
-.sidebar-menu .treeview-menu .treeview-menu {
-  padding-left: 20px;
-}
-.sidebar-menu .treeview-menu > li {
-  margin: 0;
-}
-.sidebar-menu .treeview-menu > li > a {
-  padding: 5px 5px 5px 15px;
-  display: block;
-  font-size: 14px;
-}
-.sidebar-menu .treeview-menu > li > a > .fa,
-.sidebar-menu .treeview-menu > li > a > .glyphicon,
-.sidebar-menu .treeview-menu > li > a > .ion {
-  width: 20px;
-}
-.sidebar-menu .treeview-menu > li > a > .fa-angle-left,
-.sidebar-menu .treeview-menu > li > a > .fa-angle-down {
-  width: auto;
-}
-/*
- * Component: Dropdown menus
- * -------------------------
- */
-/*Dropdowns in general*/
-.dropdown-menu {
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  border-color: #eee;
-}
-.dropdown-menu > li > a {
-  color: #777;
-}
-.dropdown-menu > li > a > .glyphicon,
-.dropdown-menu > li > a > .fa,
-.dropdown-menu > li > a > .ion {
-  margin-right: 10px;
-}
-.dropdown-menu > li > a:hover {
-  background-color: #e1e3e9;
-  color: #333;
-}
-.dropdown-menu > .divider {
-  background-color: #eee;
-}
-/*
-    Navbar custom dropdown menu
-------------------------------------
-*/
-.navbar-nav > .notifications-menu,
-.navbar-nav > .messages-menu,
-.navbar-nav > .tasks-menu {
-  position: relative;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu,
-.navbar-nav > .messages-menu > .dropdown-menu,
-.navbar-nav > .tasks-menu > .dropdown-menu {
-  width: 280px;
-  padding: 0 0 0 0!important;
-  margin: 0!important;
-  top: 100%;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li,
-.navbar-nav > .messages-menu > .dropdown-menu > li,
-.navbar-nav > .tasks-menu > .dropdown-menu > li {
-  position: relative;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li.header,
-.navbar-nav > .messages-menu > .dropdown-menu > li.header,
-.navbar-nav > .tasks-menu > .dropdown-menu > li.header {
-  border-top-left-radius: 4px;
-  border-top-right-radius: 4px;
-  border-bottom-right-radius: 0;
-  border-bottom-left-radius: 0;
-  background-color: #ffffff;
-  padding: 7px 10px;
-  border-bottom: 1px solid #f4f4f4;
-  color: #444444;
-  font-size: 14px;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a,
-.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a,
-.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {
-  border-top-left-radius: 0px;
-  border-top-right-radius: 0px;
-  border-bottom-right-radius: 4px;
-  border-bottom-left-radius: 4px;
-  font-size: 12px;
-  background-color: #fff;
-  padding: 7px 10px;
-  border-bottom: 1px solid #eeeeee;
-  color: #444!important;
-  text-align: center;
-}
-@media (max-width: 991px) {
-  .navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a,
-  .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a,
-  .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {
-    background: #fff!important;
-    color: #444!important;
-  }
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a:hover,
-.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a:hover,
-.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a:hover {
-  text-decoration: none;
-  font-weight: normal;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li .menu,
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu,
-.navbar-nav > .tasks-menu > .dropdown-menu > li .menu {
-  max-height: 200px;
-  margin: 0;
-  padding: 0;
-  list-style: none;
-  overflow-x: hidden;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a,
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a,
-.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {
-  display: block;
-  white-space: nowrap;
-  /* Prevent text from breaking */
-  border-bottom: 1px solid #f4f4f4;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a:hover,
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:hover,
-.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a:hover {
-  background: #f4f4f4;
-  text-decoration: none;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a {
-  color: #444444;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-  padding: 10px;
-}
-.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon,
-.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa,
-.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion {
-  width: 20px;
-}
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a {
-  margin: 0px;
-  padding: 10px 10px;
-}
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > div > img {
-  margin: auto 10px auto auto;
-  width: 40px;
-  height: 40px;
-}
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 {
-  padding: 0;
-  margin: 0 0 0 45px;
-  color: #444444;
-  font-size: 15px;
-  position: relative;
-}
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 > small {
-  color: #999999;
-  font-size: 10px;
-  position: absolute;
-  top: 0px;
-  right: 0px;
-}
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > p {
-  margin: 0 0 0 45px;
-  font-size: 12px;
-  color: #888888;
-}
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:before,
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
-  content: " ";
-  display: table;
-}
-.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
-  clear: both;
-}
-.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {
-  padding: 10px;
-}
-.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > h3 {
-  font-size: 14px;
-  padding: 0;
-  margin: 0 0 10px 0;
-  color: #666666;
-}
-.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > .progress {
-  padding: 0;
-  margin: 0;
-}
-.navbar-nav > .user-menu > .dropdown-menu {
-  border-top-right-radius: 0;
-  border-top-left-radius: 0;
-  padding: 1px 0 0 0;
-  border-top-width: 0;
-  width: 280px;
-}
-.navbar-nav > .user-menu > .dropdown-menu,
-.navbar-nav > .user-menu > .dropdown-menu > .user-body {
-  border-bottom-right-radius: 4px;
-  border-bottom-left-radius: 4px;
-}
-.navbar-nav > .user-menu > .dropdown-menu > li.user-header {
-  height: 175px;
-  padding: 10px;
-  text-align: center;
-}
-.navbar-nav > .user-menu > .dropdown-menu > li.user-header > img {
-  z-index: 5;
-  height: 90px;
-  width: 90px;
-  border: 3px solid;
-  border-color: transparent;
-  border-color: rgba(255, 255, 255, 0.2);
-}
-.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p {
-  z-index: 5;
-  color: #fff;
-  color: rgba(255, 255, 255, 0.8);
-  font-size: 17px;
-  margin-top: 10px;
-}
-.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > small {
-  display: block;
-  font-size: 12px;
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-body {
-  padding: 15px;
-  border-bottom: 1px solid #f4f4f4;
-  border-top: 1px solid #dddddd;
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-body:before,
-.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {
-  content: " ";
-  display: table;
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {
-  clear: both;
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-body a {
-  color: #444 !important;
-}
-@media (max-width: 991px) {
-  .navbar-nav > .user-menu > .dropdown-menu > .user-body a {
-    background: #fff !important;
-    color: #444 !important;
-  }
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-footer {
-  background-color: #f9f9f9;
-  padding: 10px;
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-footer:before,
-.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {
-  content: " ";
-  display: table;
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {
-  clear: both;
-}
-.navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default {
-  color: #666666;
-}
-.navbar-nav > .user-menu .user-image {
-  float: left;
-  width: 25px;
-  height: 25px;
-  border-radius: 50%;
-  margin-right: 10px;
-  margin-top: -2px;
-}
-@media (max-width: 767px) {
-  .navbar-nav > .user-menu .user-image {
-    float: none;
-    margin-right: 0;
-    margin-top: -8px;
-    line-height: 10px;
-  }
-}
-/* Add fade animation to dropdown menus by appending
- the class .animated-dropdown-menu to the .dropdown-menu ul (or ol)*/
-.open:not(.dropup) > .animated-dropdown-menu {
-  backface-visibility: visible !important;
-  -webkit-animation: flipInX 0.7s both;
-  -o-animation: flipInX 0.7s both;
-  animation: flipInX 0.7s both;
-}
-@keyframes flipInX {
-  0% {
-    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-    transition-timing-function: ease-in;
-    opacity: 0;
-  }
-  40% {
-    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-    transition-timing-function: ease-in;
-  }
-  60% {
-    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
-    opacity: 1;
-  }
-  80% {
-    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
-  }
-  100% {
-    transform: perspective(400px);
-  }
-}
-@-webkit-keyframes flipInX {
-  0% {
-    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-    transition-timing-function: ease-in;
-    opacity: 0;
-  }
-  40% {
-    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-    transition-timing-function: ease-in;
-  }
-  60% {
-    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
-    opacity: 1;
-  }
-  80% {
-    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
-  }
-  100% {
-    transform: perspective(400px);
-  }
-}
-/* Fix dropdown menu in navbars */
-.navbar-custom-menu > .navbar-nav > li {
-  position: relative;
-}
-.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
-  position: absolute;
-  right: 0;
-  left: auto;
-}
-@media (max-width: 991px) {
-  .navbar-custom-menu > .navbar-nav {
-    float: right;
-  }
-  .navbar-custom-menu > .navbar-nav > li {
-    position: static;
-  }
-  .navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
-    position: absolute;
-    right: 5%;
-    left: auto;
-    border: 1px solid #ddd;
-    background: #fff;
-  }
-}
-/*
- * Component: Form
- * ---------------
- */
-.form-control {
-  border-radius: 0px !important;
-  box-shadow: none;
-  border-color: #d2d6de;
-}
-.form-control:focus {
-  border-color: #3c8dbc !important;
-  box-shadow: none;
-}
-.form-control::-moz-placeholder {
-  color: #bbb;
-  opacity: 1;
-}
-.form-control:-ms-input-placeholder {
-  color: #bbb;
-}
-.form-control::-webkit-input-placeholder {
-  color: #bbb;
-}
-.form-control:not(select) {
-  -webkit-appearance: none;
-  -moz-appearance: none;
-  appearance: none;
-}
-.form-group.has-success label {
-  color: #00a65a;
-}
-.form-group.has-success .form-control {
-  border-color: #00a65a !important;
-  box-shadow: none;
-}
-.form-group.has-warning label {
-  color: #f39c12;
-}
-.form-group.has-warning .form-control {
-  border-color: #f39c12 !important;
-  box-shadow: none;
-}
-.form-group.has-error label {
-  color: #dd4b39;
-}
-.form-group.has-error .form-control {
-  border-color: #dd4b39 !important;
-  box-shadow: none;
-}
-/* Input group */
-.input-group .input-group-addon {
-  border-radius: 0px;
-  border-color: #d2d6de;
-  background-color: #fff;
-}
-/* button groups */
-.btn-group-vertical .btn.btn-flat:first-of-type,
-.btn-group-vertical .btn.btn-flat:last-of-type {
-  border-radius: 0;
-}
-.icheck > label {
-  padding-left: 0;
-}
-/*
- * Component: Progress Bar
- * -----------------------
- */
-.progress,
-.progress > .progress-bar {
-  -webkit-box-shadow: none;
-  box-shadow: none;
-}
-.progress,
-.progress > .progress-bar,
-.progress .progress-bar,
-.progress > .progress-bar .progress-bar {
-  border-radius: 1px;
-}
-/* size variation */
-.progress.sm,
-.progress-sm {
-  height: 10px;
-}
-.progress.sm,
-.progress-sm,
-.progress.sm .progress-bar,
-.progress-sm .progress-bar {
-  border-radius: 1px;
-}
-.progress.xs,
-.progress-xs {
-  height: 7px;
-}
-.progress.xs,
-.progress-xs,
-.progress.xs .progress-bar,
-.progress-xs .progress-bar {
-  border-radius: 1px;
-}
-.progress.xxs,
-.progress-xxs {
-  height: 3px;
-}
-.progress.xxs,
-.progress-xxs,
-.progress.xxs .progress-bar,
-.progress-xxs .progress-bar {
-  border-radius: 1px;
-}
-/* Vertical bars */
-.progress.vertical {
-  position: relative;
-  width: 30px;
-  height: 200px;
-  display: inline-block;
-  margin-right: 10px;
-}
-.progress.vertical > .progress-bar {
-  width: 100%!important;
-  position: absolute;
-  bottom: 0;
-}
-.progress.vertical.sm,
-.progress.vertical.progress-sm {
-  width: 20px;
-}
-.progress.vertical.xs,
-.progress.vertical.progress-xs {
-  width: 10px;
-}
-.progress.vertical.xxs,
-.progress.vertical.progress-xxs {
-  width: 3px;
-}
-.progress-group .progress-text {
-  font-weight: 600;
-}
-.progress-group .progress-number {
-  float: right;
-}
-/* Remove margins from progress bars when put in a table */
-.table tr > td .progress {
-  margin: 0;
-}
-.progress-bar-light-blue,
-.progress-bar-primary {
-  background-color: #3c8dbc;
-}
-.progress-striped .progress-bar-light-blue,
-.progress-striped .progress-bar-primary {
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-.progress-bar-green,
-.progress-bar-success {
-  background-color: #00a65a;
-}
-.progress-striped .progress-bar-green,
-.progress-striped .progress-bar-success {
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-.progress-bar-aqua,
-.progress-bar-info {
-  background-color: #00c0ef;
-}
-.progress-striped .progress-bar-aqua,
-.progress-striped .progress-bar-info {
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-.progress-bar-yellow,
-.progress-bar-warning {
-  background-color: #f39c12;
-}
-.progress-striped .progress-bar-yellow,
-.progress-striped .progress-bar-warning {
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-.progress-bar-red,
-.progress-bar-danger {
-  background-color: #dd4b39;
-}
-.progress-striped .progress-bar-red,
-.progress-striped .progress-bar-danger {
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-/*
- * Component: Small Box
- * --------------------
- */
-.small-box {
-  border-radius: 2px;
-  position: relative;
-  display: block;
-  margin-bottom: 20px;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-}
-.small-box > .inner {
-  padding: 10px;
-}
-.small-box > .small-box-footer {
-  position: relative;
-  text-align: center;
-  padding: 3px 0;
-  color: #fff;
-  color: rgba(255, 255, 255, 0.8);
-  display: block;
-  z-index: 10;
-  background: rgba(0, 0, 0, 0.1);
-  text-decoration: none;
-}
-.small-box > .small-box-footer:hover {
-  color: #fff;
-  background: rgba(0, 0, 0, 0.15);
-}
-.small-box h3 {
-  font-size: 38px;
-  font-weight: bold;
-  margin: 0 0 10px 0;
-  white-space: nowrap;
-  padding: 0;
-}
-.small-box p {
-  font-size: 15px;
-}
-.small-box p > small {
-  display: block;
-  color: #f9f9f9;
-  font-size: 13px;
-  margin-top: 5px;
-}
-.small-box h3,
-.small-box p {
-  z-index: 5px;
-}
-.small-box .icon {
-  -webkit-transition: all 0.3s linear;
-  -o-transition: all 0.3s linear;
-  transition: all 0.3s linear;
-  position: absolute;
-  top: -10px;
-  right: 10px;
-  z-index: 0;
-  font-size: 90px;
-  color: rgba(0, 0, 0, 0.15);
-}
-.small-box:hover {
-  text-decoration: none;
-  color: #f9f9f9;
-}
-.small-box:hover .icon {
-  font-size: 95px;
-}
-@media (max-width: 767px) {
-  .small-box {
-    text-align: center;
-  }
-  .small-box .icon {
-    display: none;
-  }
-  .small-box p {
-    font-size: 12px;
-  }
-}
-/*
- * Component: Box
- * --------------
- */
-.box {
-  position: relative;
-  border-radius: 3px;
-  background: #ffffff;
-  border-top: 3px solid #d2d6de;
-  margin-bottom: 20px;
-  width: 100%;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-}
-.box.box-primary {
-  border-top-color: #3c8dbc;
-}
-.box.box-info {
-  border-top-color: #00c0ef;
-}
-.box.box-danger {
-  border-top-color: #dd4b39;
-}
-.box.box-warning {
-  border-top-color: #f39c12;
-}
-.box.box-success {
-  border-top-color: #00a65a;
-}
-.box.box-default {
-  border-top-color: #d2d6de;
-}
-.box.collapsed-box .box-body,
-.box.collapsed-box .box-footer {
-  display: none;
-}
-.box .nav-stacked > li {
-  border-bottom: 1px solid #f4f4f4;
-  margin: 0;
-}
-.box .nav-stacked > li:last-of-type {
-  border-bottom: none;
-}
-.box.height-control .box-body {
-  max-height: 300px;
-  overflow: auto;
-}
-.box .border-right {
-  border-right: 1px solid #f4f4f4;
-}
-.box .border-left {
-  border-left: 1px solid #f4f4f4;
-}
-.box.box-solid {
-  border-top: 0px;
-}
-.box.box-solid > .box-header .btn.btn-default {
-  background: transparent;
-}
-.box.box-solid > .box-header .btn:hover,
-.box.box-solid > .box-header a:hover {
-  background: rgba(0, 0, 0, 0.1) !important;
-}
-.box.box-solid.box-default {
-  border: 1px solid #d2d6de;
-}
-.box.box-solid.box-default > .box-header {
-  color: #444444;
-  background: #d2d6de;
-  background-color: #d2d6de;
-}
-.box.box-solid.box-default > .box-header a,
-.box.box-solid.box-default > .box-header .btn {
-  color: #444444;
-}
-.box.box-solid.box-primary {
-  border: 1px solid #3c8dbc;
-}
-.box.box-solid.box-primary > .box-header {
-  color: #ffffff;
-  background: #3c8dbc;
-  background-color: #3c8dbc;
-}
-.box.box-solid.box-primary > .box-header a,
-.box.box-solid.box-primary > .box-header .btn {
-  color: #ffffff;
-}
-.box.box-solid.box-info {
-  border: 1px solid #00c0ef;
-}
-.box.box-solid.box-info > .box-header {
-  color: #ffffff;
-  background: #00c0ef;
-  background-color: #00c0ef;
-}
-.box.box-solid.box-info > .box-header a,
-.box.box-solid.box-info > .box-header .btn {
-  color: #ffffff;
-}
-.box.box-solid.box-danger {
-  border: 1px solid #dd4b39;
-}
-.box.box-solid.box-danger > .box-header {
-  color: #ffffff;
-  background: #dd4b39;
-  background-color: #dd4b39;
-}
-.box.box-solid.box-danger > .box-header a,
-.box.box-solid.box-danger > .box-header .btn {
-  color: #ffffff;
-}
-.box.box-solid.box-warning {
-  border: 1px solid #f39c12;
-}
-.box.box-solid.box-warning > .box-header {
-  color: #ffffff;
-  background: #f39c12;
-  background-color: #f39c12;
-}
-.box.box-solid.box-warning > .box-header a,
-.box.box-solid.box-warning > .box-header .btn {
-  color: #ffffff;
-}
-.box.box-solid.box-success {
-  border: 1px solid #00a65a;
-}
-.box.box-solid.box-success > .box-header {
-  color: #ffffff;
-  background: #00a65a;
-  background-color: #00a65a;
-}
-.box.box-solid.box-success > .box-header a,
-.box.box-solid.box-success > .box-header .btn {
-  color: #ffffff;
-}
-.box.box-solid > .box-header > .box-tools .btn {
-  border: 0;
-  box-shadow: none;
-}
-.box.box-solid[class*='bg'] > .box-header {
-  color: #fff;
-}
-.box .box-group > .box {
-  margin-bottom: 5px;
-}
-.box .knob-label {
-  text-align: center;
-  color: #333;
-  font-weight: 100;
-  font-size: 12px;
-  margin-bottom: 0.3em;
-}
-.box > .overlay,
-.box > .loading-img {
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-}
-.box .overlay {
-  z-index: 1010;
-  background: rgba(255, 255, 255, 0.7);
-  border-radius: 3px;
-}
-.box .overlay > .fa {
-  position: absolute;
-  top: 50%;
-  left: 50%;
-  margin-left: -15px;
-  margin-top: -15px;
-  color: #000;
-  font-size: 30px;
-}
-.box .overlay.dark {
-  background: rgba(0, 0, 0, 0.5);
-}
-.box-header {
-  color: #444;
-  display: block;
-  padding: 10px;
-  position: relative;
-}
-.box-header:before,
-.box-header:after {
-  content: " ";
-  display: table;
-}
-.box-header:after {
-  clear: both;
-}
-.box-header.with-border {
-  border-bottom: 1px solid #f4f4f4;
-}
-.collapsed-box .box-header.with-border {
-  border-bottom: none;
-}
-.box-header > .fa,
-.box-header > .glyphicon,
-.box-header > .ion,
-.box-header .box-title {
-  display: inline-block;
-  font-size: 18px;
-  margin: 0;
-  line-height: 1;
-}
-.box-header > .fa,
-.box-header > .glyphicon,
-.box-header > .ion {
-  margin-right: 5px;
-}
-.box-header > .box-tools {
-  position: absolute;
-  right: 10px;
-  top: 5px;
-}
-.box-header > .box-tools [data-toggle="tooltip"] {
-  position: relative;
-}
-.box-header > .box-tools.pull-right .dropdown-menu {
-  right: 0;
-  left: auto;
-}
-.btn-box-tool {
-  padding: 5px;
-  font-size: 12px;
-  background: transparent;
-  box-shadow: none!important;
-  color: #97a0b3;
-}
-.open .btn-box-tool,
-.btn-box-tool:hover {
-  color: #606c84;
-}
-.btn-box-tool:active {
-  outline: none!important;
-}
-.box-body {
-  border-top-left-radius: 0;
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 3px;
-  border-bottom-left-radius: 3px;
-  padding: 10px;
-}
-.no-header .box-body {
-  border-top-right-radius: 3px;
-  border-top-left-radius: 3px;
-}
-.box-body > .table {
-  margin-bottom: 0;
-}
-.box-body > .chart {
-  position: relative;
-  overflow: hidden;
-  width: 100%;
-}
-.box-body > .chart svg,
-.box-body > .chart canvas {
-  width: 100%!important;
-}
-.box-body .fc {
-  margin-top: 5px;
-}
-.box-body .full-width-chart {
-  margin: -19px;
-}
-.box-body.no-padding .full-width-chart {
-  margin: -9px;
-}
-.box-body .box-pane {
-  border-top-left-radius: 0;
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0;
-  border-bottom-left-radius: 3px;
-}
-.box-body .box-pane-right {
-  border-top-left-radius: 0;
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 3px;
-  border-bottom-left-radius: 0;
-}
-.box-footer {
-  border-top-left-radius: 0;
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 3px;
-  border-bottom-left-radius: 3px;
-  border-top: 1px solid #f4f4f4;
-  padding: 10px;
-  background-color: #ffffff;
-}
-.chart-legend {
-  margin: 10px 0;
-}
-@media (max-width: 991px) {
-  .chart-legend > li {
-    float: left;
-    margin-right: 10px;
-  }
-}
-/* Widget: TODO LIST */
-.todo-list {
-  margin: 0;
-  padding: 0px 0px;
-  list-style: none;
-  overflow: auto;
-}
-.todo-list > li {
-  border-radius: 2px;
-  padding: 10px;
-  background: #f4f4f4;
-  margin-bottom: 2px;
-  border-left: 2px solid #e6e7e8;
-  color: #444;
-}
-.todo-list > li:last-of-type {
-  margin-bottom: 0;
-}
-.todo-list > li.danger {
-  border-left-color: #dd4b39;
-}
-.todo-list > li.warning {
-  border-left-color: #f39c12;
-}
-.todo-list > li.info {
-  border-left-color: #00c0ef;
-}
-.todo-list > li.success {
-  border-left-color: #00a65a;
-}
-.todo-list > li.primary {
-  border-left-color: #3c8dbc;
-}
-.todo-list > li > input[type='checkbox'] {
-  margin: 0 10px 0 5px;
-}
-.todo-list > li .text {
-  display: inline-block;
-  margin-left: 5px;
-  font-weight: 600;
-}
-.todo-list > li .label {
-  margin-left: 10px;
-  font-size: 9px;
-}
-.todo-list > li .tools {
-  display: none;
-  float: right;
-  color: #dd4b39;
-}
-.todo-list > li .tools > .fa,
-.todo-list > li .tools > .glyphicon,
-.todo-list > li .tools > .ion {
-  margin-right: 5px;
-  cursor: pointer;
-}
-.todo-list > li:hover .tools {
-  display: inline-block;
-}
-.todo-list > li.done {
-  color: #999;
-}
-.todo-list > li.done .text {
-  text-decoration: line-through;
-  font-weight: 500;
-}
-.todo-list > li.done .label {
-  background: #d2d6de !important;
-}
-.todo-list .handle {
-  display: inline-block;
-  cursor: move;
-  margin: 0 5px;
-}
-/* Chat widget (DEPRECATED - this will be removed in the next major release. Use Direct Chat instead)*/
-.chat {
-  padding: 5px 20px 5px 10px;
-}
-.chat .item {
-  margin-bottom: 10px;
-}
-.chat .item:before,
-.chat .item:after {
-  content: " ";
-  display: table;
-}
-.chat .item:after {
-  clear: both;
-}
-.chat .item > img {
-  width: 40px;
-  height: 40px;
-  border: 2px solid transparent;
-  border-radius: 50% !important;
-}
-.chat .item > img.online {
-  border: 2px solid #00a65a;
-}
-.chat .item > img.offline {
-  border: 2px solid #dd4b39;
-}
-.chat .item > .message {
-  margin-left: 55px;
-  margin-top: -40px;
-}
-.chat .item > .message > .name {
-  display: block;
-  font-weight: 600;
-}
-.chat .item > .attachment {
-  border-radius: 3px;
-  background: #f4f4f4;
-  margin-left: 65px;
-  margin-right: 15px;
-  padding: 10px;
-}
-.chat .item > .attachment > h4 {
-  margin: 0 0 5px 0;
-  font-weight: 600;
-  font-size: 14px;
-}
-.chat .item > .attachment > p,
-.chat .item > .attachment > .filename {
-  font-weight: 600;
-  font-size: 13px;
-  font-style: italic;
-  margin: 0;
-}
-.chat .item > .attachment:before,
-.chat .item > .attachment:after {
-  content: " ";
-  display: table;
-}
-.chat .item > .attachment:after {
-  clear: both;
-}
-.box-input {
-  max-width: 200px;
-}
-/*
- * Component: Info Box
- * -------------------
- */
-.info-box {
-  display: block;
-  min-height: 90px;
-  background: #fff;
-  width: 100%;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  border-radius: 2px;
-  margin-bottom: 15px;
-}
-.info-box small {
-  font-size: 14px;
-}
-.info-box .progress {
-  background: rgba(0, 0, 0, 0.2);
-  margin: 5px -10px 5px -10px;
-  height: 2px;
-}
-.info-box .progress,
-.info-box .progress .progress-bar {
-  border-radius: 0;
-}
-.info-box .progress .progress-bar {
-  background: #fff;
-}
-.info-box-icon {
-  border-top-left-radius: 2px;
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0;
-  border-bottom-left-radius: 2px;
-  display: block;
-  float: left;
-  height: 90px;
-  width: 90px;
-  text-align: center;
-  font-size: 45px;
-  line-height: 90px;
-  background: rgba(0, 0, 0, 0.2);
-}
-.info-box-content {
-  padding: 5px 10px;
-  margin-left: 90px;
-}
-.info-box-number {
-  display: block;
-  font-weight: bold;
-  font-size: 18px;
-}
-.progress-description,
-.info-box-text {
-  display: block;
-  font-size: 14px;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-.info-box-text {
-  text-transform: uppercase;
-}
-.info-box-more {
-  display: block;
-}
-.progress-description {
-  margin: 0;
-}
-/*
- * Component: Timeline
- * -------------------
- */
-.timeline {
-  position: relative;
-  margin: 0 0 30px 0;
-  padding: 0;
-  list-style: none;
-}
-.timeline:before {
-  content: '';
-  position: absolute;
-  top: 0px;
-  bottom: 0;
-  width: 4px;
-  background: #ddd;
-  left: 31px;
-  margin: 0;
-  border-radius: 2px;
-}
-.timeline > li {
-  position: relative;
-  margin-right: 10px;
-  margin-bottom: 15px;
-}
-.timeline > li:before,
-.timeline > li:after {
-  content: " ";
-  display: table;
-}
-.timeline > li:after {
-  clear: both;
-}
-.timeline > li > .timeline-item {
-  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  border-radius: 3px;
-  margin-top: 0px;
-  background: #fff;
-  color: #444;
-  margin-left: 60px;
-  margin-right: 15px;
-  padding: 0;
-  position: relative;
-}
-.timeline > li > .timeline-item > .time {
-  color: #999;
-  float: right;
-  padding: 10px;
-  font-size: 12px;
-}
-.timeline > li > .timeline-item > .timeline-header {
-  margin: 0;
-  color: #555;
-  border-bottom: 1px solid #f4f4f4;
-  padding: 10px;
-  font-size: 16px;
-  line-height: 1.1;
-}
-.timeline > li > .timeline-item > .timeline-header > a {
-  font-weight: 600;
-}
-.timeline > li > .timeline-item > .timeline-body,
-.timeline > li > .timeline-item > .timeline-footer {
-  padding: 10px;
-}
-.timeline > li.time-label > span {
-  font-weight: 600;
-  padding: 5px;
-  display: inline-block;
-  background-color: #fff;
-  border-radius: 4px;
-}
-.timeline > li > .fa,
-.timeline > li > .glyphicon,
-.timeline > li > .ion {
-  width: 30px;
-  height: 30px;
-  font-size: 15px;
-  line-height: 30px;
-  position: absolute;
-  color: #666;
-  background: #d2d6de;
-  border-radius: 50%;
-  text-align: center;
-  left: 18px;
-  top: 0;
-}
-/*
- * Component: Button
- * -----------------
- */
-.btn {
-  border-radius: 3px;
-  -webkit-box-shadow: none;
-  box-shadow: none;
-  border: 1px solid transparent;
-}
-.btn.uppercase {
-  text-transform: uppercase;
-}
-.btn.btn-flat {
-  border-radius: 0;
-  -webkit-box-shadow: none;
-  -moz-box-shadow: none;
-  box-shadow: none;
-  border-width: 1px;
-}
-.btn:active {
-  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-  -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-}
-.btn:focus {
-  outline: none;
-}
-.btn.btn-file {
-  position: relative;
-  overflow: hidden;
-}
-.btn.btn-file > input[type='file'] {
-  position: absolute;
-  top: 0;
-  right: 0;
-  min-width: 100%;
-  min-height: 100%;
-  font-size: 100px;
-  text-align: right;
-  opacity: 0;
-  filter: alpha(opacity=0);
-  outline: none;
-  background: white;
-  cursor: inherit;
-  display: block;
-}
-.btn-default {
-  background-color: #f4f4f4;
-  color: #444;
-  border-color: #ddd;
-}
-.btn-default:hover,
-.btn-default:active,
-.btn-default.hover {
-  background-color: #e7e7e7 !important;
-}
-.btn-primary {
-  background-color: #3c8dbc;
-  border-color: #367fa9;
-}
-.btn-primary:hover,
-.btn-primary:active,
-.btn-primary.hover {
-  background-color: #367fa9;
-}
-.btn-success {
-  background-color: #00a65a;
-  border-color: #008d4c;
-}
-.btn-success:hover,
-.btn-success:active,
-.btn-success.hover {
-  background-color: #008d4c;
-}
-.btn-info {
-  background-color: #00c0ef;
-  border-color: #00acd6;
-}
-.btn-info:hover,
-.btn-info:active,
-.btn-info.hover {
-  background-color: #00acd6;
-}
-.btn-danger {
-  background-color: #dd4b39;
-  border-color: #d73925;
-}
-.btn-danger:hover,
-.btn-danger:active,
-.btn-danger.hover {
-  background-color: #d73925;
-}
-.btn-warning {
-  background-color: #f39c12;
-  border-color: #e08e0b;
-}
-.btn-warning:hover,
-.btn-warning:active,
-.btn-warning.hover {
-  background-color: #e08e0b;
-}
-.btn-outline {
-  border: 1px solid #fff;
-  background: transparent;
-  color: #fff;
-}
-.btn-outline:hover,
-.btn-outline:focus,
-.btn-outline:active {
-  color: rgba(255, 255, 255, 0.7);
-  border-color: rgba(255, 255, 255, 0.7);
-}
-.btn-link {
-  -webkit-box-shadow: none;
-  box-shadow: none;
-}
-.btn[class*='bg-']:hover {
-  -webkit-box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2);
-  box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2);
-}
-.btn-app {
-  border-radius: 3px;
-  position: relative;
-  padding: 15px 5px;
-  margin: 0 0 10px 10px;
-  min-width: 80px;
-  height: 60px;
-  text-align: center;
-  color: #666;
-  border: 1px solid #ddd;
-  background-color: #f4f4f4;
-  font-size: 12px;
-}
-.btn-app > .fa,
-.btn-app > .glyphicon,
-.btn-app > .ion {
-  font-size: 20px;
-  display: block;
-}
-.btn-app:hover {
-  background: #f4f4f4;
-  color: #444;
-  border-color: #aaa;
-}
-.btn-app:active,
-.btn-app:focus {
-  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-  -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-}
-.btn-app > .badge {
-  position: absolute;
-  top: -3px;
-  right: -10px;
-  font-size: 10px;
-  font-weight: 400;
-}
-/*
- * Component: Callout
- * ------------------
- */
-.callout {
-  border-radius: 3px;
-  margin: 0 0 20px 0;
-  padding: 15px 30px 15px 15px;
-  border-left: 5px solid #eee;
-}
-.callout a {
-  color: #fff;
-  text-decoration: underline;
-}
-.callout a:hover {
-  color: #eee;
-}
-.callout h4 {
-  margin-top: 0;
-  font-weight: 600;
-}
-.callout p:last-child {
-  margin-bottom: 0;
-}
-.callout code,
-.callout .highlight {
-  background-color: #fff;
-}
-.callout.callout-danger {
-  border-color: #c23321;
-}
-.callout.callout-warning {
-  border-color: #c87f0a;
-}
-.callout.callout-info {
-  border-color: #0097bc;
-}
-.callout.callout-success {
-  border-color: #00733e;
-}
-/*
- * Component: alert
- * ----------------
- */
-.alert {
-  border-radius: 3px;
-}
-.alert h4 {
-  font-weight: 600;
-}
-.alert .icon {
-  margin-right: 10px;
-}
-.alert .close {
-  color: #000;
-  opacity: 0.2;
-  filter: alpha(opacity=20);
-}
-.alert .close:hover {
-  opacity: 0.5;
-  filter: alpha(opacity=50);
-}
-.alert a {
-  color: #fff;
-  text-decoration: underline;
-}
-.alert-success {
-  border-color: #008d4c;
-}
-.alert-danger,
-.alert-error {
-  border-color: #d73925;
-}
-.alert-warning {
-  border-color: #e08e0b;
-}
-.alert-info {
-  border-color: #00acd6;
-}
-/*
- * Component: Nav
- * --------------
- */
-/* NAV PILLS */
-.nav-pills > li > a {
-  border-radius: 0;
-  border-top: 3px solid transparent;
-  color: #444;
-}
-.nav-pills > li > a > .fa,
-.nav-pills > li > a > .glyphicon,
-.nav-pills > li > a > .ion {
-  margin-right: 5px;
-}
-.nav-pills > li.active > a,
-.nav-pills > li.active > a:hover {
-  background-color: #f4f4f4;
-  border-top-color: #3c8dbc;
-  color: #444;
-}
-.nav-pills > li.active > a {
-  font-weight: 600;
-}
-.nav-pills > li > a:hover {
-  background-color: #f6f6f6;
-}
-/* NAV STACKED */
-.nav-stacked > li > a {
-  border-radius: 0;
-  border-top: 0;
-  border-left: 3px solid transparent;
-  color: #444;
-}
-.nav-stacked > li.active > a,
-.nav-stacked > li.active > a:hover {
-  background-color: #f4f4f4;
-  border-top: 0;
-  border-left-color: #3c8dbc;
-  color: #444;
-}
-.nav-stacked > li.header {
-  border-bottom: 1px solid #ddd;
-  color: #777;
-  margin-bottom: 10px;
-  padding: 5px 10px;
-  text-transform: uppercase;
-}
-/* NAV TABS */
-.nav-tabs-custom {
-  margin-bottom: 20px;
-  background: #fff;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  border-radius: 3px;
-}
-.nav-tabs-custom > .nav-tabs {
-  margin: 0;
-  border-bottom-color: #f4f4f4;
-  border-top-right-radius: 3px;
-  border-top-left-radius: 3px;
-}
-.nav-tabs-custom > .nav-tabs > li {
-  border-top: 3px solid transparent;
-  margin-bottom: -2px;
-  margin-right: 5px;
-}
-.nav-tabs-custom > .nav-tabs > li > a {
-  border-radius: 0 !important;
-}
-.nav-tabs-custom > .nav-tabs > li > a,
-.nav-tabs-custom > .nav-tabs > li > a:hover {
-  background: transparent;
-  margin: 0;
-}
-.nav-tabs-custom > .nav-tabs > li:not(.active) > a:hover,
-.nav-tabs-custom > .nav-tabs > li:not(.active) > a:focus,
-.nav-tabs-custom > .nav-tabs > li:not(.active) > a:active {
-  border-color: transparent;
-}
-.nav-tabs-custom > .nav-tabs > li.active {
-  border-top-color: #3c8dbc;
-}
-.nav-tabs-custom > .nav-tabs > li.active > a,
-.nav-tabs-custom > .nav-tabs > li.active:hover > a {
-  background-color: #fff;
-}
-.nav-tabs-custom > .nav-tabs > li.active > a {
-  border-top: 0;
-  border-left-color: #f4f4f4;
-  border-right-color: #f4f4f4;
-}
-.nav-tabs-custom > .nav-tabs > li:first-of-type {
-  margin-left: 0;
-}
-.nav-tabs-custom > .nav-tabs > li:first-of-type.active > a {
-  border-left-width: 0;
-}
-.nav-tabs-custom > .nav-tabs.pull-right {
-  float: none!important;
-}
-.nav-tabs-custom > .nav-tabs.pull-right > li {
-  float: right;
-}
-.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type {
-  margin-right: 0;
-}
-.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a {
-  border-left-width: 1px;
-  border-right-width: 0;
-}
-.nav-tabs-custom > .nav-tabs > li.header {
-  line-height: 35px;
-  padding: 0 10px;
-  font-size: 20px;
-  color: #444;
-}
-.nav-tabs-custom > .nav-tabs > li.header > .fa,
-.nav-tabs-custom > .nav-tabs > li.header > .glyphicon,
-.nav-tabs-custom > .nav-tabs > li.header > .ion {
-  margin-right: 5px;
-}
-.nav-tabs-custom > .tab-content {
-  background: #fff;
-  padding: 10px;
-  border-bottom-right-radius: 3px;
-  border-bottom-left-radius: 3px;
-}
-/* Nav tabs bottom */
-.tabs-bottom.nav-3 li a {
-  width: 3333.33333333% !important;
-}
-.tabs-bottom li a {
-  border: 0;
-}
-/* PAGINATION */
-.pagination > li > a {
-  background: #fafafa;
-  color: #666;
-}
-.pagination > li:first-of-type a,
-.pagination > li:last-of-type a {
-  border-radius: 0;
-}
-/*
- * Component: Products List
- * ------------------------
- */
-.products-list {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-.products-list > .item {
-  border-radius: 3px;
-  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  padding: 10px 0;
-  background: #fff;
-}
-.products-list > .item:before,
-.products-list > .item:after {
-  content: " ";
-  display: table;
-}
-.products-list > .item:after {
-  clear: both;
-}
-.products-list .product-img {
-  float: left;
-}
-.products-list .product-img img {
-  width: 50px;
-  height: 50px;
-}
-.products-list .product-info {
-  margin-left: 60px;
-}
-.products-list .product-title {
-  font-weight: 600;
-}
-.products-list .product-description {
-  display: block;
-  color: #999;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-.product-list-in-box > .item {
-  -webkit-box-shadow: none;
-  box-shadow: none;
-  border-radius: 0;
-  border-bottom: 1px solid #f4f4f4;
-}
-.product-list-in-box > .item:last-of-type {
-  border-bottom-width: 0;
-}
-/*
- * Component: Table
- * ----------------
- */
-.table > thead > tr > th,
-.table > tbody > tr > th,
-.table > tfoot > tr > th,
-.table > thead > tr > td,
-.table > tbody > tr > td,
-.table > tfoot > tr > td {
-  border-top: 1px solid #f4f4f4;
-}
-.table > thead > tr > th {
-  border-bottom: 2px solid #f4f4f4;
-}
-.table tr td .progress {
-  margin-top: 5px;
-}
-.table-bordered {
-  border: 1px solid #f4f4f4;
-}
-.table-bordered > thead > tr > th,
-.table-bordered > tbody > tr > th,
-.table-bordered > tfoot > tr > th,
-.table-bordered > thead > tr > td,
-.table-bordered > tbody > tr > td,
-.table-bordered > tfoot > tr > td {
-  border: 1px solid #f4f4f4;
-}
-.table-bordered > thead > tr > th,
-.table-bordered > thead > tr > td {
-  border-bottom-width: 2px;
-}
-.table.no-border,
-.table.no-border td,
-.table.no-border th {
-  border: 0;
-}
-/* .text-center in tables */
-table.text-center,
-table.text-center td,
-table.text-center th {
-  text-align: center;
-}
-.table.align th {
-  text-align: left;
-}
-.table.align td {
-  text-align: right;
-}
-/*
- * Component: Label
- * ----------------
- */
-.label-default {
-  background-color: #d2d6de;
-  color: #444;
-}
-/*
- * Component: Direct Chat
- * ----------------------
- */
-.direct-chat .box-body {
-  border-bottom-right-radius: 0;
-  border-bottom-left-radius: 0;
-  position: relative;
-  overflow-x: hidden;
-  padding: 0;
-}
-.direct-chat.chat-pane-open .direct-chat-contacts {
-  -webkit-transform: translate(0, 0);
-  -ms-transform: translate(0, 0);
-  -o-transform: translate(0, 0);
-  transform: translate(0, 0);
-}
-.direct-chat-messages {
-  -webkit-transform: translate(0, 0);
-  -ms-transform: translate(0, 0);
-  -o-transform: translate(0, 0);
-  transform: translate(0, 0);
-  padding: 10px;
-  height: 250px;
-  overflow: auto;
-}
-.direct-chat-msg,
-.direct-chat-text {
-  display: block;
-}
-.direct-chat-msg {
-  margin-bottom: 10px;
-}
-.direct-chat-msg:before,
-.direct-chat-msg:after {
-  content: " ";
-  display: table;
-}
-.direct-chat-msg:after {
-  clear: both;
-}
-.direct-chat-messages,
-.direct-chat-contacts {
-  -webkit-transition: -webkit-transform 0.5s ease-in-out;
-  -moz-transition: -moz-transform 0.5s ease-in-out;
-  -o-transition: -o-transform 0.5s ease-in-out;
-  transition: transform 0.5s ease-in-out;
-}
-.direct-chat-text {
-  border-radius: 5px;
-  position: relative;
-  padding: 5px 10px;
-  background: #d2d6de;
-  border: 1px solid #d2d6de;
-  margin: 5px 0 0 50px;
-  color: #444444;
-}
-.direct-chat-text:after,
-.direct-chat-text:before {
-  position: absolute;
-  right: 100%;
-  top: 15px;
-  border: solid transparent;
-  border-right-color: #d2d6de;
-  content: ' ';
-  height: 0;
-  width: 0;
-  pointer-events: none;
-}
-.direct-chat-text:after {
-  border-width: 5px;
-  margin-top: -5px;
-}
-.direct-chat-text:before {
-  border-width: 6px;
-  margin-top: -6px;
-}
-.right .direct-chat-text {
-  margin-right: 50px;
-  margin-left: 0;
-}
-.right .direct-chat-text:after,
-.right .direct-chat-text:before {
-  right: auto;
-  left: 100%;
-  border-right-color: transparent;
-  border-left-color: #d2d6de;
-}
-.direct-chat-img {
-  border-radius: 50%;
-  float: left;
-  width: 40px;
-  height: 40px;
-}
-.right .direct-chat-img {
-  float: right;
-}
-.direct-chat-info {
-  display: block;
-  margin-bottom: 2px;
-  font-size: 12px;
-}
-.direct-chat-name {
-  font-weight: 600;
-}
-.direct-chat-timestamp {
-  color: #999;
-}
-.direct-chat-contacts-open .direct-chat-contacts {
-  -webkit-transform: translate(0, 0);
-  -ms-transform: translate(0, 0);
-  -o-transform: translate(0, 0);
-  transform: translate(0, 0);
-}
-.direct-chat-contacts {
-  -webkit-transform: translate(100%, 0);
-  -ms-transform: translate(100%, 0);
-  -o-transform: translate(100%, 0);
-  transform: translate(100%, 0);
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  height: 250px;
-  width: 100%;
-  background: #222d32;
-  color: #fff;
-  overflow: auto;
-}
-.contacts-list > li {
-  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
-  padding: 10px;
-  margin: 0;
-}
-.contacts-list > li:before,
-.contacts-list > li:after {
-  content: " ";
-  display: table;
-}
-.contacts-list > li:after {
-  clear: both;
-}
-.contacts-list > li:last-of-type {
-  border-bottom: none;
-}
-.contacts-list-img {
-  border-radius: 50%;
-  width: 40px;
-  float: left;
-}
-.contacts-list-info {
-  margin-left: 45px;
-  color: #fff;
-}
-.contacts-list-name,
-.contacts-list-status {
-  display: block;
-}
-.contacts-list-name {
-  font-weight: 600;
-}
-.contacts-list-status {
-  font-size: 12px;
-}
-.contacts-list-date {
-  color: #aaa;
-  font-weight: normal;
-}
-.contacts-list-msg {
-  color: #999;
-}
-.direct-chat-danger .right > .direct-chat-text {
-  background: #dd4b39;
-  border-color: #dd4b39;
-  color: #ffffff;
-}
-.direct-chat-danger .right > .direct-chat-text:after,
-.direct-chat-danger .right > .direct-chat-text:before {
-  border-left-color: #dd4b39;
-}
-.direct-chat-primary .right > .direct-chat-text {
-  background: #3c8dbc;
-  border-color: #3c8dbc;
-  color: #ffffff;
-}
-.direct-chat-primary .right > .direct-chat-text:after,
-.direct-chat-primary .right > .direct-chat-text:before {
-  border-left-color: #3c8dbc;
-}
-.direct-chat-warning .right > .direct-chat-text {
-  background: #f39c12;
-  border-color: #f39c12;
-  color: #ffffff;
-}
-.direct-chat-warning .right > .direct-chat-text:after,
-.direct-chat-warning .right > .direct-chat-text:before {
-  border-left-color: #f39c12;
-}
-.direct-chat-info .right > .direct-chat-text {
-  background: #00c0ef;
-  border-color: #00c0ef;
-  color: #ffffff;
-}
-.direct-chat-info .right > .direct-chat-text:after,
-.direct-chat-info .right > .direct-chat-text:before {
-  border-left-color: #00c0ef;
-}
-.direct-chat-success .right > .direct-chat-text {
-  background: #00a65a;
-  border-color: #00a65a;
-  color: #ffffff;
-}
-.direct-chat-success .right > .direct-chat-text:after,
-.direct-chat-success .right > .direct-chat-text:before {
-  border-left-color: #00a65a;
-}
-/*
- * Component: Users List
- * ---------------------
- */
-.users-list > li {
-  width: 25%;
-  float: left;
-  padding: 10px;
-  text-align: center;
-}
-.users-list > li > img {
-  border-radius: 50%;
-  max-width: 100%;
-  height: auto;
-}
-.users-list-name,
-.users-list-date {
-  display: block;
-}
-.users-list-name {
-  font-weight: 600;
-  color: #444;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-.users-list-name:hover {
-  color: #999;
-}
-.users-list-date {
-  color: #999;
-  font-size: 12px;
-}
-/*
- * Component: Carousel
- * -------------------
- */
-.carousel-control {
-  background-image: none!important;
-}
-.carousel-control > .fa {
-  font-size: 40px;
-  position: absolute;
-  top: 50%;
-  z-index: 5;
-  display: inline-block;
-  margin-top: -20px;
-}
-/*
- * Component: modal
- * ----------------
- */
-.modal {
-  background: rgba(0, 0, 0, 0.3);
-}
-.modal-content {
-  border-radius: 0;
-  -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
-  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
-  border: 0;
-}
-@media (min-width: 768px) {
-  .modal-content {
-    -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
-    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
-  }
-}
-.modal-header {
-  border-bottom-color: #f4f4f4;
-}
-.modal-footer {
-  border-top-color: #f4f4f4;
-}
-.modal-primary .modal-header,
-.modal-primary .modal-footer {
-  border-color: #307095;
-}
-.modal-warning .modal-header,
-.modal-warning .modal-footer {
-  border-color: #c87f0a;
-}
-.modal-info .modal-header,
-.modal-info .modal-footer {
-  border-color: #0097bc;
-}
-.modal-success .modal-header,
-.modal-success .modal-footer {
-  border-color: #00733e;
-}
-.modal-danger .modal-header,
-.modal-danger .modal-footer {
-  border-color: #c23321;
-}
-/*
- * Page: Mailbox
- * -------------
- */
-.mailbox-messages > .table {
-  margin: 0;
-}
-.mailbox-controls {
-  padding: 5px;
-}
-.mailbox-controls.with-border {
-  border-bottom: 1px solid #f4f4f4;
-}
-.mailbox-read-info {
-  border-bottom: 1px solid #f4f4f4;
-  padding: 10px;
-}
-.mailbox-read-info h3 {
-  font-size: 20px;
-  margin: 0;
-}
-.mailbox-read-info h5 {
-  margin: 0;
-  padding: 5px 0 0 0;
-}
-.mailbox-read-time {
-  color: #999;
-  font-size: 13px;
-}
-.mailbox-read-message {
-  padding: 10px;
-}
-.mailbox-attachments li {
-  float: left;
-  width: 200px;
-  border: 1px solid #eee;
-  margin-bottom: 10px;
-  margin-right: 10px;
-}
-.mailbox-attachment-name {
-  font-weight: bold;
-  color: #666;
-}
-.mailbox-attachment-icon,
-.mailbox-attachment-info,
-.mailbox-attachment-size {
-  display: block;
-}
-.mailbox-attachment-info {
-  padding: 10px;
-  background: #f4f4f4;
-}
-.mailbox-attachment-size {
-  color: #999;
-  font-size: 12px;
-}
-.mailbox-attachment-icon {
-  text-align: center;
-  font-size: 65px;
-  color: #666;
-  padding: 20px 10px;
-}
-.mailbox-attachment-icon.has-img {
-  padding: 0;
-}
-.mailbox-attachment-icon.has-img > img {
-  max-width: 100%;
-  height: auto;
-}
-.mailbox .table-mailbox {
-  border-left: 1px solid #f4f4f4;
-  border-right: 1px solid #f4f4f4;
-  border-bottom: 1px solid #f4f4f4;
-}
-.mailbox .table-mailbox tr.unread > td {
-  background-color: rgba(0, 0, 0, 0.05);
-  color: #000;
-  font-weight: 600;
-}
-.mailbox .table-mailbox tr > td > .fa.fa-star,
-.mailbox .table-mailbox tr > td > .fa.fa-star-o,
-.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star,
-.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star-empty {
-  color: #f39c12;
-  cursor: pointer;
-}
-.mailbox .table-mailbox tr > td.small-col {
-  width: 30px;
-}
-.mailbox .table-mailbox tr > td.name {
-  width: 150px;
-  font-weight: 600;
-}
-.mailbox .table-mailbox tr > td.time {
-  text-align: right;
-  width: 100px;
-}
-.mailbox .table-mailbox tr > td {
-  white-space: nowrap;
-}
-.mailbox .table-mailbox tr > td > a {
-  color: #444;
-}
-@media (max-width: 991px) {
-  .mailbox .nav-stacked > li:not(.header) {
-    float: left;
-    width: 50%;
-  }
-  .mailbox .nav-stacked > li:not(.header).header {
-    border: 0!important;
-  }
-  .mailbox .search-form {
-    margin-top: 10px;
-  }
-}
-/*
- * Page: Lock Screen
- * -----------------
- */
-/* ADD THIS CLASS TO THE <BODY> TAG */
-.lockscreen {
-  background: #d2d6de;
-}
-.lockscreen-logo {
-  font-size: 35px;
-  text-align: center;
-  margin-bottom: 25px;
-  font-weight: 300;
-}
-.lockscreen-logo a {
-  color: #444;
-}
-.lockscreen-wrapper {
-  max-width: 400px;
-  margin: 0 auto;
-  margin-top: 10%;
-}
-/* User name [optional] */
-.lockscreen .lockscreen-name {
-  text-align: center;
-  font-weight: 600;
-}
-/* Will contain the image and the sign in form */
-.lockscreen-item {
-  border-radius: 4px;
-  padding: 0;
-  background: #fff;
-  position: relative;
-  margin: 10px auto 30px auto;
-  width: 290px;
-}
-/* User image */
-.lockscreen-image {
-  border-radius: 50%;
-  position: absolute;
-  left: -10px;
-  top: -25px;
-  background: #fff;
-  padding: 5px;
-  z-index: 10;
-}
-.lockscreen-image > img {
-  border-radius: 50%;
-  width: 70px;
-  height: 70px;
-}
-/* Contains the password input and the login button */
-.lockscreen-credentials {
-  margin-left: 70px;
-}
-.lockscreen-credentials .form-control {
-  border: 0 !important;
-}
-.lockscreen-credentials .btn {
-  background-color: #fff;
-  border: 0;
-  padding: 0 10px;
-}
-.lockscreen-footer {
-  margin-top: 10px;
-}
-/*
- * Page: Login & Register
- * ----------------------
- */
-.login-logo,
-.register-logo {
-  font-size: 35px;
-  text-align: center;
-  margin-bottom: 25px;
-  font-weight: 300;
-}
-.login-logo a,
-.register-logo a {
-  color: #444;
-}
-.login-page,
-.register-page {
-  background: #d2d6de;
-}
-.login-box,
-.register-box {
-  width: 360px;
-  margin: 7% auto;
-}
-@media (max-width: 768px) {
-  .login-box,
-  .register-box {
-    width: 90%;
-    margin-top: 20px;
-  }
-}
-.login-box-body,
-.register-box-body {
-  background: #fff;
-  padding: 20px;
-  color: #444;
-  border-top: 0;
-  color: #666;
-}
-.login-box-body .form-control-feedback,
-.register-box-body .form-control-feedback {
-  color: #777;
-}
-.login-box-msg,
-.register-box-msg {
-  margin: 0;
-  text-align: center;
-  padding: 0 20px 20px 20px;
-}
-.social-auth-links {
-  margin: 10px 0;
-}
-/*
- * Page: 400 and 500 error pages
- * ------------------------------
- */
-.error-page {
-  width: 600px;
-  margin: 20px auto 0 auto;
-}
-@media (max-width: 991px) {
-  .error-page {
-    width: 100%;
-  }
-}
-.error-page > .headline {
-  float: left;
-  font-size: 100px;
-  font-weight: 300;
-}
-@media (max-width: 991px) {
-  .error-page > .headline {
-    float: none;
-    text-align: center;
-  }
-}
-.error-page > .error-content {
-  margin-left: 190px;
-  display: block;
-}
-@media (max-width: 991px) {
-  .error-page > .error-content {
-    margin-left: 0;
-  }
-}
-.error-page > .error-content > h3 {
-  font-weight: 300;
-  font-size: 25px;
-}
-@media (max-width: 991px) {
-  .error-page > .error-content > h3 {
-    text-align: center;
-  }
-}
-/*
- * Page: Invoice
- * -------------
- */
-.invoice {
-  position: relative;
-  background: #fff;
-  border: 1px solid #f4f4f4;
-  padding: 20px;
-  margin: 10px 25px;
-}
-.invoice-title {
-  margin-top: 0;
-}
-/*
- * Plugin: Social Buttons
- * ----------------------
- */
-.btn-social {
-  position: relative;
-  padding-left: 44px !important;
-  text-align: left;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-.btn-social :first-child {
-  position: absolute;
-  left: 0;
-  top: 0;
-  bottom: 0;
-  width: 32px !important;
-  line-height: 34px !important;
-  font-size: 1.6em!important;
-  text-align: center;
-  border-right: 1px solid rgba(0, 0, 0, 0.2);
-}
-.btn-social.btn-lg {
-  padding-left: 61px !important;
-}
-.btn-social.btn-lg :first-child {
-  line-height: 45px;
-  width: 45px;
-  font-size: 1.8em;
-}
-.btn-social.btn-sm {
-  padding-left: 38px !important;
-}
-.btn-social.btn-sm :first-child {
-  line-height: 28px;
-  width: 28px;
-  font-size: 1.4em;
-}
-.btn-social.btn-xs {
-  padding-left: 30px !important;
-}
-.btn-social.btn-xs :first-child {
-  line-height: 20px;
-  width: 20px;
-  font-size: 1.2em;
-}
-.btn-social-icon {
-  position: relative;
-  padding-left: 44px !important;
-  text-align: left;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  height: 34px;
-  width: 34px;
-  padding: 0;
-}
-.btn-social-icon :first-child {
-  position: absolute;
-  left: 0;
-  top: 0;
-  bottom: 0;
-  width: 32px !important;
-  line-height: 34px !important;
-  font-size: 1.6em!important;
-  text-align: center;
-  border-right: 1px solid rgba(0, 0, 0, 0.2);
-}
-.btn-social-icon.btn-lg {
-  padding-left: 61px !important;
-}
-.btn-social-icon.btn-lg :first-child {
-  line-height: 45px;
-  width: 45px;
-  font-size: 1.8em;
-}
-.btn-social-icon.btn-sm {
-  padding-left: 38px !important;
-}
-.btn-social-icon.btn-sm :first-child {
-  line-height: 28px;
-  width: 28px;
-  font-size: 1.4em;
-}
-.btn-social-icon.btn-xs {
-  padding-left: 30px !important;
-}
-.btn-social-icon.btn-xs :first-child {
-  line-height: 20px;
-  width: 20px;
-  font-size: 1.2em;
-}
-.btn-social-icon :first-child {
-  border: none;
-  text-align: center;
-  width: 100%!important;
-}
-.btn-social-icon.btn-lg {
-  height: 45px;
-  width: 45px;
-  padding-left: 0;
-  padding-right: 0;
-}
-.btn-social-icon.btn-sm {
-  height: 30px;
-  width: 30px;
-  padding-left: 0;
-  padding-right: 0;
-}
-.btn-social-icon.btn-xs {
-  height: 22px;
-  width: 22px;
-  padding-left: 0;
-  padding-right: 0;
-}
-.btn-bitbucket {
-  color: #ffffff;
-  background-color: #205081;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-bitbucket:hover,
-.btn-bitbucket:focus,
-.btn-bitbucket.focus,
-.btn-bitbucket:active,
-.btn-bitbucket.active,
-.open > .dropdown-toggle.btn-bitbucket {
-  color: #ffffff;
-  background-color: #163758;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-bitbucket:active,
-.btn-bitbucket.active,
-.open > .dropdown-toggle.btn-bitbucket {
-  background-image: none;
-}
-.btn-bitbucket.disabled,
-.btn-bitbucket[disabled],
-fieldset[disabled] .btn-bitbucket,
-.btn-bitbucket.disabled:hover,
-.btn-bitbucket[disabled]:hover,
-fieldset[disabled] .btn-bitbucket:hover,
-.btn-bitbucket.disabled:focus,
-.btn-bitbucket[disabled]:focus,
-fieldset[disabled] .btn-bitbucket:focus,
-.btn-bitbucket.disabled.focus,
-.btn-bitbucket[disabled].focus,
-fieldset[disabled] .btn-bitbucket.focus,
-.btn-bitbucket.disabled:active,
-.btn-bitbucket[disabled]:active,
-fieldset[disabled] .btn-bitbucket:active,
-.btn-bitbucket.disabled.active,
-.btn-bitbucket[disabled].active,
-fieldset[disabled] .btn-bitbucket.active {
-  background-color: #205081;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-bitbucket .badge {
-  color: #205081;
-  background-color: #ffffff;
-}
-.btn-dropbox {
-  color: #ffffff;
-  background-color: #1087dd;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-dropbox:hover,
-.btn-dropbox:focus,
-.btn-dropbox.focus,
-.btn-dropbox:active,
-.btn-dropbox.active,
-.open > .dropdown-toggle.btn-dropbox {
-  color: #ffffff;
-  background-color: #0d6aad;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-dropbox:active,
-.btn-dropbox.active,
-.open > .dropdown-toggle.btn-dropbox {
-  background-image: none;
-}
-.btn-dropbox.disabled,
-.btn-dropbox[disabled],
-fieldset[disabled] .btn-dropbox,
-.btn-dropbox.disabled:hover,
-.btn-dropbox[disabled]:hover,
-fieldset[disabled] .btn-dropbox:hover,
-.btn-dropbox.disabled:focus,
-.btn-dropbox[disabled]:focus,
-fieldset[disabled] .btn-dropbox:focus,
-.btn-dropbox.disabled.focus,
-.btn-dropbox[disabled].focus,
-fieldset[disabled] .btn-dropbox.focus,
-.btn-dropbox.disabled:active,
-.btn-dropbox[disabled]:active,
-fieldset[disabled] .btn-dropbox:active,
-.btn-dropbox.disabled.active,
-.btn-dropbox[disabled].active,
-fieldset[disabled] .btn-dropbox.active {
-  background-color: #1087dd;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-dropbox .badge {
-  color: #1087dd;
-  background-color: #ffffff;
-}
-.btn-facebook {
-  color: #ffffff;
-  background-color: #3b5998;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-facebook:hover,
-.btn-facebook:focus,
-.btn-facebook.focus,
-.btn-facebook:active,
-.btn-facebook.active,
-.open > .dropdown-toggle.btn-facebook {
-  color: #ffffff;
-  background-color: #2d4373;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-facebook:active,
-.btn-facebook.active,
-.open > .dropdown-toggle.btn-facebook {
-  background-image: none;
-}
-.btn-facebook.disabled,
-.btn-facebook[disabled],
-fieldset[disabled] .btn-facebook,
-.btn-facebook.disabled:hover,
-.btn-facebook[disabled]:hover,
-fieldset[disabled] .btn-facebook:hover,
-.btn-facebook.disabled:focus,
-.btn-facebook[disabled]:focus,
-fieldset[disabled] .btn-facebook:focus,
-.btn-facebook.disabled.focus,
-.btn-facebook[disabled].focus,
-fieldset[disabled] .btn-facebook.focus,
-.btn-facebook.disabled:active,
-.btn-facebook[disabled]:active,
-fieldset[disabled] .btn-facebook:active,
-.btn-facebook.disabled.active,
-.btn-facebook[disabled].active,
-fieldset[disabled] .btn-facebook.active {
-  background-color: #3b5998;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-facebook .badge {
-  color: #3b5998;
-  background-color: #ffffff;
-}
-.btn-flickr {
-  color: #ffffff;
-  background-color: #ff0084;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-flickr:hover,
-.btn-flickr:focus,
-.btn-flickr.focus,
-.btn-flickr:active,
-.btn-flickr.active,
-.open > .dropdown-toggle.btn-flickr {
-  color: #ffffff;
-  background-color: #cc006a;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-flickr:active,
-.btn-flickr.active,
-.open > .dropdown-toggle.btn-flickr {
-  background-image: none;
-}
-.btn-flickr.disabled,
-.btn-flickr[disabled],
-fieldset[disabled] .btn-flickr,
-.btn-flickr.disabled:hover,
-.btn-flickr[disabled]:hover,
-fieldset[disabled] .btn-flickr:hover,
-.btn-flickr.disabled:focus,
-.btn-flickr[disabled]:focus,
-fieldset[disabled] .btn-flickr:focus,
-.btn-flickr.disabled.focus,
-.btn-flickr[disabled].focus,
-fieldset[disabled] .btn-flickr.focus,
-.btn-flickr.disabled:active,
-.btn-flickr[disabled]:active,
-fieldset[disabled] .btn-flickr:active,
-.btn-flickr.disabled.active,
-.btn-flickr[disabled].active,
-fieldset[disabled] .btn-flickr.active {
-  background-color: #ff0084;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-flickr .badge {
-  color: #ff0084;
-  background-color: #ffffff;
-}
-.btn-foursquare {
-  color: #ffffff;
-  background-color: #0072b1;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-foursquare:hover,
-.btn-foursquare:focus,
-.btn-foursquare.focus,
-.btn-foursquare:active,
-.btn-foursquare.active,
-.open > .dropdown-toggle.btn-foursquare {
-  color: #ffffff;
-  background-color: #00517e;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-foursquare:active,
-.btn-foursquare.active,
-.open > .dropdown-toggle.btn-foursquare {
-  background-image: none;
-}
-.btn-foursquare.disabled,
-.btn-foursquare[disabled],
-fieldset[disabled] .btn-foursquare,
-.btn-foursquare.disabled:hover,
-.btn-foursquare[disabled]:hover,
-fieldset[disabled] .btn-foursquare:hover,
-.btn-foursquare.disabled:focus,
-.btn-foursquare[disabled]:focus,
-fieldset[disabled] .btn-foursquare:focus,
-.btn-foursquare.disabled.focus,
-.btn-foursquare[disabled].focus,
-fieldset[disabled] .btn-foursquare.focus,
-.btn-foursquare.disabled:active,
-.btn-foursquare[disabled]:active,
-fieldset[disabled] .btn-foursquare:active,
-.btn-foursquare.disabled.active,
-.btn-foursquare[disabled].active,
-fieldset[disabled] .btn-foursquare.active {
-  background-color: #0072b1;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-foursquare .badge {
-  color: #0072b1;
-  background-color: #ffffff;
-}
-.btn-github {
-  color: #ffffff;
-  background-color: #444444;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-github:hover,
-.btn-github:focus,
-.btn-github.focus,
-.btn-github:active,
-.btn-github.active,
-.open > .dropdown-toggle.btn-github {
-  color: #ffffff;
-  background-color: #2b2b2b;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-github:active,
-.btn-github.active,
-.open > .dropdown-toggle.btn-github {
-  background-image: none;
-}
-.btn-github.disabled,
-.btn-github[disabled],
-fieldset[disabled] .btn-github,
-.btn-github.disabled:hover,
-.btn-github[disabled]:hover,
-fieldset[disabled] .btn-github:hover,
-.btn-github.disabled:focus,
-.btn-github[disabled]:focus,
-fieldset[disabled] .btn-github:focus,
-.btn-github.disabled.focus,
-.btn-github[disabled].focus,
-fieldset[disabled] .btn-github.focus,
-.btn-github.disabled:active,
-.btn-github[disabled]:active,
-fieldset[disabled] .btn-github:active,
-.btn-github.disabled.active,
-.btn-github[disabled].active,
-fieldset[disabled] .btn-github.active {
-  background-color: #444444;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-github .badge {
-  color: #444444;
-  background-color: #ffffff;
-}
-.btn-google-plus {
-  color: #ffffff;
-  background-color: #dd4b39;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-google-plus:hover,
-.btn-google-plus:focus,
-.btn-google-plus.focus,
-.btn-google-plus:active,
-.btn-google-plus.active,
-.open > .dropdown-toggle.btn-google-plus {
-  color: #ffffff;
-  background-color: #c23321;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-google-plus:active,
-.btn-google-plus.active,
-.open > .dropdown-toggle.btn-google-plus {
-  background-image: none;
-}
-.btn-google-plus.disabled,
-.btn-google-plus[disabled],
-fieldset[disabled] .btn-google-plus,
-.btn-google-plus.disabled:hover,
-.btn-google-plus[disabled]:hover,
-fieldset[disabled] .btn-google-plus:hover,
-.btn-google-plus.disabled:focus,
-.btn-google-plus[disabled]:focus,
-fieldset[disabled] .btn-google-plus:focus,
-.btn-google-plus.disabled.focus,
-.btn-google-plus[disabled].focus,
-fieldset[disabled] .btn-google-plus.focus,
-.btn-google-plus.disabled:active,
-.btn-google-plus[disabled]:active,
-fieldset[disabled] .btn-google-plus:active,
-.btn-google-plus.disabled.active,
-.btn-google-plus[disabled].active,
-fieldset[disabled] .btn-google-plus.active {
-  background-color: #dd4b39;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-google-plus .badge {
-  color: #dd4b39;
-  background-color: #ffffff;
-}
-.btn-instagram {
-  color: #ffffff;
-  background-color: #3f729b;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-instagram:hover,
-.btn-instagram:focus,
-.btn-instagram.focus,
-.btn-instagram:active,
-.btn-instagram.active,
-.open > .dropdown-toggle.btn-instagram {
-  color: #ffffff;
-  background-color: #305777;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-instagram:active,
-.btn-instagram.active,
-.open > .dropdown-toggle.btn-instagram {
-  background-image: none;
-}
-.btn-instagram.disabled,
-.btn-instagram[disabled],
-fieldset[disabled] .btn-instagram,
-.btn-instagram.disabled:hover,
-.btn-instagram[disabled]:hover,
-fieldset[disabled] .btn-instagram:hover,
-.btn-instagram.disabled:focus,
-.btn-instagram[disabled]:focus,
-fieldset[disabled] .btn-instagram:focus,
-.btn-instagram.disabled.focus,
-.btn-instagram[disabled].focus,
-fieldset[disabled] .btn-instagram.focus,
-.btn-instagram.disabled:active,
-.btn-instagram[disabled]:active,
-fieldset[disabled] .btn-instagram:active,
-.btn-instagram.disabled.active,
-.btn-instagram[disabled].active,
-fieldset[disabled] .btn-instagram.active {
-  background-color: #3f729b;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-instagram .badge {
-  color: #3f729b;
-  background-color: #ffffff;
-}
-.btn-linkedin {
-  color: #ffffff;
-  background-color: #007bb6;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-linkedin:hover,
-.btn-linkedin:focus,
-.btn-linkedin.focus,
-.btn-linkedin:active,
-.btn-linkedin.active,
-.open > .dropdown-toggle.btn-linkedin {
-  color: #ffffff;
-  background-color: #005983;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-linkedin:active,
-.btn-linkedin.active,
-.open > .dropdown-toggle.btn-linkedin {
-  background-image: none;
-}
-.btn-linkedin.disabled,
-.btn-linkedin[disabled],
-fieldset[disabled] .btn-linkedin,
-.btn-linkedin.disabled:hover,
-.btn-linkedin[disabled]:hover,
-fieldset[disabled] .btn-linkedin:hover,
-.btn-linkedin.disabled:focus,
-.btn-linkedin[disabled]:focus,
-fieldset[disabled] .btn-linkedin:focus,
-.btn-linkedin.disabled.focus,
-.btn-linkedin[disabled].focus,
-fieldset[disabled] .btn-linkedin.focus,
-.btn-linkedin.disabled:active,
-.btn-linkedin[disabled]:active,
-fieldset[disabled] .btn-linkedin:active,
-.btn-linkedin.disabled.active,
-.btn-linkedin[disabled].active,
-fieldset[disabled] .btn-linkedin.active {
-  background-color: #007bb6;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-linkedin .badge {
-  color: #007bb6;
-  background-color: #ffffff;
-}
-.btn-tumblr {
-  color: #ffffff;
-  background-color: #2c4762;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-tumblr:hover,
-.btn-tumblr:focus,
-.btn-tumblr.focus,
-.btn-tumblr:active,
-.btn-tumblr.active,
-.open > .dropdown-toggle.btn-tumblr {
-  color: #ffffff;
-  background-color: #1c2d3f;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-tumblr:active,
-.btn-tumblr.active,
-.open > .dropdown-toggle.btn-tumblr {
-  background-image: none;
-}
-.btn-tumblr.disabled,
-.btn-tumblr[disabled],
-fieldset[disabled] .btn-tumblr,
-.btn-tumblr.disabled:hover,
-.btn-tumblr[disabled]:hover,
-fieldset[disabled] .btn-tumblr:hover,
-.btn-tumblr.disabled:focus,
-.btn-tumblr[disabled]:focus,
-fieldset[disabled] .btn-tumblr:focus,
-.btn-tumblr.disabled.focus,
-.btn-tumblr[disabled].focus,
-fieldset[disabled] .btn-tumblr.focus,
-.btn-tumblr.disabled:active,
-.btn-tumblr[disabled]:active,
-fieldset[disabled] .btn-tumblr:active,
-.btn-tumblr.disabled.active,
-.btn-tumblr[disabled].active,
-fieldset[disabled] .btn-tumblr.active {
-  background-color: #2c4762;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-tumblr .badge {
-  color: #2c4762;
-  background-color: #ffffff;
-}
-.btn-twitter {
-  color: #ffffff;
-  background-color: #55acee;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-twitter:hover,
-.btn-twitter:focus,
-.btn-twitter.focus,
-.btn-twitter:active,
-.btn-twitter.active,
-.open > .dropdown-toggle.btn-twitter {
-  color: #ffffff;
-  background-color: #2795e9;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-twitter:active,
-.btn-twitter.active,
-.open > .dropdown-toggle.btn-twitter {
-  background-image: none;
-}
-.btn-twitter.disabled,
-.btn-twitter[disabled],
-fieldset[disabled] .btn-twitter,
-.btn-twitter.disabled:hover,
-.btn-twitter[disabled]:hover,
-fieldset[disabled] .btn-twitter:hover,
-.btn-twitter.disabled:focus,
-.btn-twitter[disabled]:focus,
-fieldset[disabled] .btn-twitter:focus,
-.btn-twitter.disabled.focus,
-.btn-twitter[disabled].focus,
-fieldset[disabled] .btn-twitter.focus,
-.btn-twitter.disabled:active,
-.btn-twitter[disabled]:active,
-fieldset[disabled] .btn-twitter:active,
-.btn-twitter.disabled.active,
-.btn-twitter[disabled].active,
-fieldset[disabled] .btn-twitter.active {
-  background-color: #55acee;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-twitter .badge {
-  color: #55acee;
-  background-color: #ffffff;
-}
-.btn-vk {
-  color: #ffffff;
-  background-color: #587ea3;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-vk:hover,
-.btn-vk:focus,
-.btn-vk.focus,
-.btn-vk:active,
-.btn-vk.active,
-.open > .dropdown-toggle.btn-vk {
-  color: #ffffff;
-  background-color: #466482;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-vk:active,
-.btn-vk.active,
-.open > .dropdown-toggle.btn-vk {
-  background-image: none;
-}
-.btn-vk.disabled,
-.btn-vk[disabled],
-fieldset[disabled] .btn-vk,
-.btn-vk.disabled:hover,
-.btn-vk[disabled]:hover,
-fieldset[disabled] .btn-vk:hover,
-.btn-vk.disabled:focus,
-.btn-vk[disabled]:focus,
-fieldset[disabled] .btn-vk:focus,
-.btn-vk.disabled.focus,
-.btn-vk[disabled].focus,
-fieldset[disabled] .btn-vk.focus,
-.btn-vk.disabled:active,
-.btn-vk[disabled]:active,
-fieldset[disabled] .btn-vk:active,
-.btn-vk.disabled.active,
-.btn-vk[disabled].active,
-fieldset[disabled] .btn-vk.active {
-  background-color: #587ea3;
-  border-color: rgba(0, 0, 0, 0.2);
-}
-.btn-vk .badge {
-  color: #587ea3;
-  background-color: #ffffff;
-}
-/*
- * Plugin: Full Calendar
- * ---------------------
- */
-.fc-button {
-  background: #f4f4f4;
-  background-image: none;
-  color: #444;
-  border-color: #ddd;
-  border-bottom-color: #ddd;
-}
-.fc-button:hover,
-.fc-button:active,
-.fc-button.hover {
-  background-color: #e9e9e9;
-}
-.fc-header-title h2 {
-  font-size: 15px;
-  line-height: 1.6em;
-  color: #666;
-  margin-left: 10px;
-}
-.fc-header-right {
-  padding-right: 10px;
-}
-.fc-header-left {
-  padding-left: 10px;
-}
-.fc-widget-header {
-  background: #fafafa;
-}
-.fc-grid {
-  width: 100%;
-  border: 0;
-}
-.fc-widget-header:first-of-type,
-.fc-widget-content:first-of-type {
-  border-left: 0;
-  border-right: 0;
-}
-.fc-widget-header:last-of-type,
-.fc-widget-content:last-of-type {
-  border-right: 0;
-}
-.fc-toolbar {
-  padding: 10px;
-  margin: 0;
-}
-.fc-day-number {
-  font-size: 20px;
-  font-weight: 300;
-  padding-right: 10px;
-}
-.fc-color-picker {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-.fc-color-picker > li {
-  float: left;
-  font-size: 30px;
-  margin-right: 5px;
-  line-height: 30px;
-}
-.fc-color-picker > li .fa {
-  -webkit-transition: -webkit-transform linear 0.3s;
-  -moz-transition: -moz-transform linear 0.3s;
-  -o-transition: -o-transform linear 0.3s;
-  transition: transform linear 0.3s;
-}
-.fc-color-picker > li .fa:hover {
-  -webkit-transform: rotate(30deg);
-  -ms-transform: rotate(30deg);
-  -o-transform: rotate(30deg);
-  transform: rotate(30deg);
-}
-#add-new-event {
-  -webkit-transition: all linear 0.3s;
-  -o-transition: all linear 0.3s;
-  transition: all linear 0.3s;
-}
-.external-event {
-  padding: 5px 10px;
-  font-weight: bold;
-  margin-bottom: 4px;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-  border-radius: 3px;
-  cursor: move;
-}
-.external-event:hover {
-  box-shadow: inset 0 0 90px rgba(0, 0, 0, 0.2);
-}
-/*
- * General: Miscellaneous
- * ----------------------
- */
-/* 10px padding and margins */
-.pad {
-  padding: 10px;
-}
-.margin {
-  margin: 10px;
-}
-.margin-bottom {
-  margin-bottom: 20px;
-}
-/* Display inline */
-.inline {
-  display: inline;
-  width: auto;
-}
-/* Description Blocks */
-.description-block {
-  display: block;
-  margin: 10px 0;
-  text-align: center;
-}
-.description-block.margin-bottom {
-  margin-bottom: 25px;
-}
-.description-block > .description-header {
-  margin: 0;
-  padding: 0;
-  font-weight: 600;
-  font-size: 16px;
-}
-.description-block > .description-text {
-  text-transform: uppercase;
-}
-/* Background colors */
-.bg-red,
-.bg-yellow,
-.bg-aqua,
-.bg-blue,
-.bg-light-blue,
-.bg-green,
-.bg-navy,
-.bg-teal,
-.bg-olive,
-.bg-lime,
-.bg-orange,
-.bg-fuchsia,
-.bg-purple,
-.bg-maroon,
-.bg-black,
-.bg-red-active,
-.bg-yellow-active,
-.bg-aqua-active,
-.bg-blue-active,
-.bg-light-blue-active,
-.bg-green-active,
-.bg-navy-active,
-.bg-teal-active,
-.bg-olive-active,
-.bg-lime-active,
-.bg-orange-active,
-.bg-fuchsia-active,
-.bg-purple-active,
-.bg-maroon-active,
-.bg-black-active,
-.callout.callout-danger,
-.callout.callout-warning,
-.callout.callout-info,
-.callout.callout-success,
-.alert-success,
-.alert-danger,
-.alert-error,
-.alert-warning,
-.alert-info,
-.label-danger,
-.label-info,
-.label-waring,
-.label-primary,
-.label-success,
-.modal-primary .modal-body,
-.modal-primary .modal-header,
-.modal-primary .modal-footer,
-.modal-warning .modal-body,
-.modal-warning .modal-header,
-.modal-warning .modal-footer,
-.modal-info .modal-body,
-.modal-info .modal-header,
-.modal-info .modal-footer,
-.modal-success .modal-body,
-.modal-success .modal-header,
-.modal-success .modal-footer,
-.modal-danger .modal-body,
-.modal-danger .modal-header,
-.modal-danger .modal-footer {
-  color: #fff !important;
-}
-.bg-gray {
-  color: #000;
-  background-color: #d2d6de !important;
-}
-.bg-black {
-  background-color: #111111 !important;
-}
-.bg-red,
-.callout.callout-danger,
-.alert-danger,
-.alert-error,
-.label-danger,
-.modal-danger .modal-body {
-  background-color: #dd4b39 !important;
-}
-.bg-yellow,
-.callout.callout-warning,
-.alert-warning,
-.label-waring,
-.modal-warning .modal-body {
-  background-color: #f39c12 !important;
-}
-.bg-aqua,
-.callout.callout-info,
-.alert-info,
-.label-info,
-.modal-info .modal-body {
-  background-color: #00c0ef !important;
-}
-.bg-blue {
-  background-color: #0073b7 !important;
-}
-.bg-light-blue,
-.label-primary,
-.modal-primary .modal-body {
-  background-color: #3c8dbc !important;
-}
-.bg-green,
-.callout.callout-success,
-.alert-success,
-.label-success,
-.modal-success .modal-body {
-  background-color: #00a65a !important;
-}
-.bg-navy {
-  background-color: #001f3f !important;
-}
-.bg-teal {
-  background-color: #39cccc !important;
-}
-.bg-olive {
-  background-color: #3d9970 !important;
-}
-.bg-lime {
-  background-color: #01ff70 !important;
-}
-.bg-orange {
-  background-color: #ff851b !important;
-}
-.bg-fuchsia {
-  background-color: #f012be !important;
-}
-.bg-purple {
-  background-color: #605ca8 !important;
-}
-.bg-maroon {
-  background-color: #d81b60 !important;
-}
-.bg-gray-active {
-  color: #000;
-  background-color: #b5bbc8 !important;
-}
-.bg-black-active {
-  background-color: #000000 !important;
-}
-.bg-red-active,
-.modal-danger .modal-header,
-.modal-danger .modal-footer {
-  background-color: #d33724 !important;
-}
-.bg-yellow-active,
-.modal-warning .modal-header,
-.modal-warning .modal-footer {
-  background-color: #db8b0b !important;
-}
-.bg-aqua-active,
-.modal-info .modal-header,
-.modal-info .modal-footer {
-  background-color: #00a7d0 !important;
-}
-.bg-blue-active {
-  background-color: #005384 !important;
-}
-.bg-light-blue-active,
-.modal-primary .modal-header,
-.modal-primary .modal-footer {
-  background-color: #357ca5 !important;
-}
-.bg-green-active,
-.modal-success .modal-header,
-.modal-success .modal-footer {
-  background-color: #008d4c !important;
-}
-.bg-navy-active {
-  background-color: #001a35 !important;
-}
-.bg-teal-active {
-  background-color: #30bbbb !important;
-}
-.bg-olive-active {
-  background-color: #368763 !important;
-}
-.bg-lime-active {
-  background-color: #00e765 !important;
-}
-.bg-orange-active {
-  background-color: #ff7701 !important;
-}
-.bg-fuchsia-active {
-  background-color: #db0ead !important;
-}
-.bg-purple-active {
-  background-color: #555299 !important;
-}
-.bg-maroon-active {
-  background-color: #ca195a !important;
-}
-[class^="bg-"].disabled {
-  opacity: 0.65;
-  filter: alpha(opacity=65);
-}
-/* Text colors */
-.text-red {
-  color: #dd4b39 !important;
-}
-.text-yellow {
-  color: #f39c12 !important;
-}
-.text-aqua {
-  color: #00c0ef !important;
-}
-.text-blue {
-  color: #0073b7 !important;
-}
-.text-black {
-  color: #111111 !important;
-}
-.text-light-blue {
-  color: #3c8dbc !important;
-}
-.text-green {
-  color: #00a65a !important;
-}
-.text-gray {
-  color: #d2d6de !important;
-}
-.text-navy {
-  color: #001f3f !important;
-}
-.text-teal {
-  color: #39cccc !important;
-}
-.text-olive {
-  color: #3d9970 !important;
-}
-.text-lime {
-  color: #01ff70 !important;
-}
-.text-orange {
-  color: #ff851b !important;
-}
-.text-fuchsia {
-  color: #f012be !important;
-}
-.text-purple {
-  color: #605ca8 !important;
-}
-.text-maroon {
-  color: #d81b60 !important;
-}
-/*Hide elements by display none only*/
-.hide {
-  display: none !important;
-}
-/* Remove borders */
-.no-border {
-  border: 0px !important;
-}
-/* Remove padding */
-.no-padding {
-  padding: 0px !important;
-}
-/* Remove margins */
-.no-margin {
-  margin: 0px !important;
-}
-/* Remove box shadow */
-.no-shadow {
-  box-shadow: none!important;
-}
-/* Unstyled List */
-.list-unstyled,
-.chart-legend,
-.contacts-list,
-.users-list,
-.mailbox-attachments {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-/* Remove border radius */
-.flat {
-

<TRUNCATED>

[24/27] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/content.xml b/core/persistence-jpa/src/test/resources/content.xml
index b61cb95..7b11faa 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -124,9 +124,9 @@ under the License.
   <AnyTypeClass name="minimal group"/>
   <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/>
   
-  <AnyType name="OTHER" kind="ANY_OBJECT"/>
-  <AnyTypeClass name="minimal other"/>
-  <AnyType_AnyTypeClass anyType_name="OTHER" anyTypeClass_name="minimal other"/>
+  <AnyType name="PRINTER" kind="ANY_OBJECT"/>
+  <AnyTypeClass name="minimal printer"/>
+  <AnyType_AnyTypeClass anyType_name="PRINTER" anyTypeClass_name="minimal printer"/>
       
   <AnyTypeClass name="csv"/>
 
@@ -135,10 +135,10 @@ under the License.
   <Realm id="3" name="even" parent_id="1"/>
   <Realm id="4" name="two" parent_id="3" accountPolicy_id="5" passwordPolicy_id="2"/>
   
-  <AnyObject id="1" realm_id="1" type_name="OTHER"
+  <AnyObject id="1" realm_id="1" type_name="PRINTER"
              creator="admin" lastModifier="admin" 
              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <AnyObject id="2" realm_id="1" type_name="OTHER"
+  <AnyObject id="2" realm_id="1" type_name="PRINTER"
              creator="admin" lastModifier="admin" 
              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
@@ -286,7 +286,7 @@ under the License.
                conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
   <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
-  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="minimal other" 
+  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="other" 
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
@@ -347,9 +347,21 @@ under the License.
 
   <VirSchema name="mvirtualdata"/>
         
-  <APlainAttr id="1" owner_id="2" schema_name="cool"/>
-  <APlainAttrValue id="1" attribute_id="1" booleanValue="1"/>
-  
+  <PlainSchema name="model" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="location" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+    
+  <APlainAttr id="1" owner_id="1" schema_name="model"/>
+  <APlainAttrValue id="1" attribute_id="1" stringValue="Canon MFC8030"/>
+  <APlainAttr id="2" owner_id="1" schema_name="location"/>
+  <APlainAttrValue id="2" attribute_id="2" stringValue="1st floor"/>
+    
+  <APlainAttr id="3" owner_id="2" schema_name="model"/>
+  <APlainAttrValue id="3" attribute_id="3" stringValue="HP Laserjet 1300n"/>
+  <APlainAttr id="4" owner_id="2" schema_name="location"/>
+  <APlainAttrValue id="4" attribute_id="4" stringValue="2nd floor"/>
+
   <UPlainAttr id="99" owner_id="1" schema_name="type"/>
   <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
   <UPlainAttr id="100" owner_id="1" schema_name="fullname"/>
@@ -473,7 +485,7 @@ under the License.
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.db.table.version}"
+                version="${connid.database.version}"
                 jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValu
 es":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required
 ":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]}]'/>
   <ConnInstance_capabilities ConnInstance_id="101" capability="AUTHENTICATE"/>
   <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_CREATE"/>
@@ -536,7 +548,7 @@ under the License.
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.db.table.version}"
+                version="${connid.database.version}"
                 jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"
 defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"java.lang.Boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityco
 nnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test2"]}]'/>
   <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_UPDATE"/>
@@ -546,7 +558,7 @@ under the License.
   <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
-                displayName="H2-testsync" version="${connid.db.table.version}"
+                displayName="H2-testsync" version="${connid.database.version}"
                 jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Sync capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_CREATE"/>
@@ -556,6 +568,17 @@ under the License.
   <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_DELETE"/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="SEARCH"/>
   
+  <ConnInstance id="108" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
+                displayName="Scripted SQL" version="${connid.database.version}"
+                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScript&quot;,&quot;displayName&quot;:&quot;testScript&quot;,&quot;helpMessage&quot;:&quot;testScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;host&quot;,&quot;displayName&quot;:&quot;Host&quot;,&quot;helpMessage&quot;:&quot;&lt;b
 &gt;Host&lt;/b&gt;&lt;br/&gt;Enter the name of the host where the database is running.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;localhost&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;port&quot;,&quot;displayName&quot;:&quot;Port&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;TCP Port&lt;/b&gt;&lt;br/&gt;Enter the port number the database server is listening on.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;3306&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;database&quot;,&quot;displayName&quot;:&quot;Database&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Database&lt;/b&gt;&lt;br/&gt;Enter the name of the database on the database server that contains the table.&quot;,&quot;type&
 quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;createScript&quot;,&quot;displayName&quot;:&quot;createScript&quot;,&quot;helpMessage&quot;:&quot;createScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcUrlTemplate&quot;,&quot;displayName&quot;:&quot;JDBC Connection URL&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver Connection URL.&lt;br/&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br/&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentati
 on.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;jdbc:mysql://%h:%p/%d&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.url}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jndiProperties&quot;,&quot;displayName&quot;:&quot;Initial JNDI Properties&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br/&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.&quot;,&quot;type&quot;:&quot;[Ljava.lang.String;&quot;,&quot;required&quot;:false,&quot;order&quot;:21,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;enableEmptyString&quot;,&quot;displayName&quot;:&quot;Enable writing empty string&quot;,&quot;
 helpMessage&quot;:&quot;&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br/&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;allNative&quot;,&quot;displayName&quot;:&quot;All native&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;All native&lt;/b&gt;&lt;br/&gt;Select to retrieve all data type of the columns in a native format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:16,&quot;confidential&quot;:false,&quot;defaul
 tValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;User Password&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User Password&lt;/b&gt;&lt;br/&gt;Enter a user account that has permission to access accounts table.&quot;,&quot;type&quot;:&quot;org.identityconnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:5,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.password}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;validConnectionQuery&quot;,&quot;displayName&quot;:&quot;Validate Connection Query&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br/&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy tab
 le could be more efficient.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;reloadScriptOnExecution&quot;,&quot;displayName&quot;:&quot;reloadScriptOnExecution&quot;,&quot;helpMessage&quot;:&quot;reloadScriptOnExecution&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;true&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScriptFileName&quot;,&quot;displayName&quot;:&quot;schemaScriptFileName&quot;,&quot;helpMessage&quot;:&quot;schemaScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&qu
 ot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcDriver&quot;,&quot;displayName&quot;:&quot;JDBC Driver&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;com.mysql.jdbc.Driver&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.driver}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScriptFileName&quot;,&quot;displayName&quot;:&quot;testScriptFileName&quot;,&quot;helpMessage&quot;:&quot;testScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&qu
 ot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;quoting&quot;,&quot;displayName&quot;:&quot;Name Quoting&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br/&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selections (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quo
 t;createScriptFileName&quot;,&quot;displayName&quot;:&quot;createScriptFileName&quot;,&quot;helpMessage&quot;:&quot;createScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;clearTextPasswordToScript&quot;,&quot;displayName&quot;:&quot;clearTextPasswordToScript&quot;,&quot;helpMessage&quot;:&quot;clearTextPasswordToScript&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;nativeTimestamps&quot;,&quot;displayName&quot;:&quot;Native Timestamps&quot;,&quot;helpMessage&quot;:&quot;&lt;
 b&gt;Native Timestamps&lt;/b&gt;&lt;br/&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScript&quot;,&quot;displayName&quot;:&quot;syncScript&quot;,&quot;helpMessage&quot;:&quot;syncScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;autoCommit&quot;,&quot;displayName&quot;:&quot;autoCommit&quot;,&quot;helpMessage&quot;:&quot;autoCommit&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential
 &quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;scriptingLanguage&quot;,&quot;displayName&quot;:&quot;scriptingLanguage&quot;,&quot;helpMessage&quot;:&quot;scriptingLanguage&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;GROOVY&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;GROOVY&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;datasource&quot;,&quot;displayName&quot;:&quot;Datasource Path&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br/&gt;Enter the JDBC Data Source Name/Path to connect to the Oracle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br/&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;&quot;,&q
 uot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:20,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScript&quot;,&quot;displayName&quot;:&quot;deleteScript&quot;,&quot;helpMessage&quot;:&quot;deleteScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;rethrowAllSQLExceptions&quot;,&quot;displayName&quot;:&quot;Rethrow all SQLExceptions&quot;,&quot;helpMessage&quot;:&quot;If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.&quot;,&quot;type&quot;:&quot;boolean&quot;,
 &quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScriptFileName&quot;,&quot;displayName&quot;:&quot;syncScriptFileName&quot;,&quot;helpMessage&quot;:&quot;syncScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SyncScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScript&quot;,&quot;displayName&quot;:&quot;updateScript&quot;,&quot;helpMessage&quot;:&quot;updateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&q
 uot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;user&quot;,&quot;displayName&quot;:&quot;User&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User&lt;/b&gt;&lt;br/&gt;Enter the name of the mandatory Database user with permission to account table.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.username}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScriptFileName&quot;,&quot;displayName&quot;:&quot;deleteScriptFileName&quot;,&quot;helpMessage&quot;:&quot;deleteScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;n
 ame&quot;:&quot;searchScriptFileName&quot;,&quot;displayName&quot;:&quot;searchScriptFileName&quot;,&quot;helpMessage&quot;:&quot;searchScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SearchScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;searchScript&quot;,&quot;displayName&quot;:&quot;searchScript&quot;,&quot;helpMessage&quot;:&quot;searchScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="SYNC"/>
+  
   <ExternalResource name="ws-target-resource-1" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" propagationMode="TWO_PHASES"
                     propagationPriority="0" propagationPrimary="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
@@ -657,6 +680,13 @@ under the License.
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
+  <ExternalResource name="resource-db-scripted" connector_id="108"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" syncTraceLevel="ALL" updateTraceLevel="ALL"
+                    enforceMandatoryCondition="0"
+                    propagationMode="ONE_PHASE" propagationPrimary="0" propagationPriority="0"
+                    creator="admin" lastModifier="admin" 
+                    creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+
   <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
   <Policy_ExternalResource accountPolicy_id="5" resource_name="resource-testdb"/>
     
@@ -817,7 +847,7 @@ under the License.
                intAttrName="rderToBePropagated" intMappingType="GroupDerivedSchema" mandatoryCondition="false"
                connObjectKey="0" password="0" purpose="PROPAGATION"/>
   <MappingItem id="209" extAttrName="membership" mapping_id="9"
-               intAttrName="mderToBePropagated" intMappingType="AnyDerivedSchema" mandatoryCondition="false"
+               intAttrName="mderToBePropagated" intMappingType="AnyObjectDerivedSchema" mandatoryCondition="false"
                connObjectKey="0" password="0" purpose="PROPAGATION"/>
                          
   <Provision id="10" resource_name="ws-target-resource-update-resetsynctoken" anyType_name="USER" objectClass="__ACCOUNT__"
@@ -924,7 +954,16 @@ under the License.
   <MappingItem id="334" mapping_id="19" extAttrName="userId" 
                intMappingType="Username" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  
+
+  <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" 
+               intMappingType="AnyObjectKey" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="BOTH"/>
+  <MappingItem id="406" mapping_id="21" extAttrName="location" 
+               intAttrName="location" intMappingType="AnyObjectPlainSchema"
+               mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/>
+    
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="1" propagationMode="TWO_PHASES" propagationOperation="UPDATE"
         objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" anyTypeKind="USER" anyKey="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
@@ -1055,6 +1094,9 @@ under the License.
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="27" propagationMode="ONE_PHASE" propagationOperation="CREATE"
         objectClassName="__ACCOUNT__" resource_name="resource-testdb" anyTypeKind="USER" anyKey="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
+  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="28" name="Scripted SQL" resource_name="resource-db-scripted"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="0" fullReconciliation="0"
+        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
 
   <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
                 sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
index cc49d62..e23143a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
@@ -67,9 +67,6 @@ import org.springframework.util.ClassUtils;
 
 public class ConnectorFacadeProxy implements Connector {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ConnectorFacadeProxy.class);
 
     /**
@@ -138,7 +135,7 @@ public class ConnectorFacadeProxy implements Connector {
         Uid result = null;
 
         if (activeConnInstance.getCapabilities().contains(ConnectorCapability.AUTHENTICATE)) {
-            final Future<Uid> future = asyncFacade.authenticate(
+            Future<Uid> future = asyncFacade.authenticate(
                     connector, username, new GuardedString(password.toCharArray()), options);
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -173,7 +170,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("create");
 
-            final Future<Uid> future = asyncFacade.create(connector, objectClass, attrs, options);
+            Future<Uid> future = asyncFacade.create(connector, objectClass, attrs, options);
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
             } catch (java.util.concurrent.TimeoutException e) {
@@ -207,7 +204,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("update");
 
-            final Future<Uid> future = asyncFacade.update(connector, objectClass, uid, attrs, options);
+            Future<Uid> future = asyncFacade.update(connector, objectClass, uid, attrs, options);
 
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -241,7 +238,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("delete");
 
-            final Future<Uid> future = asyncFacade.delete(connector, objectClass, uid, options);
+            Future<Uid> future = asyncFacade.delete(connector, objectClass, uid, options);
 
             try {
                 future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -279,7 +276,7 @@ public class ConnectorFacadeProxy implements Connector {
         SyncToken result = null;
 
         if (activeConnInstance.getCapabilities().contains(ConnectorCapability.SYNC)) {
-            final Future<SyncToken> future = asyncFacade.getLatestSyncToken(connector, objectClass);
+            Future<SyncToken> future = asyncFacade.getLatestSyncToken(connector, objectClass);
 
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -350,7 +347,9 @@ public class ConnectorFacadeProxy implements Connector {
         try {
             return future == null ? null : future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
-            future.cancel(true);
+            if (future != null) {
+                future.cancel(true);
+            }
             throw new TimeoutException("Request timeout");
         } catch (Exception e) {
             LOG.error("Connector request execution failure", e);
@@ -363,8 +362,8 @@ public class ConnectorFacadeProxy implements Connector {
     }
 
     @Override
-    public List<ConnectorObject> search(final ObjectClass objectClass, final Filter filter,
-            final OperationOptions options) {
+    public List<ConnectorObject> search(
+            final ObjectClass objectClass, final Filter filter, final OperationOptions options) {
 
         final List<ConnectorObject> result = new ArrayList<>();
 
@@ -401,8 +400,8 @@ public class ConnectorFacadeProxy implements Connector {
     public Attribute getObjectAttribute(final ObjectClass objectClass, final Uid uid, final OperationOptions options,
             final String attributeName) {
 
-        final Future<Attribute> future = asyncFacade.getObjectAttribute(connector, objectClass, uid, options,
-                attributeName);
+        Future<Attribute> future = asyncFacade.getObjectAttribute(
+                connector, objectClass, uid, options, attributeName);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -422,7 +421,7 @@ public class ConnectorFacadeProxy implements Connector {
     public Set<Attribute> getObjectAttributes(final ObjectClass objectClass, final Uid uid,
             final OperationOptions options) {
 
-        final Future<Set<Attribute>> future = asyncFacade.getObjectAttributes(connector, objectClass, uid, options);
+        Future<Set<Attribute>> future = asyncFacade.getObjectAttributes(connector, objectClass, uid, options);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -440,7 +439,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public Set<String> getSchemaNames(final boolean includeSpecial) {
-        final Future<Set<String>> future = asyncFacade.getSchemaNames(connector, includeSpecial);
+        Future<Set<String>> future = asyncFacade.getSchemaNames(connector, includeSpecial);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -458,7 +457,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public Set<ObjectClass> getSupportedObjectClasses() {
-        final Future<Set<ObjectClass>> future = asyncFacade.getSupportedObjectClasses(connector);
+        Future<Set<ObjectClass>> future = asyncFacade.getSupportedObjectClasses(connector);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -476,7 +475,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public void validate() {
-        final Future<String> future = asyncFacade.test(connector);
+        Future<String> future = asyncFacade.test(connector);
         try {
             future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -494,7 +493,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public void test() {
-        final Future<String> future = asyncFacade.test(connector);
+        Future<String> future = asyncFacade.test(connector);
         try {
             future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
index 888329c..b43e911 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
@@ -282,7 +282,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
                 ? IntMappingType.UserVirtualSchema
                 : any.getType().getKind() == AnyTypeKind.GROUP
                         ? IntMappingType.GroupVirtualSchema
-                        : IntMappingType.AnyVirtualSchema;
+                        : IntMappingType.AnyObjectVirtualSchema;
 
         Map<String, ConnectorObject> resources = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 90f5e91..92a9bd3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -93,7 +93,7 @@ abstract class AbstractAnyDataBinder {
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractAnyDataBinder.class);
 
     private static final IntMappingType[] FOR_MANDATORY = new IntMappingType[] {
-        IntMappingType.AnyPlainSchema, IntMappingType.AnyDerivedSchema,
+        IntMappingType.AnyObjectPlainSchema, IntMappingType.AnyObjectDerivedSchema,
         IntMappingType.UserPlainSchema, IntMappingType.UserDerivedSchema,
         IntMappingType.GroupPlainSchema, IntMappingType.GroupDerivedSchema };
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 462a488..237792b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -33,14 +33,18 @@ import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.RelationshipTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -53,6 +57,9 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
         "plainAttrs", "derAttrs", "virAttrs", "resources"
     };
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Transactional(readOnly = true)
     @Override
     public AnyObjectTO getAnyObjectTO(final Long key) {
@@ -62,6 +69,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
     @Override
     public AnyObjectTO getAnyObjectTO(final AnyObject anyObject) {
         AnyObjectTO anyObjectTO = new AnyObjectTO();
+        anyObjectTO.setType(anyObject.getType().getKey());
 
         BeanUtils.copyProperties(anyObject, anyObjectTO, IGNORE_PROPERTIES);
 
@@ -103,6 +111,14 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
 
     @Override
     public void create(final AnyObject anyObject, final AnyObjectTO anyObjectTO) {
+        AnyType type = anyTypeDAO.find(anyObjectTO.getType());
+        if (type == null) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+            sce.getElements().add(anyObjectTO.getType());
+            throw sce;
+        }
+        anyObject.setType(type);
+
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
         // relationships

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index 59f8994..a73f5b9 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -70,6 +70,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class);
 
+    @Autowired
     protected AnyObjectDAO anyObjectDAO;
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
index 479d342..c52c3cf 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
@@ -29,14 +29,12 @@ import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.job.SyncJob;
 import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
-import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.SyncResultsHandler;
 import org.identityconnectors.framework.common.objects.SyncToken;
 import org.quartz.JobExecutionException;
@@ -133,8 +131,8 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
             }
         }
 
-        try {
-            for (Provision provision : syncTask.getResource().getProvisions()) {
+        for (Provision provision : syncTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
                 SyncResultsHandler handler;
                 switch (provision.getAnyType().getKind()) {
                     case USER:
@@ -150,37 +148,32 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
                         handler = ahandler;
                 }
 
-                SyncToken latestSyncToken = null;
-                if (provision.getMapping() != null && !syncTask.isFullReconciliation()) {
-                    latestSyncToken = connector.getLatestSyncToken(ObjectClass.ACCOUNT);
-                }
+                try {
+                    SyncToken latestSyncToken = null;
+                    if (!syncTask.isFullReconciliation()) {
+                        latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
+                    }
 
-                if (syncTask.isFullReconciliation()) {
-                    if (provision.getMapping() != null) {
+                    if (syncTask.isFullReconciliation()) {
                         connector.getAllObjects(provision.getObjectClass(), handler,
                                 connector.getOperationOptions(provision.getMapping().getItems()));
-                    }
-                } else {
-                    if (provision.getMapping() != null) {
+                    } else {
                         connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler,
                                 connector.getOperationOptions(provision.getMapping().getItems()));
                     }
-                }
 
-                if (!dryRun && !syncTask.isFullReconciliation()) {
-                    try {
-                        ExternalResource resource = resourceDAO.find(syncTask.getResource().getKey());
-                        if (provision.getMapping() != null) {
+                    if (!dryRun && !syncTask.isFullReconciliation()) {
+                        try {
                             provision.setSyncToken(latestSyncToken);
+                            resourceDAO.save(provision.getResource());
+                        } catch (Exception e) {
+                            throw new JobExecutionException("While updating SyncToken", e);
                         }
-                        resourceDAO.save(resource);
-                    } catch (Exception e) {
-                        throw new JobExecutionException("While updating SyncToken", e);
                     }
+                } catch (Throwable t) {
+                    throw new JobExecutionException("While syncing on connector", t);
                 }
             }
-        } catch (Throwable t) {
-            throw new JobExecutionException("While syncing on connector", t);
         }
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
index 14c94f70..c3d11a9 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
@@ -167,7 +167,7 @@ public class SyncUtils {
         switch (connObjectKeyItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case AnyPlainSchema:
+            case AnyObjectPlainSchema:
                 PlainAttrValue value = anyUtils.newPlainAttrValue();
 
                 PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
@@ -191,7 +191,7 @@ public class SyncUtils {
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
-            case AnyDerivedSchema:
+            case AnyObjectDerivedSchema:
                 anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), uid);
                 for (Any<?, ?, ?> any : anys) {
                     result.add(any.getKey());
@@ -200,7 +200,7 @@ public class SyncUtils {
 
             case UserKey:
             case GroupKey:
-            case AnyKey:
+            case AnyObjectKey:
                 Any<?, ?, ?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(uid));
                 if (any != null) {
                     result.add(any.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
new file mode 100644
index 0000000..7cf4a08
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -0,0 +1,290 @@
+/*
+ * 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.core.rest.cxf.service;
+
+import static org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl.LOG;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.service.AnyService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+
+public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
+        extends AbstractServiceImpl
+        implements AnyService<TO, MOD> {
+
+    protected abstract AbstractAnyLogic<TO, MOD> getAnyLogic();
+
+    @Override
+    public TO read(final Long key) {
+        return getAnyLogic().read(key);
+    }
+
+    @Override
+    public PagedResult<TO> list(final AnyListQuery listQuery) {
+        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        return buildPagedResult(
+                getAnyLogic().list(
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                getAnyLogic().count(listQuery.getRealms()));
+    }
+
+    @Override
+    public PagedResult<TO> search(final AnySearchQuery searchQuery) {
+        CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        SearchCond cond = getSearchCond(searchQuery.getFiql());
+        return buildPagedResult(
+                getAnyLogic().search(
+                        cond,
+                        searchQuery.getPage(),
+                        searchQuery.getSize(),
+                        getOrderByClauses(searchQuery.getOrderBy()),
+                        searchQuery.getRealms()),
+                searchQuery.getPage(),
+                searchQuery.getSize(),
+                getAnyLogic().searchCount(cond, searchQuery.getRealms()));
+    }
+
+    @Override
+    public Response create(final TO anyTO) {
+        TO created = getAnyLogic().create(anyTO);
+        return createResponse(created.getKey(), created);
+    }
+
+    @Override
+    public Response update(final Long key, final MOD anyMod) {
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        anyMod.setKey(key);
+        TO updated = getAnyLogic().update(anyMod);
+        return modificationResponse(updated);
+    }
+
+    @Override
+    public Response delete(final Long key) {
+        TO group = getAnyLogic().read(key);
+
+        checkETag(group.getETagValue());
+
+        TO deleted = getAnyLogic().delete(key);
+        return modificationResponse(deleted);
+    }
+
+    @Override
+    public Response bulkDeassociation(
+            final Long key, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
+
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        TO updated;
+        switch (type) {
+            case UNLINK:
+                updated = getAnyLogic().unlink(key, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case UNASSIGN:
+                updated = getAnyLogic().unassign(key, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case DEPROVISION:
+                updated = getAnyLogic().deprovision(key, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            default:
+                updated = getAnyLogic().read(key);
+        }
+
+        BulkActionResult result = new BulkActionResult();
+
+        if (type == ResourceDeassociationActionType.UNLINK) {
+            for (ResourceKey resourceName : resourceNames) {
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
+            }
+        }
+
+        return modificationResponse(result);
+    }
+
+    @Override
+    public Response bulkAssociation(
+            final Long key, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) {
+
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        TO updated;
+        switch (type) {
+            case LINK:
+                updated = getAnyLogic().link(
+                        key,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()));
+                break;
+
+            case ASSIGN:
+                updated = getAnyLogic().assign(
+                        key,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            case PROVISION:
+                updated = getAnyLogic().provision(
+                        key,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            default:
+                updated = getAnyLogic().read(key);
+        }
+
+        BulkActionResult result = new BulkActionResult();
+
+        if (type == ResourceAssociationActionType.LINK) {
+            for (ResourceKey resourceName : associationMod.getTargetResources()) {
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
+            }
+        }
+
+        return modificationResponse(result);
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        AbstractAnyLogic<TO, MOD> logic = getAnyLogic();
+
+        BulkActionResult result = new BulkActionResult();
+
+        switch (bulkAction.getOperation()) {
+            case DELETE:
+                for (String key : bulkAction.getTargets()) {
+                    try {
+                        result.getResults().put(
+                                String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
+                                BulkActionResult.Status.SUCCESS);
+                    } catch (Exception e) {
+                        LOG.error("Error performing delete for user {}", key, e);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
+                    }
+                }
+                break;
+
+            case SUSPEND:
+                if (logic instanceof UserLogic) {
+                    for (String key : bulkAction.getTargets()) {
+                        StatusMod statusMod = new StatusMod();
+                        statusMod.setKey(Long.valueOf(key));
+                        statusMod.setType(StatusMod.ModType.SUSPEND);
+                        try {
+                            result.getResults().put(
+                                    String.valueOf(((UserLogic) logic).status(statusMod).getKey()),
+                                    BulkActionResult.Status.SUCCESS);
+                        } catch (Exception e) {
+                            LOG.error("Error performing suspend for user {}", key, e);
+                            result.getResults().put(key, BulkActionResult.Status.FAILURE);
+                        }
+                    }
+                }
+                break;
+
+            case REACTIVATE:
+                for (String key : bulkAction.getTargets()) {
+                    StatusMod statusMod = new StatusMod();
+                    statusMod.setKey(Long.valueOf(key));
+                    statusMod.setType(StatusMod.ModType.REACTIVATE);
+                    try {
+                        result.getResults().put(
+                                String.valueOf(((UserLogic) logic).status(statusMod).getKey()),
+                                BulkActionResult.Status.SUCCESS);
+                    } catch (Exception e) {
+                        LOG.error("Error performing reactivate for user {}", key, e);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
+                    }
+                }
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
new file mode 100644
index 0000000..ce6390a
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.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.core.rest.cxf.service;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.AnyObjectLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AnyObjectServiceImpl extends AbstractAnyService<AnyObjectTO, AnyObjectMod> implements AnyObjectService {
+
+    @Autowired
+    private AnyObjectLogic logic;
+
+    @Override
+    protected AbstractAnyLogic<AnyObjectTO, AnyObjectMod> getAnyLogic() {
+        return logic;
+    }
+
+    @Override
+    public PagedResult<AnyObjectTO> list(final String type, final AnyListQuery listQuery) {
+        if (StringUtils.isBlank(type)) {
+            return super.list(listQuery);
+        }
+
+        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        return buildPagedResult(
+                logic.list(
+                        type,
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                getAnyLogic().count(listQuery.getRealms()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index bd24f22..d80caf9 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -27,11 +27,12 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.wrap.BooleanWrap;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.core.logic.ConnectorLogic;
@@ -87,17 +88,12 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final Long key,
+    public List<ConnIdObjectClass> getSupportedObjectClasses(final Long key,
             final ConnInstanceTO connInstanceTO) {
 
         connInstanceTO.setKey(key);
 
-        List<String> objectClasses = logic.getSupportedObjectClasses(connInstanceTO);
-        List<ConnIdObjectClassTO> result = new ArrayList<>(objectClasses.size());
-        for (String objectClass : objectClasses) {
-            result.add(new ConnIdObjectClassTO(objectClass));
-        }
-        return result;
+        return CollectionWrapper.wrap(logic.getSupportedObjectClasses(connInstanceTO), ConnIdObjectClass.class);
     }
 
     @Override


[25/27] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
index 001d71c..7d48b46 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
@@ -19,47 +19,21 @@
 package org.apache.syncope.common.rest.api.service;
 
 import java.util.List;
-import javax.validation.constraints.NotNull;
-import javax.ws.rs.BeanParam;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
-import javax.ws.rs.POST;
 import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 import org.apache.cxf.jaxrs.model.wadl.Description;
 import org.apache.cxf.jaxrs.model.wadl.Descriptions;
 import org.apache.cxf.jaxrs.model.wadl.DocTarget;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
-import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.wrap.ResourceKey;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
 /**
  * REST operations for groups.
  */
 @Path("groups")
-public interface GroupService extends JAXRSService {
-
-    /**
-     * Reads the group matching the provided groupKey.
-     *
-     * @param groupKey key of group to be read
-     * @return group with matching id
-     */
-    @GET
-    @Path("{groupKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    GroupTO read(@NotNull @PathParam("groupKey") Long groupKey);
+public interface GroupService extends AnyService<GroupTO, GroupMod> {
 
     /**
      * This method is similar to {@link #read(Long)}, but uses different authentication handling to ensure that a user
@@ -76,134 +50,4 @@ public interface GroupService extends JAXRSService {
     @Path("own")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     List<GroupTO> own();
-
-    /**
-     * Returns a paged list of existing groups matching the given query.
-     *
-     * @param listQuery query conditions
-     * @return paged list of existing groups matching the given query
-     */
-    @GET
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<GroupTO> list(@BeanParam AnyListQuery listQuery);
-
-    /**
-     * Returns a paged list of groups matching the given query.
-     *
-     * @param searchQuery query conditions
-     * @return paged list of groups matching the given query
-     */
-    @GET
-    @Path("search")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<GroupTO> search(@BeanParam AnySearchQuery searchQuery);
-
-    /**
-     * Creates a new group.
-     *
-     * @param groupTO group to be created
-     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created group as well as the group itself
-     * enriched with propagation status information - {@link GroupTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>Location</tt> header of created group as well as the "
-                + "group itself enriched with propagation status information - <tt>GroupTO</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response create(@NotNull GroupTO groupTO);
-
-    /**
-     * Updates group matching the provided groupKey.
-     *
-     * @param groupKey key of group to be updated
-     * @param groupMod modification to be applied to group matching the provided groupKey
-     * @return <tt>Response</tt> object featuring the updated group enriched with propagation status information
-     * - {@link GroupTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the updated group enriched with propagation status information - "
-                + "<tt>GroupTO</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{groupKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response update(@NotNull @PathParam("groupKey") Long groupKey, @NotNull GroupMod groupMod);
-
-    /**
-     * Deletes group matching provided groupKey.
-     *
-     * @param groupKey key of group to be deleted
-     * @return <tt>Response</tt> object featuring the deleted group enriched with propagation status information
-     * - {@link GroupTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the deleted group enriched with propagation status information - "
-                + "<tt>GroupTO</tt> as <tt>Entity</tt>")
-    })
-    @DELETE
-    @Path("{groupKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response delete(@NotNull @PathParam("groupKey") Long groupKey);
-
-    /**
-     * Executes resource-related operations on given group.
-     *
-     * @param groupKey group id.
-     * @param type resource association action type
-     * @param resourceNames external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring
-     * {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{groupKey}/deassociate/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkDeassociation(
-            @NotNull @PathParam("groupKey") Long groupKey,
-            @NotNull @PathParam("type") ResourceDeassociationActionType type,
-            @NotNull List<ResourceKey> resourceNames);
-
-    /**
-     * Executes resource-related operations on given group.
-     *
-     * @param groupKey group id.
-     * @param type resource association action type
-     * @param resourceNames external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{groupKey}/associate/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkAssociation(
-            @NotNull @PathParam("groupKey") Long groupKey,
-            @NotNull @PathParam("type") ResourceAssociationActionType type,
-            @NotNull List<ResourceKey> resourceNames);
-
-    /**
-     * Executes the provided bulk action.
-     *
-     * @param bulkAction list of group ids against which the bulk action will be performed.
-     * @return Bulk action result
-     */
-    @POST
-    @Path("bulk")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    BulkActionResult bulk(@NotNull BulkAction bulkAction);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
index 4866f95..bf1e6b7 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
@@ -18,13 +18,9 @@
  */
 package org.apache.syncope.common.rest.api.service;
 
-import java.util.List;
 import javax.validation.constraints.NotNull;
-import javax.ws.rs.BeanParam;
 import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
 import javax.ws.rs.OPTIONS;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
@@ -36,86 +32,45 @@ import javax.ws.rs.core.Response;
 import org.apache.cxf.jaxrs.model.wadl.Description;
 import org.apache.cxf.jaxrs.model.wadl.Descriptions;
 import org.apache.cxf.jaxrs.model.wadl.DocTarget;
-import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
-import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.wrap.ResourceKey;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
 /**
  * REST operations for users.
  */
 @Path("users")
-public interface UserService extends JAXRSService {
+public interface UserService extends AnyService<UserTO, UserMod> {
 
     /**
      * Gives the username for the provided user key.
      *
-     * @param userKey user key
-     * @return <tt>Response</tt> object featuring HTTP header with username matching the given userKey
+     * @param key user key
+     * @return <tt>Response</tt> object featuring HTTP header with username matching the given key
      */
     @Descriptions({
         @Description(target = DocTarget.RESPONSE,
-                value = "Featuring HTTP header with username matching the given userKey")
+                value = "Featuring HTTP header with username matching the given key")
     })
     @OPTIONS
-    @Path("{userKey}/username")
-    Response getUsername(@NotNull @PathParam("userKey") Long userKey);
+    @Path("{key}/username")
+    Response getUsername(@NotNull @PathParam("key") Long key);
 
     /**
      * Gives the user key for the provided username.
      *
      * @param username username
-     * @return <tt>Response</tt> object featuring HTTP header with userKey matching the given username
+     * @return <tt>Response</tt> object featuring HTTP header with key matching the given username
      */
     @Descriptions({
         @Description(target = DocTarget.RESPONSE,
-                value = "Featuring HTTP header with userKey matching the given username")
+                value = "Featuring HTTP header with key matching the given username")
     })
     @OPTIONS
-    @Path("{username}/userKey")
+    @Path("{username}/key")
     Response getUserKey(@NotNull @PathParam("username") String username);
 
     /**
-     * Reads the user matching the provided userKey.
-     *
-     * @param userKey id of user to be read
-     * @return User matching the provided userKey
-     */
-    @GET
-    @Path("{userKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    UserTO read(@NotNull @PathParam("userKey") Long userKey);
-
-    /**
-     * Returns a paged list of existing users matching the given query.
-     *
-     * @param listQuery query conditions
-     * @return paged list of existing users matching the given query
-     */
-    @GET
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> list(@BeanParam AnyListQuery listQuery);
-
-    /**
-     * Returns a paged list of users matching the given query.
-     *
-     * @param searchQuery query conditions
-     * @return paged list of users matching the given query
-     */
-    @GET
-    @Path("search")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> search(@BeanParam AnySearchQuery searchQuery);
-
-    /**
      * Creates a new user.
      *
      * @param userTO user to be created
@@ -136,28 +91,9 @@ public interface UserService extends JAXRSService {
             @DefaultValue("true") @QueryParam("storePassword") boolean storePassword);
 
     /**
-     * Updates user matching the provided userKey.
+     * Performs a status update on user matching provided key.
      *
-     * @param userKey id of user to be updated
-     * @param userMod modification to be applied to user matching the provided userKey
-     * @return <tt>Response</tt> object featuring the updated user enriched with propagation status information
-     * - {@link UserTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the updated user enriched with propagation status information - "
-                + "<tt>UserTO</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{userKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response update(@NotNull @PathParam("userKey") Long userKey, @NotNull UserMod userMod);
-
-    /**
-     * Performs a status update on user matching provided userKey.
-     *
-     * @param userKey id of user to be subjected to status update
+     * @param key id of user to be subjected to status update
      * @param statusMod status update details
      * @return <tt>Response</tt> object featuring the updated user enriched with propagation status information
      * - {@link UserTO} as <tt>Entity</tt>
@@ -168,78 +104,8 @@ public interface UserService extends JAXRSService {
                 + "<tt>UserTO</tt> as <tt>Entity</tt>")
     })
     @POST
-    @Path("{userKey}/status")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response status(@NotNull @PathParam("userKey") Long userKey, @NotNull StatusMod statusMod);
-
-    /**
-     * Deletes user matching provided userKey.
-     *
-     * @param userKey id of user to be deleted
-     * @return <tt>Response</tt> object featuring the deleted user enriched with propagation status information
-     * - {@link UserTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the deleted user enriched with propagation status information - "
-                + "<tt>UserTO</tt> as <tt>Entity</tt>")
-    })
-    @DELETE
-    @Path("{userKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response delete(@NotNull @PathParam("userKey") Long userKey);
-
-    /**
-     * Executes resource-related operations on given user.
-     *
-     * @param userKey user key
-     * @param type resource de-association action type
-     * @param resourceNames external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{userKey}/bulkDeassociation/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkDeassociation(
-            @NotNull @PathParam("userKey") Long userKey,
-            @NotNull @PathParam("type") ResourceDeassociationActionType type,
-            @NotNull List<ResourceKey> resourceNames);
-
-    /**
-     * Executes resource-related operations on given user.
-     *
-     * @param userKey user key.
-     * @param type resource association action type
-     * @param associationMod external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE, value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{userKey}/bulkAssociation/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkAssociation(
-            @NotNull @PathParam("userKey") Long userKey,
-            @NotNull @PathParam("type") ResourceAssociationActionType type,
-            @NotNull ResourceAssociationMod associationMod);
-
-    /**
-     * Executes the provided bulk action.
-     *
-     * @param bulkAction list of user keys against which the bulk action will be performed.
-     * @return Bulk action result
-     */
-    @POST
-    @Path("bulk")
+    @Path("{key}/status")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    BulkActionResult bulk(@NotNull BulkAction bulkAction);
+    Response status(@NotNull @PathParam("key") Long key, @NotNull StatusMod statusMod);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index 83e90da..d24b08e 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -30,8 +30,8 @@ import org.apache.syncope.core.misc.RealmUtils;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 
-public abstract class AbstractAnyLogic<T extends AnyTO, V extends AnyMod>
-        extends AbstractResourceAssociator<T> {
+public abstract class AbstractAnyLogic<TO extends AnyTO, MOD extends AnyMod>
+        extends AbstractResourceAssociator<TO> {
 
     private static class StartsWithPredicate implements Predicate<String> {
 
@@ -67,17 +67,19 @@ public abstract class AbstractAnyLogic<T extends AnyTO, V extends AnyMod>
         return effective;
     }
 
-    public abstract T read(Long key);
+    public abstract TO read(Long key);
 
     public abstract int count(List<String> realms);
 
-    public abstract T update(V anyMod);
+    public abstract TO create(TO anyTO);
 
-    public abstract T delete(Long key);
+    public abstract TO update(MOD anyMod);
 
-    public abstract List<T> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
+    public abstract TO delete(Long key);
 
-    public abstract List<T> search(
+    public abstract List<TO> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
+
+    public abstract List<TO> search(
             SearchCond searchCondition, int page, int size, List<OrderByClause> orderBy, List<String> realms);
 
     public abstract int searchCount(SearchCond searchCondition, List<String> realms);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 4919097..257bf42 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -29,6 +29,7 @@ import javax.annotation.Resource;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.AnyObjectMod;
@@ -107,9 +108,19 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     public List<AnyObjectTO> list(
             final int page, final int size, final List<OrderByClause> orderBy, final List<String> realms) {
 
-        return CollectionUtils.collect(anyObjectDAO.findAll(
-                getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms),
-                page, size, orderBy),
+        return list(null, page, size, orderBy, realms);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_LIST + "')")
+    @Transactional(readOnly = true)
+    public List<AnyObjectTO> list(final String type,
+            final int page, final int size, final List<OrderByClause> orderBy, final List<String> realms) {
+
+        Set<String> effectiveRealms = getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms);
+
+        return CollectionUtils.collect(StringUtils.isBlank(type)
+                ? anyObjectDAO.findAll(effectiveRealms, page, size, orderBy)
+                : anyObjectDAO.findAll(type, effectiveRealms, page, size, orderBy),
                 new Transformer<AnyObject, AnyObjectTO>() {
 
                     @Override
@@ -147,10 +158,10 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_CREATE + "')")
+    @Override
     public AnyObjectTO create(final AnyObjectTO anyObjectTO) {
         if (anyObjectTO.getRealm() == null) {
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
-            throw sce;
+            throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
         }
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_CREATE),
@@ -163,6 +174,10 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
         AnyObjectTO actual = attrTransformer.transform(anyObjectTO);
         LOG.debug("Transformed: {}", actual);
 
+        if (anyObjectTO.getType() == null) {
+            throw SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+        }
+
         /*
          * Actual operations: workflow, propagation
          */
@@ -181,7 +196,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
         }
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
-                Collections.singleton(anyObjectMod.getRealm()));
+                Collections.singleton(anyObject.getRealm().getFullPath()));
         if (effectiveRealms.isEmpty()) {
             throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index 93af622..b0cfa03 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -25,7 +25,9 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
@@ -96,7 +98,13 @@ public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
         }
 
         AnyTypeTO deleted = binder.getAnyTypeTO(anyType);
-        anyTypeDAO.delete(key);
+        try {
+            anyTypeDAO.delete(key);
+        } catch (IllegalArgumentException e) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+            sce.getElements().add(e.getMessage());
+            throw sce;
+        }
         return deleted;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index d9216da..877a272 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -166,6 +166,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_CREATE + "')")
+    @Override
     public GroupTO create(final GroupTO groupTO) {
         if (groupTO.getRealm() == null) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 4ecab47..28e5cab 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -183,6 +183,12 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_CREATE + "')")
+    @Override
+    public UserTO create(final UserTO userTO) {
+        return create(userTO, true);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.USER_CREATE + "')")
     public UserTO create(final UserTO userTO, final boolean storePassword) {
         if (userTO.getRealm() == null) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
index 807ea0f..6257d59 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
@@ -196,6 +196,7 @@ public class ConnObjectUtils {
             final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
 
         T anyTO = anyUtils.newAnyTO();
+        anyTO.setType(provision.getAnyType().getKey());
 
         // 1. fill with data from connector object
         anyTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
@@ -206,6 +207,7 @@ public class ConnObjectUtils {
             switch (item.getIntMappingType()) {
                 case UserKey:
                 case GroupKey:
+                case AnyObjectKey:
                     break;
 
                 case Password:
@@ -252,6 +254,7 @@ public class ConnObjectUtils {
 
                 case UserPlainSchema:
                 case GroupPlainSchema:
+                case AnyObjectPlainSchema:
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
 
@@ -292,6 +295,7 @@ public class ConnObjectUtils {
 
                 case UserDerivedSchema:
                 case GroupDerivedSchema:
+                case AnyObjectDerivedSchema:
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
                     anyTO.getDerAttrs().add(attrTO);
@@ -299,6 +303,7 @@ public class ConnObjectUtils {
 
                 case UserVirtualSchema:
                 case GroupVirtualSchema:
+                case AnyObjectVirtualSchema:
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
index 140c5ad..e655809 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
@@ -154,7 +154,7 @@ public final class MappingUtils {
             try {
                 if (mapping.getIntMappingType() == IntMappingType.UserVirtualSchema
                         || mapping.getIntMappingType() == IntMappingType.GroupVirtualSchema
-                        || mapping.getIntMappingType() == IntMappingType.AnyVirtualSchema) {
+                        || mapping.getIntMappingType() == IntMappingType.AnyObjectVirtualSchema) {
 
                     LOG.debug("Expire entry cache {}-{}", any.getKey(), mapping.getIntAttrName());
                     virAttrCache.expire(any.getType().getKey(), any.getKey(), mapping.getIntAttrName());
@@ -270,7 +270,7 @@ public final class MappingUtils {
         switch (mapItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case AnyPlainSchema:
+            case AnyObjectPlainSchema:
                 final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
                 schema = plainSchemaDAO.find(mapItem.getIntAttrName());
                 schemaType = schema == null ? AttrSchemaType.String : schema.getType();
@@ -278,7 +278,7 @@ public final class MappingUtils {
 
             case UserVirtualSchema:
             case GroupVirtualSchema:
-            case AnyVirtualSchema:
+            case AnyObjectVirtualSchema:
                 VirSchemaDAO virSchemaDAO = context.getBean(VirSchemaDAO.class);
                 VirSchema virSchema = virSchemaDAO.find(mapItem.getIntAttrName());
                 readOnlyVirSchema = (virSchema != null && virSchema.isReadonly());
@@ -442,7 +442,7 @@ public final class MappingUtils {
         switch (mappingItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case AnyPlainSchema:
+            case AnyObjectPlainSchema:
                 for (Any<?, ?, ?> any : anys) {
                     PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
                     if (attr != null) {
@@ -464,7 +464,7 @@ public final class MappingUtils {
 
             case UserVirtualSchema:
             case GroupVirtualSchema:
-            case AnyVirtualSchema:
+            case AnyObjectVirtualSchema:
                 for (Any<?, ?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     VirAttr<?> virAttr = any.getVirAttr(mappingItem.getIntAttrName());
@@ -501,7 +501,7 @@ public final class MappingUtils {
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
-            case AnyDerivedSchema:
+            case AnyObjectDerivedSchema:
                 for (Any<?, ?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     DerAttr<?> derAttr = any.getDerAttr(mappingItem.getIntAttrName());
@@ -521,7 +521,7 @@ public final class MappingUtils {
 
             case UserKey:
             case GroupKey:
-            case AnyKey:
+            case AnyObjectKey:
                 for (Any<?, ?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     attrValue = anyUtils.newPlainAttrValue();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
index a67cbf5..c7efa8a 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
@@ -37,6 +37,7 @@ import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
 import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
 
 /**
  * Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
@@ -98,6 +99,12 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                     leaf = SearchCond.getLeafCond(attributeCond);
                 } else {
                     switch (specialAttrName) {
+                        case TYPE:
+                            AnyTypeCond typeCond = new AnyTypeCond();
+                            typeCond.setAnyTypeName(value);
+                            leaf = SearchCond.getLeafCond(typeCond);
+                            break;
+
                         case GROUPS:
                             MembershipCond groupCond = new MembershipCond();
                             groupCond.setGroupKey(Long.valueOf(value));

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
index 26068e9..caa9c54 100644
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
+++ b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.misc.search;
 
 import static org.junit.Assert.assertEquals;
 
+import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.SpecialAttr;
 import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
@@ -28,6 +29,7 @@ import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
 import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
 import org.junit.Test;
 
 public class SearchCondConverterTest {
@@ -119,6 +121,18 @@ public class SearchCondConverterTest {
     }
 
     @Test
+    public void type() {
+        String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder().type("PRINTER").query();
+        assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
+
+        AnyTypeCond acond = new AnyTypeCond();
+        acond.setAnyTypeName("PRINTER");
+        SearchCond simpleCond = SearchCond.getLeafCond(acond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
     public void and() {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().
                 is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
index bd2f938..11d3c8e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -20,6 +20,8 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -28,7 +30,11 @@ import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 
 public interface AnyObjectDAO extends AnyDAO<AnyObject> {
 
-    List<AnyObject> findByAnyType(String anyTypeName);
+    List<AnyObject> findAll(String anyTypeName,
+            Set<String> adminRealms, int page, int itemsPerPage);
+
+    List<AnyObject> findAll(String anyTypeName,
+            Set<String> adminRealms, int page, int itemsPerPage, List<OrderByClause> orderBy);
 
     List<Group> findDynGroupMemberships(AnyObject anyObject);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
new file mode 100644
index 0000000..a12a3e7
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.persistence.api.dao.search;
+
+public class AnyTypeCond extends AbstractSearchCond {
+
+    private static final long serialVersionUID = 4298076973281246633L;
+
+    private String anyTypeName;
+
+    public String getAnyTypeName() {
+        return anyTypeName;
+    }
+
+    public void setAnyTypeName(final String anyTypeName) {
+        this.anyTypeName = anyTypeName;
+    }
+
+    @Override
+    public boolean isValid() {
+        return anyTypeName != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
index d942591..82da594 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
@@ -35,6 +35,8 @@ public class SearchCond extends AbstractSearchCond {
 
     private Type type;
 
+    private AnyTypeCond anyTypeCond;
+
     private AnyCond anyCond;
 
     private AttributeCond attributeCond;
@@ -51,6 +53,15 @@ public class SearchCond extends AbstractSearchCond {
 
     private SearchCond rightNodeCond;
 
+    public static SearchCond getLeafCond(final AnyTypeCond anyTypeCond) {
+        SearchCond nodeCond = new SearchCond();
+
+        nodeCond.type = Type.LEAF;
+        nodeCond.anyTypeCond = anyTypeCond;
+
+        return nodeCond;
+    }
+
     public static SearchCond getLeafCond(final AttributeCond attributeCond) {
         SearchCond nodeCond = new SearchCond();
 
@@ -173,6 +184,14 @@ public class SearchCond extends AbstractSearchCond {
         }
     }
 
+    public AnyTypeCond getAnyTypeCond() {
+        return anyTypeCond;
+    }
+
+    public void setAnyTypeCond(final AnyTypeCond anyTypeCond) {
+        this.anyTypeCond = anyTypeCond;
+    }
+
     public AnyCond getAnyCond() {
         return anyCond;
     }
@@ -256,9 +275,10 @@ public class SearchCond extends AbstractSearchCond {
         switch (type) {
             case LEAF:
             case NOT_LEAF:
-                isValid = (anyCond != null || attributeCond != null
+                isValid = (anyTypeCond != null || anyCond != null || attributeCond != null
                         || relationshipCond != null || membershipCond != null
                         || roleCond != null || resourceCond != null)
+                        && (anyTypeCond == null || anyTypeCond.isValid())
                         && (anyCond == null || anyCond.isValid())
                         && (attributeCond == null || attributeCond.isValid())
                         && (membershipCond == null || membershipCond.isValid())

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 298f5c4..968f990 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -33,6 +34,9 @@ import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
@@ -43,7 +47,6 @@ import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
-import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -77,12 +80,21 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     }
 
     @Override
-    public List<AnyObject> findByAnyType(final String anyTypeName) {
-        TypedQuery<AnyObject> query = entityManager.createQuery(
-                "SELECT e FROM " + JPAAnyObject.class.getSimpleName() + " e WHERE e.type.name=:name", AnyObject.class);
-        query.setParameter("name", anyTypeName);
+    public final List<AnyObject> findAll(final String anyTypeName,
+            final Set<String> adminRealms, final int page, final int itemsPerPage) {
 
-        return query.getResultList();
+        return findAll(anyTypeName, adminRealms, page, itemsPerPage, Collections.<OrderByClause>emptyList());
+    }
+
+    @Override
+    public final List<AnyObject> findAll(final String anyTypeName,
+            final Set<String> adminRealms, final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
+
+        AnyTypeCond anyTypeCond = new AnyTypeCond();
+        anyTypeCond.setAnyTypeName(anyTypeName);
+
+        return searchDAO.search(adminRealms, SearchCond.getLeafCond(anyTypeCond), page, itemsPerPage, orderBy,
+                getAnyUtils().getAnyTypeKind());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index 6a14e58..b8ab75d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -53,6 +53,7 @@ import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
 import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
 import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
@@ -420,6 +421,10 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
 
             case LEAF:
             case NOT_LEAF:
+                if (nodeCond.getAnyTypeCond() != null && AnyTypeKind.ANY_OBJECT == type) {
+                    query.append(getQuery(nodeCond.getAnyTypeCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+                }
                 if (nodeCond.getRelationshipCond() != null
                         && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
 
@@ -470,6 +475,23 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
         return query;
     }
 
+    private String getQuery(final AnyTypeCond cond, final boolean not, final List<Object> parameters,
+            final SearchSupport svs) {
+
+        StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+                append(svs.field().name).append(" WHERE type_name");
+
+        if (not) {
+            query.append("<>");
+        } else {
+            query.append('=');
+        }
+
+        query.append('?').append(setParameter(parameters, cond.getAnyTypeName()));
+
+        return query.toString();
+    }
+
     private String getQuery(final RelationshipCond cond, final boolean not, final List<Object> parameters,
             final SearchSupport svs) {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
index 9d0f798..645c60c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
@@ -321,7 +321,7 @@ public class JPAAnyUtils implements AnyUtils {
                 break;
 
             case ANY_OBJECT:
-                result = IntMappingType.AnyPlainSchema;
+                result = IntMappingType.AnyObjectPlainSchema;
                 break;
 
             case USER:
@@ -344,7 +344,7 @@ public class JPAAnyUtils implements AnyUtils {
                 break;
 
             case ANY_OBJECT:
-                result = IntMappingType.AnyDerivedSchema;
+                result = IntMappingType.AnyObjectDerivedSchema;
                 break;
 
             case USER:
@@ -367,7 +367,7 @@ public class JPAAnyUtils implements AnyUtils {
                 break;
 
             case ANY_OBJECT:
-                result = IntMappingType.AnyVirtualSchema;
+                result = IntMappingType.AnyObjectVirtualSchema;
                 break;
 
             case USER:

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
index 227f0fd..2066f6f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
@@ -115,7 +115,7 @@ public class JPAMapping extends AbstractEntity<Long> implements Mapping {
     protected boolean addConnObjectKeyItem(final MappingItem connObjectKeyItem) {
         if (IntMappingType.UserVirtualSchema == connObjectKeyItem.getIntMappingType()
                 || IntMappingType.GroupVirtualSchema == connObjectKeyItem.getIntMappingType()
-                || IntMappingType.AnyVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.AnyObjectVirtualSchema == connObjectKeyItem.getIntMappingType()
                 || IntMappingType.Password == connObjectKeyItem.getIntMappingType()) {
 
             throw new IllegalArgumentException("Virtual attributes cannot be set as ConnObjectKey");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
index 2aa587f..ae9a117 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
@@ -143,7 +143,7 @@ public class JPAMappingItem extends AbstractEntity<Long> implements MappingItem
         switch (getIntMappingType()) {
             case UserKey:
             case GroupKey:
-            case AnyKey:
+            case AnyObjectKey:
                 name = "id";
                 break;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
index e3a4a74..e149969 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -48,6 +49,15 @@ public class AnyObjectTest extends AbstractTest {
     }
 
     @Test
+    public void findAllByType() {
+        List<AnyObject> list = anyObjectDAO.findAll("PRINTER", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertFalse(list.isEmpty());
+
+        list = anyObjectDAO.findAll("UNEXISTING", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
     public void find() {
         AnyObject anyObject = anyObjectDAO.find(2L);
         assertNotNull(anyObject);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
index fcc3982..018f632 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
@@ -30,7 +30,6 @@ import java.util.List;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.cxf.ws.addressing.v200403.Relationship;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
@@ -44,6 +43,7 @@ import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
 import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
 import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -72,7 +72,7 @@ public class AnySearchTest extends AbstractTest {
     public void anyObjectMatch() {
         AnyObject anyObject = anyObjectDAO.find(1L);
         assertNotNull(anyObject);
-        
+
         RelationshipCond cond = new RelationshipCond();
         cond.setAnyObjectKey(2L);
         assertTrue(searchDAO.matches(anyObject, SearchCond.getLeafCond(cond), AnyTypeKind.ANY_OBJECT));
@@ -385,6 +385,26 @@ public class AnySearchTest extends AbstractTest {
     }
 
     @Test
+    public void searchByType() {
+        AnyTypeCond tcond = new AnyTypeCond();
+        tcond.setAnyTypeName("PRINTER");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(tcond);
+        assertTrue(searchCondition.isValid());
+
+        List<AnyObject> printers = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
+        assertNotNull(printers);
+        assertEquals(2, printers.size());
+
+        tcond.setAnyTypeName("UNEXISTING");
+        printers = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
+        assertNotNull(printers);
+        assertTrue(printers.isEmpty());
+    }
+
+    @Test
     public void userOrderBy() {
         AnyCond usernameLeafCond = new AnyCond(AnyCond.Type.EQ);
         usernameLeafCond.setSchema("username");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
index 2337a32..13937cc 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
@@ -57,10 +57,10 @@ public class AnyTypeTest extends AbstractTest {
         assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
         assertFalse(groupType.getClasses().isEmpty());
 
-        AnyType otherType = anyTypeDAO.find("OTHER");
+        AnyType otherType = anyTypeDAO.find("PRINTER");
         assertNotNull(otherType);
         assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
-        assertEquals("OTHER", otherType.getKey());
+        assertEquals("PRINTER", otherType.getKey());
     }
 
     @Test
@@ -100,11 +100,11 @@ public class AnyTypeTest extends AbstractTest {
 
     @Test
     public void delete() {
-        AnyType otherType = anyTypeDAO.find("OTHER");
+        AnyType otherType = anyTypeDAO.find("PRINTER");
         assertNotNull(otherType);
 
         anyTypeDAO.delete(otherType.getKey());
-        assertNull(anyTypeDAO.find("OTHER"));
+        assertNull(anyTypeDAO.find("PRINTER"));
     }
 
     @Test(expected = IllegalArgumentException.class)

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
index 967a6be..7e86689 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
@@ -47,7 +47,7 @@ public class PlainSchemaTest extends AbstractTest {
     @Test
     public void findAll() {
         List<PlainSchema> schemas = plainSchemaDAO.findAll();
-        assertEquals(40, schemas.size());
+        assertEquals(42, schemas.size());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
index ee9a9f7..c058db7 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
@@ -82,7 +82,7 @@ public class ResourceTest extends AbstractTest {
     public void findAll() {
         List<ExternalResource> resources = resourceDAO.findAll();
         assertNotNull(resources);
-        assertEquals(18, resources.size());
+        assertEquals(19, resources.size());
     }
 
     @Test
@@ -294,7 +294,7 @@ public class ResourceTest extends AbstractTest {
         item = entityFactory.newEntity(MappingItem.class);
         item.setIntAttrName("mderiveddata");
         item.setExtAttrName("mderiveddata");
-        item.setIntMappingType(IntMappingType.AnyDerivedSchema);
+        item.setIntMappingType(IntMappingType.AnyObjectDerivedSchema);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
index 43d65d1..a4aed30 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
@@ -67,7 +67,7 @@ public class TaskTest extends AbstractTest {
         assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.SCHEDULED).size());
-        assertEquals(9, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
+        assertEquals(10, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
         assertEquals(11, taskDAO.findAll(TaskType.PUSH).size());
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
index b32e970..50b4c56 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
@@ -158,7 +158,7 @@ public class GroupTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
-        user.add(anyTypeClassDAO.find("minimal other"));
+        user.add(anyTypeClassDAO.find("other"));
 
         UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
         attr.setOwner(user);
@@ -250,13 +250,13 @@ public class GroupTest extends AbstractTest {
     public void adynMembership() {
         // 0. create any object matching the condition below
         AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
-        anyObject.setType(anyTypeDAO.find("OTHER"));
+        anyObject.setType(anyTypeDAO.find("PRINTER"));
         anyObject.setRealm(realmDAO.find("/even/two"));
 
         APlainAttr attr = entityFactory.newEntity(APlainAttr.class);
         attr.setOwner(anyObject);
-        attr.setSchema(plainSchemaDAO.find("cool"));
-        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        attr.setSchema(plainSchemaDAO.find("model"));
+        attr.add("Canon MFC8030", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
         anyObject.add(attr);
 
         anyObject = anyObjectDAO.save(anyObject);
@@ -269,7 +269,7 @@ public class GroupTest extends AbstractTest {
         group.setName("new");
 
         ADynGroupMembership dynMembership = entityFactory.newEntity(ADynGroupMembership.class);
-        dynMembership.setFIQLCond("cool==true");
+        dynMembership.setFIQLCond("model==Canon MFC8030");
         dynMembership.setGroup(group);
 
         group.setADynMembership(dynMembership);
@@ -288,7 +288,7 @@ public class GroupTest extends AbstractTest {
 
         // 3. verify that expected any objects have the created group dynamically assigned
         assertEquals(2, actual.getADynMembership().getMembers().size());
-        assertEquals(new HashSet<>(Arrays.asList(2L, newAnyObjectKey)),
+        assertEquals(new HashSet<>(Arrays.asList(1L, newAnyObjectKey)),
                 CollectionUtils.collect(actual.getADynMembership().getMembers(), new Transformer<AnyObject, Long>() {
 
                     @Override
@@ -297,7 +297,7 @@ public class GroupTest extends AbstractTest {
                     }
                 }, new HashSet<Long>()));
 
-        anyObject = anyObjectDAO.find(2L);
+        anyObject = anyObjectDAO.find(1L);
         assertNotNull(anyObject);
         Collection<Group> dynGroupMemberships = findDynGroupMemberships(anyObject);
         assertEquals(1, dynGroupMemberships.size());
@@ -310,7 +310,7 @@ public class GroupTest extends AbstractTest {
 
         actual = groupDAO.find(actual.getKey());
         assertEquals(1, actual.getADynMembership().getMembers().size());
-        assertEquals(2L, actual.getADynMembership().getMembers().get(0).getKey(), 0);
+        assertEquals(1L, actual.getADynMembership().getMembers().get(0).getKey(), 0);
 
         // 5. delete group and verify that dynamic membership was also removed
         Long dynMembershipKey = actual.getADynMembership().getKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
index b92debb..7d363c2 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
@@ -79,7 +79,9 @@ public class PlainSchemaTest extends AbstractTest {
         // check for associated mappings
         Set<MappingItem> mapItems = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
                 for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (schema.getKey().equals(mapItem.getIntAttrName())) {
                         mapItems.add(mapItem);
@@ -103,7 +105,9 @@ public class PlainSchemaTest extends AbstractTest {
         // check for mappings deletion
         mapItems = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
                 for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if ("fullname".equals(mapItem.getIntAttrName())) {
                         mapItems.add(mapItem);
@@ -128,7 +132,9 @@ public class PlainSchemaTest extends AbstractTest {
         // check for associated mappings
         Set<MappingItem> mappings = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
                 for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (schema.getKey().equals(mapItem.getIntAttrName())) {
                         mappings.add(mapItem);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
index 71fa878..5fdc803 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
@@ -88,7 +88,7 @@ public class RoleTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
-        user.add(anyTypeClassDAO.find("minimal other"));
+        user.add(anyTypeClassDAO.find("other"));
 
         UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
         attr.setOwner(user);


[13/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..cf51170
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
@@ -0,0 +1,173 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <style>
+      span#actionLink{
+        margin-left: 1px;
+        margin-right: 1px;
+      }
+    </style>
+  </wicket:head>
+  <wicket:panel>
+    <span wicket:id="panelClaim">[plus]</span>
+    <span wicket:id="panelManageResources">[plus]</span>
+    <span wicket:id="panelManageUsers">[plus]</span>
+    <span wicket:id="panelManageGroups">[plus]</span>
+    <span wicket:id="panelDryRun">[plus]</span>
+    <span wicket:id="panelExecute">[plus]</span>
+    <span wicket:id="panelEnable">[plus]</span>
+    <span wicket:id="panelSearch">[plus]</span>
+    <span wicket:id="panelCreate">[plus]</span>
+    <span wicket:id="panelUserTemplate">[plus]</span>
+    <span wicket:id="panelGroupTemplate">[plus]</span>
+    <span wicket:id="panelReset">[plus]</span>
+    <span wicket:id="panelEdit">[plus]</span>
+    <span wicket:id="panelExport">[plus]</span>
+    <span wicket:id="panelDelete">[plus]</span>
+    <span wicket:id="panelSelect">[plus]</span>
+    <span wicket:id="panelSuspend">[plus]</span>
+    <span wicket:id="panelReactivate">[plus]</span>
+    <span wicket:id="panelReload">[plus]</span>
+    <span wicket:id="panelChangeView">[plus]</span>
+    <span wicket:id="panelUnlink">[plus]</span>
+    <span wicket:id="panelLink">[plus]</span>
+    <span wicket:id="panelUnassign">[plus]</span>
+    <span wicket:id="panelAssign">[plus]</span>
+    <span wicket:id="panelDeprovision">[plus]</span>
+    <span wicket:id="panelProvision">[plus]</span>
+    <span wicket:id="panelZoomIn">[plus]</span>
+    <span wicket:id="panelZoomOut">[plus]</span>
+
+    <wicket:fragment wicket:id="fragmentClaim">
+      <a href="#" wicket:id="claimLink"><img id="actionLink" src="img/actions/claim.png" alt="claim icon" title="Claim"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentManageResources">
+      <a href="#" wicket:id="manageResourcesLink"><img id="actionLink" src="img/actions/resources-icon.png" alt="manage resources icon" title="Manage resources"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentManageUsers">
+      <a href="#" wicket:id="manageUsersLink"><img id="actionLink" src="img/actions/users-icon.png" alt="manage users icon" title="Manage users"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentManageGroups">
+      <a href="#" wicket:id="manageGroupsLink"><img id="actionLink" src="img/actions/groups-icon.png" alt="manage groups icon" title="Manage groups"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentCreate">
+      <a href="#" wicket:id="createLink"><img id="actionLink" src="img/actions/create.png" alt="create icon" title="Create"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentSearch">
+      <a href="#" wicket:id="searchLink"><img id="actionLink" src="img/actions/search.png" alt="search icon" title="Search and modify"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentEnable">
+      <a href="#" wicket:id="enableLink"><img id="actionLink" src="img/actions/enable.png" alt="enable icon" title="Enable / Disable"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentEdit">
+      <a href="#" wicket:id="editLink"><img id="actionLink" src="img/actions/edit.png" alt="edit icon" title="Edit"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentReset">
+      <a href="#" wicket:id="resetLink"><img id="actionLink" src="img/actions/reset.png" alt="reset icon" title="Reset sync token"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentUserTemplate">
+      <a href="#" wicket:id="userTemplateLink"><img id="actionLink" src="img/actions/user_template.png" alt="user template icon" title="Specify user template"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentGroupTemplate">
+      <a href="#" wicket:id="groupTemplateLink"><img id="actionLink" src="img/actions/groups-icon.png" alt="group template icon"  title="Specify group template"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentDelete">
+      <a href="#" wicket:id="deleteLink"><img id="actionLink" src="img/actions/delete.png" alt="delete icon" title="Delete"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentDryRun">
+      <a href="#" wicket:id="dryRunLink"><img id="actionLink" src="img/actions/dryrun.png" alt="dryrun icon" title="DryRun"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentExecute">
+      <a href="#" wicket:id="executeLink"><img id="actionLink" src="img/actions/execute.png" alt="execute icon" title="Execute"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentSelect">
+      <a href="#" wicket:id="selectLink"><img id="actionLink" src="img/actions/select.png" alt="select icon" title="Select"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentExport">
+      <a href="#" wicket:id="exportLink"><img id="actionLink" src="img/actions/export.png" alt="export icon" title="Export"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentSuspend">
+      <a href="#" wicket:id="suspendLink"><img id="actionLink" src="img/actions/suspend.png" alt="suspend icon" title="Suspend"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentReactivate">
+      <a href="#" wicket:id="reactivateLink"><img id="actionLink" src="img/actions/reactivate.png" alt="reactivate icon" title="Reactivate"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentReload">
+      <a href="#" wicket:id="reloadLink"><img id="actionLink" src="img/actions/reload.png" alt="reload icon" title="Reload"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentChangeView">
+      <a href="#" wicket:id="changeViewLink"><img id="actionLink" src="img/actions/settings-icon.png" alt="Change view icon" title="Change view"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentUnlink">
+      <a href="#" wicket:id="unlinkLink"><img id="actionLink" src="img/actions/unlink-icon.png" alt="Unlink icon"  title="Unlink"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentLink">
+      <a href="#" wicket:id="linkLink"><img id="actionLink" src="img/actions/link-icon.png" alt="Link icon"  title="Link"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentUnassign">
+      <a href="#" wicket:id="unassignLink"><img id="actionLink" src="img/actions/unassign-icon.png" alt="Unassign icon"  title="Unassign"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentAssign">
+      <a href="#" wicket:id="assignLink"><img id="actionLink" src="img/actions/assign-icon.png" alt="Assign icon"  title="Assign"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentDeprovision">
+      <a href="#" wicket:id="deprovisionLink"><img id="actionLink" src="img/actions/deprovision-icon.png" alt="De-provision icon"  title="De-provision"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentProvision">
+      <a href="#" wicket:id="provisionLink"><img id="actionLink" src="img/actions/provision-icon.png" alt="Provision icon"  title="Provision"/></a>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="fragmentZoomIn">
+      <a href="#" wicket:id="zoomInLink"><i class="fa fa-search-plus"></i></a>
+    </wicket:fragment>
+    
+    <wicket:fragment wicket:id="fragmentZoomOut">
+      <a href="#" wicket:id="zoomOutLink"><i class="fa fa-search-minus"></i></a>
+    </wicket:fragment>
+    
+    <wicket:fragment wicket:id="emptyFragment">
+    </wicket:fragment>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.html
new file mode 100644
index 0000000..fc7596f
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.html
@@ -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.
+-->
+<wicket:extend>
+    <input type="checkbox" class="checkbox" wicket:id="checkboxField"/>
+</wicket:extend>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.html
new file mode 100644
index 0000000..12d5bf2
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.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:extend>
+    <select class="ui-widget-content ui-corner-all medium_dynamicsize"
+            wicket:id="dropDownChoiceField" />
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxNumberFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxNumberFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxNumberFieldPanel.html
new file mode 100644
index 0000000..3a719d1
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxNumberFieldPanel.html
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+<wicket:extend>
+    <input type="text" class="ui-widget-content ui-corner-all medium_dynamicsize"
+           wicket:id="numberField" />
+</wicket:extend>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.html
new file mode 100644
index 0000000..1833140
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.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:panel>
+    <span wicket:id="paletteField">[Palette]</span>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPasswordFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPasswordFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPasswordFieldPanel.html
new file mode 100644
index 0000000..1f7b8f3
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPasswordFieldPanel.html
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+<wicket:extend>
+    <input type="password" class="ui-widget-content ui-corner-all long_dynamicsize"
+           wicket:id="passwordField" />
+</wicket:extend>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.html
new file mode 100644
index 0000000..e6f1d7c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.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>
+    <input type="text" class="ui-widget-content ui-corner-all long_dynamicsize" wicket:id="textField"/>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel_1.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel_1.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel_1.html
new file mode 100644
index 0000000..e6f1d7c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel_1.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>
+    <input type="text" class="ui-widget-content ui-corner-all long_dynamicsize" wicket:id="textField"/>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.html
new file mode 100644
index 0000000..6b2556f
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.html
@@ -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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:extend>
+    <input style="display: none;" wicket:id="textField"/>
+    <span style="margin-right: 20px;">
+      <div style="display: table-cell;">
+        <form wicket:id="uploadForm" encType="multipart/form-data" method="post" accept-charset="UTF-8">
+          <input wicket:id="fileUpload" type="file"/>
+          <div style="top: -25px; left: 100%; position: relative; vertical-align: middle;">
+            <a href="#" wicket:id="uploadLink"><img src="img/file-upload.png" alt="upload" title="upload" style="vertical-align: middle;"/></a>
+            <a href="#" wicket:id="downloadLink"><img src="img/file-download.png" alt="download" title="download" style="vertical-align: middle;"/></a>
+            <a href="#" wicket:id="resetLink"><img src="img/disable.png" alt="disable" title="remove value" style="vertical-align: middle;"/></a>
+            <span wicket:id="preview"/>
+          </div>
+          <span wicket:id="previewContainer">
+            <span wicket:id="panelPreview">[panelPreview]</span>
+            <wicket:fragment wicket:id="previewFragment">
+              <div wicket:id = "previewer" class="ui-widget-content ui-corner-all"></div>
+            </wicket:fragment>
+            <wicket:fragment wicket:id="emptyFragment">
+            </wicket:fragment>
+          </span>
+        </form>
+      </div>
+    </span>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/CheckBoxMultipleChoiceFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/CheckBoxMultipleChoiceFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/CheckBoxMultipleChoiceFieldPanel.html
new file mode 100644
index 0000000..52f1da9
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/CheckBoxMultipleChoiceFieldPanel.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>
+    <wicket:panel>
+        <span wicket:id="checkBoxMultipleChoice" />
+    </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTextFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTextFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTextFieldPanel.html
new file mode 100644
index 0000000..caaf991
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTextFieldPanel.html
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+<wicket:extend>
+    <input type="text" class="text ui-widget-content ui-corner-all date_size"
+           wicket:id="field"/>
+</wicket:extend>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.html
new file mode 100644
index 0000000..e3a191b
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.html
@@ -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.
+-->
+<wicket:extend>
+    <span wicket:id="field"/>
+</wicket:extend>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.properties
new file mode 100644
index 0000000..9a39f4c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.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.
+field.DateTimeFieldPanel$DateTimeFormValidator=Field '${label0}' must be fully valued

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_it.properties
new file mode 100644
index 0000000..c524834
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_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.
+field.DateTimeFieldPanel$DateTimeFormValidator=Il campo '${label0}' dev'essere completamente valorizzato

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_pt_BR.properties
new file mode 100644
index 0000000..95be437
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel_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.
+field.DateTimeFieldPanel$DateTimeFormValidator=Campo'${label0}' precisa ser preenchido 

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.html
new file mode 100644
index 0000000..c4b75f0
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.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.
+-->
+<wicket:panel>
+  <a href="#" wicket:id="link">
+          <span wicket:id="linkTitle"/> 
+  </a>
+</wicket:panel>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel_1.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel_1.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel_1.html
new file mode 100644
index 0000000..c4b75f0
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel_1.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.
+-->
+<wicket:panel>
+  <a href="#" wicket:id="link">
+          <span wicket:id="linkTitle"/> 
+  </a>
+</wicket:panel>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html
new file mode 100644
index 0000000..f14e105
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html
@@ -0,0 +1,31 @@
+<!--
+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>
+
+    <a href="#" wicket:id="propagationPurposeLink"><i class="fa fa-arrow-circle-o-right"></i></a>
+
+    <a href="#" wicket:id="synchronizationPurposeLink"><i class="fa fa-arrow-circle-o-left"></i></a>
+
+    <a href="#" wicket:id="bothPurposeLink"><i class="fa fa-exchange"></i></a>
+
+    <a href="#" wicket:id="nonePurposeLink"><i class="fa fa-chain-broken"></i></a>
+
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html
new file mode 100644
index 0000000..e35205c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html
@@ -0,0 +1,35 @@
+<!--
+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>
+    <span wicket:id="multiValueContainer">
+      <span wicket:id="view">
+        <span wicket:id="panel">[form field]</span>
+        <a wicket:id="drop"><img src="img/minus-icon.png" alt="remove icon" class="drop_button" /></a>
+        <span wicket:id="panelPlus">[plus]</span>
+        <br />
+      </span>
+      <wicket:fragment wicket:id="fragmentPlus">
+        <a wicket:id="add"><i class="fa fa-plus"></i></a>
+      </wicket:fragment>
+      <wicket:fragment wicket:id="emptyFragment">
+      </wicket:fragment>
+    </span>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.properties
new file mode 100644
index 0000000..958e9e0
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.properties
@@ -0,0 +1,22 @@
+# 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.
+minLength=Minimum password size
+maxLength=Maximum password size
+historyLength=Password history length
+digitRequired=Password must contain one or more digits
+prefixesNotPermitted=Password prefixes not permitted
+apply=Save

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_it.properties
new file mode 100644
index 0000000..4c92961
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_it.properties
@@ -0,0 +1,22 @@
+# 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.
+minLength=Lunghezza minima password
+maxLength=Lunghezza massima password
+historyLength=Lunghezza storico password
+digitRequired=La password deve contenere uno o pi\u00f9 numeri
+prefixesNotPermitted=Prefissi password non permessi
+apply=Salva

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_pt_BR.properties
new file mode 100644
index 0000000..d4f5693
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel_pt_BR.properties
@@ -0,0 +1,22 @@
+# 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.
+minLength=Tamanho m\u00EDnimo de senha
+maxLength=Tamanho m\u00E1ximo de senha
+historyLength=Tamanho dos hist\u00F3rico de senha
+digitRequired=Senha precisa contar um ou mais d\u00EDgitos
+prefixesNotPermitted=Prefixos de senha n\u00E3o permitidos
+apply=Salvar

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.html
new file mode 100644
index 0000000..5800d77
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.html
@@ -0,0 +1,69 @@
+<?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 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 style="display: inline-table;">
+      <input type="hidden" wicket:id="recorder"/>
+
+      <div style="display: table-row">
+        <div id="choices" style="display: table-cell; text-align: center; font-weight: bold;">
+          <span wicket:id="availableHeader">[available header]</span>
+        </div>
+
+        <div id="buttons" style="display: table-cell;">
+        </div>
+
+        <div id="selections" style="display: table-cell; text-align: center; font-weight: bold;">
+          <span wicket:id="selectedHeader">[selected header]</span>
+        </div>
+      </div>
+
+      <div style="display: table-row">
+        <div id="choices" style="display: table-cell;">
+          <select class="choicesSelect" style="min-width: 100px;" wicket:id="choices">[choices]</select>	
+        </div>
+
+        <div id="buttons" style="display: table-cell; width: 30px; text-align: center; vertical-align: middle;">
+          <div style="padding-bottom: 2px;">
+            <a wicket:id="addAllButton"><img src="img/addAll.png" alt="remove icon"/></a>
+          </div>
+          <div style="padding-top: 2px; padding-bottom: 2px;">
+            <a wicket:id="removeAllButton"><img src="img/removeAll.png" alt="move up icon"/></a>
+          </div>
+          <div style="padding-top: 2px; padding-bottom: 2px;">
+            <a wicket:id="addButton"><img src="img/add.png" alt="add icon"/></a>
+          </div>
+          <div style="padding-top: 2px; padding-bottom: 2px;">
+            <a wicket:id="removeButton"><img src="img/remove.png" alt="remove icon"/></a>
+          </div>
+          <div style="padding-top: 2px; padding-bottom: 2px;">
+            <a wicket:id="moveUpButton"><img src="img/moveUp.png" alt="move up icon"/></a>
+          </div>
+          <div style="padding-top: 2px;">
+            <a wicket:id="moveDownButton"><img src="img/moveDown.png" alt="move down icon"/></a>
+          </div>
+        </div>
+
+        <div id="selections" style="display: table-cell;">
+          <select class="selectionSelect" style="min-width: 100px;" wicket:id="selection">[selection]</select>	
+        </div>
+      </div>
+    </div>
+  </wicket:panel>
+</html>

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index 91d982e..76552e6 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@ -176,7 +176,6 @@ public interface ConnectorService extends JAXRSService {
      */
     @POST
     @Path("check")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     boolean check(@NotNull ConnInstanceTO connInstanceTO);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index f2d75af..fe9519d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -373,12 +373,14 @@ under the License.
     
     <jquery.version>2.1.3</jquery.version>
     <jquery-ui.version>1.11.4</jquery-ui.version>
+    <jquery-cookie.version>1.4.1-1</jquery-cookie.version>
     <bootstrap.version>3.3.4</bootstrap.version>
     <bootstrap-select.version>1.6.3</bootstrap-select.version>
     <font-awesome.version>4.3.0</font-awesome.version>
     <ionicons.version>2.0.1</ionicons.version>
     <highlightjs.version>8.4-4</highlightjs.version>
     <codemirror.version>5.1</codemirror.version>
+    <jsplumb.version>1.6.4</jsplumb.version>
     
     <wicket.version>7.0.0-M5</wicket.version>
     <wicket-jqueryui.version>7.0.0-M5</wicket-jqueryui.version>
@@ -947,6 +949,17 @@ under the License.
         <artifactId>codemirror</artifactId>
         <version>${codemirror.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.webjars</groupId>
+        <artifactId>jsplumb</artifactId>
+        <version>${jsplumb.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.webjars</groupId>
+        <artifactId>jquery-cookie</artifactId>
+        <version>${jquery-cookie.version}</version>
+      </dependency>
+      
       
       <dependency>
         <groupId>com.beust</groupId>


[02/27] syncope git commit: [SYNCOPE-156] providing basic layout for realms and administration pages

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/console.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/console.css b/client/console/src/main/resources/META-INF/resources/css/console.css
new file mode 100644
index 0000000..06c5bc5
--- /dev/null
+++ b/client/console/src/main/resources/META-INF/resources/css/console.css
@@ -0,0 +1,4066 @@
+@import url(//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);
+/*!
+ *   AdminLTE v2.0.4
+ *   Author: Almsaeed Studio
+ *	 Website: Almsaeed Studio <http://almsaeedstudio.com>
+ *   License: Open source - MIT
+ *           Please visit http://opensource.org/licenses/MIT for more information
+!*/
+/*
+ * Core: Genral Layout Style
+ * -------------------------
+ */
+html,
+body {
+  min-height: 100%;
+}
+.layout-boxed html,
+.layout-boxed body {
+  height: 100%;
+}
+body {
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+  font-weight: 400;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+/* Layout */
+.wrapper {
+  min-height: 100%;
+  position: static;
+  overflow: hidden;
+}
+.wrapper:before,
+.wrapper:after {
+  content: " ";
+  display: table;
+}
+.wrapper:after {
+  clear: both;
+}
+.layout-boxed .wrapper {
+  max-width: 1250px;
+  margin: 0 auto;
+  min-height: 100%;
+  box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
+  position: relative;
+}
+.layout-boxed {
+  background: url('../img/boxed-bg.jpg') repeat fixed;
+}
+/*
+ * Content Wrapper - contins main content
+ * ```.right-side has been deprecated as of v2.0.0 in favor of .content-wrapper  ```
+ */
+.content-wrapper,
+.right-side,
+.main-footer {
+  -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -moz-transition: -moz-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -o-transition: -o-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  transition: transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -o-transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  margin-left: 230px;
+  z-index: 820;
+}
+.layout-top-nav .content-wrapper,
+.layout-top-nav .right-side,
+.layout-top-nav .main-footer {
+  margin-left: 0;
+}
+@media (max-width: 767px) {
+  .content-wrapper,
+  .right-side,
+  .main-footer {
+    margin-left: 0;
+  }
+}
+@media (min-width: 768px) {
+  .sidebar-collapse .content-wrapper,
+  .sidebar-collapse .right-side,
+  .sidebar-collapse .main-footer {
+    margin-left: 0;
+  }
+}
+@media (max-width: 767px) {
+  .sidebar-open .content-wrapper,
+  .sidebar-open .right-side,
+  .sidebar-open .main-footer {
+    -webkit-transform: translate(230px, 0);
+    -ms-transform: translate(230px, 0);
+    -o-transform: translate(230px, 0);
+    transform: translate(230px, 0);
+  }
+}
+.content-wrapper,
+.right-side {
+  min-height: 100%;
+  background-color: #ecf0f5;
+  z-index: 800;
+}
+.main-footer {
+  background: #fff;
+  padding: 15px;
+  color: #444;
+  border-top: 1px solid #eee;
+}
+/* Fixed layout */
+.fixed .main-header,
+.fixed .main-sidebar,
+.fixed .left-side {
+  position: fixed;
+}
+.fixed .main-header {
+  top: 0;
+  right: 0;
+  left: 0;
+}
+.fixed .content-wrapper,
+.fixed .right-side {
+  padding-top: 50px;
+}
+@media (max-width: 767px) {
+  .fixed .content-wrapper,
+  .fixed .right-side {
+    padding-top: 100px;
+  }
+}
+.fixed.layout-boxed .wrapper {
+  max-width: 100%;
+}
+/* Content */
+.content {
+  min-height: 250px;
+  padding: 15px;
+  margin-right: auto;
+  margin-left: auto;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+/* H1 - H6 font */
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+  font-family: 'Source Sans Pro', sans-serif;
+}
+/* General Links */
+a {
+  color: #3c8dbc;
+}
+a:hover,
+a:active,
+a:focus {
+  outline: none;
+  text-decoration: none;
+  color: #72afd2;
+}
+/* Page Header */
+.page-header {
+  margin: 10px 0 20px 0;
+  font-size: 22px;
+}
+.page-header > small {
+  color: #666;
+  display: block;
+  margin-top: 5px;
+}
+/*
+ * Component: Main Header
+ * ----------------------
+ */
+.main-header {
+  position: relative;
+  max-height: 100px;
+  z-index: 1030;
+}
+.main-header > .navbar {
+  margin-bottom: 0;
+  margin-left: 230px;
+  border: none;
+  min-height: 50px;
+  border-radius: 0;
+}
+.layout-top-nav .main-header > .navbar {
+  margin-left: 0!important;
+}
+.main-header #navbar-search-input {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: transparent;
+}
+.main-header #navbar-search-input:focus,
+.main-header #navbar-search-input:active {
+  border-color: rgba(0, 0, 0, 0.1) !important;
+  background: rgba(255, 255, 255, 0.9);
+}
+.main-header #navbar-search-input::-moz-placeholder {
+  color: #ccc;
+  opacity: 1;
+}
+.main-header #navbar-search-input:-ms-input-placeholder {
+  color: #ccc;
+}
+.main-header #navbar-search-input::-webkit-input-placeholder {
+  color: #ccc;
+}
+.main-header .navbar-custom-menu,
+.main-header .navbar-right {
+  margin-right: 5px;
+  float: right;
+}
+@media (max-width: 991px) {
+  .main-header .navbar-custom-menu a,
+  .main-header .navbar-right a {
+    color: inherit;
+    background: transparent;
+  }
+}
+@media (max-width: 767px) {
+  .main-header .navbar-right {
+    float: none;
+  }
+  .navbar-collapse .main-header .navbar-right {
+    margin: 7.5px -15px;
+  }
+  .main-header .navbar-right > li {
+    color: inherit;
+    border: 0;
+  }
+}
+.main-header .sidebar-toggle {
+  float: left;
+  background-color: transparent;
+  background-image: none;
+  padding: 15px 15px;
+  font-family: fontAwesome;
+}
+.main-header .sidebar-toggle:before {
+  content: "\f0c9";
+}
+.main-header .sidebar-toggle:hover {
+  color: #fff;
+}
+.main-header .sidebar-toggle .icon-bar {
+  display: none;
+}
+.main-header .navbar .nav > li.user > a > .fa,
+.main-header .navbar .nav > li.user > a > .glyphicon,
+.main-header .navbar .nav > li.user > a > .ion {
+  margin-right: 5px;
+}
+.main-header .navbar .nav > li > a > .label {
+  position: absolute;
+  top: 9px;
+  right: 7px;
+  text-align: center;
+  font-size: 9px;
+  padding: 2px 3px;
+  line-height: .9;
+}
+.main-header .logo {
+  display: block;
+  float: left;
+  height: 50px;
+  font-size: 20px;
+  line-height: 50px;
+  text-align: center;
+  width: 230px;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  padding: 0 15px;
+  font-weight: 300;
+}
+.main-header .navbar-brand {
+  color: #fff;
+}
+.content-header {
+  position: relative;
+  padding: 15px 15px 0 15px;
+}
+.content-header > h1 {
+  margin: 0;
+  font-size: 24px;
+}
+.content-header > h1 > small {
+  font-size: 15px;
+  display: inline-block;
+  padding-left: 4px;
+  font-weight: 300;
+}
+.content-header > .breadcrumb {
+  float: right;
+  background: transparent;
+  margin-top: 0px;
+  margin-bottom: 0;
+  font-size: 12px;
+  padding: 7px 5px;
+  position: absolute;
+  top: 15px;
+  right: 10px;
+  border-radius: 2px;
+}
+.content-header > .breadcrumb > li > a {
+  color: #444;
+  text-decoration: none;
+  display: inline-block;
+}
+.content-header > .breadcrumb > li > a > .fa,
+.content-header > .breadcrumb > li > a > .glyphicon,
+.content-header > .breadcrumb > li > a > .ion {
+  margin-right: 5px;
+}
+.content-header > .breadcrumb > li + li:before {
+  content: '>\00a0';
+}
+@media (max-width: 991px) {
+  .content-header > .breadcrumb {
+    position: relative;
+    margin-top: 5px;
+    top: 0;
+    right: 0;
+    float: none;
+    background: #d2d6de;
+    padding-left: 10px;
+  }
+  .content-header > .breadcrumb li:before {
+    color: #97a0b3;
+  }
+}
+.navbar-toggle {
+  color: #fff;
+  border: 0;
+  margin: 0;
+  padding: 15px 15px;
+}
+@media (max-width: 991px) {
+  .navbar-custom-menu .navbar-nav > li {
+    float: left;
+  }
+  .navbar-custom-menu .navbar-nav {
+    margin: 0;
+    float: left;
+  }
+  .navbar-custom-menu .navbar-nav > li > a {
+    padding-top: 15px;
+    padding-bottom: 15px;
+    line-height: 20px;
+  }
+}
+@media (max-width: 767px) {
+  .main-header {
+    position: relative;
+  }
+  .main-header .logo,
+  .main-header .navbar {
+    width: 100%;
+    float: none;
+    position: relative!important;
+  }
+  .main-header .navbar {
+    margin: 0;
+  }
+  .main-header .navbar-custom-menu {
+    float: right;
+  }
+  .main-sidebar,
+  .left-side {
+    padding-top: 100px!important;
+  }
+}
+/*
+ * Component: Sidebar
+ * ------------------
+ */
+.main-sidebar,
+.left-side {
+  position: absolute;
+  top: 0;
+  left: 0;
+  padding-top: 50px;
+  min-height: 100%;
+  width: 230px;
+  z-index: 810;
+  -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -moz-transition: -moz-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -o-transition: -o-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  transition: transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+}
+@media (max-width: 767px) {
+  .main-sidebar,
+  .left-side {
+    -webkit-transform: translate(-230px, 0);
+    -ms-transform: translate(-230px, 0);
+    -o-transform: translate(-230px, 0);
+    transform: translate(-230px, 0);
+  }
+}
+@media (min-width: 768px) {
+  .sidebar-collapse .main-sidebar,
+  .sidebar-collapse .left-side {
+    -webkit-transform: translate(-230px, 0);
+    -ms-transform: translate(-230px, 0);
+    -o-transform: translate(-230px, 0);
+    transform: translate(-230px, 0);
+  }
+}
+@media (max-width: 767px) {
+  .sidebar-open .main-sidebar,
+  .sidebar-open .left-side {
+    -webkit-transform: translate(0, 0);
+    -ms-transform: translate(0, 0);
+    -o-transform: translate(0, 0);
+    transform: translate(0, 0);
+  }
+}
+.sidebar {
+  padding-bottom: 10px;
+}
+.fixed .sidebar {
+  overflow: auto;
+  height: 100%;
+}
+.sidebar-form input:focus {
+  border-color: transparent!important;
+}
+.user-panel {
+  padding: 10px;
+}
+.user-panel:before,
+.user-panel:after {
+  content: " ";
+  display: table;
+}
+.user-panel:after {
+  clear: both;
+}
+.user-panel > .image > img {
+  width: 45px;
+  height: 45px;
+}
+.user-panel > .info {
+  font-weight: 600;
+  padding: 5px 5px 5px 15px;
+  font-size: 14px;
+  line-height: 1;
+}
+.user-panel > .info > p {
+  margin-bottom: 9px;
+}
+.user-panel > .info > a {
+  text-decoration: none;
+  padding-right: 5px;
+  margin-top: 3px;
+  font-size: 11px;
+  font-weight: normal;
+}
+.user-panel > .info > a > .fa,
+.user-panel > .info > a > .ion,
+.user-panel > .info > a > .glyphicon {
+  margin-right: 3px;
+}
+.sidebar-menu {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+.sidebar-menu > li {
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.sidebar-menu > li > a {
+  padding: 12px 5px 12px 15px;
+  display: block;
+}
+.sidebar-menu > li > a > .fa,
+.sidebar-menu > li > a > .glyphicon,
+.sidebar-menu > li > a > .ion {
+  width: 20px;
+}
+.sidebar-menu > li .label,
+.sidebar-menu > li .badge {
+  margin-top: 3px;
+  margin-right: 5px;
+}
+.sidebar-menu li.header {
+  padding: 10px 25px 10px 15px;
+  font-size: 12px;
+}
+.sidebar-menu li > a > .fa-angle-left {
+  width: auto;
+  height: auto;
+  padding: 0;
+  margin-right: 10px;
+  margin-top: 3px;
+}
+.sidebar-menu li.active > a > .fa-angle-left {
+  -webkit-transform: rotate(-90deg);
+  -ms-transform: rotate(-90deg);
+  -o-transform: rotate(-90deg);
+  transform: rotate(-90deg);
+}
+.sidebar-menu li.active > .treeview-menu {
+  display: block;
+}
+.sidebar-menu .treeview-menu {
+  display: none;
+  list-style: none;
+  padding: 0;
+  margin: 0;
+  padding-left: 5px;
+}
+.sidebar-menu .treeview-menu .treeview-menu {
+  padding-left: 20px;
+}
+.sidebar-menu .treeview-menu > li {
+  margin: 0;
+}
+.sidebar-menu .treeview-menu > li > a {
+  padding: 5px 5px 5px 15px;
+  display: block;
+  font-size: 14px;
+}
+.sidebar-menu .treeview-menu > li > a > .fa,
+.sidebar-menu .treeview-menu > li > a > .glyphicon,
+.sidebar-menu .treeview-menu > li > a > .ion {
+  width: 20px;
+}
+.sidebar-menu .treeview-menu > li > a > .fa-angle-left,
+.sidebar-menu .treeview-menu > li > a > .fa-angle-down {
+  width: auto;
+}
+/*
+ * Component: Dropdown menus
+ * -------------------------
+ */
+/*Dropdowns in general*/
+.dropdown-menu {
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  border-color: #eee;
+}
+.dropdown-menu > li > a {
+  color: #777;
+}
+.dropdown-menu > li > a > .glyphicon,
+.dropdown-menu > li > a > .fa,
+.dropdown-menu > li > a > .ion {
+  margin-right: 10px;
+}
+.dropdown-menu > li > a:hover {
+  background-color: #e1e3e9;
+  color: #333;
+}
+.dropdown-menu > .divider {
+  background-color: #eee;
+}
+/*
+    Navbar custom dropdown menu
+------------------------------------
+*/
+.navbar-nav > .notifications-menu,
+.navbar-nav > .messages-menu,
+.navbar-nav > .tasks-menu {
+  position: relative;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu,
+.navbar-nav > .messages-menu > .dropdown-menu,
+.navbar-nav > .tasks-menu > .dropdown-menu {
+  width: 280px;
+  padding: 0 0 0 0!important;
+  margin: 0!important;
+  top: 100%;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li,
+.navbar-nav > .messages-menu > .dropdown-menu > li,
+.navbar-nav > .tasks-menu > .dropdown-menu > li {
+  position: relative;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li.header,
+.navbar-nav > .messages-menu > .dropdown-menu > li.header,
+.navbar-nav > .tasks-menu > .dropdown-menu > li.header {
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  background-color: #ffffff;
+  padding: 7px 10px;
+  border-bottom: 1px solid #f4f4f4;
+  color: #444444;
+  font-size: 14px;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a,
+.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a,
+.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {
+  border-top-left-radius: 0px;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+  font-size: 12px;
+  background-color: #fff;
+  padding: 7px 10px;
+  border-bottom: 1px solid #eeeeee;
+  color: #444!important;
+  text-align: center;
+}
+@media (max-width: 991px) {
+  .navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a,
+  .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a,
+  .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {
+    background: #fff!important;
+    color: #444!important;
+  }
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a:hover,
+.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a:hover,
+.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a:hover {
+  text-decoration: none;
+  font-weight: normal;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu,
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu {
+  max-height: 200px;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  overflow-x: hidden;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a,
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {
+  display: block;
+  white-space: nowrap;
+  /* Prevent text from breaking */
+  border-bottom: 1px solid #f4f4f4;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a:hover,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:hover,
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a:hover {
+  background: #f4f4f4;
+  text-decoration: none;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a {
+  color: #444444;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  padding: 10px;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion {
+  width: 20px;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a {
+  margin: 0px;
+  padding: 10px 10px;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > div > img {
+  margin: auto 10px auto auto;
+  width: 40px;
+  height: 40px;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 {
+  padding: 0;
+  margin: 0 0 0 45px;
+  color: #444444;
+  font-size: 15px;
+  position: relative;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 > small {
+  color: #999999;
+  font-size: 10px;
+  position: absolute;
+  top: 0px;
+  right: 0px;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > p {
+  margin: 0 0 0 45px;
+  font-size: 12px;
+  color: #888888;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:before,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
+  content: " ";
+  display: table;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
+  clear: both;
+}
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {
+  padding: 10px;
+}
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > h3 {
+  font-size: 14px;
+  padding: 0;
+  margin: 0 0 10px 0;
+  color: #666666;
+}
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > .progress {
+  padding: 0;
+  margin: 0;
+}
+.navbar-nav > .user-menu > .dropdown-menu {
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+  padding: 1px 0 0 0;
+  border-top-width: 0;
+  width: 280px;
+}
+.navbar-nav > .user-menu > .dropdown-menu,
+.navbar-nav > .user-menu > .dropdown-menu > .user-body {
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header {
+  height: 175px;
+  padding: 10px;
+  text-align: center;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > img {
+  z-index: 5;
+  height: 90px;
+  width: 90px;
+  border: 3px solid;
+  border-color: transparent;
+  border-color: rgba(255, 255, 255, 0.2);
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p {
+  z-index: 5;
+  color: #fff;
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 17px;
+  margin-top: 10px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > small {
+  display: block;
+  font-size: 12px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-body {
+  padding: 15px;
+  border-bottom: 1px solid #f4f4f4;
+  border-top: 1px solid #dddddd;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-body:before,
+.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {
+  content: " ";
+  display: table;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {
+  clear: both;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-body a {
+  color: #444 !important;
+}
+@media (max-width: 991px) {
+  .navbar-nav > .user-menu > .dropdown-menu > .user-body a {
+    background: #fff !important;
+    color: #444 !important;
+  }
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer {
+  background-color: #f9f9f9;
+  padding: 10px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer:before,
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {
+  content: " ";
+  display: table;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {
+  clear: both;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default {
+  color: #666666;
+}
+.navbar-nav > .user-menu .user-image {
+  float: left;
+  width: 25px;
+  height: 25px;
+  border-radius: 50%;
+  margin-right: 10px;
+  margin-top: -2px;
+}
+@media (max-width: 767px) {
+  .navbar-nav > .user-menu .user-image {
+    float: none;
+    margin-right: 0;
+    margin-top: -8px;
+    line-height: 10px;
+  }
+}
+/* Add fade animation to dropdown menus by appending
+ the class .animated-dropdown-menu to the .dropdown-menu ul (or ol)*/
+.open:not(.dropup) > .animated-dropdown-menu {
+  backface-visibility: visible !important;
+  -webkit-animation: flipInX 0.7s both;
+  -o-animation: flipInX 0.7s both;
+  animation: flipInX 0.7s both;
+}
+@keyframes flipInX {
+  0% {
+    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    transition-timing-function: ease-in;
+    opacity: 0;
+  }
+  40% {
+    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    transition-timing-function: ease-in;
+  }
+  60% {
+    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+    opacity: 1;
+  }
+  80% {
+    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+  }
+  100% {
+    transform: perspective(400px);
+  }
+}
+@-webkit-keyframes flipInX {
+  0% {
+    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    transition-timing-function: ease-in;
+    opacity: 0;
+  }
+  40% {
+    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    transition-timing-function: ease-in;
+  }
+  60% {
+    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+    opacity: 1;
+  }
+  80% {
+    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+  }
+  100% {
+    transform: perspective(400px);
+  }
+}
+/* Fix dropdown menu in navbars */
+.navbar-custom-menu > .navbar-nav > li {
+  position: relative;
+}
+.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+@media (max-width: 991px) {
+  .navbar-custom-menu > .navbar-nav {
+    float: right;
+  }
+  .navbar-custom-menu > .navbar-nav > li {
+    position: static;
+  }
+  .navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
+    position: absolute;
+    right: 5%;
+    left: auto;
+    border: 1px solid #ddd;
+    background: #fff;
+  }
+}
+/*
+ * Component: Form
+ * ---------------
+ */
+.form-control {
+  border-radius: 0px !important;
+  box-shadow: none;
+  border-color: #d2d6de;
+}
+.form-control:focus {
+  border-color: #3c8dbc !important;
+  box-shadow: none;
+}
+.form-control::-moz-placeholder {
+  color: #bbb;
+  opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+  color: #bbb;
+}
+.form-control::-webkit-input-placeholder {
+  color: #bbb;
+}
+.form-control:not(select) {
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+}
+.form-group.has-success label {
+  color: #00a65a;
+}
+.form-group.has-success .form-control {
+  border-color: #00a65a !important;
+  box-shadow: none;
+}
+.form-group.has-warning label {
+  color: #f39c12;
+}
+.form-group.has-warning .form-control {
+  border-color: #f39c12 !important;
+  box-shadow: none;
+}
+.form-group.has-error label {
+  color: #dd4b39;
+}
+.form-group.has-error .form-control {
+  border-color: #dd4b39 !important;
+  box-shadow: none;
+}
+/* Input group */
+.input-group .input-group-addon {
+  border-radius: 0px;
+  border-color: #d2d6de;
+  background-color: #fff;
+}
+/* button groups */
+.btn-group-vertical .btn.btn-flat:first-of-type,
+.btn-group-vertical .btn.btn-flat:last-of-type {
+  border-radius: 0;
+}
+.icheck > label {
+  padding-left: 0;
+}
+/*
+ * Component: Progress Bar
+ * -----------------------
+ */
+.progress,
+.progress > .progress-bar {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.progress,
+.progress > .progress-bar,
+.progress .progress-bar,
+.progress > .progress-bar .progress-bar {
+  border-radius: 1px;
+}
+/* size variation */
+.progress.sm,
+.progress-sm {
+  height: 10px;
+}
+.progress.sm,
+.progress-sm,
+.progress.sm .progress-bar,
+.progress-sm .progress-bar {
+  border-radius: 1px;
+}
+.progress.xs,
+.progress-xs {
+  height: 7px;
+}
+.progress.xs,
+.progress-xs,
+.progress.xs .progress-bar,
+.progress-xs .progress-bar {
+  border-radius: 1px;
+}
+.progress.xxs,
+.progress-xxs {
+  height: 3px;
+}
+.progress.xxs,
+.progress-xxs,
+.progress.xxs .progress-bar,
+.progress-xxs .progress-bar {
+  border-radius: 1px;
+}
+/* Vertical bars */
+.progress.vertical {
+  position: relative;
+  width: 30px;
+  height: 200px;
+  display: inline-block;
+  margin-right: 10px;
+}
+.progress.vertical > .progress-bar {
+  width: 100%!important;
+  position: absolute;
+  bottom: 0;
+}
+.progress.vertical.sm,
+.progress.vertical.progress-sm {
+  width: 20px;
+}
+.progress.vertical.xs,
+.progress.vertical.progress-xs {
+  width: 10px;
+}
+.progress.vertical.xxs,
+.progress.vertical.progress-xxs {
+  width: 3px;
+}
+.progress-group .progress-text {
+  font-weight: 600;
+}
+.progress-group .progress-number {
+  float: right;
+}
+/* Remove margins from progress bars when put in a table */
+.table tr > td .progress {
+  margin: 0;
+}
+.progress-bar-light-blue,
+.progress-bar-primary {
+  background-color: #3c8dbc;
+}
+.progress-striped .progress-bar-light-blue,
+.progress-striped .progress-bar-primary {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-green,
+.progress-bar-success {
+  background-color: #00a65a;
+}
+.progress-striped .progress-bar-green,
+.progress-striped .progress-bar-success {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-aqua,
+.progress-bar-info {
+  background-color: #00c0ef;
+}
+.progress-striped .progress-bar-aqua,
+.progress-striped .progress-bar-info {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-yellow,
+.progress-bar-warning {
+  background-color: #f39c12;
+}
+.progress-striped .progress-bar-yellow,
+.progress-striped .progress-bar-warning {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-red,
+.progress-bar-danger {
+  background-color: #dd4b39;
+}
+.progress-striped .progress-bar-red,
+.progress-striped .progress-bar-danger {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+/*
+ * Component: Small Box
+ * --------------------
+ */
+.small-box {
+  border-radius: 2px;
+  position: relative;
+  display: block;
+  margin-bottom: 20px;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+.small-box > .inner {
+  padding: 10px;
+}
+.small-box > .small-box-footer {
+  position: relative;
+  text-align: center;
+  padding: 3px 0;
+  color: #fff;
+  color: rgba(255, 255, 255, 0.8);
+  display: block;
+  z-index: 10;
+  background: rgba(0, 0, 0, 0.1);
+  text-decoration: none;
+}
+.small-box > .small-box-footer:hover {
+  color: #fff;
+  background: rgba(0, 0, 0, 0.15);
+}
+.small-box h3 {
+  font-size: 38px;
+  font-weight: bold;
+  margin: 0 0 10px 0;
+  white-space: nowrap;
+  padding: 0;
+}
+.small-box p {
+  font-size: 15px;
+}
+.small-box p > small {
+  display: block;
+  color: #f9f9f9;
+  font-size: 13px;
+  margin-top: 5px;
+}
+.small-box h3,
+.small-box p {
+  z-index: 5px;
+}
+.small-box .icon {
+  -webkit-transition: all 0.3s linear;
+  -o-transition: all 0.3s linear;
+  transition: all 0.3s linear;
+  position: absolute;
+  top: -10px;
+  right: 10px;
+  z-index: 0;
+  font-size: 90px;
+  color: rgba(0, 0, 0, 0.15);
+}
+.small-box:hover {
+  text-decoration: none;
+  color: #f9f9f9;
+}
+.small-box:hover .icon {
+  font-size: 95px;
+}
+@media (max-width: 767px) {
+  .small-box {
+    text-align: center;
+  }
+  .small-box .icon {
+    display: none;
+  }
+  .small-box p {
+    font-size: 12px;
+  }
+}
+/*
+ * Component: Box
+ * --------------
+ */
+.box {
+  position: relative;
+  border-radius: 3px;
+  background: #ffffff;
+  border-top: 3px solid #d2d6de;
+  margin-bottom: 20px;
+  width: 100%;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+.box.box-primary {
+  border-top-color: #3c8dbc;
+}
+.box.box-info {
+  border-top-color: #00c0ef;
+}
+.box.box-danger {
+  border-top-color: #dd4b39;
+}
+.box.box-warning {
+  border-top-color: #f39c12;
+}
+.box.box-success {
+  border-top-color: #00a65a;
+}
+.box.box-default {
+  border-top-color: #d2d6de;
+}
+.box.collapsed-box .box-body,
+.box.collapsed-box .box-footer {
+  display: none;
+}
+.box .nav-stacked > li {
+  border-bottom: 1px solid #f4f4f4;
+  margin: 0;
+}
+.box .nav-stacked > li:last-of-type {
+  border-bottom: none;
+}
+.box.height-control .box-body {
+  max-height: 300px;
+  overflow: auto;
+}
+.box .border-right {
+  border-right: 1px solid #f4f4f4;
+}
+.box .border-left {
+  border-left: 1px solid #f4f4f4;
+}
+.box.box-solid {
+  border-top: 0px;
+}
+.box.box-solid > .box-header .btn.btn-default {
+  background: transparent;
+}
+.box.box-solid > .box-header .btn:hover,
+.box.box-solid > .box-header a:hover {
+  background: rgba(0, 0, 0, 0.1) !important;
+}
+.box.box-solid.box-default {
+  border: 1px solid #d2d6de;
+}
+.box.box-solid.box-default > .box-header {
+  color: #444444;
+  background: #d2d6de;
+  background-color: #d2d6de;
+}
+.box.box-solid.box-default > .box-header a,
+.box.box-solid.box-default > .box-header .btn {
+  color: #444444;
+}
+.box.box-solid.box-primary {
+  border: 1px solid #3c8dbc;
+}
+.box.box-solid.box-primary > .box-header {
+  color: #ffffff;
+  background: #3c8dbc;
+  background-color: #3c8dbc;
+}
+.box.box-solid.box-primary > .box-header a,
+.box.box-solid.box-primary > .box-header .btn {
+  color: #ffffff;
+}
+.box.box-solid.box-info {
+  border: 1px solid #00c0ef;
+}
+.box.box-solid.box-info > .box-header {
+  color: #ffffff;
+  background: #00c0ef;
+  background-color: #00c0ef;
+}
+.box.box-solid.box-info > .box-header a,
+.box.box-solid.box-info > .box-header .btn {
+  color: #ffffff;
+}
+.box.box-solid.box-danger {
+  border: 1px solid #dd4b39;
+}
+.box.box-solid.box-danger > .box-header {
+  color: #ffffff;
+  background: #dd4b39;
+  background-color: #dd4b39;
+}
+.box.box-solid.box-danger > .box-header a,
+.box.box-solid.box-danger > .box-header .btn {
+  color: #ffffff;
+}
+.box.box-solid.box-warning {
+  border: 1px solid #f39c12;
+}
+.box.box-solid.box-warning > .box-header {
+  color: #ffffff;
+  background: #f39c12;
+  background-color: #f39c12;
+}
+.box.box-solid.box-warning > .box-header a,
+.box.box-solid.box-warning > .box-header .btn {
+  color: #ffffff;
+}
+.box.box-solid.box-success {
+  border: 1px solid #00a65a;
+}
+.box.box-solid.box-success > .box-header {
+  color: #ffffff;
+  background: #00a65a;
+  background-color: #00a65a;
+}
+.box.box-solid.box-success > .box-header a,
+.box.box-solid.box-success > .box-header .btn {
+  color: #ffffff;
+}
+.box.box-solid > .box-header > .box-tools .btn {
+  border: 0;
+  box-shadow: none;
+}
+.box.box-solid[class*='bg'] > .box-header {
+  color: #fff;
+}
+.box .box-group > .box {
+  margin-bottom: 5px;
+}
+.box .knob-label {
+  text-align: center;
+  color: #333;
+  font-weight: 100;
+  font-size: 12px;
+  margin-bottom: 0.3em;
+}
+.box > .overlay,
+.box > .loading-img {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+.box .overlay {
+  z-index: 1010;
+  background: rgba(255, 255, 255, 0.7);
+  border-radius: 3px;
+}
+.box .overlay > .fa {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  margin-left: -15px;
+  margin-top: -15px;
+  color: #000;
+  font-size: 30px;
+}
+.box .overlay.dark {
+  background: rgba(0, 0, 0, 0.5);
+}
+.box-header {
+  color: #444;
+  display: block;
+  padding: 10px;
+  position: relative;
+}
+.box-header:before,
+.box-header:after {
+  content: " ";
+  display: table;
+}
+.box-header:after {
+  clear: both;
+}
+.box-header.with-border {
+  border-bottom: 1px solid #f4f4f4;
+}
+.collapsed-box .box-header.with-border {
+  border-bottom: none;
+}
+.box-header > .fa,
+.box-header > .glyphicon,
+.box-header > .ion,
+.box-header .box-title {
+  display: inline-block;
+  font-size: 18px;
+  margin: 0;
+  line-height: 1;
+}
+.box-header > .fa,
+.box-header > .glyphicon,
+.box-header > .ion {
+  margin-right: 5px;
+}
+.box-header > .box-tools {
+  position: absolute;
+  right: 10px;
+  top: 5px;
+}
+.box-header > .box-tools [data-toggle="tooltip"] {
+  position: relative;
+}
+.box-header > .box-tools.pull-right .dropdown-menu {
+  right: 0;
+  left: auto;
+}
+.btn-box-tool {
+  padding: 5px;
+  font-size: 12px;
+  background: transparent;
+  box-shadow: none!important;
+  color: #97a0b3;
+}
+.open .btn-box-tool,
+.btn-box-tool:hover {
+  color: #606c84;
+}
+.btn-box-tool:active {
+  outline: none!important;
+}
+.box-body {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+  padding: 10px;
+}
+.no-header .box-body {
+  border-top-right-radius: 3px;
+  border-top-left-radius: 3px;
+}
+.box-body > .table {
+  margin-bottom: 0;
+}
+.box-body > .chart {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+}
+.box-body > .chart svg,
+.box-body > .chart canvas {
+  width: 100%!important;
+}
+.box-body .fc {
+  margin-top: 5px;
+}
+.box-body .full-width-chart {
+  margin: -19px;
+}
+.box-body.no-padding .full-width-chart {
+  margin: -9px;
+}
+.box-body .box-pane {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 3px;
+}
+.box-body .box-pane-right {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 0;
+}
+.box-footer {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+  border-top: 1px solid #f4f4f4;
+  padding: 10px;
+  background-color: #ffffff;
+}
+.chart-legend {
+  margin: 10px 0;
+}
+@media (max-width: 991px) {
+  .chart-legend > li {
+    float: left;
+    margin-right: 10px;
+  }
+}
+/* Widget: TODO LIST */
+.todo-list {
+  margin: 0;
+  padding: 0px 0px;
+  list-style: none;
+  overflow: auto;
+}
+.todo-list > li {
+  border-radius: 2px;
+  padding: 10px;
+  background: #f4f4f4;
+  margin-bottom: 2px;
+  border-left: 2px solid #e6e7e8;
+  color: #444;
+}
+.todo-list > li:last-of-type {
+  margin-bottom: 0;
+}
+.todo-list > li.danger {
+  border-left-color: #dd4b39;
+}
+.todo-list > li.warning {
+  border-left-color: #f39c12;
+}
+.todo-list > li.info {
+  border-left-color: #00c0ef;
+}
+.todo-list > li.success {
+  border-left-color: #00a65a;
+}
+.todo-list > li.primary {
+  border-left-color: #3c8dbc;
+}
+.todo-list > li > input[type='checkbox'] {
+  margin: 0 10px 0 5px;
+}
+.todo-list > li .text {
+  display: inline-block;
+  margin-left: 5px;
+  font-weight: 600;
+}
+.todo-list > li .label {
+  margin-left: 10px;
+  font-size: 9px;
+}
+.todo-list > li .tools {
+  display: none;
+  float: right;
+  color: #dd4b39;
+}
+.todo-list > li .tools > .fa,
+.todo-list > li .tools > .glyphicon,
+.todo-list > li .tools > .ion {
+  margin-right: 5px;
+  cursor: pointer;
+}
+.todo-list > li:hover .tools {
+  display: inline-block;
+}
+.todo-list > li.done {
+  color: #999;
+}
+.todo-list > li.done .text {
+  text-decoration: line-through;
+  font-weight: 500;
+}
+.todo-list > li.done .label {
+  background: #d2d6de !important;
+}
+.todo-list .handle {
+  display: inline-block;
+  cursor: move;
+  margin: 0 5px;
+}
+/* Chat widget (DEPRECATED - this will be removed in the next major release. Use Direct Chat instead)*/
+.chat {
+  padding: 5px 20px 5px 10px;
+}
+.chat .item {
+  margin-bottom: 10px;
+}
+.chat .item:before,
+.chat .item:after {
+  content: " ";
+  display: table;
+}
+.chat .item:after {
+  clear: both;
+}
+.chat .item > img {
+  width: 40px;
+  height: 40px;
+  border: 2px solid transparent;
+  border-radius: 50% !important;
+}
+.chat .item > img.online {
+  border: 2px solid #00a65a;
+}
+.chat .item > img.offline {
+  border: 2px solid #dd4b39;
+}
+.chat .item > .message {
+  margin-left: 55px;
+  margin-top: -40px;
+}
+.chat .item > .message > .name {
+  display: block;
+  font-weight: 600;
+}
+.chat .item > .attachment {
+  border-radius: 3px;
+  background: #f4f4f4;
+  margin-left: 65px;
+  margin-right: 15px;
+  padding: 10px;
+}
+.chat .item > .attachment > h4 {
+  margin: 0 0 5px 0;
+  font-weight: 600;
+  font-size: 14px;
+}
+.chat .item > .attachment > p,
+.chat .item > .attachment > .filename {
+  font-weight: 600;
+  font-size: 13px;
+  font-style: italic;
+  margin: 0;
+}
+.chat .item > .attachment:before,
+.chat .item > .attachment:after {
+  content: " ";
+  display: table;
+}
+.chat .item > .attachment:after {
+  clear: both;
+}
+.box-input {
+  max-width: 200px;
+}
+/*
+ * Component: Info Box
+ * -------------------
+ */
+.info-box {
+  display: block;
+  min-height: 90px;
+  background: #fff;
+  width: 100%;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  border-radius: 2px;
+  margin-bottom: 15px;
+}
+.info-box small {
+  font-size: 14px;
+}
+.info-box .progress {
+  background: rgba(0, 0, 0, 0.2);
+  margin: 5px -10px 5px -10px;
+  height: 2px;
+}
+.info-box .progress,
+.info-box .progress .progress-bar {
+  border-radius: 0;
+}
+.info-box .progress .progress-bar {
+  background: #fff;
+}
+.info-box-icon {
+  border-top-left-radius: 2px;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 2px;
+  display: block;
+  float: left;
+  height: 90px;
+  width: 90px;
+  text-align: center;
+  font-size: 45px;
+  line-height: 90px;
+  background: rgba(0, 0, 0, 0.2);
+}
+.info-box-content {
+  padding: 5px 10px;
+  margin-left: 90px;
+}
+.info-box-number {
+  display: block;
+  font-weight: bold;
+  font-size: 18px;
+}
+.progress-description,
+.info-box-text {
+  display: block;
+  font-size: 14px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.info-box-text {
+  text-transform: uppercase;
+}
+.info-box-more {
+  display: block;
+}
+.progress-description {
+  margin: 0;
+}
+/*
+ * Component: Timeline
+ * -------------------
+ */
+.timeline {
+  position: relative;
+  margin: 0 0 30px 0;
+  padding: 0;
+  list-style: none;
+}
+.timeline:before {
+  content: '';
+  position: absolute;
+  top: 0px;
+  bottom: 0;
+  width: 4px;
+  background: #ddd;
+  left: 31px;
+  margin: 0;
+  border-radius: 2px;
+}
+.timeline > li {
+  position: relative;
+  margin-right: 10px;
+  margin-bottom: 15px;
+}
+.timeline > li:before,
+.timeline > li:after {
+  content: " ";
+  display: table;
+}
+.timeline > li:after {
+  clear: both;
+}
+.timeline > li > .timeline-item {
+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  border-radius: 3px;
+  margin-top: 0px;
+  background: #fff;
+  color: #444;
+  margin-left: 60px;
+  margin-right: 15px;
+  padding: 0;
+  position: relative;
+}
+.timeline > li > .timeline-item > .time {
+  color: #999;
+  float: right;
+  padding: 10px;
+  font-size: 12px;
+}
+.timeline > li > .timeline-item > .timeline-header {
+  margin: 0;
+  color: #555;
+  border-bottom: 1px solid #f4f4f4;
+  padding: 10px;
+  font-size: 16px;
+  line-height: 1.1;
+}
+.timeline > li > .timeline-item > .timeline-header > a {
+  font-weight: 600;
+}
+.timeline > li > .timeline-item > .timeline-body,
+.timeline > li > .timeline-item > .timeline-footer {
+  padding: 10px;
+}
+.timeline > li.time-label > span {
+  font-weight: 600;
+  padding: 5px;
+  display: inline-block;
+  background-color: #fff;
+  border-radius: 4px;
+}
+.timeline > li > .fa,
+.timeline > li > .glyphicon,
+.timeline > li > .ion {
+  width: 30px;
+  height: 30px;
+  font-size: 15px;
+  line-height: 30px;
+  position: absolute;
+  color: #666;
+  background: #d2d6de;
+  border-radius: 50%;
+  text-align: center;
+  left: 18px;
+  top: 0;
+}
+/*
+ * Component: Button
+ * -----------------
+ */
+.btn {
+  border-radius: 3px;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  border: 1px solid transparent;
+}
+.btn.uppercase {
+  text-transform: uppercase;
+}
+.btn.btn-flat {
+  border-radius: 0;
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+  border-width: 1px;
+}
+.btn:active {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn:focus {
+  outline: none;
+}
+.btn.btn-file {
+  position: relative;
+  overflow: hidden;
+}
+.btn.btn-file > input[type='file'] {
+  position: absolute;
+  top: 0;
+  right: 0;
+  min-width: 100%;
+  min-height: 100%;
+  font-size: 100px;
+  text-align: right;
+  opacity: 0;
+  filter: alpha(opacity=0);
+  outline: none;
+  background: white;
+  cursor: inherit;
+  display: block;
+}
+.btn-default {
+  background-color: #f4f4f4;
+  color: #444;
+  border-color: #ddd;
+}
+.btn-default:hover,
+.btn-default:active,
+.btn-default.hover {
+  background-color: #e7e7e7 !important;
+}
+.btn-primary {
+  background-color: #3c8dbc;
+  border-color: #367fa9;
+}
+.btn-primary:hover,
+.btn-primary:active,
+.btn-primary.hover {
+  background-color: #367fa9;
+}
+.btn-success {
+  background-color: #00a65a;
+  border-color: #008d4c;
+}
+.btn-success:hover,
+.btn-success:active,
+.btn-success.hover {
+  background-color: #008d4c;
+}
+.btn-info {
+  background-color: #00c0ef;
+  border-color: #00acd6;
+}
+.btn-info:hover,
+.btn-info:active,
+.btn-info.hover {
+  background-color: #00acd6;
+}
+.btn-danger {
+  background-color: #dd4b39;
+  border-color: #d73925;
+}
+.btn-danger:hover,
+.btn-danger:active,
+.btn-danger.hover {
+  background-color: #d73925;
+}
+.btn-warning {
+  background-color: #f39c12;
+  border-color: #e08e0b;
+}
+.btn-warning:hover,
+.btn-warning:active,
+.btn-warning.hover {
+  background-color: #e08e0b;
+}
+.btn-outline {
+  border: 1px solid #fff;
+  background: transparent;
+  color: #fff;
+}
+.btn-outline:hover,
+.btn-outline:focus,
+.btn-outline:active {
+  color: rgba(255, 255, 255, 0.7);
+  border-color: rgba(255, 255, 255, 0.7);
+}
+.btn-link {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.btn[class*='bg-']:hover {
+  -webkit-box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2);
+}
+.btn-app {
+  border-radius: 3px;
+  position: relative;
+  padding: 15px 5px;
+  margin: 0 0 10px 10px;
+  min-width: 80px;
+  height: 60px;
+  text-align: center;
+  color: #666;
+  border: 1px solid #ddd;
+  background-color: #f4f4f4;
+  font-size: 12px;
+}
+.btn-app > .fa,
+.btn-app > .glyphicon,
+.btn-app > .ion {
+  font-size: 20px;
+  display: block;
+}
+.btn-app:hover {
+  background: #f4f4f4;
+  color: #444;
+  border-color: #aaa;
+}
+.btn-app:active,
+.btn-app:focus {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn-app > .badge {
+  position: absolute;
+  top: -3px;
+  right: -10px;
+  font-size: 10px;
+  font-weight: 400;
+}
+/*
+ * Component: Callout
+ * ------------------
+ */
+.callout {
+  border-radius: 3px;
+  margin: 0 0 20px 0;
+  padding: 15px 30px 15px 15px;
+  border-left: 5px solid #eee;
+}
+.callout a {
+  color: #fff;
+  text-decoration: underline;
+}
+.callout a:hover {
+  color: #eee;
+}
+.callout h4 {
+  margin-top: 0;
+  font-weight: 600;
+}
+.callout p:last-child {
+  margin-bottom: 0;
+}
+.callout code,
+.callout .highlight {
+  background-color: #fff;
+}
+.callout.callout-danger {
+  border-color: #c23321;
+}
+.callout.callout-warning {
+  border-color: #c87f0a;
+}
+.callout.callout-info {
+  border-color: #0097bc;
+}
+.callout.callout-success {
+  border-color: #00733e;
+}
+/*
+ * Component: alert
+ * ----------------
+ */
+.alert {
+  border-radius: 3px;
+}
+.alert h4 {
+  font-weight: 600;
+}
+.alert .icon {
+  margin-right: 10px;
+}
+.alert .close {
+  color: #000;
+  opacity: 0.2;
+  filter: alpha(opacity=20);
+}
+.alert .close:hover {
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+}
+.alert a {
+  color: #fff;
+  text-decoration: underline;
+}
+.alert-success {
+  border-color: #008d4c;
+}
+.alert-danger,
+.alert-error {
+  border-color: #d73925;
+}
+.alert-warning {
+  border-color: #e08e0b;
+}
+.alert-info {
+  border-color: #00acd6;
+}
+/*
+ * Component: Nav
+ * --------------
+ */
+/* NAV PILLS */
+.nav-pills > li > a {
+  border-radius: 0;
+  border-top: 3px solid transparent;
+  color: #444;
+}
+.nav-pills > li > a > .fa,
+.nav-pills > li > a > .glyphicon,
+.nav-pills > li > a > .ion {
+  margin-right: 5px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover {
+  background-color: #f4f4f4;
+  border-top-color: #3c8dbc;
+  color: #444;
+}
+.nav-pills > li.active > a {
+  font-weight: 600;
+}
+.nav-pills > li > a:hover {
+  background-color: #f6f6f6;
+}
+/* NAV STACKED */
+.nav-stacked > li > a {
+  border-radius: 0;
+  border-top: 0;
+  border-left: 3px solid transparent;
+  color: #444;
+}
+.nav-stacked > li.active > a,
+.nav-stacked > li.active > a:hover {
+  background-color: #f4f4f4;
+  border-top: 0;
+  border-left-color: #3c8dbc;
+  color: #444;
+}
+.nav-stacked > li.header {
+  border-bottom: 1px solid #ddd;
+  color: #777;
+  margin-bottom: 10px;
+  padding: 5px 10px;
+  text-transform: uppercase;
+}
+/* NAV TABS */
+.nav-tabs-custom {
+  margin-bottom: 20px;
+  background: #fff;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  border-radius: 3px;
+}
+.nav-tabs-custom > .nav-tabs {
+  margin: 0;
+  border-bottom-color: #f4f4f4;
+  border-top-right-radius: 3px;
+  border-top-left-radius: 3px;
+}
+.nav-tabs-custom > .nav-tabs > li {
+  border-top: 3px solid transparent;
+  margin-bottom: -2px;
+  margin-right: 5px;
+}
+.nav-tabs-custom > .nav-tabs > li > a {
+  border-radius: 0 !important;
+}
+.nav-tabs-custom > .nav-tabs > li > a,
+.nav-tabs-custom > .nav-tabs > li > a:hover {
+  background: transparent;
+  margin: 0;
+}
+.nav-tabs-custom > .nav-tabs > li:not(.active) > a:hover,
+.nav-tabs-custom > .nav-tabs > li:not(.active) > a:focus,
+.nav-tabs-custom > .nav-tabs > li:not(.active) > a:active {
+  border-color: transparent;
+}
+.nav-tabs-custom > .nav-tabs > li.active {
+  border-top-color: #3c8dbc;
+}
+.nav-tabs-custom > .nav-tabs > li.active > a,
+.nav-tabs-custom > .nav-tabs > li.active:hover > a {
+  background-color: #fff;
+}
+.nav-tabs-custom > .nav-tabs > li.active > a {
+  border-top: 0;
+  border-left-color: #f4f4f4;
+  border-right-color: #f4f4f4;
+}
+.nav-tabs-custom > .nav-tabs > li:first-of-type {
+  margin-left: 0;
+}
+.nav-tabs-custom > .nav-tabs > li:first-of-type.active > a {
+  border-left-width: 0;
+}
+.nav-tabs-custom > .nav-tabs.pull-right {
+  float: none!important;
+}
+.nav-tabs-custom > .nav-tabs.pull-right > li {
+  float: right;
+}
+.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type {
+  margin-right: 0;
+}
+.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a {
+  border-left-width: 1px;
+  border-right-width: 0;
+}
+.nav-tabs-custom > .nav-tabs > li.header {
+  line-height: 35px;
+  padding: 0 10px;
+  font-size: 20px;
+  color: #444;
+}
+.nav-tabs-custom > .nav-tabs > li.header > .fa,
+.nav-tabs-custom > .nav-tabs > li.header > .glyphicon,
+.nav-tabs-custom > .nav-tabs > li.header > .ion {
+  margin-right: 5px;
+}
+.nav-tabs-custom > .tab-content {
+  background: #fff;
+  padding: 10px;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+/* Nav tabs bottom */
+.tabs-bottom.nav-3 li a {
+  width: 3333.33333333% !important;
+}
+.tabs-bottom li a {
+  border: 0;
+}
+/* PAGINATION */
+.pagination > li > a {
+  background: #fafafa;
+  color: #666;
+}
+.pagination > li:first-of-type a,
+.pagination > li:last-of-type a {
+  border-radius: 0;
+}
+/*
+ * Component: Products List
+ * ------------------------
+ */
+.products-list {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+.products-list > .item {
+  border-radius: 3px;
+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  padding: 10px 0;
+  background: #fff;
+}
+.products-list > .item:before,
+.products-list > .item:after {
+  content: " ";
+  display: table;
+}
+.products-list > .item:after {
+  clear: both;
+}
+.products-list .product-img {
+  float: left;
+}
+.products-list .product-img img {
+  width: 50px;
+  height: 50px;
+}
+.products-list .product-info {
+  margin-left: 60px;
+}
+.products-list .product-title {
+  font-weight: 600;
+}
+.products-list .product-description {
+  display: block;
+  color: #999;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.product-list-in-box > .item {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  border-radius: 0;
+  border-bottom: 1px solid #f4f4f4;
+}
+.product-list-in-box > .item:last-of-type {
+  border-bottom-width: 0;
+}
+/*
+ * Component: Table
+ * ----------------
+ */
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+  border-top: 1px solid #f4f4f4;
+}
+.table > thead > tr > th {
+  border-bottom: 2px solid #f4f4f4;
+}
+.table tr td .progress {
+  margin-top: 5px;
+}
+.table-bordered {
+  border: 1px solid #f4f4f4;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+  border: 1px solid #f4f4f4;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+  border-bottom-width: 2px;
+}
+.table.no-border,
+.table.no-border td,
+.table.no-border th {
+  border: 0;
+}
+/* .text-center in tables */
+table.text-center,
+table.text-center td,
+table.text-center th {
+  text-align: center;
+}
+.table.align th {
+  text-align: left;
+}
+.table.align td {
+  text-align: right;
+}
+/*
+ * Component: Label
+ * ----------------
+ */
+.label-default {
+  background-color: #d2d6de;
+  color: #444;
+}
+/*
+ * Component: Direct Chat
+ * ----------------------
+ */
+.direct-chat .box-body {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  position: relative;
+  overflow-x: hidden;
+  padding: 0;
+}
+.direct-chat.chat-pane-open .direct-chat-contacts {
+  -webkit-transform: translate(0, 0);
+  -ms-transform: translate(0, 0);
+  -o-transform: translate(0, 0);
+  transform: translate(0, 0);
+}
+.direct-chat-messages {
+  -webkit-transform: translate(0, 0);
+  -ms-transform: translate(0, 0);
+  -o-transform: translate(0, 0);
+  transform: translate(0, 0);
+  padding: 10px;
+  height: 250px;
+  overflow: auto;
+}
+.direct-chat-msg,
+.direct-chat-text {
+  display: block;
+}
+.direct-chat-msg {
+  margin-bottom: 10px;
+}
+.direct-chat-msg:before,
+.direct-chat-msg:after {
+  content: " ";
+  display: table;
+}
+.direct-chat-msg:after {
+  clear: both;
+}
+.direct-chat-messages,
+.direct-chat-contacts {
+  -webkit-transition: -webkit-transform 0.5s ease-in-out;
+  -moz-transition: -moz-transform 0.5s ease-in-out;
+  -o-transition: -o-transform 0.5s ease-in-out;
+  transition: transform 0.5s ease-in-out;
+}
+.direct-chat-text {
+  border-radius: 5px;
+  position: relative;
+  padding: 5px 10px;
+  background: #d2d6de;
+  border: 1px solid #d2d6de;
+  margin: 5px 0 0 50px;
+  color: #444444;
+}
+.direct-chat-text:after,
+.direct-chat-text:before {
+  position: absolute;
+  right: 100%;
+  top: 15px;
+  border: solid transparent;
+  border-right-color: #d2d6de;
+  content: ' ';
+  height: 0;
+  width: 0;
+  pointer-events: none;
+}
+.direct-chat-text:after {
+  border-width: 5px;
+  margin-top: -5px;
+}
+.direct-chat-text:before {
+  border-width: 6px;
+  margin-top: -6px;
+}
+.right .direct-chat-text {
+  margin-right: 50px;
+  margin-left: 0;
+}
+.right .direct-chat-text:after,
+.right .direct-chat-text:before {
+  right: auto;
+  left: 100%;
+  border-right-color: transparent;
+  border-left-color: #d2d6de;
+}
+.direct-chat-img {
+  border-radius: 50%;
+  float: left;
+  width: 40px;
+  height: 40px;
+}
+.right .direct-chat-img {
+  float: right;
+}
+.direct-chat-info {
+  display: block;
+  margin-bottom: 2px;
+  font-size: 12px;
+}
+.direct-chat-name {
+  font-weight: 600;
+}
+.direct-chat-timestamp {
+  color: #999;
+}
+.direct-chat-contacts-open .direct-chat-contacts {
+  -webkit-transform: translate(0, 0);
+  -ms-transform: translate(0, 0);
+  -o-transform: translate(0, 0);
+  transform: translate(0, 0);
+}
+.direct-chat-contacts {
+  -webkit-transform: translate(100%, 0);
+  -ms-transform: translate(100%, 0);
+  -o-transform: translate(100%, 0);
+  transform: translate(100%, 0);
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  height: 250px;
+  width: 100%;
+  background: #222d32;
+  color: #fff;
+  overflow: auto;
+}
+.contacts-list > li {
+  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+  padding: 10px;
+  margin: 0;
+}
+.contacts-list > li:before,
+.contacts-list > li:after {
+  content: " ";
+  display: table;
+}
+.contacts-list > li:after {
+  clear: both;
+}
+.contacts-list > li:last-of-type {
+  border-bottom: none;
+}
+.contacts-list-img {
+  border-radius: 50%;
+  width: 40px;
+  float: left;
+}
+.contacts-list-info {
+  margin-left: 45px;
+  color: #fff;
+}
+.contacts-list-name,
+.contacts-list-status {
+  display: block;
+}
+.contacts-list-name {
+  font-weight: 600;
+}
+.contacts-list-status {
+  font-size: 12px;
+}
+.contacts-list-date {
+  color: #aaa;
+  font-weight: normal;
+}
+.contacts-list-msg {
+  color: #999;
+}
+.direct-chat-danger .right > .direct-chat-text {
+  background: #dd4b39;
+  border-color: #dd4b39;
+  color: #ffffff;
+}
+.direct-chat-danger .right > .direct-chat-text:after,
+.direct-chat-danger .right > .direct-chat-text:before {
+  border-left-color: #dd4b39;
+}
+.direct-chat-primary .right > .direct-chat-text {
+  background: #3c8dbc;
+  border-color: #3c8dbc;
+  color: #ffffff;
+}
+.direct-chat-primary .right > .direct-chat-text:after,
+.direct-chat-primary .right > .direct-chat-text:before {
+  border-left-color: #3c8dbc;
+}
+.direct-chat-warning .right > .direct-chat-text {
+  background: #f39c12;
+  border-color: #f39c12;
+  color: #ffffff;
+}
+.direct-chat-warning .right > .direct-chat-text:after,
+.direct-chat-warning .right > .direct-chat-text:before {
+  border-left-color: #f39c12;
+}
+.direct-chat-info .right > .direct-chat-text {
+  background: #00c0ef;
+  border-color: #00c0ef;
+  color: #ffffff;
+}
+.direct-chat-info .right > .direct-chat-text:after,
+.direct-chat-info .right > .direct-chat-text:before {
+  border-left-color: #00c0ef;
+}
+.direct-chat-success .right > .direct-chat-text {
+  background: #00a65a;
+  border-color: #00a65a;
+  color: #ffffff;
+}
+.direct-chat-success .right > .direct-chat-text:after,
+.direct-chat-success .right > .direct-chat-text:before {
+  border-left-color: #00a65a;
+}
+/*
+ * Component: Users List
+ * ---------------------
+ */
+.users-list > li {
+  width: 25%;
+  float: left;
+  padding: 10px;
+  text-align: center;
+}
+.users-list > li > img {
+  border-radius: 50%;
+  max-width: 100%;
+  height: auto;
+}
+.users-list-name,
+.users-list-date {
+  display: block;
+}
+.users-list-name {
+  font-weight: 600;
+  color: #444;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.users-list-name:hover {
+  color: #999;
+}
+.users-list-date {
+  color: #999;
+  font-size: 12px;
+}
+/*
+ * Component: Carousel
+ * -------------------
+ */
+.carousel-control {
+  background-image: none!important;
+}
+.carousel-control > .fa {
+  font-size: 40px;
+  position: absolute;
+  top: 50%;
+  z-index: 5;
+  display: inline-block;
+  margin-top: -20px;
+}
+/*
+ * Component: modal
+ * ----------------
+ */
+.modal {
+  background: rgba(0, 0, 0, 0.3);
+}
+.modal-content {
+  border-radius: 0;
+  -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
+  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
+  border: 0;
+}
+@media (min-width: 768px) {
+  .modal-content {
+    -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
+    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125) !important;
+  }
+}
+.modal-header {
+  border-bottom-color: #f4f4f4;
+}
+.modal-footer {
+  border-top-color: #f4f4f4;
+}
+.modal-primary .modal-header,
+.modal-primary .modal-footer {
+  border-color: #307095;
+}
+.modal-warning .modal-header,
+.modal-warning .modal-footer {
+  border-color: #c87f0a;
+}
+.modal-info .modal-header,
+.modal-info .modal-footer {
+  border-color: #0097bc;
+}
+.modal-success .modal-header,
+.modal-success .modal-footer {
+  border-color: #00733e;
+}
+.modal-danger .modal-header,
+.modal-danger .modal-footer {
+  border-color: #c23321;
+}
+/*
+ * Page: Mailbox
+ * -------------
+ */
+.mailbox-messages > .table {
+  margin: 0;
+}
+.mailbox-controls {
+  padding: 5px;
+}
+.mailbox-controls.with-border {
+  border-bottom: 1px solid #f4f4f4;
+}
+.mailbox-read-info {
+  border-bottom: 1px solid #f4f4f4;
+  padding: 10px;
+}
+.mailbox-read-info h3 {
+  font-size: 20px;
+  margin: 0;
+}
+.mailbox-read-info h5 {
+  margin: 0;
+  padding: 5px 0 0 0;
+}
+.mailbox-read-time {
+  color: #999;
+  font-size: 13px;
+}
+.mailbox-read-message {
+  padding: 10px;
+}
+.mailbox-attachments li {
+  float: left;
+  width: 200px;
+  border: 1px solid #eee;
+  margin-bottom: 10px;
+  margin-right: 10px;
+}
+.mailbox-attachment-name {
+  font-weight: bold;
+  color: #666;
+}
+.mailbox-attachment-icon,
+.mailbox-attachment-info,
+.mailbox-attachment-size {
+  display: block;
+}
+.mailbox-attachment-info {
+  padding: 10px;
+  background: #f4f4f4;
+}
+.mailbox-attachment-size {
+  color: #999;
+  font-size: 12px;
+}
+.mailbox-attachment-icon {
+  text-align: center;
+  font-size: 65px;
+  color: #666;
+  padding: 20px 10px;
+}
+.mailbox-attachment-icon.has-img {
+  padding: 0;
+}
+.mailbox-attachment-icon.has-img > img {
+  max-width: 100%;
+  height: auto;
+}
+.mailbox .table-mailbox {
+  border-left: 1px solid #f4f4f4;
+  border-right: 1px solid #f4f4f4;
+  border-bottom: 1px solid #f4f4f4;
+}
+.mailbox .table-mailbox tr.unread > td {
+  background-color: rgba(0, 0, 0, 0.05);
+  color: #000;
+  font-weight: 600;
+}
+.mailbox .table-mailbox tr > td > .fa.fa-star,
+.mailbox .table-mailbox tr > td > .fa.fa-star-o,
+.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star,
+.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star-empty {
+  color: #f39c12;
+  cursor: pointer;
+}
+.mailbox .table-mailbox tr > td.small-col {
+  width: 30px;
+}
+.mailbox .table-mailbox tr > td.name {
+  width: 150px;
+  font-weight: 600;
+}
+.mailbox .table-mailbox tr > td.time {
+  text-align: right;
+  width: 100px;
+}
+.mailbox .table-mailbox tr > td {
+  white-space: nowrap;
+}
+.mailbox .table-mailbox tr > td > a {
+  color: #444;
+}
+@media (max-width: 991px) {
+  .mailbox .nav-stacked > li:not(.header) {
+    float: left;
+    width: 50%;
+  }
+  .mailbox .nav-stacked > li:not(.header).header {
+    border: 0!important;
+  }
+  .mailbox .search-form {
+    margin-top: 10px;
+  }
+}
+/*
+ * Page: Lock Screen
+ * -----------------
+ */
+/* ADD THIS CLASS TO THE <BODY> TAG */
+.lockscreen {
+  background: #d2d6de;
+}
+.lockscreen-logo {
+  font-size: 35px;
+  text-align: center;
+  margin-bottom: 25px;
+  font-weight: 300;
+}
+.lockscreen-logo a {
+  color: #444;
+}
+.lockscreen-wrapper {
+  max-width: 400px;
+  margin: 0 auto;
+  margin-top: 10%;
+}
+/* User name [optional] */
+.lockscreen .lockscreen-name {
+  text-align: center;
+  font-weight: 600;
+}
+/* Will contain the image and the sign in form */
+.lockscreen-item {
+  border-radius: 4px;
+  padding: 0;
+  background: #fff;
+  position: relative;
+  margin: 10px auto 30px auto;
+  width: 290px;
+}
+/* User image */
+.lockscreen-image {
+  border-radius: 50%;
+  position: absolute;
+  left: -10px;
+  top: -25px;
+  background: #fff;
+  padding: 5px;
+  z-index: 10;
+}
+.lockscreen-image > img {
+  border-radius: 50%;
+  width: 70px;
+  height: 70px;
+}
+/* Contains the password input and the login button */
+.lockscreen-credentials {
+  margin-left: 70px;
+}
+.lockscreen-credentials .form-control {
+  border: 0 !important;
+}
+.lockscreen-credentials .btn {
+  background-color: #fff;
+  border: 0;
+  padding: 0 10px;
+}
+.lockscreen-footer {
+  margin-top: 10px;
+}
+/*
+ * Page: Login & Register
+ * ----------------------
+ */
+.login-logo,
+.register-logo {
+  font-size: 35px;
+  text-align: center;
+  margin-bottom: 25px;
+  font-weight: 300;
+}
+.login-logo a,
+.register-logo a {
+  color: #444;
+}
+.login-page,
+.register-page {
+  background: #d2d6de;
+}
+.login-box,
+.register-box {
+  width: 360px;
+  margin: 7% auto;
+}
+@media (max-width: 768px) {
+  .login-box,
+  .register-box {
+    width: 90%;
+    margin-top: 20px;
+  }
+}
+.login-box-body,
+.register-box-body {
+  background: #fff;
+  padding: 20px;
+  color: #444;
+  border-top: 0;
+  color: #666;
+}
+.login-box-body .form-control-feedback,
+.register-box-body .form-control-feedback {
+  color: #777;
+}
+.login-box-msg,
+.register-box-msg {
+  margin: 0;
+  text-align: center;
+  padding: 0 20px 20px 20px;
+}
+.social-auth-links {
+  margin: 10px 0;
+}
+/*
+ * Page: 400 and 500 error pages
+ * ------------------------------
+ */
+.error-page {
+  width: 600px;
+  margin: 20px auto 0 auto;
+}
+@media (max-width: 991px) {
+  .error-page {
+    width: 100%;
+  }
+}
+.error-page > .headline {
+  float: left;
+  font-size: 100px;
+  font-weight: 300;
+}
+@media (max-width: 991px) {
+  .error-page > .headline {
+    float: none;
+    text-align: center;
+  }
+}
+.error-page > .error-content {
+  margin-left: 190px;
+  display: block;
+}
+@media (max-width: 991px) {
+  .error-page > .error-content {
+    margin-left: 0;
+  }
+}
+.error-page > .error-content > h3 {
+  font-weight: 300;
+  font-size: 25px;
+}
+@media (max-width: 991px) {
+  .error-page > .error-content > h3 {
+    text-align: center;
+  }
+}
+/*
+ * Page: Invoice
+ * -------------
+ */
+.invoice {
+  position: relative;
+  background: #fff;
+  border: 1px solid #f4f4f4;
+  padding: 20px;
+  margin: 10px 25px;
+}
+.invoice-title {
+  margin-top: 0;
+}
+/*
+ * Plugin: Social Buttons
+ * ----------------------
+ */
+.btn-social {
+  position: relative;
+  padding-left: 44px !important;
+  text-align: left;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.btn-social :first-child {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  width: 32px !important;
+  line-height: 34px !important;
+  font-size: 1.6em!important;
+  text-align: center;
+  border-right: 1px solid rgba(0, 0, 0, 0.2);
+}
+.btn-social.btn-lg {
+  padding-left: 61px !important;
+}
+.btn-social.btn-lg :first-child {
+  line-height: 45px;
+  width: 45px;
+  font-size: 1.8em;
+}
+.btn-social.btn-sm {
+  padding-left: 38px !important;
+}
+.btn-social.btn-sm :first-child {
+  line-height: 28px;
+  width: 28px;
+  font-size: 1.4em;
+}
+.btn-social.btn-xs {
+  padding-left: 30px !important;
+}
+.btn-social.btn-xs :first-child {
+  line-height: 20px;
+  width: 20px;
+  font-size: 1.2em;
+}
+.btn-social-icon {
+  position: relative;
+  padding-left: 44px !important;
+  text-align: left;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  height: 34px;
+  width: 34px;
+  padding: 0;
+}
+.btn-social-icon :first-child {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  width: 32px !important;
+  line-height: 34px !important;
+  font-size: 1.6em!important;
+  text-align: center;
+  border-right: 1px solid rgba(0, 0, 0, 0.2);
+}
+.btn-social-icon.btn-lg {
+  padding-left: 61px !important;
+}
+.btn-social-icon.btn-lg :first-child {
+  line-height: 45px;
+  width: 45px;
+  font-size: 1.8em;
+}
+.btn-social-icon.btn-sm {
+  padding-left: 38px !important;
+}
+.btn-social-icon.btn-sm :first-child {
+  line-height: 28px;
+  width: 28px;
+  font-size: 1.4em;
+}
+.btn-social-icon.btn-xs {
+  padding-left: 30px !important;
+}
+.btn-social-icon.btn-xs :first-child {
+  line-height: 20px;
+  width: 20px;
+  font-size: 1.2em;
+}
+.btn-social-icon :first-child {
+  border: none;
+  text-align: center;
+  width: 100%!important;
+}
+.btn-social-icon.btn-lg {
+  height: 45px;
+  width: 45px;
+  padding-left: 0;
+  padding-right: 0;
+}
+.btn-social-icon.btn-sm {
+  height: 30px;
+  width: 30px;
+  padding-left: 0;
+  padding-right: 0;
+}
+.btn-social-icon.btn-xs {
+  height: 22px;
+  width: 22px;
+  padding-left: 0;
+  padding-right: 0;
+}
+.btn-bitbucket {
+  color: #ffffff;
+  background-color: #205081;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-bitbucket:hover,
+.btn-bitbucket:focus,
+.btn-bitbucket.focus,
+.btn-bitbucket:active,
+.btn-bitbucket.active,
+.open > .dropdown-toggle.btn-bitbucket {
+  color: #ffffff;
+  background-color: #163758;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-bitbucket:active,
+.btn-bitbucket.active,
+.open > .dropdown-toggle.btn-bitbucket {
+  background-image: none;
+}
+.btn-bitbucket.disabled,
+.btn-bitbucket[disabled],
+fieldset[disabled] .btn-bitbucket,
+.btn-bitbucket.disabled:hover,
+.btn-bitbucket[disabled]:hover,
+fieldset[disabled] .btn-bitbucket:hover,
+.btn-bitbucket.disabled:focus,
+.btn-bitbucket[disabled]:focus,
+fieldset[disabled] .btn-bitbucket:focus,
+.btn-bitbucket.disabled.focus,
+.btn-bitbucket[disabled].focus,
+fieldset[disabled] .btn-bitbucket.focus,
+.btn-bitbucket.disabled:active,
+.btn-bitbucket[disabled]:active,
+fieldset[disabled] .btn-bitbucket:active,
+.btn-bitbucket.disabled.active,
+.btn-bitbucket[disabled].active,
+fieldset[disabled] .btn-bitbucket.active {
+  background-color: #205081;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-bitbucket .badge {
+  color: #205081;
+  background-color: #ffffff;
+}
+.btn-dropbox {
+  color: #ffffff;
+  background-color: #1087dd;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-dropbox:hover,
+.btn-dropbox:focus,
+.btn-dropbox.focus,
+.btn-dropbox:active,
+.btn-dropbox.active,
+.open > .dropdown-toggle.btn-dropbox {
+  color: #ffffff;
+  background-color: #0d6aad;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-dropbox:active,
+.btn-dropbox.active,
+.open > .dropdown-toggle.btn-dropbox {
+  background-image: none;
+}
+.btn-dropbox.disabled,
+.btn-dropbox[disabled],
+fieldset[disabled] .btn-dropbox,
+.btn-dropbox.disabled:hover,
+.btn-dropbox[disabled]:hover,
+fieldset[disabled] .btn-dropbox:hover,
+.btn-dropbox.disabled:focus,
+.btn-dropbox[disabled]:focus,
+fieldset[disabled] .btn-dropbox:focus,
+.btn-dropbox.disabled.focus,
+.btn-dropbox[disabled].focus,
+fieldset[disabled] .btn-dropbox.focus,
+.btn-dropbox.disabled:active,
+.btn-dropbox[disabled]:active,
+fieldset[disabled] .btn-dropbox:active,
+.btn-dropbox.disabled.active,
+.btn-dropbox[disabled].active,
+fieldset[disabled] .btn-dropbox.active {
+  background-color: #1087dd;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-dropbox .badge {
+  color: #1087dd;
+  background-color: #ffffff;
+}
+.btn-facebook {
+  color: #ffffff;
+  background-color: #3b5998;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-facebook:hover,
+.btn-facebook:focus,
+.btn-facebook.focus,
+.btn-facebook:active,
+.btn-facebook.active,
+.open > .dropdown-toggle.btn-facebook {
+  color: #ffffff;
+  background-color: #2d4373;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-facebook:active,
+.btn-facebook.active,
+.open > .dropdown-toggle.btn-facebook {
+  background-image: none;
+}
+.btn-facebook.disabled,
+.btn-facebook[disabled],
+fieldset[disabled] .btn-facebook,
+.btn-facebook.disabled:hover,
+.btn-facebook[disabled]:hover,
+fieldset[disabled] .btn-facebook:hover,
+.btn-facebook.disabled:focus,
+.btn-facebook[disabled]:focus,
+fieldset[disabled] .btn-facebook:focus,
+.btn-facebook.disabled.focus,
+.btn-facebook[disabled].focus,
+fieldset[disabled] .btn-facebook.focus,
+.btn-facebook.disabled:active,
+.btn-facebook[disabled]:active,
+fieldset[disabled] .btn-facebook:active,
+.btn-facebook.disabled.active,
+.btn-facebook[disabled].active,
+fieldset[disabled] .btn-facebook.active {
+  background-color: #3b5998;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-facebook .badge {
+  color: #3b5998;
+  background-color: #ffffff;
+}
+.btn-flickr {
+  color: #ffffff;
+  background-color: #ff0084;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-flickr:hover,
+.btn-flickr:focus,
+.btn-flickr.focus,
+.btn-flickr:active,
+.btn-flickr.active,
+.open > .dropdown-toggle.btn-flickr {
+  color: #ffffff;
+  background-color: #cc006a;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-flickr:active,
+.btn-flickr.active,
+.open > .dropdown-toggle.btn-flickr {
+  background-image: none;
+}
+.btn-flickr.disabled,
+.btn-flickr[disabled],
+fieldset[disabled] .btn-flickr,
+.btn-flickr.disabled:hover,
+.btn-flickr[disabled]:hover,
+fieldset[disabled] .btn-flickr:hover,
+.btn-flickr.disabled:focus,
+.btn-flickr[disabled]:focus,
+fieldset[disabled] .btn-flickr:focus,
+.btn-flickr.disabled.focus,
+.btn-flickr[disabled].focus,
+fieldset[disabled] .btn-flickr.focus,
+.btn-flickr.disabled:active,
+.btn-flickr[disabled]:active,
+fieldset[disabled] .btn-flickr:active,
+.btn-flickr.disabled.active,
+.btn-flickr[disabled].active,
+fieldset[disabled] .btn-flickr.active {
+  background-color: #ff0084;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-flickr .badge {
+  color: #ff0084;
+  background-color: #ffffff;
+}
+.btn-foursquare {
+  color: #ffffff;
+  background-color: #0072b1;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-foursquare:hover,
+.btn-foursquare:focus,
+.btn-foursquare.focus,
+.btn-foursquare:active,
+.btn-foursquare.active,
+.open > .dropdown-toggle.btn-foursquare {
+  color: #ffffff;
+  background-color: #00517e;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-foursquare:active,
+.btn-foursquare.active,
+.open > .dropdown-toggle.btn-foursquare {
+  background-image: none;
+}
+.btn-foursquare.disabled,
+.btn-foursquare[disabled],
+fieldset[disabled] .btn-foursquare,
+.btn-foursquare.disabled:hover,
+.btn-foursquare[disabled]:hover,
+fieldset[disabled] .btn-foursquare:hover,
+.btn-foursquare.disabled:focus,
+.btn-foursquare[disabled]:focus,
+fieldset[disabled] .btn-foursquare:focus,
+.btn-foursquare.disabled.focus,
+.btn-foursquare[disabled].focus,
+fieldset[disabled] .btn-foursquare.focus,
+.btn-foursquare.disabled:active,
+.btn-foursquare[disabled]:active,
+fieldset[disabled] .btn-foursquare:active,
+.btn-foursquare.disabled.active,
+.btn-foursquare[disabled].active,
+fieldset[disabled] .btn-foursquare.active {
+  background-color: #0072b1;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-foursquare .badge {
+  color: #0072b1;
+  background-color: #ffffff;
+}
+.btn-github {
+  color: #ffffff;
+  background-color: #444444;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-github:hover,
+.btn-github:focus,
+.btn-github.focus,
+.btn-github:active,
+.btn-github.active,
+.open > .dropdown-toggle.btn-github {
+  color: #ffffff;
+  background-color: #2b2b2b;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-github:active,
+.btn-github.active,
+.open > .dropdown-toggle.btn-github {
+  background-image: none;
+}
+.btn-github.disabled,
+.btn-github[disabled],
+fieldset[disabled] .btn-github,
+.btn-github.disabled:hover,
+.btn-github[disabled]:hover,
+fieldset[disabled] .btn-github:hover,
+.btn-github.disabled:focus,
+.btn-github[disabled]:focus,
+fieldset[disabled] .btn-github:focus,
+.btn-github.disabled.focus,
+.btn-github[disabled].focus,
+fieldset[disabled] .btn-github.focus,
+.btn-github.disabled:active,
+.btn-github[disabled]:active,
+fieldset[disabled] .btn-github:active,
+.btn-github.disabled.active,
+.btn-github[disabled].active,
+fieldset[disabled] .btn-github.active {
+  background-color: #444444;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-github .badge {
+  color: #444444;
+  background-color: #ffffff;
+}
+.btn-google-plus {
+  color: #ffffff;
+  background-color: #dd4b39;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-google-plus:hover,
+.btn-google-plus:focus,
+.btn-google-plus.focus,
+.btn-google-plus:active,
+.btn-google-plus.active,
+.open > .dropdown-toggle.btn-google-plus {
+  color: #ffffff;
+  background-color: #c23321;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-google-plus:active,
+.btn-google-plus.active,
+.open > .dropdown-toggle.btn-google-plus {
+  background-image: none;
+}
+.btn-google-plus.disabled,
+.btn-google-plus[disabled],
+fieldset[disabled] .btn-google-plus,
+.btn-google-plus.disabled:hover,
+.btn-google-plus[disabled]:hover,
+fieldset[disabled] .btn-google-plus:hover,
+.btn-google-plus.disabled:focus,
+.btn-google-plus[disabled]:focus,
+fieldset[disabled] .btn-google-plus:focus,
+.btn-google-plus.disabled.focus,
+.btn-google-plus[disabled].focus,
+fieldset[disabled] .btn-google-plus.focus,
+.btn-google-plus.disabled:active,
+.btn-google-plus[disabled]:active,
+fieldset[disabled] .btn-google-plus:active,
+.btn-google-plus.disabled.active,
+.btn-google-plus[disabled].active,
+fieldset[disabled] .btn-google-plus.active {
+  background-color: #dd4b39;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-google-plus .badge {
+  color: #dd4b39;
+  background-color: #ffffff;
+}
+.btn-instagram {
+  color: #ffffff;
+  background-color: #3f729b;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-instagram:hover,
+.btn-instagram:focus,
+.btn-instagram.focus,
+.btn-instagram:active,
+.btn-instagram.active,
+.open > .dropdown-toggle.btn-instagram {
+  color: #ffffff;
+  background-color: #305777;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-instagram:active,
+.btn-instagram.active,
+.open > .dropdown-toggle.btn-instagram {
+  background-image: none;
+}
+.btn-instagram.disabled,
+.btn-instagram[disabled],
+fieldset[disabled] .btn-instagram,
+.btn-instagram.disabled:hover,
+.btn-instagram[disabled]:hover,
+fieldset[disabled] .btn-instagram:hover,
+.btn-instagram.disabled:focus,
+.btn-instagram[disabled]:focus,
+fieldset[disabled] .btn-instagram:focus,
+.btn-instagram.disabled.focus,
+.btn-instagram[disabled].focus,
+fieldset[disabled] .btn-instagram.focus,
+.btn-instagram.disabled:active,
+.btn-instagram[disabled]:active,
+fieldset[disabled] .btn-instagram:active,
+.btn-instagram.disabled.active,
+.btn-instagram[disabled].active,
+fieldset[disabled] .btn-instagram.active {
+  background-color: #3f729b;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-instagram .badge {
+  color: #3f729b;
+  background-color: #ffffff;
+}
+.btn-linkedin {
+  color: #ffffff;
+  background-color: #007bb6;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-linkedin:hover,
+.btn-linkedin:focus,
+.btn-linkedin.focus,
+.btn-linkedin:active,
+.btn-linkedin.active,
+.open > .dropdown-toggle.btn-linkedin {
+  color: #ffffff;
+  background-color: #005983;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-linkedin:active,
+.btn-linkedin.active,
+.open > .dropdown-toggle.btn-linkedin {
+  background-image: none;
+}
+.btn-linkedin.disabled,
+.btn-linkedin[disabled],
+fieldset[disabled] .btn-linkedin,
+.btn-linkedin.disabled:hover,
+.btn-linkedin[disabled]:hover,
+fieldset[disabled] .btn-linkedin:hover,
+.btn-linkedin.disabled:focus,
+.btn-linkedin[disabled]:focus,
+fieldset[disabled] .btn-linkedin:focus,
+.btn-linkedin.disabled.focus,
+.btn-linkedin[disabled].focus,
+fieldset[disabled] .btn-linkedin.focus,
+.btn-linkedin.disabled:active,
+.btn-linkedin[disabled]:active,
+fieldset[disabled] .btn-linkedin:active,
+.btn-linkedin.disabled.active,
+.btn-linkedin[disabled].active,
+fieldset[disabled] .btn-linkedin.active {
+  background-color: #007bb6;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-linkedin .badge {
+  color: #007bb6;
+  background-color: #ffffff;
+}
+.btn-tumblr {
+  color: #ffffff;
+  background-color: #2c4762;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-tumblr:hover,
+.btn-tumblr:focus,
+.btn-tumblr.focus,
+.btn-tumblr:active,
+.btn-tumblr.active,
+.open > .dropdown-toggle.btn-tumblr {
+  color: #ffffff;
+  background-color: #1c2d3f;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-tumblr:active,
+.btn-tumblr.active,
+.open > .dropdown-toggle.btn-tumblr {
+  background-image: none;
+}
+.btn-tumblr.disabled,
+.btn-tumblr[disabled],
+fieldset[disabled] .btn-tumblr,
+.btn-tumblr.disabled:hover,
+.btn-tumblr[disabled]:hover,
+fieldset[disabled] .btn-tumblr:hover,
+.btn-tumblr.disabled:focus,
+.btn-tumblr[disabled]:focus,
+fieldset[disabled] .btn-tumblr:focus,
+.btn-tumblr.disabled.focus,
+.btn-tumblr[disabled].focus,
+fieldset[disabled] .btn-tumblr.focus,
+.btn-tumblr.disabled:active,
+.btn-tumblr[disabled]:active,
+fieldset[disabled] .btn-tumblr:active,
+.btn-tumblr.disabled.active,
+.btn-tumblr[disabled].active,
+fieldset[disabled] .btn-tumblr.active {
+  background-color: #2c4762;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-tumblr .badge {
+  color: #2c4762;
+  background-color: #ffffff;
+}
+.btn-twitter {
+  color: #ffffff;
+  background-color: #55acee;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-twitter:hover,
+.btn-twitter:focus,
+.btn-twitter.focus,
+.btn-twitter:active,
+.btn-twitter.active,
+.open > .dropdown-toggle.btn-twitter {
+  color: #ffffff;
+  background-color: #2795e9;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-twitter:active,
+.btn-twitter.active,
+.open > .dropdown-toggle.btn-twitter {
+  background-image: none;
+}
+.btn-twitter.disabled,
+.btn-twitter[disabled],
+fieldset[disabled] .btn-twitter,
+.btn-twitter.disabled:hover,
+.btn-twitter[disabled]:hover,
+fieldset[disabled] .btn-twitter:hover,
+.btn-twitter.disabled:focus,
+.btn-twitter[disabled]:focus,
+fieldset[disabled] .btn-twitter:focus,
+.btn-twitter.disabled.focus,
+.btn-twitter[disabled].focus,
+fieldset[disabled] .btn-twitter.focus,
+.btn-twitter.disabled:active,
+.btn-twitter[disabled]:active,
+fieldset[disabled] .btn-twitter:active,
+.btn-twitter.disabled.active,
+.btn-twitter[disabled].active,
+fieldset[disabled] .btn-twitter.active {
+  background-color: #55acee;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-twitter .badge {
+  color: #55acee;
+  background-color: #ffffff;
+}
+.btn-vk {
+  color: #ffffff;
+  background-color: #587ea3;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-vk:hover,
+.btn-vk:focus,
+.btn-vk.focus,
+.btn-vk:active,
+.btn-vk.active,
+.open > .dropdown-toggle.btn-vk {
+  color: #ffffff;
+  background-color: #466482;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-vk:active,
+.btn-vk.active,
+.open > .dropdown-toggle.btn-vk {
+  background-image: none;
+}
+.btn-vk.disabled,
+.btn-vk[disabled],
+fieldset[disabled] .btn-vk,
+.btn-vk.disabled:hover,
+.btn-vk[disabled]:hover,
+fieldset[disabled] .btn-vk:hover,
+.btn-vk.disabled:focus,
+.btn-vk[disabled]:focus,
+fieldset[disabled] .btn-vk:focus,
+.btn-vk.disabled.focus,
+.btn-vk[disabled].focus,
+fieldset[disabled] .btn-vk.focus,
+.btn-vk.disabled:active,
+.btn-vk[disabled]:active,
+fieldset[disabled] .btn-vk:active,
+.btn-vk.disabled.active,
+.btn-vk[disabled].active,
+fieldset[disabled] .btn-vk.active {
+  background-color: #587ea3;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-vk .badge {
+  color: #587ea3;
+  background-color: #ffffff;
+}
+/*
+ * Plugin: Full Calendar
+ * ---------------------
+ */
+.fc-button {
+  background: #f4f4f4;
+  background-image: none;
+  color: #444;
+  border-color: #ddd;
+  border-bottom-color: #ddd;
+}
+.fc-button:hover,
+.fc-button:active,
+.fc-button.hover {
+  background-color: #e9e9e9;
+}
+.fc-header-title h2 {
+  font-size: 15px;
+  line-height: 1.6em;
+  color: #666;
+  margin-left: 10px;
+}
+.fc-header-right {
+  padding-right: 10px;
+}
+.fc-header-left {
+  padding-left: 10px;
+}
+.fc-widget-header {
+  background: #fafafa;
+}
+.fc-grid {
+  width: 100%;
+  border: 0;
+}
+.fc-widget-header:first-of-type,
+.fc-widget-content:first-of-type {
+  border-left: 0;
+  border-right: 0;
+}
+.fc-widget-header:last-of-type,
+.fc-widget-content:last-of-type {
+  border-right: 0;
+}
+.fc-toolbar {
+  padding: 10px;
+  margin: 0;
+}
+.fc-day-number {
+  font-size: 20px;
+  font-weight: 300;
+  padding-right: 10px;
+}
+.fc-color-picker {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+.fc-color-picker > li {
+  float: left;
+  font-size: 30px;
+  margin-right: 5px;
+  line-height: 30px;
+}
+.fc-color-picker > li .fa {
+  -webkit-transition: -webkit-transform linear 0.3s;
+  -moz-transition: -moz-transform linear 0.3s;
+  -o-transition: -o-transform linear 0.3s;
+  transition: transform linear 0.3s;
+}
+.fc-color-picker > li .fa:hover {
+  -webkit-transform: rotate(30deg);
+  -ms-transform: rotate(30deg);
+  -o-transform: rotate(30deg);
+  transform: rotate(30deg);
+}
+#add-new-event {
+  -webkit-transition: all linear 0.3s;
+  -o-transition: all linear 0.3s;
+  transition: all linear 0.3s;
+}
+.external-event {
+  padding: 5px 10px;
+  font-weight: bold;
+  margin-bottom: 4px;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  border-radius: 3px;
+  cursor: move;
+}
+.external-event:hover {
+  box-shadow: inset 0 0 90px rgba(0, 0, 0, 0.2);
+}
+/*
+ * General: Miscellaneous
+ * ----------------------
+ */
+/* 10px padding and margins */
+.pad {
+  padding: 10px;
+}
+.margin {
+  margin: 10px;
+}
+.margin-bottom {
+  margin-bottom: 20px;
+}
+/* Display inline */
+.inline {
+  display: inline;
+  width: auto;
+}
+/* Description Blocks */
+.description-block {
+  display: block;
+  margin: 10px 0;
+  text-align: center;
+}
+.description-block.margin-bottom {
+  margin-bottom: 25px;
+}
+.description-block > .description-header {
+  margin: 0;
+  padding: 0;
+  font-weight: 600;
+  font-size: 16px;
+}
+.description-block > .description-text {
+  text-transform: uppercase;
+}
+/* Background colors */
+.bg-red,
+.bg-yellow,
+.bg-aqua,
+.bg-blue,
+.bg-light-blue,
+.bg-green,
+.bg-navy,
+.bg-teal,
+.bg-olive,
+.bg-lime,
+.bg-orange,
+.bg-fuchsia,
+.bg-purple,
+.bg-maroon,
+.bg-black,
+.bg-red-active,
+.bg-yellow-active,
+.bg-aqua-active,
+.bg-blue-active,
+.bg-light-blue-active,
+.bg-green-active,
+.bg-navy-active,
+.bg-teal-active,
+.bg-olive-active,
+.bg-lime-active,
+.bg-orange-active,
+.bg-fuchsia-active,
+.bg-purple-active,
+.bg-maroon-active,
+.bg-black-active,
+.callout.callout-danger,
+.callout.callout-warning,
+.callout.callout-info,
+.callout.callout-success,
+.alert-success,
+.alert-danger,
+.alert-error,
+.alert-warning,
+.alert-info,
+.label-danger,
+.label-info,
+.label-waring,
+.label-primary,
+.label-success,
+.modal-primary .modal-body,
+.modal-primary .modal-header,
+.modal-primary .modal-footer,
+.modal-warning .modal-body,
+.modal-warning .modal-header,
+.modal-warning .modal-footer,
+.modal-info .modal-body,
+.modal-info .modal-header,
+.modal-info .modal-footer,
+.modal-success .modal-body,
+.modal-success .modal-header,
+.modal-success .modal-footer,
+.modal-danger .modal-body,
+.modal-danger .modal-header,
+.modal-danger .modal-footer {
+  color: #fff !important;
+}
+.bg-gray {
+  color: #000;
+  background-color: #d2d6de !important;
+}
+.bg-black {
+  background-color: #111111 !important;
+}
+.bg-red,
+.callout.callout-danger,
+.alert-danger,
+.alert-error,
+.label-danger,
+.modal-danger .modal-body {
+  background-color: #dd4b39 !important;
+}
+.bg-yellow,
+.callout.callout-warning,
+.alert-warning,
+.label-waring,
+.modal-warning .modal-body {
+  background-color: #f39c12 !important;
+}
+.bg-aqua,
+.callout.callout-info,
+.alert-info,
+.label-info,
+.modal-info .modal-body {
+  background-color: #00c0ef !important;
+}
+.bg-blue {
+  background-color: #0073b7 !important;
+}
+.bg-light-blue,
+.label-primary,
+.modal-primary .modal-body {
+  background-color: #3c8dbc !important;
+}
+.bg-green,
+.callout.callout-success,
+.alert-success,
+.label-success,
+.modal-success .modal-body {
+  background-color: #00a65a !important;
+}
+.bg-navy {
+  background-color: #001f3f !important;
+}
+.bg-teal {
+  background-color: #39cccc !important;
+}
+.bg-olive {
+  background-color: #3d9970 !important;
+}
+.bg-lime {
+  background-color: #01ff70 !important;
+}
+.bg-orange {
+  background-color: #ff851b !important;
+}
+.bg-fuchsia {
+  background-color: #f012be !important;
+}
+.bg-purple {
+  background-color: #605ca8 !important;
+}
+.bg-maroon {
+  background-color: #d81b60 !important;
+}
+.bg-gray-active {
+  color: #000;
+  background-color: #b5bbc8 !important;
+}
+.bg-black-active {
+  background-color: #000000 !important;
+}
+.bg-red-active,
+.modal-danger .modal-header,
+.modal-danger .modal-footer {
+  background-color: #d33724 !important;
+}
+.bg-yellow-active,
+.modal-warning .modal-header,
+.modal-warning .modal-footer {
+  background-color: #db8b0b !important;
+}
+.bg-aqua-active,
+.modal-info .modal-header,
+.modal-info .modal-footer {
+  background-color: #00a7d0 !important;
+}
+.bg-blue-active {
+  background-color: #005384 !important;
+}
+.bg-light-blue-active,
+.modal-primary .modal-header,
+.modal-primary .modal-footer {
+  background-color: #357ca5 !important;
+}
+.bg-green-active,
+.modal-success .modal-header,
+.modal-success .modal-footer {
+  background-color: #008d4c !important;
+}
+.bg-navy-active {
+  background-color: #001a35 !important;
+}
+.bg-teal-active {
+  background-color: #30bbbb !important;
+}
+.bg-olive-active {
+  background-color: #368763 !important;
+}
+.bg-lime-active {
+  background-color: #00e765 !important;
+}
+.bg-orange-active {
+  background-color: #ff7701 !important;
+}
+.bg-fuchsia-active {
+  background-color: #db0ead !important;
+}
+.bg-purple-active {
+  background-color: #555299 !important;
+}
+.bg-maroon-active {
+  background-color: #ca195a !important;
+}
+[class^="bg-"].disabled {
+  opacity: 0.65;
+  filter: alpha(opacity=65);
+}
+/* Text colors */
+.text-red {
+  color: #dd4b39 !important;
+}
+.text-yellow {
+  color: #f39c12 !important;
+}
+.text-aqua {
+  color: #00c0ef !important;
+}
+.text-blue {
+  color: #0073b7 !important;
+}
+.text-black {
+  color: #111111 !important;
+}
+.text-light-blue {
+  color: #3c8dbc !important;
+}
+.text-green {
+  color: #00a65a !important;
+}
+.text-gray {
+  color: #d2d6de !important;
+}
+.text-navy {
+  color: #001f3f !important;
+}
+.text-teal {
+  color: #39cccc !important;
+}
+.text-olive {
+  color: #3d9970 !important;
+}
+.text-lime {
+  color: #01ff70 !important;
+}
+.text-orange {
+  color: #ff851b !important;
+}
+.text-fuchsia {
+  color: #f012be !important;
+}
+.text-purple {
+  color: #605ca8 !important;
+}
+.text-maroon {
+  color: #d81b60 !important;
+}
+/*Hide elements by display none only*/
+.hide {
+  display: none !important;
+}
+/* Remove borders */
+.no-border {
+  border: 0px !important;
+}
+/* Remove padding */
+.no-padding {
+  padding: 0px !important;
+}
+/* Remove margins */
+.no-margin {
+  margin: 0px !important;
+}
+/* Remove box shadow */
+.no-shadow {
+  box-shadow: none!important;
+}
+/* Unstyled List */
+.list-unstyled,
+.chart-legend,
+.contacts-list,
+.users-list,
+.mailbox-attachments {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+/* Remove border radius */
+.flat {
+  bo

<TRUNCATED>

[08/27] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/SYNCOPE-666
Commit: 6edda65a62ab61e637847cb60ad034cd0b09a7ce
Parents: 7610c62 4ded5ba
Author: fmartelli <fa...@gmail.com>
Authored: Wed Jun 3 14:06:26 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Wed Jun 3 14:06:26 2015 +0200

----------------------------------------------------------------------
 .../syncope/client/console/pages/Reports.java   |  12 ++
 .../syncope/client/console/pages/Tasks.java     |   9 ++
 .../console/panels/NotificationTasks.java       |   3 +
 .../client/console/panels/RuntimePanel.java     | 130 +++++++++++++++++++
 .../client/console/panels/SchedTasks.java       |   3 +
 .../client/console/panels/SyncTasksPanel.java   |   6 +-
 .../client/console/rest/JobRestClient.java      |  31 +++++
 .../client/console/rest/ReportRestClient.java   |  25 +++-
 .../client/console/rest/TaskRestClient.java     |  25 +++-
 .../html/repeater/data/table/JobColumn.java     |  66 ++++++++++
 .../syncope/client/console/pages/Reports.html   |  13 ++
 .../syncope/client/console/pages/Tasks.html     |  15 +++
 .../client/console/panels/RuntimePanel.html     |  49 +++++++
 .../syncope/core/logic/AbstractJobLogic.java    |  15 ++-
 14 files changed, 398 insertions(+), 4 deletions(-)
----------------------------------------------------------------------



[20/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
[SYNCOPE-156] working with resource and connector topology


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

Branch: refs/heads/SYNCOPE-666
Commit: 34ec6712df74f0e7267363f0ea044295af35b5aa
Parents: eb5915f
Author: fmartelli <fa...@gmail.com>
Authored: Mon Jun 8 22:26:38 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Jun 8 22:26:38 2015 +0200

----------------------------------------------------------------------
 client/console/pom.xml                          |   12 +
 .../client/console/SyncopeConsoleSession.java   |    3 +-
 .../console/commons/ActionTableCheckGroup.java  |   40 +
 .../commons/AttributableDataProvider.java       |  103 +
 .../client/console/commons/JexlHelpUtils.java   |   59 +
 .../client/console/pages/AbstractBasePage.java  |    6 +
 .../console/pages/AbstractStatusModalPage.java  |   30 +
 .../syncope/client/console/pages/BasePage.java  |    7 +-
 .../console/pages/BulkActionModalPage.java      |  166 +
 .../pages/BulkActionResultModalPage.java        |   99 +
 .../console/pages/ConnectorModalPage.java       |  477 ++
 .../console/pages/ProvisioningModalPage.java    |  253 ++
 .../syncope/client/console/pages/Realms.java    |  147 +
 .../client/console/pages/ResourceModalPage.java |  204 +
 .../panels/AbstractSearchResultPanel.java       |  346 ++
 .../client/console/panels/AccountPolicy.java    |   35 +
 .../console/panels/ActionDataTablePanel.java    |  145 +
 .../console/panels/AjaxDataTablePanel.java      |  142 +
 .../console/panels/AnnotatedBeanPanel.java      |   66 +
 .../syncope/client/console/panels/Any.java      |   35 +
 .../client/console/panels/Connectors.java       |  385 ++
 .../client/console/panels/DataTablePanel.java   |  113 +
 .../client/console/panels/PasswordPolicy.java   |   35 +
 .../syncope/client/console/panels/Realm.java    |   49 +
 .../client/console/panels/RealmDetails.java     |   41 +
 .../console/panels/ResourceConnConfPanel.java   |  189 +
 .../console/panels/ResourceDetailsPanel.java    |  306 ++
 .../console/panels/ResourceMappingPanel.java    |  644 +++
 .../console/panels/ResourceSecurityPanel.java   |  186 +
 .../client/console/panels/Resources.java        |  485 +++
 .../console/rest/ConnectorRestClient.java       |    6 +-
 .../client/console/rest/RealmRestClient.java    |   38 +
 .../client/console/topology/Topology.java       |  521 +++
 .../client/console/topology/TopologyNode.java   |  123 +
 .../console/topology/TopologyNodePanel.java     |  205 +
 .../topology/TopologyReloadBehavior.java        |   61 +
 .../markup/html/ClearIndicatingAjaxButton.java  |   76 +
 .../markup/html/ClearIndicatingAjaxLink.java    |   61 +
 .../repeater/data/table/ActionResultColumn.java |   77 +
 .../data/table/CheckBoxGroupSelectorPanel.java  |   34 +
 .../html/repeater/data/table/CheckBoxPanel.java |   43 +
 .../repeater/data/table/CheckGroupColumn.java   |   54 +
 .../wicket/markup/html/form/ActionLink.java     |   85 +
 .../markup/html/form/ActionLinksPanel.java      |  609 +++
 .../markup/html/form/AjaxTextFieldPanel.java    |    4 +-
 .../html/form/IndicatingOnConfirmAjaxLink.java  |   58 +
 .../META-INF/resources/css/console.css          | 4066 ------------------
 .../META-INF/resources/css/fieldstyle.css       |  191 +
 .../META-INF/resources/css/syncopeConsole.css   |  170 +-
 .../META-INF/resources/css/topology.css         |  160 +
 .../resources/META-INF/resources/js/topology.js |  244 ++
 .../console/pages/AbstractStatusModalPage.html  |  122 +
 .../pages/AbstractStatusModalPage.properties    |   19 +
 .../pages/AbstractStatusModalPage_it.properties |   19 +
 .../AbstractStatusModalPage_pt_BR.properties    |   19 +
 .../client/console/pages/BaseModalPage.html     |   23 +-
 .../syncope/client/console/pages/BasePage.html  |   11 +-
 .../console/pages/BulkActionModalPage.html      |   45 +
 .../pages/BulkActionModalPage.properties        |   17 +
 .../pages/BulkActionModalPage_it.properties     |   17 +
 .../pages/BulkActionModalPage_pt_BR.properties  |   17 +
 .../pages/BulkActionResultModalPage.html        |   57 +
 .../pages/BulkActionResultModalPage.properties  |   19 +
 .../BulkActionResultModalPage_it.properties     |   19 +
 .../BulkActionResultModalPage_pt_BR.properties  |   19 +
 .../console/pages/ConnectorModalPage.html       |  161 +
 .../console/pages/ConnectorModalPage.properties |   43 +
 .../pages/ConnectorModalPage_it.properties      |   43 +
 .../pages/ConnectorModalPage_pt_BR.properties   |   43 +
 .../syncope/client/console/pages/Realms.html    |   91 +-
 .../client/console/pages/ResourceModalPage.html |   56 +
 .../console/pages/ResourceModalPage.properties  |   60 +
 .../pages/ResourceModalPage_it.properties       |   60 +
 .../pages/ResourceModalPage_pt_BR.properties    |   60 +
 .../panels/AbstractSearchResultPanel.html       |   43 +
 .../panels/AbstractSearchResultPanel.properties |   30 +
 .../AbstractSearchResultPanel_it.properties     |   30 +
 .../AbstractSearchResultPanel_pt_BR.properties  |   30 +
 .../client/console/panels/AccountPolicy.html    |   29 +
 .../console/panels/ActionDataTablePanel.html    |   45 +
 .../console/panels/AjaxDataTablePanel.html      |   47 +
 .../console/panels/AnnotatedBeanPanel.html      |   98 +
 .../panels/AnnotatedBeanPanel.properties        |   20 +
 .../panels/AnnotatedBeanPanel_it.properties     |   20 +
 .../panels/AnnotatedBeanPanel_pt_BR.properties  |   20 +
 .../syncope/client/console/panels/Any.html      |   29 +
 .../client/console/panels/Connectors.html       |   57 +
 .../client/console/panels/Connectors.properties |   34 +
 .../console/panels/Connectors_it.properties     |   34 +
 .../console/panels/Connectors_pt_BR.properties  |   32 +
 .../client/console/panels/PasswordPolicy.html   |   29 +
 .../syncope/client/console/panels/Realm.html    |   93 +
 .../client/console/panels/RealmDetails.html     |   45 +
 .../console/panels/ResourceConnConfPanel.html   |   40 +
 .../console/panels/ResourceDetailsPanel.html    |  137 +
 .../console/panels/ResourceMappingPanel.html    |  114 +
 .../console/panels/ResourceSecurityPanel.html   |   56 +
 .../panels/ResourceSecurityPanel.properties     |   19 +
 .../panels/ResourceSecurityPanel_it.properties  |   19 +
 .../ResourceSecurityPanel_pt_BR.properties      |   19 +
 .../client/console/panels/Resources.html        |   52 +
 .../client/console/panels/Resources.properties  |   34 +
 .../console/panels/Resources_it.properties      |   34 +
 .../console/panels/Resources_pt_BR.properties   |   32 +
 .../client/console/topology/Topology.html       |   52 +
 .../client/console/topology/Topology.properties |   17 +
 .../console/topology/TopologyNodePanel.html     |   67 +
 .../topology/TopologyNodePanel.properties       |   20 +
 .../topology/TopologyNodePanel_it.properties    |   20 +
 .../topology/TopologyNodePanel_pt_BR.properties |   20 +
 .../console/topology/Topology_it.properties     |   17 +
 .../console/topology/Topology_pt_BR.properties  |   17 +
 .../data/table/CheckBoxGroupSelectorPanel.html  |   21 +
 .../html/repeater/data/table/CheckBoxPanel.html |   23 +
 .../markup/html/form/ActionLinksPanel.html      |  173 +
 .../markup/html/form/AjaxCheckBoxPanel.html     |   21 +
 .../html/form/AjaxDropDownChoicePanel.html      |   24 +
 .../markup/html/form/AjaxNumberFieldPanel.html  |   22 +
 .../markup/html/form/AjaxPalettePanel.html      |   23 +
 .../html/form/AjaxPasswordFieldPanel.html       |   22 +
 .../markup/html/form/AjaxTextFieldPanel.html    |   23 +
 .../markup/html/form/AjaxTextFieldPanel_1.html  |   23 +
 .../markup/html/form/BinaryFieldPanel.html      |   44 +
 .../form/CheckBoxMultipleChoiceFieldPanel.html  |   23 +
 .../markup/html/form/DateTextFieldPanel.html    |   22 +
 .../markup/html/form/DateTimeFieldPanel.html    |   21 +
 .../html/form/DateTimeFieldPanel.properties     |   17 +
 .../html/form/DateTimeFieldPanel_it.properties  |   17 +
 .../form/DateTimeFieldPanel_pt_BR.properties    |   17 +
 .../wicket/markup/html/form/FieldPanel.html     |   34 +
 .../wicket/markup/html/form/FieldPanel_1.html   |   34 +
 .../wicket/markup/html/form/LinkPanel.html      |   23 +
 .../wicket/markup/html/form/LinkPanel_1.html    |   23 +
 .../markup/html/form/MappingPurposePanel.html   |   31 +
 .../markup/html/form/MultiFieldPanel.html       |   35 +
 .../markup/html/form/MultiFieldPanel.properties |   22 +
 .../html/form/MultiFieldPanel_it.properties     |   22 +
 .../html/form/MultiFieldPanel_pt_BR.properties  |   22 +
 .../wicket/markup/html/form/NonI18nPalette.html |   69 +
 .../markup/html/form/SpinnerFieldPanel.html     |   29 +
 .../rest/api/service/ConnectorService.java      |    1 -
 pom.xml                                         |   13 +
 142 files changed, 10983 insertions(+), 4196 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/pom.xml
----------------------------------------------------------------------
diff --git a/client/console/pom.xml b/client/console/pom.xml
index a558d30..4ef7c9c 100644
--- a/client/console/pom.xml
+++ b/client/console/pom.xml
@@ -110,6 +110,18 @@ under the License.
       <groupId>org.webjars</groupId>
       <artifactId>codemirror</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>jsplumb</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>jquery-cookie</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>jquery-ui</artifactId>
+    </dependency>
   </dependencies>
   
   <build>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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 f162357..25394c7 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
@@ -157,7 +157,8 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
 
     public <T> T getService(final String etag, final Class<T> serviceClass) {
         T serviceInstance = getCachedService(serviceClass);
-        WebClient.client(serviceInstance).match(new EntityTag(etag), false);
+        WebClient.client(serviceInstance).match(new EntityTag(etag), false).
+                type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
 
         return serviceInstance;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/commons/ActionTableCheckGroup.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/ActionTableCheckGroup.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/ActionTableCheckGroup.java
new file mode 100644
index 0000000..453e0c0
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/ActionTableCheckGroup.java
@@ -0,0 +1,40 @@
+/*
+ * 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.commons;
+
+import java.util.Collection;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.model.IModel;
+
+public class ActionTableCheckGroup<T> extends CheckGroup<T> {
+
+    private static final long serialVersionUID = 1288270558573401394L;
+
+    public ActionTableCheckGroup(final String id, final Collection<T> collection) {
+        super(id, collection);
+    }
+
+    public ActionTableCheckGroup(final String id, final IModel<Collection<T>> model) {
+        super(id, model);
+    }
+
+    public boolean isCheckable(final T element) {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
new file mode 100644
index 0000000..1890a80
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
@@ -0,0 +1,103 @@
+/*
+ * 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.commons;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+
+public class AttributableDataProvider extends SortableDataProvider<AbstractAttributableTO, String> {
+
+    private static final long serialVersionUID = 6267494272884913376L;
+
+    private final SortableAttributableProviderComparator comparator;
+
+    private String fiql = null;
+
+    private final int paginatorRows;
+
+    private final boolean filtered;
+
+    private final AbstractSubjectRestClient restClient;
+
+    private final String realm = "/";
+
+    public AttributableDataProvider(final AbstractSubjectRestClient restClient,
+            final int paginatorRows, final boolean filtered) {
+
+        super();
+
+        this.restClient = restClient;
+        this.filtered = filtered;
+        this.paginatorRows = paginatorRows;
+
+        // default sorting
+        setSort("key", SortOrder.ASCENDING);
+
+        this.comparator = new SortableAttributableProviderComparator(this);
+    }
+
+    public void setFIQL(final String fiql) {
+        this.fiql = fiql;
+    }
+
+    @Override
+    public Iterator<? extends AbstractAttributableTO> iterator(final long first, final long count) {
+        List<? extends AbstractAttributableTO> result;
+
+        final int page = ((int) first / paginatorRows);
+
+        if (filtered) {
+            result = fiql == null
+                    ? Collections.<AbstractAttributableTO>emptyList()
+                    : restClient.search(realm, fiql, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
+        } else {
+            result = restClient.list(realm, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
+        }
+
+        Collections.sort(result, comparator);
+        return result.iterator();
+    }
+
+    @Override
+    public long size() {
+        long result;
+
+        if (filtered) {
+            result = fiql == null
+                    ? 0
+                    : restClient.searchCount(realm, fiql);
+        } else {
+            result = restClient.count(realm);
+        }
+
+        return result;
+    }
+
+    @Override
+    public IModel<AbstractAttributableTO> model(final AbstractAttributableTO object) {
+        return new CompoundPropertyModel<>(object);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/commons/JexlHelpUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/JexlHelpUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/JexlHelpUtils.java
new file mode 100644
index 0000000..ab8dcfb
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/JexlHelpUtils.java
@@ -0,0 +1,59 @@
+/*
+ * 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.commons;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.link.ExternalLink;
+
+public final class JexlHelpUtils {
+
+    private static final String JEXL_SYNTAX_URL = "http://commons.apache.org/jexl/reference/syntax.html";
+
+    private JexlHelpUtils() {
+        // private constructor for static utility class
+    }
+
+    public static WebMarkupContainer getJexlHelpWebContainer(final String wicketId) {
+        final WebMarkupContainer jexlHelp = new WebMarkupContainer(wicketId);
+        jexlHelp.setVisible(false);
+        jexlHelp.setOutputMarkupPlaceholderTag(true);
+        jexlHelp.setOutputMarkupId(true);
+        jexlHelp.add(new ExternalLink("jexlLink", JEXL_SYNTAX_URL));
+        return jexlHelp;
+    }
+
+    public static AjaxLink<Void> getAjaxLink(final WebMarkupContainer wmc, final String wicketId) {
+        AjaxLink<Void> questionMarkJexlHelp = new AjaxLink<Void>(wicketId) {
+
+            private static final long serialVersionUID = -1838017408000591382L;
+
+            private boolean toogle = false;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                toogle ^= true;
+                wmc.setVisible(toogle);
+                target.add(wmc);
+            }
+        };
+        return questionMarkJexlHelp;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractBasePage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractBasePage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractBasePage.java
index d63de02..bd88711 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractBasePage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractBasePage.java
@@ -22,6 +22,7 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.init.MIMETypesLoader;
 import org.apache.syncope.client.console.panels.NotificationPanel;
 import org.apache.syncope.client.console.rest.ConfigurationRestClient;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.rest.ReportRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
@@ -51,6 +52,8 @@ public class AbstractBasePage extends WebPage {
 
     protected static final String APPLY = "apply";
 
+    protected static final String FORM = "form";
+
     protected final HeaderItem meta = new MetaHeaderItem("X-UA-Compatible", "IE=edge");
 
     @SpringBean
@@ -72,6 +75,9 @@ public class AbstractBasePage extends WebPage {
     protected ResourceRestClient resourceRestClient;
 
     @SpringBean
+    protected ConnectorRestClient connectorRestClient;
+
+    @SpringBean
     protected ReportRestClient reportRestClient;
 
     @SpringBean

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractStatusModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractStatusModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractStatusModalPage.java
new file mode 100644
index 0000000..f5dfbca
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/AbstractStatusModalPage.java
@@ -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.
+ */
+package org.apache.syncope.client.console.pages;
+
+import org.apache.wicket.markup.html.panel.Fragment;
+
+public class AbstractStatusModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = 6633408683036028540L;
+
+    public AbstractStatusModalPage() {
+        add(new Fragment("pwdMgtFields", "emptyFragment", this));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index 71a9c7f..20c3458 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.pages;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
+import org.apache.syncope.client.console.topology.Topology;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
@@ -92,6 +93,10 @@ public class BasePage extends AbstractBasePage implements IAjaxIndicatorAware {
         add(liContainer);
         liContainer.add(new BookmarkablePageLink<>("realms", Realms.class));
         
+        liContainer = new WebMarkupContainer(getLIContainerId("topology"));
+        add(liContainer);
+        liContainer.add(new BookmarkablePageLink<>("topology", Topology.class));
+        
         add(new BookmarkablePageLink<Page>("logout", Logout.class));
 
         // set 'active' menu item
@@ -150,7 +155,7 @@ public class BasePage extends AbstractBasePage implements IAjaxIndicatorAware {
      * @param window window
      * @param container container
      */
-    protected void setWindowClosedCallback(final ModalWindow window, final WebMarkupContainer container) {
+    public void setWindowClosedCallback(final ModalWindow window, final WebMarkupContainer container) {
         window.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
 
             private static final long serialVersionUID = 8804221891699487139L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
new file mode 100644
index 0000000..65dfa58
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+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.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.markup.html.form.Form;
+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.springframework.beans.BeanUtils;
+
+public class BulkActionModalPage<T, S> extends BaseModalPage {
+
+    private static final long serialVersionUID = 4114026480146090962L;
+
+    public BulkActionModalPage(
+            final ModalWindow window,
+            final Collection<T> items,
+            final List<IColumn<T, S>> columns,
+            final Collection<ActionLink.ActionType> actions,
+            final BaseRestClient bulkActionExecutor,
+            final String idFieldName,
+            final String pageId) {
+
+        super();
+
+        final SortableDataProvider<T, S> dataProvider = new SortableDataProvider<T, S>() {
+
+            private static final long serialVersionUID = 5291903859908641954L;
+
+            @Override
+            public Iterator<? extends T> iterator(final long first, final long count) {
+                return items.iterator();
+            }
+
+            @Override
+            public long size() {
+                return items.size();
+            }
+
+            @Override
+            public IModel<T> model(final T object) {
+                return new CompoundPropertyModel<>(object);
+            }
+        };
+
+        add(new AjaxFallbackDefaultDataTable<>(
+                "selectedObjects",
+                new ArrayList<>(columns.subList(1, columns.size() - 1)),
+                dataProvider,
+                Integer.MAX_VALUE).setVisible(items != null && !items.isEmpty()));
+
+        @SuppressWarnings("rawtypes")
+        final ActionLinksPanel actionPanel = new ActionLinksPanel("actions", new Model(), getPageReference());
+        add(actionPanel);
+
+        for (ActionLink.ActionType action : actions) {
+            final BulkAction bulkAction = new BulkAction();
+            for (T item : items) {
+                try {
+                    bulkAction.getTargets().add(getTargetId(item, idFieldName).toString());
+                } catch (IllegalAccessException | InvocationTargetException e) {
+                    LOG.error("Error retrieving item id {}", idFieldName, e);
+                }
+            }
+
+            switch (action) {
+                case DELETE:
+                    bulkAction.setOperation(BulkAction.Type.DELETE);
+                    break;
+                case SUSPEND:
+                    bulkAction.setOperation(BulkAction.Type.SUSPEND);
+                    break;
+                case REACTIVATE:
+                    bulkAction.setOperation(BulkAction.Type.REACTIVATE);
+                    break;
+                case EXECUTE:
+                    bulkAction.setOperation(BulkAction.Type.EXECUTE);
+                    break;
+                case DRYRUN:
+                    bulkAction.setOperation(BulkAction.Type.DRYRUN);
+                    break;
+                default:
+                    LOG.error("Bulk action type not supported");
+            }
+
+            actionPanel.add(new ActionLink() {
+
+                private static final long serialVersionUID = -3722207913631435501L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target) {
+                    try {
+                        final BulkActionResult res = (BulkActionResult) bulkActionExecutor.getClass().
+                                getMethod("bulkAction", BulkAction.class).invoke(bulkActionExecutor, bulkAction);
+
+                        setResponsePage(new BulkActionResultModalPage<>(window, items, columns, res, idFieldName));
+                    } catch (NoSuchMethodException | SecurityException | IllegalAccessException 
+                            | IllegalArgumentException | InvocationTargetException e) {
+                        error(getString(Constants.ERROR)
+                                + ": Operation " + bulkAction.getOperation() + " not supported");
+                        feedbackPanel.refresh(target);
+                    }
+
+                }
+            }, action, pageId, !items.isEmpty());
+        }
+
+        final Form<Void> form = new Form<>(FORM);
+        add(form);
+
+        final AjaxButton cancel = new ClearIndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL), getPageReference()) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                window.close(target);
+            }
+        };
+
+        cancel.setDefaultFormProcessing(false);
+        form.add(cancel);
+    }
+
+    private Object getTargetId(final Object target, final String idFieldName)
+            throws IllegalAccessException, InvocationTargetException {
+
+        return BeanUtils.getPropertyDescriptor(target.getClass(), idFieldName).
+                getReadMethod().invoke(target, new Object[0]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
new file mode 100644
index 0000000..72a789f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionResultColumn;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+
+/**
+ * Show user or group status after performing a successful operation.
+ * @param <T>
+ * @param <S>
+ */
+public class BulkActionResultModalPage<T, S> extends BaseModalPage {
+
+    /**
+     * Serial version id.
+     */
+    private static final long serialVersionUID = 2646115294319713724L;
+
+    public BulkActionResultModalPage(
+            final ModalWindow window,
+            final Collection<T> items,
+            final List<IColumn<T, S>> columns,
+            final BulkActionResult results,
+            final String idFieldName) {
+
+        super();
+
+        final List<IColumn<T, S>> newColumnList = new ArrayList<>(columns.subList(1, columns.size() - 1));
+        newColumnList.add(newColumnList.size(), new ActionResultColumn<T, S>(results, idFieldName));
+
+        final SortableDataProvider<T, S> dataProvider = new SortableDataProvider<T, S>() {
+
+            private static final long serialVersionUID = 5291903859908641954L;
+
+            @Override
+            public Iterator<? extends T> iterator(final long first, final long count) {
+                return items.iterator();
+            }
+
+            @Override
+            public long size() {
+                return items.size();
+            }
+
+            @Override
+            public IModel<T> model(final T object) {
+                return new CompoundPropertyModel<>(object);
+            }
+        };
+
+        add(new AjaxFallbackDefaultDataTable<>(
+                "selectedObjects",
+                newColumnList,
+                dataProvider,
+                Integer.MAX_VALUE).setVisible(items != null && !items.isEmpty()));
+
+        final AjaxLink<Void> close = new IndicatingAjaxLink<Void>("close") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                window.close(target);
+            }
+        };
+
+        add(close);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java
new file mode 100644
index 0000000..f35da6a
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java
@@ -0,0 +1,477 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.apache.wicket.validation.validator.RangeValidator;
+
+/**
+ * Modal window with Connector form.
+ */
+public class ConnectorModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = -2025535531121434050L;
+
+    @SpringBean
+    private ConnectorRestClient restClient;
+
+    private final Map<String, Map<String, Map<String, ConnBundleTO>>> mapConnBundleTOs;
+
+    private final List<ConnectorCapability> selectedCapabilities;
+
+    private ConnBundleTO bundleTO;
+
+    private List<ConnConfProperty> properties;
+
+    private final WebMarkupContainer propertiesContainer;
+
+    public ConnectorModalPage(final PageReference pageRef, final ModalWindow window,
+            final ConnInstanceTO connInstanceTO) {
+
+        super();
+
+        this.add(new Label("new", connInstanceTO.getKey() == 0
+                ? new ResourceModel("new")
+                : new Model<>(StringUtils.EMPTY)));
+        this.add(new Label("key", connInstanceTO.getKey() == 0
+                ? StringUtils.EMPTY
+                : connInstanceTO.getKey()));
+
+        // general data setup
+        selectedCapabilities = new ArrayList<>(connInstanceTO.getKey() == 0
+                ? EnumSet.noneOf(ConnectorCapability.class)
+                : connInstanceTO.getCapabilities());
+
+        mapConnBundleTOs = new HashMap<>();
+        for (ConnBundleTO connBundleTO : restClient.getAllBundles()) {
+            // by location
+            if (!mapConnBundleTOs.containsKey(connBundleTO.getLocation())) {
+                mapConnBundleTOs.put(connBundleTO.getLocation(), new HashMap<String, Map<String, ConnBundleTO>>());
+            }
+            final Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connBundleTO.getLocation());
+
+            // by name
+            if (!byLocation.containsKey(connBundleTO.getBundleName())) {
+                byLocation.put(connBundleTO.getBundleName(), new HashMap<String, ConnBundleTO>());
+            }
+            final Map<String, ConnBundleTO> byName = byLocation.get(connBundleTO.getBundleName());
+
+            // by version
+            if (!byName.containsKey(connBundleTO.getVersion())) {
+                byName.put(connBundleTO.getVersion(), connBundleTO);
+            }
+        }
+
+        bundleTO = getSelectedBundleTO(connInstanceTO);
+        properties = fillProperties(bundleTO, connInstanceTO);
+
+        // form - first tab
+        final Form<ConnInstanceTO> connectorForm = new Form<>(FORM);
+        connectorForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
+        connectorForm.setOutputMarkupId(true);
+        add(connectorForm);
+
+        propertiesContainer = new WebMarkupContainer("container");
+        propertiesContainer.setOutputMarkupId(true);
+        connectorForm.add(propertiesContainer);
+
+        final Form<ConnInstanceTO> connectorPropForm = new Form<>("connectorPropForm");
+        connectorPropForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
+        connectorPropForm.setOutputMarkupId(true);
+        propertiesContainer.add(connectorPropForm);
+
+        final AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
+                "displayName", "display name", new PropertyModel<String>(connInstanceTO, "displayName"));
+        displayName.setOutputMarkupId(true);
+        displayName.addRequiredLabel();
+        connectorForm.add(displayName);
+
+        final AjaxDropDownChoicePanel<String> location = new AjaxDropDownChoicePanel<>("location", "location",
+                new Model<>(bundleTO == null ? null : bundleTO.getLocation()));
+        ((DropDownChoice<String>) location.getField()).setNullValid(true);
+        location.setStyleSheet("long_dynamicsize");
+        location.setChoices(new ArrayList<>(mapConnBundleTOs.keySet()));
+        location.setRequired(true);
+        location.addRequiredLabel();
+        location.setOutputMarkupId(true);
+        location.setEnabled(connInstanceTO.getKey() == 0);
+        location.getField().setOutputMarkupId(true);
+        connectorForm.add(location);
+
+        final AjaxDropDownChoicePanel<String> connectorName = new AjaxDropDownChoicePanel<>("connectorName",
+                "connectorName",
+                new Model<>(bundleTO == null ? null : bundleTO.getBundleName()));
+        ((DropDownChoice<String>) connectorName.getField()).setNullValid(true);
+        connectorName.setStyleSheet("long_dynamicsize");
+        connectorName.setChoices(bundleTO == null
+                ? new ArrayList<String>()
+                : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet()));
+        connectorName.setRequired(true);
+        connectorName.addRequiredLabel();
+        connectorName.setEnabled(connInstanceTO.getLocation() != null);
+        connectorName.setOutputMarkupId(true);
+        connectorName.setEnabled(connInstanceTO.getKey() == 0);
+        connectorName.getField().setOutputMarkupId(true);
+        connectorForm.add(connectorName);
+
+        final AjaxDropDownChoicePanel<String> version = new AjaxDropDownChoicePanel<>("version", "version",
+                new Model<>(bundleTO == null ? null : bundleTO.getVersion()));
+        version.setStyleSheet("long_dynamicsize");
+        version.setChoices(bundleTO == null
+                ? new ArrayList<String>()
+                : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).
+                        get(connInstanceTO.getBundleName()).keySet()));
+        version.setRequired(true);
+        version.addRequiredLabel();
+        version.setEnabled(connInstanceTO.getBundleName() != null);
+        version.setOutputMarkupId(true);
+        version.addRequiredLabel();
+        version.getField().setOutputMarkupId(true);
+        connectorForm.add(version);
+
+        final SpinnerFieldPanel<Integer> connRequestTimeout = new SpinnerFieldPanel<>("connRequestTimeout",
+                "connRequestTimeout", Integer.class,
+                new PropertyModel<Integer>(connInstanceTO, "connRequestTimeout"), 0, null);
+        connRequestTimeout.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(connRequestTimeout);
+
+        if (connInstanceTO.getPoolConf() == null) {
+            connInstanceTO.setPoolConf(new ConnPoolConfTO());
+        }
+        final SpinnerFieldPanel<Integer> poolMaxObjects = new SpinnerFieldPanel<>("poolMaxObjects", "poolMaxObjects",
+                Integer.class,
+                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxObjects"), 0, null);
+        poolMaxObjects.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(poolMaxObjects);
+        final SpinnerFieldPanel<Integer> poolMinIdle = new SpinnerFieldPanel<>("poolMinIdle", "poolMinIdle",
+                Integer.class,
+                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "minIdle"), 0, null);
+        poolMinIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(poolMinIdle);
+        final SpinnerFieldPanel<Integer> poolMaxIdle = new SpinnerFieldPanel<>("poolMaxIdle", "poolMaxIdle",
+                Integer.class,
+                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxIdle"), 0, null);
+        poolMaxIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(poolMaxIdle);
+        final SpinnerFieldPanel<Long> poolMaxWait = new SpinnerFieldPanel<>("poolMaxWait", "poolMaxWait", Long.class,
+                new PropertyModel<Long>(connInstanceTO.getPoolConf(), "maxWait"), 0L, null);
+        poolMaxWait.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
+        connectorForm.add(poolMaxWait);
+        final SpinnerFieldPanel<Long> poolMinEvictableIdleTime = new SpinnerFieldPanel<>("poolMinEvictableIdleTime",
+                "poolMinEvictableIdleTime", Long.class,
+                new PropertyModel<Long>(connInstanceTO.getPoolConf(), "minEvictableIdleTimeMillis"),
+                0L, null);
+        poolMinEvictableIdleTime.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
+        connectorForm.add(poolMinEvictableIdleTime);
+
+        // form - first tab - onchange()
+        location.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                ((DropDownChoice<String>) location.getField()).setNullValid(false);
+                connInstanceTO.setLocation(location.getModelObject());
+                target.add(location);
+
+                connectorName.setChoices(new ArrayList<>(
+                        mapConnBundleTOs.get(location.getModelObject()).keySet()));
+                connectorName.setEnabled(true);
+                connectorName.getField().setModelValue(null);
+                target.add(connectorName);
+
+                version.setChoices(new ArrayList<String>());
+                version.getField().setModelValue(null);
+                version.setEnabled(false);
+                target.add(version);
+
+                properties.clear();
+                target.add(propertiesContainer);
+            }
+        });
+        connectorName.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                ((DropDownChoice<String>) connectorName.getField()).setNullValid(false);
+                connInstanceTO.setBundleName(connectorName.getModelObject());
+                target.add(connectorName);
+
+                List<String> versions = new ArrayList<>(
+                        mapConnBundleTOs.get(location.getModelObject()).get(connectorName.getModelObject()).keySet());
+                version.setChoices(versions);
+                version.setEnabled(true);
+                if (versions.size() == 1) {
+                    selectVersion(target, connInstanceTO, version, versions.get(0));
+                    version.getField().setModelObject(versions.get(0));
+                } else {
+                    version.getField().setModelValue(null);
+                    properties.clear();
+                    target.add(propertiesContainer);
+                }
+                target.add(version);
+            }
+        });
+        version.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                selectVersion(target, connInstanceTO, version, version.getModelObject());
+            }
+        });
+
+        // form - second tab (properties)
+        final ListView<ConnConfProperty> connPropView = new ConnConfPropertyListView("connectorProperties",
+                new PropertyModel<List<ConnConfProperty>>(this, "properties"),
+                true, connInstanceTO.getConfiguration());
+        connPropView.setOutputMarkupId(true);
+        connectorPropForm.add(connPropView);
+
+        final AjaxButton check = new IndicatingAjaxButton("check", new ResourceModel("check")) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
+
+                // ensure that connector bundle information is in sync
+                conn.setBundleName(bundleTO.getBundleName());
+                conn.setVersion(bundleTO.getVersion());
+                conn.setConnectorName(bundleTO.getConnectorName());
+
+                if (restClient.check(conn)) {
+                    info(getString("success_connection"));
+                } else {
+                    error(getString("error_connection"));
+                }
+
+                feedbackPanel.refresh(target);
+            }
+        };
+        connectorPropForm.add(check);
+
+        // form - third tab (capabilities)
+        final IModel<List<ConnectorCapability>> capabilities
+                = new LoadableDetachableModel<List<ConnectorCapability>>() {
+
+                    private static final long serialVersionUID = 5275935387613157437L;
+
+                    @Override
+                    protected List<ConnectorCapability> load() {
+                        return Arrays.asList(ConnectorCapability.values());
+                    }
+                };
+        CheckBoxMultipleChoice<ConnectorCapability> capabilitiesPalette = new CheckBoxMultipleChoice<>(
+                "capabilitiesPalette",
+                new PropertyModel<List<ConnectorCapability>>(this, "selectedCapabilities"), capabilities);
+
+        capabilitiesPalette.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+            }
+        });
+
+        connectorForm.add(capabilitiesPalette);
+
+        // form - submit / cancel buttons
+        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new Model<>(getString(SUBMIT))) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
+
+                conn.setConnectorName(bundleTO.getConnectorName());
+                conn.setBundleName(bundleTO.getBundleName());
+                conn.setVersion(bundleTO.getVersion());
+                conn.getConfiguration().clear();
+                conn.getConfiguration().addAll(connPropView.getModelObject());
+
+                // Set the model object's capabilities to capabilitiesPalette's converted Set
+                conn.getCapabilities().clear();
+                conn.getCapabilities().addAll(selectedCapabilities.isEmpty()
+                        ? EnumSet.noneOf(ConnectorCapability.class)
+                        : EnumSet.copyOf(selectedCapabilities));
+
+                // Reset pool configuration if all fields are null
+                if (conn.getPoolConf() != null
+                        && conn.getPoolConf().getMaxIdle() == null
+                        && conn.getPoolConf().getMaxObjects() == null
+                        && conn.getPoolConf().getMaxWait() == null
+                        && conn.getPoolConf().getMinEvictableIdleTimeMillis() == null
+                        && conn.getPoolConf().getMinIdle() == null) {
+
+                    conn.setPoolConf(null);
+                }
+
+                try {
+                    if (connInstanceTO.getKey() == 0) {
+                        restClient.create(conn);
+                    } else {
+                        restClient.update(conn);
+                    }
+
+                    ((BasePage) pageRef.getPage()).setModalResult(true);
+                    window.close(target);
+                } catch (SyncopeClientException e) {
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                    ((BasePage) pageRef.getPage()).setModalResult(false);
+                    LOG.error("While creating or updating connector {}", conn, e);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+        String entitlements = connInstanceTO.getKey() == 0
+                ? Entitlement.CONNECTOR_CREATE : Entitlement.CONNECTOR_UPDATE;
+
+        MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, entitlements);
+        connectorForm.add(submit);
+
+        final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                window.close(target);
+            }
+        };
+        cancel.setDefaultFormProcessing(false);
+        connectorForm.add(cancel);
+    }
+
+    private ConnBundleTO getSelectedBundleTO(final ConnInstanceTO connInstanceTO) {
+        ConnBundleTO result = null;
+        if (connInstanceTO != null
+                && StringUtils.isNotBlank(connInstanceTO.getLocation())
+                && StringUtils.isNotBlank(connInstanceTO.getBundleName())
+                && StringUtils.isNotBlank(connInstanceTO.getVersion())
+                && mapConnBundleTOs.containsKey(connInstanceTO.getLocation())) {
+
+            Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connInstanceTO.getLocation());
+            if (byLocation.containsKey(connInstanceTO.getBundleName())) {
+                Map<String, ConnBundleTO> byName = byLocation.get(connInstanceTO.getBundleName());
+                if (byName.containsKey(connInstanceTO.getVersion())) {
+                    result = byName.get(connInstanceTO.getVersion());
+                }
+            }
+        }
+        return result;
+    }
+
+    private List<ConnConfProperty> fillProperties(final ConnBundleTO bundleTO, final ConnInstanceTO connInstanceTO) {
+        final List<ConnConfProperty> props = new ArrayList<>();
+
+        if (bundleTO != null) {
+            for (ConnConfPropSchema key : bundleTO.getProperties()) {
+                final ConnConfProperty property = new ConnConfProperty();
+                property.setSchema(key);
+                if (connInstanceTO.getKey() != 0
+                        && connInstanceTO.getConfigurationMap().containsKey(key.getName())
+                        && connInstanceTO.getConfigurationMap().get(key.getName()).getValues() != null) {
+
+                    property.getValues().addAll(connInstanceTO.getConfigurationMap().get(key.getName()).getValues());
+                    property.setOverridable(connInstanceTO.getConfigurationMap().get(key.getName()).isOverridable());
+                }
+
+                if (property.getValues().isEmpty() && !key.getDefaultValues().isEmpty()) {
+                    property.getValues().addAll(key.getDefaultValues());
+                }
+
+                props.add(property);
+            }
+        }
+
+        // re-order properties (implements Comparable)
+        Collections.sort(props);
+        return props;
+    }
+
+    private void selectVersion(final AjaxRequestTarget target, final ConnInstanceTO connInstanceTO,
+            final AjaxDropDownChoicePanel<String> version, final String versionValue) {
+
+        connInstanceTO.setVersion(versionValue);
+        target.add(version);
+
+        bundleTO = getSelectedBundleTO(connInstanceTO);
+        properties = fillProperties(bundleTO, connInstanceTO);
+        target.add(propertiesContainer);
+    }
+
+    public List<ConnConfProperty> getProperties() {
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
new file mode 100644
index 0000000..af1d0b5
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.status.AbstractStatusBeanProvider;
+import org.apache.syncope.client.console.commons.status.ConnObjectWrapper;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.commons.status.StatusUtils;
+import org.apache.syncope.client.console.panels.ActionDataTablePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.AbstractWrappable;
+import org.apache.syncope.common.lib.wrap.SubjectKey;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+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.ISortableDataProvider;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.StringResourceModel;
+
+public class ProvisioningModalPage<T extends AbstractAttributableTO> extends AbstractStatusModalPage {
+
+    private static final long serialVersionUID = -4285220460543213901L;
+
+    private static final int ROWS_PER_PAGE = 10;
+
+    private final ResourceTO resourceTO;
+
+    private final Class<? extends AbstractAttributableTO> typeRef;
+
+    private final PageReference pageRef;
+
+    private final ModalWindow window;
+
+    private final StatusUtils statusUtils;
+
+    private final String realm = "/";
+
+    public ProvisioningModalPage(
+            final PageReference pageRef,
+            final ModalWindow window,
+            final ResourceTO resourceTO,
+            final Class<T> typeRef) {
+
+        super();
+
+        this.pageRef = pageRef;
+        this.window = window;
+        this.resourceTO = resourceTO;
+        this.typeRef = typeRef;
+
+        statusUtils = new StatusUtils((UserTO.class.isAssignableFrom(typeRef) ? userRestClient : groupRestClient));
+
+        add(new Label("displayName", StringUtils.EMPTY));
+
+        final List<IColumn<StatusBean, String>> columns = new ArrayList<>();
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("key", this, null, "Attributable key"),
+                "attributableKey", "attributableKey"));
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("name", this, null, "Attributable name"),
+                "attributableName", "attributableName"));
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("resourceName", this, null, "Resource name"),
+                "resourceName", "resourceName"));
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("accountLink", this, null, "Account link"),
+                "accountLink", "accountLink"));
+        columns.add(new AbstractColumn<StatusBean, String>(
+                new StringResourceModel("status", this, null, "")) {
+
+                    private static final long serialVersionUID = -3503023501954863131L;
+
+                    @Override
+                    public String getCssClass() {
+                        return "action";
+                    }
+
+                    @Override
+                    public void populateItem(
+                            final Item<ICellPopulator<StatusBean>> cellItem,
+                            final String componentId,
+                            final IModel<StatusBean> model) {
+                                cellItem.
+                                add(statusUtils.getStatusImagePanel(componentId, model.getObject().getStatus()));
+                            }
+                });
+
+        final ActionDataTablePanel<StatusBean, String> table = new ActionDataTablePanel<>(
+                "resourceDatatable",
+                columns,
+                (ISortableDataProvider<StatusBean, String>) new StatusBeanProvider(),
+                ROWS_PER_PAGE,
+                pageRef);
+
+        final String pageId = "Resources";
+
+        table.addAction(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    bulkAssociationAction(target, ResourceDeassociationActionType.UNLINK, table, columns);
+                } catch (Exception e) {
+                    LOG.error("Error unlinkink resources", e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+        }, ActionLink.ActionType.UNLINK, pageId);
+
+        table.addAction(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    bulkAssociationAction(target, ResourceDeassociationActionType.DEPROVISION, table, columns);
+                } catch (Exception e) {
+                    LOG.error("Error de-provisioning user", e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+        }, ActionLink.ActionType.DEPROVISION, pageId);
+
+        table.addAction(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    bulkAssociationAction(target, ResourceDeassociationActionType.UNASSIGN, table, columns);
+                } catch (Exception e) {
+                    LOG.error("Error unassigning resources", e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+        }, ActionLink.ActionType.UNASSIGN, pageId);
+
+        table.addCancelButton(window);
+
+        add(table);
+    }
+
+    private class StatusBeanProvider extends AbstractStatusBeanProvider {
+
+        private static final long serialVersionUID = 4287357360778016173L;
+
+        public StatusBeanProvider() {
+            super("accountLink");
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public List<StatusBean> getStatusBeans() {
+            final String fiql = SyncopeClient.getUserSearchConditionBuilder().hasResources(resourceTO.getKey()).query();
+
+            final List<T> subjects = new ArrayList<>();
+            if (UserTO.class.isAssignableFrom(typeRef)) {
+                subjects.addAll((List<T>) userRestClient.search(
+                        realm, fiql, 1, ROWS_PER_PAGE, new SortParam<>("key", true)));
+            } else {
+                subjects.addAll((List<T>) groupRestClient.search(
+                        realm, fiql, 1, ROWS_PER_PAGE, new SortParam<>("key", true)));
+            }
+
+            final List<ConnObjectWrapper> connObjects = statusUtils.getConnectorObjects(
+                    (List<AbstractSubjectTO>) subjects, Collections.<String>singleton(resourceTO.getKey()));
+
+            final List<StatusBean> statusBeans = new ArrayList<>(connObjects.size() + 1);
+            final LinkedHashMap<String, StatusBean> initialStatusBeanMap = new LinkedHashMap<>(connObjects.size());
+
+            for (ConnObjectWrapper entry : connObjects) {
+                final StatusBean statusBean = statusUtils.getStatusBean(entry.getAttributable(),
+                        entry.getResourceName(),
+                        entry.getConnObjectTO(),
+                        GroupTO.class.isAssignableFrom(typeRef));
+
+                initialStatusBeanMap.put(entry.getResourceName(), statusBean);
+                statusBeans.add(statusBean);
+            }
+
+            return statusBeans;
+        }
+    }
+
+    private void bulkAssociationAction(
+            final AjaxRequestTarget target,
+            final ResourceDeassociationActionType type,
+            final ActionDataTablePanel<StatusBean, String> table,
+            final List<IColumn<StatusBean, String>> columns) {
+
+        final List<StatusBean> beans = new ArrayList<>(table.getModelObject());
+        List<SubjectKey> subjectKeys = new ArrayList<>();
+        for (StatusBean bean : beans) {
+            LOG.debug("Selected bean {}", bean);
+            subjectKeys.add(AbstractWrappable.getInstance(SubjectKey.class, bean.getAttributableId()));
+        }
+
+        if (beans.isEmpty()) {
+            window.close(target);
+        } else {
+            final BulkActionResult res = resourceRestClient.bulkAssociationAction(
+                    resourceTO.getKey(), typeRef, type, subjectKeys);
+
+            ((BasePage) pageRef.getPage()).setModalResult(true);
+
+            setResponsePage(new BulkActionResultModalPage<>(window, beans, columns, res, "attributableKey"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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 6ff73f4..daee99c 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,13 +18,160 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.client.console.panels.Realm;
+import org.apache.syncope.client.console.rest.RealmRestClient;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+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.repeater.RepeatingView;
+import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class Realms extends BasePage {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
+    protected static final Logger LOG = LoggerFactory.getLogger(Realms.class);
+
+    @SpringBean
+    private RealmRestClient realmRestClient;
+
+    private final WebMarkupContainer content;
+
     public Realms(final PageParameters parameters) {
         super(parameters);
+
+        final List<RealmTO> realms = realmRestClient.list();
+        Collections.sort(realms, new RealmNameComparator());
+
+        add(getParentMap(realms), 0L, Realms.this);
+
+        content = new WebMarkupContainer("content");
+        content.setOutputMarkupId(true);
+        add(content);
+
+        content.add(new Label("header", "Root realm"));
+        content.add(new Label("body", "Root realm"));
+    }
+
+    private void add(final Map<Long, List<RealmTO>> parentMap, final Long key, final MarkupContainer container) {
+        final RepeatingView listItems = new RepeatingView("list");
+        container.add(listItems);
+
+        for (final RealmTO realm : parentMap.get(key)) {
+            final Fragment fragment;
+
+            final AjaxLink<Void> link = new AjaxLink<Void>("link") {
+
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target) {
+                    send(Realms.this, Broadcast.EXACT, new ControlSidebarClick<>(realm, target));
+                }
+            };
+
+            link.add(new Label("name", new PropertyModel<String>(realm, "name")));
+
+            if (parentMap.containsKey(realm.getKey()) && !parentMap.get(realm.getKey()).isEmpty()) {
+                fragment = new Fragment(String.valueOf(realm.getKey()), "withChildren", Realms.this);
+                add(parentMap, realm.getKey(), fragment);
+            } else {
+                fragment = new Fragment(String.valueOf(realm.getKey()), "withoutChildren", Realms.this);
+            }
+
+            fragment.add(link);
+            listItems.add(fragment);
+        }
+    }
+
+    private Map<Long, List<RealmTO>> getParentMap(final List<RealmTO> realms) {
+        final Map<Long, List<RealmTO>> res = new HashMap<>();
+        res.put(0L, new ArrayList<RealmTO>());
+
+        final Map<Long, List<RealmTO>> cache = new HashMap<>();
+
+        for (RealmTO realm : realms) {
+            if (res.containsKey(realm.getParent())) {
+                res.get(realm.getParent()).add(realm);
+
+                final List<RealmTO> children = new ArrayList<>();
+                res.put(realm.getKey(), children);
+
+                if (cache.containsKey(realm.getKey())) {
+                    children.addAll(cache.get(realm.getKey()));
+                    cache.remove(realm.getKey());
+                }
+            } else if (cache.containsKey(realm.getParent())) {
+                cache.get(realm.getParent()).add(realm);
+            } else {
+                final List<RealmTO> children = new ArrayList<>();
+                children.add(realm);
+                cache.put(realm.getParent(), children);
+            }
+        }
+
+        return res;
+    }
+
+    private static class RealmNameComparator implements Comparator<RealmTO>, Serializable {
+
+        private static final long serialVersionUID = 7085057398406518811L;
+
+        @Override
+        public int compare(final RealmTO r1, final RealmTO r2) {
+            return r1.getName().compareTo(r2.getName());
+        }
+    }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        super.onEvent(event);
+
+        if (event.getPayload() instanceof ControlSidebarClick) {
+            @SuppressWarnings("unchecked")
+            final ControlSidebarClick<RealmTO> controlSidebarClick = ControlSidebarClick.class.cast(event.getPayload());
+            content.addOrReplace(new Label("header", controlSidebarClick.getObj().getName()));
+            content.addOrReplace(new Realm("body", controlSidebarClick.getObj()));
+            controlSidebarClick.getTarget().add(content);
+        }
+    }
+
+    private static class ControlSidebarClick<T> {
+
+        private final AjaxRequestTarget target;
+
+        private final T obj;
+
+        public ControlSidebarClick(
+                final T obj, final AjaxRequestTarget target) {
+            this.obj = obj;
+            this.target = target;
+        }
+
+        public T getObj() {
+            return obj;
+        }
+
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
new file mode 100644
index 0000000..aa9dbfc
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.AnnotatedBeanPanel;
+import org.apache.syncope.client.console.panels.ResourceConnConfPanel;
+import org.apache.syncope.client.console.panels.ResourceDetailsPanel;
+import org.apache.syncope.client.console.panels.ResourceMappingPanel;
+import org.apache.syncope.client.console.panels.ResourceSecurityPanel;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.ResourceModel;
+
+/**
+ * Modal window with Resource form.
+ */
+public class ResourceModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = 1734415311027284221L;
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public ResourceModalPage(final PageReference pageRef, final ModalWindow window, final ResourceTO resourceTO,
+            final boolean createFlag) {
+
+        super();
+
+        final Form<ResourceTO> form = new Form<>(FORM);
+        form.setModel(new CompoundPropertyModel<>(resourceTO));
+
+        //--------------------------------
+        // Resource details panel
+        //--------------------------------
+        form.add(new ResourceDetailsPanel("details", resourceTO,
+                resourceRestClient.getPropagationActionsClasses(), createFlag));
+
+        form.add(new AnnotatedBeanPanel("systeminformation", resourceTO));
+        //--------------------------------
+
+        //--------------------------------
+        // Resource mapping panels
+        //--------------------------------
+        form.add(new ResourceMappingPanel("umapping", resourceTO, AttributableType.USER));
+        form.add(new ResourceMappingPanel("gmapping", resourceTO, AttributableType.GROUP));
+        //--------------------------------
+
+        //--------------------------------
+        // Resource connector configuration panel
+        //--------------------------------
+        ResourceConnConfPanel resourceConnConfPanel = new ResourceConnConfPanel("connconf", resourceTO, createFlag);
+        MetaDataRoleAuthorizationStrategy.authorize(resourceConnConfPanel, ENABLE, Entitlement.CONNECTOR_READ);
+        form.add(resourceConnConfPanel);
+        //--------------------------------
+
+        //--------------------------------
+        // Resource security panel
+        //--------------------------------
+        form.add(new ResourceSecurityPanel("security", resourceTO));
+        //--------------------------------
+
+        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                final ResourceTO resourceTO = (ResourceTO) form.getDefaultModelObject();
+
+                boolean accountIdError = false;
+
+                if (resourceTO.getUmapping() == null || resourceTO.getUmapping().getItems().isEmpty()) {
+                    resourceTO.setUmapping(null);
+                } else {
+                    int uAccountIdCount = 0;
+                    for (MappingItemTO item : resourceTO.getUmapping().getItems()) {
+                        if (item.isAccountid()) {
+                            uAccountIdCount++;
+                        }
+                    }
+                    accountIdError = uAccountIdCount != 1;
+                }
+
+                if (resourceTO.getGmapping() == null || resourceTO.getGmapping().getItems().isEmpty()) {
+                    resourceTO.setGmapping(null);
+                } else {
+                    int rAccountIdCount = 0;
+                    for (MappingItemTO item : resourceTO.getGmapping().getItems()) {
+                        if (item.isAccountid()) {
+                            rAccountIdCount++;
+                        }
+                    }
+                    accountIdError |= rAccountIdCount != 1;
+                }
+
+                if (accountIdError) {
+                    error(getString("accountIdValidation"));
+                    feedbackPanel.refresh(target);
+                } else {
+                    try {
+                        if (createFlag) {
+                            resourceRestClient.create(resourceTO);
+                        } else {
+                            resourceRestClient.update(resourceTO);
+                        }
+
+                        if (pageRef != null && pageRef.getPage() instanceof AbstractBasePage) {
+                            ((AbstractBasePage) pageRef.getPage()).setModalResult(true);
+                        }
+                        window.close(target);
+                    } catch (Exception e) {
+                        LOG.error("Failure managing resource {}", resourceTO, e);
+                        error(getString(Constants.ERROR) + ": " + e.getMessage());
+                        feedbackPanel.refresh(target);
+                    }
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+
+        form.add(submit);
+        form.setDefaultButton(submit);
+
+        final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                window.close(target);
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+            }
+        };
+
+        cancel.setDefaultFormProcessing(false);
+        form.add(cancel);
+
+        add(form);
+
+        MetaDataRoleAuthorizationStrategy.authorize(
+                submit, ENABLE, createFlag ? Entitlement.RESOURCE_CREATE : Entitlement.RESOURCE_UPDATE);
+    }
+
+    /**
+     * Generic resource event.
+     */
+    public static class ResourceEvent {
+
+        /**
+         * Request target.
+         */
+        private final AjaxRequestTarget target;
+
+        /**
+         * Constructor.
+         *
+         * @param target request target.
+         */
+        public ResourceEvent(final AjaxRequestTarget target) {
+            this.target = target;
+        }
+
+        /**
+         * Target getter.
+         *
+         * @return request target.
+         */
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+    }
+}


[04/27] syncope git commit: [SYNCOPE-156] providing basic layout for realms and administration pages

Posted by il...@apache.org.
[SYNCOPE-156] providing basic layout for realms and administration pages


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

Branch: refs/heads/SYNCOPE-666
Commit: 4759d035f7ff8cb176493d292031429a9ef2afad
Parents: 7f2c8a4
Author: fmartelli <fa...@gmail.com>
Authored: Tue May 12 18:30:28 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Tue May 12 18:30:28 2015 +0200

----------------------------------------------------------------------
 .../syncope/client/console/pages/BasePage.java  |    4 +
 .../syncope/client/console/pages/Realms.java    |   30 +
 .../META-INF/resources/css/AdminLTE.css         |  602 ++-
 .../resources/css/AdminLTE_skins/_all-skins.css | 1203 +++++-
 .../resources/css/AdminLTE_skins/skin-black.css |   66 +-
 .../resources/css/AdminLTE_skins/skin-blue.css  |   32 +-
 .../resources/css/AdminLTE_skins/skin-green.css |   27 +-
 .../css/AdminLTE_skins/skin-purple.css          |   27 +-
 .../resources/css/AdminLTE_skins/skin-red.css   |   27 +-
 .../css/AdminLTE_skins/skin-yellow.css          |   27 +-
 .../META-INF/resources/css/console.css          | 4066 ++++++++++++++++++
 .../META-INF/resources/css/syncopeConsole.css   |   47 +
 .../META-INF/resources/js/AdminLTE-app.min.js   |    4 +-
 .../syncope/client/console/pages/BasePage.html  |    9 +-
 .../syncope/client/console/pages/Realms.html    |  112 +
 15 files changed, 5849 insertions(+), 434 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index 7855813..71a9c7f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -88,6 +88,10 @@ public class BasePage extends AbstractBasePage implements IAjaxIndicatorAware {
         MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, Entitlement.WORKFLOW_DEF_READ);
         liContainer.add(link);
 
+        liContainer = new WebMarkupContainer(getLIContainerId("realms"));
+        add(liContainer);
+        liContainer.add(new BookmarkablePageLink<>("realms", Realms.class));
+        
         add(new BookmarkablePageLink<Page>("logout", Logout.class));
 
         // set 'active' menu item

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/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
new file mode 100644
index 0000000..6ff73f4
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -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.
+ */
+package org.apache.syncope.client.console.pages;
+
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+public class Realms extends BasePage {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    public Realms(final PageParameters parameters) {
+        super(parameters);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE.css
index 06c5bc5..147a648 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE.css
@@ -1,6 +1,6 @@
-@import url(//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);
+@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);
 /*!
- *   AdminLTE v2.0.4
+ *   AdminLTE v2.1.0
  *   Author: Almsaeed Studio
  *	 Website: Almsaeed Studio <http://almsaeedstudio.com>
  *   License: Open source - MIT
@@ -29,8 +29,8 @@ body {
 /* Layout */
 .wrapper {
   min-height: 100%;
-  position: static;
-  overflow: hidden;
+  position: relative;
+  overflow: hidden!important;
 }
 .wrapper:before,
 .wrapper:after {
@@ -51,19 +51,16 @@ body {
   background: url('../img/boxed-bg.jpg') repeat fixed;
 }
 /*
- * Content Wrapper - contins main content
+ * Content Wrapper - contains the main content
  * ```.right-side has been deprecated as of v2.0.0 in favor of .content-wrapper  ```
  */
 .content-wrapper,
 .right-side,
 .main-footer {
-  -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -moz-transition: -moz-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: -o-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -webkit-transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: margin-left 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: -webkit-transform 0.3s ease-in-out, margin 0.3s ease-in-out;
+  -moz-transition: -moz-transform 0.3s ease-in-out, margin 0.3s ease-in-out;
+  -o-transition: -o-transform 0.3s ease-in-out, margin 0.3s ease-in-out;
+  transition: transform 0.3s ease-in-out, margin 0.3s ease-in-out;
   margin-left: 230px;
   z-index: 820;
 }
@@ -106,7 +103,7 @@ body {
   background: #fff;
   padding: 15px;
   color: #444;
-  border-top: 1px solid #eee;
+  border-top: 1px solid #d2d6de;
 }
 /* Fixed layout */
 .fixed .main-header,
@@ -187,6 +184,9 @@ a:focus {
   z-index: 1030;
 }
 .main-header > .navbar {
+  -webkit-transition: margin-left 0.3s ease-in-out;
+  -o-transition: margin-left 0.3s ease-in-out;
+  transition: margin-left 0.3s ease-in-out;
   margin-bottom: 0;
   margin-left: 230px;
   border: none;
@@ -217,7 +217,6 @@ a:focus {
 }
 .main-header .navbar-custom-menu,
 .main-header .navbar-right {
-  margin-right: 5px;
   float: right;
 }
 @media (max-width: 991px) {
@@ -252,6 +251,10 @@ a:focus {
 .main-header .sidebar-toggle:hover {
   color: #fff;
 }
+.main-header .sidebar-toggle:focus,
+.main-header .sidebar-toggle:active {
+  background: transparent;
+}
 .main-header .sidebar-toggle .icon-bar {
   display: none;
 }
@@ -270,6 +273,9 @@ a:focus {
   line-height: .9;
 }
 .main-header .logo {
+  -webkit-transition: width 0.3s ease-in-out;
+  -o-transition: width 0.3s ease-in-out;
+  transition: width 0.3s ease-in-out;
   display: block;
   float: left;
   height: 50px;
@@ -280,6 +286,13 @@ a:focus {
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   padding: 0 15px;
   font-weight: 300;
+  overflow: hidden;
+}
+.main-header .logo .logo-lg {
+  display: block;
+}
+.main-header .logo .logo-mini {
+  display: none;
 }
 .main-header .navbar-brand {
   color: #fff;
@@ -378,6 +391,17 @@ a:focus {
     padding-top: 100px!important;
   }
 }
+@media (max-width: 991px) {
+  .navbar-collapse.pull-left {
+    float: none!important;
+  }
+  .navbar-collapse.pull-left + .navbar-custom-menu {
+    display: block;
+    position: absolute;
+    top: 0;
+    right: 40px;
+  }
+}
 /*
  * Component: Sidebar
  * ------------------
@@ -391,10 +415,10 @@ a:focus {
   min-height: 100%;
   width: 230px;
   z-index: 810;
-  -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -moz-transition: -moz-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: -o-transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: transform 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: -webkit-transform 0.3s ease-in-out, width 0.3s ease-in-out;
+  -moz-transition: -moz-transform 0.3s ease-in-out, width 0.3s ease-in-out;
+  -o-transition: -o-transform 0.3s ease-in-out, width 0.3s ease-in-out;
+  transition: transform 0.3s ease-in-out, width 0.3s ease-in-out;
 }
 @media (max-width: 767px) {
   .main-sidebar,
@@ -426,15 +450,14 @@ a:focus {
 .sidebar {
   padding-bottom: 10px;
 }
-.fixed .sidebar {
-  overflow: auto;
-  height: 100%;
-}
 .sidebar-form input:focus {
   border-color: transparent!important;
 }
 .user-panel {
+  position: relative;
+  width: 100%;
   padding: 10px;
+  overflow: hidden;
 }
 .user-panel:before,
 .user-panel:after {
@@ -445,16 +468,18 @@ a:focus {
   clear: both;
 }
 .user-panel > .image > img {
-  width: 45px;
-  height: 45px;
+  width: 100%;
+  max-width: 45px;
+  height: auto;
 }
 .user-panel > .info {
-  font-weight: 600;
   padding: 5px 5px 5px 15px;
-  font-size: 14px;
   line-height: 1;
+  position: absolute;
+  left: 55px;
 }
 .user-panel > .info > p {
+  font-weight: 600;
   margin-bottom: 9px;
 }
 .user-panel > .info > a {
@@ -462,7 +487,6 @@ a:focus {
   padding-right: 5px;
   margin-top: 3px;
   font-size: 11px;
-  font-weight: normal;
 }
 .user-panel > .info > a > .fa,
 .user-panel > .info > a > .ion,
@@ -541,12 +565,331 @@ a:focus {
   width: auto;
 }
 /*
+ * Component: Sidebar Mini
+ */
+@media (min-width: 768px) {
+  .sidebar-mini.sidebar-collapse .content-wrapper,
+  .sidebar-mini.sidebar-collapse .right-side,
+  .sidebar-mini.sidebar-collapse .main-footer {
+    margin-left: 50px!important;
+    z-index: 840;
+  }
+  .sidebar-mini.sidebar-collapse .main-sidebar {
+    -webkit-transform: translate(0, 0);
+    -ms-transform: translate(0, 0);
+    -o-transform: translate(0, 0);
+    transform: translate(0, 0);
+    width: 50px!important;
+    z-index: 850;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li {
+    position: relative;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li > a {
+    margin-right: 0;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > span {
+    border-top-right-radius: 4px;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li:not(.treeview) > a > span {
+    border-bottom-right-radius: 4px;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
+    padding-top: 5px;
+    padding-bottom: 5px;
+    border-bottom-right-radius: 4px;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right),
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
+    display: block!important;
+    position: absolute;
+    width: 180px;
+    left: 50px;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span {
+    top: 0;
+    margin-left: -3px;
+    padding: 12px 5px 12px 20px;
+    background-color: inherit;
+  }
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
+    top: 44px;
+    margin-left: 0;
+  }
+  .sidebar-mini.sidebar-collapse .main-sidebar .user-panel > .info,
+  .sidebar-mini.sidebar-collapse .sidebar-form,
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > span,
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu,
+  .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > .pull-right,
+  .sidebar-mini.sidebar-collapse .sidebar-menu li.header {
+    display: none!important;
+  }
+  .sidebar-mini.sidebar-collapse .main-header .logo {
+    width: 50px;
+  }
+  .sidebar-mini.sidebar-collapse .main-header .logo > .logo-mini {
+    display: block;
+    margin-left: -15px;
+    margin-right: -15px;
+    font-size: 18px;
+  }
+  .sidebar-mini.sidebar-collapse .main-header .logo > .logo-lg {
+    display: none;
+  }
+  .sidebar-mini.sidebar-collapse .main-header .navbar {
+    margin-left: 50px;
+  }
+}
+.sidebar-menu,
+.main-sidebar .user-panel,
+.sidebar-menu > li.header {
+  white-space: nowrap!important;
+  overflow: hidden;
+}
+.sidebar-menu:hover {
+  overflow: visible;
+}
+.sidebar-form,
+.sidebar-menu > li.header {
+  overflow: hidden;
+  text-overflow: clip;
+}
+.sidebar-menu li > a {
+  position: relative;
+}
+.sidebar-menu li > a > .pull-right {
+  position: absolute;
+  top: 50%;
+  right: 10px;
+  margin-top: -7px;
+}
+/*
+ * Component: Control sidebar. By default, this is the right sidebar.
+ */
+.control-sidebar-bg {
+  position: fixed;
+  z-index: 1000;
+  bottom: 0;
+}
+.control-sidebar-bg,
+.control-sidebar {
+  top: 0;
+  right: -230px;
+  width: 230px;
+  -webkit-transition: right 0.3s ease-in-out;
+  -o-transition: right 0.3s ease-in-out;
+  transition: right 0.3s ease-in-out;
+}
+.control-sidebar {
+  position: absolute;
+  padding-top: 50px;
+  z-index: 1010;
+}
+@media (max-width: 768px) {
+  .control-sidebar {
+    padding-top: 100px;
+  }
+}
+.control-sidebar > .tab-content {
+  padding: 10px 15px;
+}
+.control-sidebar.control-sidebar-open,
+.control-sidebar.control-sidebar-open + .control-sidebar-bg {
+  right: 0;
+}
+.control-sidebar-open .control-sidebar-bg,
+.control-sidebar-open .control-sidebar {
+  right: 0;
+}
+@media (min-width: 768px) {
+  .control-sidebar-open .content-wrapper,
+  .control-sidebar-open .right-side,
+  .control-sidebar-open .main-footer {
+    margin-right: 230px;
+  }
+}
+.control-sidebar-tabs > li:first-of-type > a {
+  margin-left: 1px;
+}
+.control-sidebar-tabs > li:first-of-type > a,
+.control-sidebar-tabs > li:first-of-type > a:hover {
+  border-left-width: 0!important;
+}
+.control-sidebar-tabs > li > a {
+  border-radius: 0 !important;
+}
+.control-sidebar-tabs > li > a,
+.control-sidebar-tabs > li > a:hover {
+  border-top: none;
+  border-right: none;
+  border-left: 1px solid transparent!important;
+  border-bottom: 1px solid transparent!important;
+}
+.control-sidebar-tabs > li > a .icon {
+  font-size: 16px;
+}
+.control-sidebar-tabs > li.active > a,
+.control-sidebar-tabs > li.active > a:hover,
+.control-sidebar-tabs > li.active > a:focus,
+.control-sidebar-tabs > li.active > a:active {
+  border-top: none!important;
+  border-right: none!important;
+  border-bottom: none!important;
+}
+@media (max-width: 768px) {
+  .control-sidebar-tabs {
+    display: table;
+  }
+  .control-sidebar-tabs > li {
+    display: table-cell !important;
+  }
+}
+.control-sidebar-heading {
+  font-weight: 400;
+  font-size: 16px;
+  padding: 10px 0;
+  margin-bottom: 10px;
+}
+.control-sidebar-subheading {
+  display: block;
+  font-weight: 400;
+  font-size: 14px;
+}
+.control-sidebar-menu {
+  list-style: none;
+  padding: 0;
+  margin: 0 -15px;
+}
+.control-sidebar-menu > li > a {
+  display: block;
+  padding: 10px 15px;
+}
+.control-sidebar-menu > li > a:before,
+.control-sidebar-menu > li > a:after {
+  content: " ";
+  display: table;
+}
+.control-sidebar-menu > li > a:after {
+  clear: both;
+}
+.control-sidebar-menu > li > a > .control-sidebar-subheading {
+  margin-top: 0;
+}
+.control-sidebar-menu .menu-icon {
+  float: left;
+  width: 35px;
+  height: 35px;
+  border-radius: 50%;
+  text-align: center;
+  line-height: 35px;
+}
+.control-sidebar-menu .menu-info {
+  margin-left: 45px;
+  margin-top: 3px;
+}
+.control-sidebar-menu .menu-info > .control-sidebar-subheading {
+  margin: 0;
+}
+.control-sidebar-menu .menu-info > p {
+  margin: 0;
+  font-size: 11px;
+}
+.control-sidebar-menu .progress {
+  margin: 0;
+}
+.control-sidebar-dark {
+  color: #b8c7ce;
+}
+.control-sidebar-dark,
+.control-sidebar-dark + .control-sidebar-bg {
+  background: #222d32;
+}
+.control-sidebar-dark .control-sidebar-tabs {
+  border-bottom: #1c2529;
+}
+.control-sidebar-dark .control-sidebar-tabs > li > a {
+  background: #181f23;
+  color: #b8c7ce;
+}
+.control-sidebar-dark .control-sidebar-tabs > li > a,
+.control-sidebar-dark .control-sidebar-tabs > li > a:hover {
+  border-left-color: #141a1d !important;
+  border-bottom-color: #141a1d !important;
+}
+.control-sidebar-dark .control-sidebar-tabs > li > a:hover,
+.control-sidebar-dark .control-sidebar-tabs > li > a:focus,
+.control-sidebar-dark .control-sidebar-tabs > li > a:active {
+  background: #1c2529;
+}
+.control-sidebar-dark .control-sidebar-tabs > li.active > a,
+.control-sidebar-dark .control-sidebar-tabs > li.active > a:hover,
+.control-sidebar-dark .control-sidebar-tabs > li.active > a:focus,
+.control-sidebar-dark .control-sidebar-tabs > li.active > a:active {
+  background: #222d32;
+  color: #fff;
+}
+.control-sidebar-dark .control-sidebar-heading,
+.control-sidebar-dark .control-sidebar-subheading {
+  color: #fff;
+}
+.control-sidebar-dark .control-sidebar-menu > li > a:hover {
+  background: #1e282c;
+}
+.control-sidebar-dark .control-sidebar-menu > li > a .menu-info > p {
+  color: #b8c7ce;
+}
+.control-sidebar-light {
+  color: #5e5e5e;
+}
+.control-sidebar-light,
+.control-sidebar-light + .control-sidebar-bg {
+  background: #f9fafc;
+  border-left: 1px solid #d2d6de;
+}
+.control-sidebar-light .control-sidebar-tabs {
+  border-bottom: #d2d6de;
+}
+.control-sidebar-light .control-sidebar-tabs > li > a {
+  background: #e8ecf4;
+  color: #444444;
+}
+.control-sidebar-light .control-sidebar-tabs > li > a,
+.control-sidebar-light .control-sidebar-tabs > li > a:hover {
+  border-left-color: #d2d6de !important;
+  border-bottom-color: #d2d6de !important;
+}
+.control-sidebar-light .control-sidebar-tabs > li > a:hover,
+.control-sidebar-light .control-sidebar-tabs > li > a:focus,
+.control-sidebar-light .control-sidebar-tabs > li > a:active {
+  background: #eff1f7;
+}
+.control-sidebar-light .control-sidebar-tabs > li.active > a,
+.control-sidebar-light .control-sidebar-tabs > li.active > a:hover,
+.control-sidebar-light .control-sidebar-tabs > li.active > a:focus,
+.control-sidebar-light .control-sidebar-tabs > li.active > a:active {
+  background: #f9fafc;
+  color: #111;
+}
+.control-sidebar-light .control-sidebar-heading,
+.control-sidebar-light .control-sidebar-subheading {
+  color: #111;
+}
+.control-sidebar-light .control-sidebar-menu {
+  margin-left: -14px;
+}
+.control-sidebar-light .control-sidebar-menu > li > a:hover {
+  background: #f4f4f5;
+}
+.control-sidebar-light .control-sidebar-menu > li > a .menu-info > p {
+  color: #5e5e5e;
+}
+/*
  * Component: Dropdown menus
  * -------------------------
  */
 /*Dropdowns in general*/
 .dropdown-menu {
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  box-shadow: none;
   border-color: #eee;
 }
 .dropdown-menu > li > a {
@@ -564,10 +907,10 @@ a:focus {
 .dropdown-menu > .divider {
   background-color: #eee;
 }
-/*
-    Navbar custom dropdown menu
-------------------------------------
-*/
+.navbar-nav .dropdown-menu {
+  -webkit-box-shadow: none !important;
+  box-shadow: none !important;
+}
 .navbar-nav > .notifications-menu,
 .navbar-nav > .messages-menu,
 .navbar-nav > .tasks-menu {
@@ -831,23 +1174,23 @@ a:focus {
 }
 @-webkit-keyframes flipInX {
   0% {
-    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-    transition-timing-function: ease-in;
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+    -webkit-transition-timing-function: ease-in;
     opacity: 0;
   }
   40% {
-    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-    transition-timing-function: ease-in;
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+    -webkit-transition-timing-function: ease-in;
   }
   60% {
-    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
     opacity: 1;
   }
   80% {
-    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
   }
   100% {
-    transform: perspective(400px);
+    -webkit-transform: perspective(400px);
   }
 }
 /* Fix dropdown menu in navbars */
@@ -1298,19 +1641,23 @@ a:focus {
   margin-bottom: 0.3em;
 }
 .box > .overlay,
-.box > .loading-img {
+.overlay-wrapper > .overlay,
+.box > .loading-img,
+.overlay-wrapper > .loading-img {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
 }
-.box .overlay {
-  z-index: 1010;
+.box .overlay,
+.overlay-wrapper .overlay {
+  z-index: 50;
   background: rgba(255, 255, 255, 0.7);
   border-radius: 3px;
 }
-.box .overlay > .fa {
+.box .overlay > .fa,
+.overlay-wrapper .overlay > .fa {
   position: absolute;
   top: 50%;
   left: 50%;
@@ -1319,23 +1666,30 @@ a:focus {
   color: #000;
   font-size: 30px;
 }
-.box .overlay.dark {
+.box .overlay.dark,
+.overlay-wrapper .overlay.dark {
   background: rgba(0, 0, 0, 0.5);
 }
-.box-header {
-  color: #444;
-  display: block;
-  padding: 10px;
-  position: relative;
-}
 .box-header:before,
-.box-header:after {
+.box-body:before,
+.box-footer:before,
+.box-header:after,
+.box-body:after,
+.box-footer:after {
   content: " ";
   display: table;
 }
-.box-header:after {
+.box-header:after,
+.box-body:after,
+.box-footer:after {
   clear: both;
 }
+.box-header {
+  color: #444;
+  display: block;
+  padding: 10px;
+  position: relative;
+}
 .box-header.with-border {
   border-bottom: 1px solid #f4f4f4;
 }
@@ -1396,15 +1750,6 @@ a:focus {
 .box-body > .table {
   margin-bottom: 0;
 }
-.box-body > .chart {
-  position: relative;
-  overflow: hidden;
-  width: 100%;
-}
-.box-body > .chart svg,
-.box-body > .chart canvas {
-  width: 100%!important;
-}
 .box-body .fc {
   margin-top: 5px;
 }
@@ -1981,6 +2326,12 @@ a:focus {
  * Component: Nav
  * --------------
  */
+.nav > li > a:hover,
+.nav > li > a:active,
+.nav > li > a:focus {
+  color: #444;
+  background: #f7f7f7;
+}
 /* NAV PILLS */
 .nav-pills > li > a {
   border-radius: 0;
@@ -1993,17 +2344,13 @@ a:focus {
   margin-right: 5px;
 }
 .nav-pills > li.active > a,
-.nav-pills > li.active > a:hover {
-  background-color: #f4f4f4;
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
   border-top-color: #3c8dbc;
-  color: #444;
 }
 .nav-pills > li.active > a {
   font-weight: 600;
 }
-.nav-pills > li > a:hover {
-  background-color: #f6f6f6;
-}
 /* NAV STACKED */
 .nav-stacked > li > a {
   border-radius: 0;
@@ -2013,10 +2360,8 @@ a:focus {
 }
 .nav-stacked > li.active > a,
 .nav-stacked > li.active > a:hover {
-  background-color: #f4f4f4;
   border-top: 0;
   border-left-color: #3c8dbc;
-  color: #444;
 }
 .nav-stacked > li.header {
   border-bottom: 1px solid #ddd;
@@ -2044,6 +2389,7 @@ a:focus {
   margin-right: 5px;
 }
 .nav-tabs-custom > .nav-tabs > li > a {
+  color: #444;
   border-radius: 0 !important;
 }
 .nav-tabs-custom > .nav-tabs > li > a,
@@ -2051,6 +2397,9 @@ a:focus {
   background: transparent;
   margin: 0;
 }
+.nav-tabs-custom > .nav-tabs > li > a:hover {
+  color: #999;
+}
 .nav-tabs-custom > .nav-tabs > li:not(.active) > a:hover,
 .nav-tabs-custom > .nav-tabs > li:not(.active) > a:focus,
 .nav-tabs-custom > .nav-tabs > li:not(.active) > a:active {
@@ -2062,9 +2411,10 @@ a:focus {
 .nav-tabs-custom > .nav-tabs > li.active > a,
 .nav-tabs-custom > .nav-tabs > li.active:hover > a {
   background-color: #fff;
+  color: #444;
 }
 .nav-tabs-custom > .nav-tabs > li.active > a {
-  border-top: 0;
+  border-top-color: transparent;
   border-left-color: #f4f4f4;
   border-right-color: #f4f4f4;
 }
@@ -2072,7 +2422,7 @@ a:focus {
   margin-left: 0;
 }
 .nav-tabs-custom > .nav-tabs > li:first-of-type.active > a {
-  border-left-width: 0;
+  border-left-color: transparent;
 }
 .nav-tabs-custom > .nav-tabs.pull-right {
   float: none!important;
@@ -2083,9 +2433,12 @@ a:focus {
 .nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type {
   margin-right: 0;
 }
-.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a {
+.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type > a {
   border-left-width: 1px;
-  border-right-width: 0;
+}
+.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a {
+  border-left-color: #f4f4f4;
+  border-right-color: transparent;
 }
 .nav-tabs-custom > .nav-tabs > li.header {
   line-height: 35px;
@@ -2104,21 +2457,16 @@ a:focus {
   border-bottom-right-radius: 3px;
   border-bottom-left-radius: 3px;
 }
-/* Nav tabs bottom */
-.tabs-bottom.nav-3 li a {
-  width: 3333.33333333% !important;
-}
-.tabs-bottom li a {
-  border: 0;
+.nav-tabs-custom .dropdown.open > a:active,
+.nav-tabs-custom .dropdown.open > a:focus {
+  background: transparent;
+  color: #999;
 }
 /* PAGINATION */
 .pagination > li > a {
   background: #fafafa;
   color: #666;
-}
-.pagination > li:first-of-type a,
-.pagination > li:last-of-type a {
-  border-radius: 0;
+  border-radius: 0 !important;
 }
 /*
  * Component: Products List
@@ -2346,10 +2694,10 @@ table.text-center th {
   transform: translate(0, 0);
 }
 .direct-chat-contacts {
-  -webkit-transform: translate(100%, 0);
-  -ms-transform: translate(100%, 0);
-  -o-transform: translate(100%, 0);
-  transform: translate(100%, 0);
+  -webkit-transform: translate(101%, 0);
+  -ms-transform: translate(101%, 0);
+  -o-transform: translate(101%, 0);
+  transform: translate(101%, 0);
   position: absolute;
   top: 0;
   bottom: 0;
@@ -2456,11 +2804,15 @@ table.text-center th {
   padding: 10px;
   text-align: center;
 }
-.users-list > li > img {
+.users-list > li img {
   border-radius: 50%;
   max-width: 100%;
   height: auto;
 }
+.users-list > li > a:hover,
+.users-list > li > a:hover .users-list-name {
+  color: #999;
+}
 .users-list-name,
 .users-list-date {
   display: block;
@@ -2472,9 +2824,6 @@ table.text-center th {
   white-space: nowrap;
   text-overflow: ellipsis;
 }
-.users-list-name:hover {
-  color: #999;
-}
 .users-list-date {
   color: #999;
   font-size: 12px;
@@ -2608,52 +2957,6 @@ table.text-center th {
   max-width: 100%;
   height: auto;
 }
-.mailbox .table-mailbox {
-  border-left: 1px solid #f4f4f4;
-  border-right: 1px solid #f4f4f4;
-  border-bottom: 1px solid #f4f4f4;
-}
-.mailbox .table-mailbox tr.unread > td {
-  background-color: rgba(0, 0, 0, 0.05);
-  color: #000;
-  font-weight: 600;
-}
-.mailbox .table-mailbox tr > td > .fa.fa-star,
-.mailbox .table-mailbox tr > td > .fa.fa-star-o,
-.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star,
-.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star-empty {
-  color: #f39c12;
-  cursor: pointer;
-}
-.mailbox .table-mailbox tr > td.small-col {
-  width: 30px;
-}
-.mailbox .table-mailbox tr > td.name {
-  width: 150px;
-  font-weight: 600;
-}
-.mailbox .table-mailbox tr > td.time {
-  text-align: right;
-  width: 100px;
-}
-.mailbox .table-mailbox tr > td {
-  white-space: nowrap;
-}
-.mailbox .table-mailbox tr > td > a {
-  color: #444;
-}
-@media (max-width: 991px) {
-  .mailbox .nav-stacked > li:not(.header) {
-    float: left;
-    width: 50%;
-  }
-  .mailbox .nav-stacked > li:not(.header).header {
-    border: 0!important;
-  }
-  .mailbox .search-form {
-    margin-top: 10px;
-  }
-}
 /*
  * Page: Lock Screen
  * -----------------
@@ -3581,7 +3884,6 @@ fieldset[disabled] .btn-vk.active {
  * General: Miscellaneous
  * ----------------------
  */
-/* 10px padding and margins */
 .pad {
   padding: 10px;
 }
@@ -3591,12 +3893,10 @@ fieldset[disabled] .btn-vk.active {
 .margin-bottom {
   margin-bottom: 20px;
 }
-/* Display inline */
 .inline {
   display: inline;
   width: auto;
 }
-/* Description Blocks */
 .description-block {
   display: block;
   margin: 10px 0;
@@ -3614,7 +3914,6 @@ fieldset[disabled] .btn-vk.active {
 .description-block > .description-text {
   text-transform: uppercase;
 }
-/* Background colors */
 .bg-red,
 .bg-yellow,
 .bg-aqua,
@@ -3807,7 +4106,6 @@ fieldset[disabled] .btn-vk.active {
   opacity: 0.65;
   filter: alpha(opacity=65);
 }
-/* Text colors */
 .text-red {
   color: #dd4b39 !important;
 }
@@ -3856,27 +4154,21 @@ fieldset[disabled] .btn-vk.active {
 .text-maroon {
   color: #d81b60 !important;
 }
-/*Hide elements by display none only*/
 .hide {
   display: none !important;
 }
-/* Remove borders */
 .no-border {
   border: 0px !important;
 }
-/* Remove padding */
 .no-padding {
   padding: 0px !important;
 }
-/* Remove margins */
 .no-margin {
   margin: 0px !important;
 }
-/* Remove box shadow */
 .no-shadow {
   box-shadow: none!important;
 }
-/* Unstyled List */
 .list-unstyled,
 .chart-legend,
 .contacts-list,
@@ -3886,7 +4178,6 @@ fieldset[disabled] .btn-vk.active {
   margin: 0;
   padding: 0;
 }
-/* Remove border radius */
 .flat {
   border-radius: 0 !important;
 }
@@ -3895,15 +4186,11 @@ fieldset[disabled] .btn-vk.active {
 .text-bold.table th {
   font-weight: 700;
 }
-/* _fix for sparkline tooltip */
 .jqstooltip {
   padding: 5px!important;
   width: auto!important;
   height: auto!important;
 }
-/*
-Gradient Background colors
-*/
 .bg-teal-gradient {
   background: #39cccc !important;
   background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;
@@ -4020,6 +4307,15 @@ Gradient Background colors
   opacity: 1;
   filter: alpha(opacity=100);
 }
+.chart {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+}
+.chart svg,
+.chart canvas {
+  width: 100%!important;
+}
 /*
  * Misc: print
  * -----------

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/_all-skins.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/_all-skins.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/_all-skins.css
index 0571afd..0548915 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/_all-skins.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/_all-skins.css
@@ -17,9 +17,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-blue .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-blue .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -49,11 +46,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-blue .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-blue .main-header .logo:hover {
-  background: #357ca5;
+  background-color: #357ca5;
 }
 .skin-blue .main-header li.user-header {
   background-color: #3c8dbc;
@@ -61,6 +55,11 @@
 .skin-blue .content-header {
   background: transparent;
 }
+.skin-blue .wrapper,
+.skin-blue .main-sidebar,
+.skin-blue .left-side {
+  background-color: #222d32;
+}
 .skin-blue .user-panel > .info,
 .skin-blue .user-panel > .info > a {
   color: #fff;
@@ -71,9 +70,8 @@
 }
 .skin-blue .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-blue .sidebar-menu > li > a:hover,
+.skin-blue .sidebar-menu > li:hover > a,
 .skin-blue .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -83,11 +81,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-blue .wrapper,
-.skin-blue .main-sidebar,
-.skin-blue .left-side {
-  background: #222d32;
-}
 .skin-blue .sidebar a {
   color: #b8c7ce;
 }
@@ -112,9 +105,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-blue .sidebar-form input[type="text"] {
   color: #666;
@@ -143,11 +136,174 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-blue.layout-top-nav .main-header > .logo > a {
+.skin-blue.layout-top-nav .main-header > .logo:hover {
+  background-color: #3b8ab8;
+}
+/*
+ * Skin: Blue
+ * ----------
+ */
+.skin-blue-light .main-header .navbar {
+  background-color: #3c8dbc;
+}
+.skin-blue-light .main-header .navbar .nav > li > a {
+  color: #ffffff;
+}
+.skin-blue-light .main-header .navbar .nav > li > a:hover,
+.skin-blue-light .main-header .navbar .nav > li > a:active,
+.skin-blue-light .main-header .navbar .nav > li > a:focus,
+.skin-blue-light .main-header .navbar .nav .open > a,
+.skin-blue-light .main-header .navbar .nav .open > a:hover,
+.skin-blue-light .main-header .navbar .nav .open > a:focus {
+  background: rgba(0, 0, 0, 0.1);
+  color: #f6f6f6;
+}
+.skin-blue-light .main-header .navbar .sidebar-toggle {
+  color: #ffffff;
+}
+.skin-blue-light .main-header .navbar .sidebar-toggle:hover {
+  color: #f6f6f6;
+  background: rgba(0, 0, 0, 0.1);
+}
+.skin-blue-light .main-header .navbar .sidebar-toggle {
+  color: #fff;
+}
+.skin-blue-light .main-header .navbar .sidebar-toggle:hover {
+  background-color: #367fa9;
+}
+@media (max-width: 767px) {
+  .skin-blue-light .main-header .navbar .dropdown-menu li.divider {
+    background-color: rgba(255, 255, 255, 0.1);
+  }
+  .skin-blue-light .main-header .navbar .dropdown-menu li a {
+    color: #fff;
+  }
+  .skin-blue-light .main-header .navbar .dropdown-menu li a:hover {
+    background: #367fa9;
+  }
+}
+.skin-blue-light .main-header .logo {
+  background-color: #3c8dbc;
+  color: #ffffff;
+  border-bottom: 0px solid transparent;
+}
+.skin-blue-light .main-header .logo:hover {
+  background-color: #3b8ab8;
+}
+.skin-blue-light .main-header li.user-header {
+  background-color: #3c8dbc;
+}
+.skin-blue-light .content-header {
+  background: transparent;
+}
+.skin-blue-light .wrapper,
+.skin-blue-light .main-sidebar,
+.skin-blue-light .left-side {
+  background-color: #f9fafc;
+}
+.skin-blue-light .content-wrapper,
+.skin-blue-light .main-footer {
+  border-left: 1px solid #d2d6de;
+}
+.skin-blue-light .user-panel > .info,
+.skin-blue-light .user-panel > .info > a {
+  color: #444444;
+}
+.skin-blue-light .sidebar-menu > li {
+  -webkit-transition: border-left-color 0.3s ease;
+  -o-transition: border-left-color 0.3s ease;
+  transition: border-left-color 0.3s ease;
+}
+.skin-blue-light .sidebar-menu > li.header {
+  color: #848484;
+  background: #f9fafc;
+}
+.skin-blue-light .sidebar-menu > li > a {
+  border-left: 3px solid transparent;
+  font-weight: 600;
+}
+.skin-blue-light .sidebar-menu > li:hover > a,
+.skin-blue-light .sidebar-menu > li.active > a {
+  color: #000000;
+  background: #f4f4f5;
+}
+.skin-blue-light .sidebar-menu > li.active {
+  border-left-color: #3c8dbc;
+}
+.skin-blue-light .sidebar-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-blue-light .sidebar-menu > li > .treeview-menu {
+  background: #f4f4f5;
+}
+.skin-blue-light .sidebar a {
+  color: #444444;
+}
+.skin-blue-light .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-blue-light .treeview-menu > li > a {
+  color: #777777;
+}
+.skin-blue-light .treeview-menu > li.active > a,
+.skin-blue-light .treeview-menu > li > a:hover {
+  color: #000000;
+}
+.skin-blue-light .treeview-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-blue-light .sidebar-form {
+  border-radius: 3px;
+  border: 1px solid #d2d6de;
+  margin: 10px 10px;
+}
+.skin-blue-light .sidebar-form input[type="text"],
+.skin-blue-light .sidebar-form .btn {
+  box-shadow: none;
+  background-color: #fff;
+  border: 1px solid transparent;
+  height: 35px;
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
+}
+.skin-blue-light .sidebar-form input[type="text"] {
+  color: #666;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-blue-light .sidebar-form input[type="text"]:focus,
+.skin-blue-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #fff;
+  color: #666;
+}
+.skin-blue-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left-color: #fff;
+}
+.skin-blue-light .sidebar-form .btn {
+  color: #999;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+}
+@media (min-width: 768px) {
+  .skin-blue-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
+    border-left: 1px solid #d2d6de;
+  }
+}
+.skin-blue-light .main-footer {
+  border-top-color: #d2d6de;
+}
+.skin-blue.layout-top-nav .main-header > .logo {
+  background-color: #3c8dbc;
   color: #ffffff;
+  border-bottom: 0px solid transparent;
 }
 .skin-blue.layout-top-nav .main-header > .logo:hover {
-  background: #3b8ab8;
+  background-color: #3b8ab8;
 }
 /*
  * Skin: Black
@@ -180,9 +336,6 @@
   background: #ffffff;
   color: #999999;
 }
-.skin-black .main-header > .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-black .main-header > .navbar .sidebar-toggle {
   color: #333333;
 }
@@ -208,11 +361,8 @@
   border-bottom: 0px solid transparent;
   border-right: 1px solid #eee;
 }
-.skin-black .main-header > .logo > a {
-  color: #333333;
-}
 .skin-black .main-header > .logo:hover {
-  background: #fcfcfc;
+  background-color: #fcfcfc;
 }
 @media (max-width: 767px) {
   .skin-black .main-header > .logo {
@@ -221,11 +371,8 @@
     border-bottom: 0px solid transparent;
     border-right: none;
   }
-  .skin-black .main-header > .logo > a {
-    color: #ffffff;
-  }
   .skin-black .main-header > .logo:hover {
-    background: #1f1f1f;
+    background-color: #1f1f1f;
   }
 }
 .skin-black .main-header li.user-header {
@@ -235,62 +382,59 @@
   background: transparent;
   box-shadow: none;
 }
-.skin-black .user-panel > .image > img {
-  border: 1px solid #444;
+.skin-black .wrapper,
+.skin-black .main-sidebar,
+.skin-black .left-side {
+  background-color: #222d32;
 }
 .skin-black .user-panel > .info,
 .skin-black .user-panel > .info > a {
-  color: #eee;
-}
-.skin-black .main-sidebar,
-.skin-black .left-side,
-.skin-black .wrapper {
-  background: #222;
+  color: #fff;
 }
-.skin-black .sidebar > .sidebar-menu > li.header {
-  background: #1d1d1d;
-  color: rgba(255, 255, 255, 0.4);
+.skin-black .sidebar-menu > li.header {
+  color: #4b646f;
+  background: #1a2226;
 }
-.skin-black .sidebar > .sidebar-menu > li > a {
-  margin-right: 1px;
+.skin-black .sidebar-menu > li > a {
   border-left: 3px solid transparent;
 }
-.skin-black .sidebar > .sidebar-menu > li > a:hover,
-.skin-black .sidebar > .sidebar-menu > li.active > a {
-  color: #fff;
-  background: #444;
-  border-left-color: #fff;
+.skin-black .sidebar-menu > li:hover > a,
+.skin-black .sidebar-menu > li.active > a {
+  color: #ffffff;
+  background: #1e282c;
+  border-left-color: #ffffff;
 }
-.skin-black .sidebar > .sidebar-menu > li > .treeview-menu {
-  background: #333;
+.skin-black .sidebar-menu > li > .treeview-menu {
+  margin: 0 1px;
+  background: #2c3b41;
 }
 .skin-black .sidebar a {
-  color: #eee;
+  color: #b8c7ce;
 }
 .skin-black .sidebar a:hover {
   text-decoration: none;
 }
 .skin-black .treeview-menu > li > a {
-  color: #ccc;
+  color: #8aa4af;
 }
 .skin-black .treeview-menu > li.active > a,
 .skin-black .treeview-menu > li > a:hover {
-  color: #fff;
+  color: #ffffff;
 }
 .skin-black .sidebar-form {
   border-radius: 3px;
-  border: 1px solid #3c3c3c;
+  border: 1px solid #374850;
   margin: 10px 10px;
 }
 .skin-black .sidebar-form input[type="text"],
 .skin-black .sidebar-form .btn {
   box-shadow: none;
-  background-color: #3c3c3c;
+  background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-black .sidebar-form input[type="text"] {
   color: #666;
@@ -315,6 +459,181 @@
   border-bottom-left-radius: 0 !important;
 }
 /*
+ * Skin: Black
+ * -----------
+ */
+/* skin-black navbar */
+.skin-black-light .main-header {
+  -webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
+  box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
+}
+.skin-black-light .main-header .navbar-toggle {
+  color: #333;
+}
+.skin-black-light .main-header .navbar-brand {
+  color: #333;
+  border-right: 1px solid #eee;
+}
+.skin-black-light .main-header > .navbar {
+  background-color: #ffffff;
+}
+.skin-black-light .main-header > .navbar .nav > li > a {
+  color: #333333;
+}
+.skin-black-light .main-header > .navbar .nav > li > a:hover,
+.skin-black-light .main-header > .navbar .nav > li > a:active,
+.skin-black-light .main-header > .navbar .nav > li > a:focus,
+.skin-black-light .main-header > .navbar .nav .open > a,
+.skin-black-light .main-header > .navbar .nav .open > a:hover,
+.skin-black-light .main-header > .navbar .nav .open > a:focus {
+  background: #ffffff;
+  color: #999999;
+}
+.skin-black-light .main-header > .navbar .sidebar-toggle {
+  color: #333333;
+}
+.skin-black-light .main-header > .navbar .sidebar-toggle:hover {
+  color: #999999;
+  background: #ffffff;
+}
+.skin-black-light .main-header > .navbar > .sidebar-toggle {
+  color: #333;
+  border-right: 1px solid #eee;
+}
+.skin-black-light .main-header > .navbar .navbar-nav > li > a {
+  border-right: 1px solid #eee;
+}
+.skin-black-light .main-header > .navbar .navbar-custom-menu .navbar-nav > li > a,
+.skin-black-light .main-header > .navbar .navbar-right > li > a {
+  border-left: 1px solid #eee;
+  border-right-width: 0;
+}
+.skin-black-light .main-header > .logo {
+  background-color: #ffffff;
+  color: #333333;
+  border-bottom: 0px solid transparent;
+  border-right: 1px solid #eee;
+}
+.skin-black-light .main-header > .logo:hover {
+  background-color: #fcfcfc;
+}
+@media (max-width: 767px) {
+  .skin-black-light .main-header > .logo {
+    background-color: #222222;
+    color: #ffffff;
+    border-bottom: 0px solid transparent;
+    border-right: none;
+  }
+  .skin-black-light .main-header > .logo:hover {
+    background-color: #1f1f1f;
+  }
+}
+.skin-black-light .main-header li.user-header {
+  background-color: #222;
+}
+.skin-black-light .content-header {
+  background: transparent;
+  box-shadow: none;
+}
+.skin-black-light .wrapper,
+.skin-black-light .main-sidebar,
+.skin-black-light .left-side {
+  background-color: #f9fafc;
+}
+.skin-black-light .content-wrapper,
+.skin-black-light .main-footer {
+  border-left: 1px solid #d2d6de;
+}
+.skin-black-light .user-panel > .info,
+.skin-black-light .user-panel > .info > a {
+  color: #444444;
+}
+.skin-black-light .sidebar-menu > li {
+  -webkit-transition: border-left-color 0.3s ease;
+  -o-transition: border-left-color 0.3s ease;
+  transition: border-left-color 0.3s ease;
+}
+.skin-black-light .sidebar-menu > li.header {
+  color: #848484;
+  background: #f9fafc;
+}
+.skin-black-light .sidebar-menu > li > a {
+  border-left: 3px solid transparent;
+  font-weight: 600;
+}
+.skin-black-light .sidebar-menu > li:hover > a,
+.skin-black-light .sidebar-menu > li.active > a {
+  color: #000000;
+  background: #f4f4f5;
+}
+.skin-black-light .sidebar-menu > li.active {
+  border-left-color: #ffffff;
+}
+.skin-black-light .sidebar-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-black-light .sidebar-menu > li > .treeview-menu {
+  background: #f4f4f5;
+}
+.skin-black-light .sidebar a {
+  color: #444444;
+}
+.skin-black-light .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-black-light .treeview-menu > li > a {
+  color: #777777;
+}
+.skin-black-light .treeview-menu > li.active > a,
+.skin-black-light .treeview-menu > li > a:hover {
+  color: #000000;
+}
+.skin-black-light .treeview-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-black-light .sidebar-form {
+  border-radius: 3px;
+  border: 1px solid #d2d6de;
+  margin: 10px 10px;
+}
+.skin-black-light .sidebar-form input[type="text"],
+.skin-black-light .sidebar-form .btn {
+  box-shadow: none;
+  background-color: #fff;
+  border: 1px solid transparent;
+  height: 35px;
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
+}
+.skin-black-light .sidebar-form input[type="text"] {
+  color: #666;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-black-light .sidebar-form input[type="text"]:focus,
+.skin-black-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #fff;
+  color: #666;
+}
+.skin-black-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left-color: #fff;
+}
+.skin-black-light .sidebar-form .btn {
+  color: #999;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+}
+@media (min-width: 768px) {
+  .skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
+    border-left: 1px solid #d2d6de;
+  }
+}
+/*
  * Skin: Green
  * -----------
  */
@@ -333,9 +652,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-green .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-green .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -365,11 +681,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-green .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-green .main-header .logo:hover {
-  background: #008749;
+  background-color: #008749;
 }
 .skin-green .main-header li.user-header {
   background-color: #00a65a;
@@ -377,6 +690,11 @@
 .skin-green .content-header {
   background: transparent;
 }
+.skin-green .wrapper,
+.skin-green .main-sidebar,
+.skin-green .left-side {
+  background-color: #222d32;
+}
 .skin-green .user-panel > .info,
 .skin-green .user-panel > .info > a {
   color: #fff;
@@ -387,9 +705,8 @@
 }
 .skin-green .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-green .sidebar-menu > li > a:hover,
+.skin-green .sidebar-menu > li:hover > a,
 .skin-green .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -399,11 +716,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-green .wrapper,
-.skin-green .main-sidebar,
-.skin-green .left-side {
-  background: #222d32;
-}
 .skin-green .sidebar a {
   color: #b8c7ce;
 }
@@ -428,9 +740,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-green .sidebar-form input[type="text"] {
   color: #666;
@@ -455,61 +767,210 @@
   border-bottom-left-radius: 0 !important;
 }
 /*
- * Skin: Red
- * ---------
+ * Skin: Green
+ * -----------
  */
-.skin-red .main-header .navbar {
-  background-color: #dd4b39;
+.skin-green-light .main-header .navbar {
+  background-color: #00a65a;
 }
-.skin-red .main-header .navbar .nav > li > a {
+.skin-green-light .main-header .navbar .nav > li > a {
   color: #ffffff;
 }
-.skin-red .main-header .navbar .nav > li > a:hover,
-.skin-red .main-header .navbar .nav > li > a:active,
-.skin-red .main-header .navbar .nav > li > a:focus,
-.skin-red .main-header .navbar .nav .open > a,
-.skin-red .main-header .navbar .nav .open > a:hover,
-.skin-red .main-header .navbar .nav .open > a:focus {
+.skin-green-light .main-header .navbar .nav > li > a:hover,
+.skin-green-light .main-header .navbar .nav > li > a:active,
+.skin-green-light .main-header .navbar .nav > li > a:focus,
+.skin-green-light .main-header .navbar .nav .open > a,
+.skin-green-light .main-header .navbar .nav .open > a:hover,
+.skin-green-light .main-header .navbar .nav .open > a:focus {
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-red .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
-.skin-red .main-header .navbar .sidebar-toggle {
+.skin-green-light .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
-.skin-red .main-header .navbar .sidebar-toggle:hover {
+.skin-green-light .main-header .navbar .sidebar-toggle:hover {
   color: #f6f6f6;
   background: rgba(0, 0, 0, 0.1);
 }
-.skin-red .main-header .navbar .sidebar-toggle {
+.skin-green-light .main-header .navbar .sidebar-toggle {
   color: #fff;
 }
-.skin-red .main-header .navbar .sidebar-toggle:hover {
-  background-color: #d73925;
+.skin-green-light .main-header .navbar .sidebar-toggle:hover {
+  background-color: #008d4c;
 }
 @media (max-width: 767px) {
-  .skin-red .main-header .navbar .dropdown-menu li.divider {
+  .skin-green-light .main-header .navbar .dropdown-menu li.divider {
     background-color: rgba(255, 255, 255, 0.1);
   }
-  .skin-red .main-header .navbar .dropdown-menu li a {
+  .skin-green-light .main-header .navbar .dropdown-menu li a {
     color: #fff;
   }
-  .skin-red .main-header .navbar .dropdown-menu li a:hover {
-    background: #d73925;
+  .skin-green-light .main-header .navbar .dropdown-menu li a:hover {
+    background: #008d4c;
   }
 }
-.skin-red .main-header .logo {
-  background-color: #d73925;
+.skin-green-light .main-header .logo {
+  background-color: #00a65a;
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-red .main-header .logo > a {
+.skin-green-light .main-header .logo:hover {
+  background-color: #00a157;
+}
+.skin-green-light .main-header li.user-header {
+  background-color: #00a65a;
+}
+.skin-green-light .content-header {
+  background: transparent;
+}
+.skin-green-light .wrapper,
+.skin-green-light .main-sidebar,
+.skin-green-light .left-side {
+  background-color: #f9fafc;
+}
+.skin-green-light .content-wrapper,
+.skin-green-light .main-footer {
+  border-left: 1px solid #d2d6de;
+}
+.skin-green-light .user-panel > .info,
+.skin-green-light .user-panel > .info > a {
+  color: #444444;
+}
+.skin-green-light .sidebar-menu > li {
+  -webkit-transition: border-left-color 0.3s ease;
+  -o-transition: border-left-color 0.3s ease;
+  transition: border-left-color 0.3s ease;
+}
+.skin-green-light .sidebar-menu > li.header {
+  color: #848484;
+  background: #f9fafc;
+}
+.skin-green-light .sidebar-menu > li > a {
+  border-left: 3px solid transparent;
+  font-weight: 600;
+}
+.skin-green-light .sidebar-menu > li:hover > a,
+.skin-green-light .sidebar-menu > li.active > a {
+  color: #000000;
+  background: #f4f4f5;
+}
+.skin-green-light .sidebar-menu > li.active {
+  border-left-color: #00a65a;
+}
+.skin-green-light .sidebar-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-green-light .sidebar-menu > li > .treeview-menu {
+  background: #f4f4f5;
+}
+.skin-green-light .sidebar a {
+  color: #444444;
+}
+.skin-green-light .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-green-light .treeview-menu > li > a {
+  color: #777777;
+}
+.skin-green-light .treeview-menu > li.active > a,
+.skin-green-light .treeview-menu > li > a:hover {
+  color: #000000;
+}
+.skin-green-light .treeview-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-green-light .sidebar-form {
+  border-radius: 3px;
+  border: 1px solid #d2d6de;
+  margin: 10px 10px;
+}
+.skin-green-light .sidebar-form input[type="text"],
+.skin-green-light .sidebar-form .btn {
+  box-shadow: none;
+  background-color: #fff;
+  border: 1px solid transparent;
+  height: 35px;
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
+}
+.skin-green-light .sidebar-form input[type="text"] {
+  color: #666;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-green-light .sidebar-form input[type="text"]:focus,
+.skin-green-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #fff;
+  color: #666;
+}
+.skin-green-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left-color: #fff;
+}
+.skin-green-light .sidebar-form .btn {
+  color: #999;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+}
+@media (min-width: 768px) {
+  .skin-green-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
+    border-left: 1px solid #d2d6de;
+  }
+}
+/*
+ * Skin: Red
+ * ---------
+ */
+.skin-red .main-header .navbar {
+  background-color: #dd4b39;
+}
+.skin-red .main-header .navbar .nav > li > a {
   color: #ffffff;
 }
+.skin-red .main-header .navbar .nav > li > a:hover,
+.skin-red .main-header .navbar .nav > li > a:active,
+.skin-red .main-header .navbar .nav > li > a:focus,
+.skin-red .main-header .navbar .nav .open > a,
+.skin-red .main-header .navbar .nav .open > a:hover,
+.skin-red .main-header .navbar .nav .open > a:focus {
+  background: rgba(0, 0, 0, 0.1);
+  color: #f6f6f6;
+}
+.skin-red .main-header .navbar .sidebar-toggle {
+  color: #ffffff;
+}
+.skin-red .main-header .navbar .sidebar-toggle:hover {
+  color: #f6f6f6;
+  background: rgba(0, 0, 0, 0.1);
+}
+.skin-red .main-header .navbar .sidebar-toggle {
+  color: #fff;
+}
+.skin-red .main-header .navbar .sidebar-toggle:hover {
+  background-color: #d73925;
+}
+@media (max-width: 767px) {
+  .skin-red .main-header .navbar .dropdown-menu li.divider {
+    background-color: rgba(255, 255, 255, 0.1);
+  }
+  .skin-red .main-header .navbar .dropdown-menu li a {
+    color: #fff;
+  }
+  .skin-red .main-header .navbar .dropdown-menu li a:hover {
+    background: #d73925;
+  }
+}
+.skin-red .main-header .logo {
+  background-color: #d73925;
+  color: #ffffff;
+  border-bottom: 0px solid transparent;
+}
 .skin-red .main-header .logo:hover {
-  background: #d33724;
+  background-color: #d33724;
 }
 .skin-red .main-header li.user-header {
   background-color: #dd4b39;
@@ -517,6 +978,11 @@
 .skin-red .content-header {
   background: transparent;
 }
+.skin-red .wrapper,
+.skin-red .main-sidebar,
+.skin-red .left-side {
+  background-color: #222d32;
+}
 .skin-red .user-panel > .info,
 .skin-red .user-panel > .info > a {
   color: #fff;
@@ -527,9 +993,8 @@
 }
 .skin-red .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-red .sidebar-menu > li > a:hover,
+.skin-red .sidebar-menu > li:hover > a,
 .skin-red .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -539,11 +1004,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-red .wrapper,
-.skin-red .main-sidebar,
-.skin-red .left-side {
-  background: #222d32;
-}
 .skin-red .sidebar a {
   color: #b8c7ce;
 }
@@ -568,9 +1028,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-red .sidebar-form input[type="text"] {
   color: #666;
@@ -595,6 +1055,161 @@
   border-bottom-left-radius: 0 !important;
 }
 /*
+ * Skin: Red
+ * ---------
+ */
+.skin-red-light .main-header .navbar {
+  background-color: #dd4b39;
+}
+.skin-red-light .main-header .navbar .nav > li > a {
+  color: #ffffff;
+}
+.skin-red-light .main-header .navbar .nav > li > a:hover,
+.skin-red-light .main-header .navbar .nav > li > a:active,
+.skin-red-light .main-header .navbar .nav > li > a:focus,
+.skin-red-light .main-header .navbar .nav .open > a,
+.skin-red-light .main-header .navbar .nav .open > a:hover,
+.skin-red-light .main-header .navbar .nav .open > a:focus {
+  background: rgba(0, 0, 0, 0.1);
+  color: #f6f6f6;
+}
+.skin-red-light .main-header .navbar .sidebar-toggle {
+  color: #ffffff;
+}
+.skin-red-light .main-header .navbar .sidebar-toggle:hover {
+  color: #f6f6f6;
+  background: rgba(0, 0, 0, 0.1);
+}
+.skin-red-light .main-header .navbar .sidebar-toggle {
+  color: #fff;
+}
+.skin-red-light .main-header .navbar .sidebar-toggle:hover {
+  background-color: #d73925;
+}
+@media (max-width: 767px) {
+  .skin-red-light .main-header .navbar .dropdown-menu li.divider {
+    background-color: rgba(255, 255, 255, 0.1);
+  }
+  .skin-red-light .main-header .navbar .dropdown-menu li a {
+    color: #fff;
+  }
+  .skin-red-light .main-header .navbar .dropdown-menu li a:hover {
+    background: #d73925;
+  }
+}
+.skin-red-light .main-header .logo {
+  background-color: #dd4b39;
+  color: #ffffff;
+  border-bottom: 0px solid transparent;
+}
+.skin-red-light .main-header .logo:hover {
+  background-color: #dc4735;
+}
+.skin-red-light .main-header li.user-header {
+  background-color: #dd4b39;
+}
+.skin-red-light .content-header {
+  background: transparent;
+}
+.skin-red-light .wrapper,
+.skin-red-light .main-sidebar,
+.skin-red-light .left-side {
+  background-color: #f9fafc;
+}
+.skin-red-light .content-wrapper,
+.skin-red-light .main-footer {
+  border-left: 1px solid #d2d6de;
+}
+.skin-red-light .user-panel > .info,
+.skin-red-light .user-panel > .info > a {
+  color: #444444;
+}
+.skin-red-light .sidebar-menu > li {
+  -webkit-transition: border-left-color 0.3s ease;
+  -o-transition: border-left-color 0.3s ease;
+  transition: border-left-color 0.3s ease;
+}
+.skin-red-light .sidebar-menu > li.header {
+  color: #848484;
+  background: #f9fafc;
+}
+.skin-red-light .sidebar-menu > li > a {
+  border-left: 3px solid transparent;
+  font-weight: 600;
+}
+.skin-red-light .sidebar-menu > li:hover > a,
+.skin-red-light .sidebar-menu > li.active > a {
+  color: #000000;
+  background: #f4f4f5;
+}
+.skin-red-light .sidebar-menu > li.active {
+  border-left-color: #dd4b39;
+}
+.skin-red-light .sidebar-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-red-light .sidebar-menu > li > .treeview-menu {
+  background: #f4f4f5;
+}
+.skin-red-light .sidebar a {
+  color: #444444;
+}
+.skin-red-light .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-red-light .treeview-menu > li > a {
+  color: #777777;
+}
+.skin-red-light .treeview-menu > li.active > a,
+.skin-red-light .treeview-menu > li > a:hover {
+  color: #000000;
+}
+.skin-red-light .treeview-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-red-light .sidebar-form {
+  border-radius: 3px;
+  border: 1px solid #d2d6de;
+  margin: 10px 10px;
+}
+.skin-red-light .sidebar-form input[type="text"],
+.skin-red-light .sidebar-form .btn {
+  box-shadow: none;
+  background-color: #fff;
+  border: 1px solid transparent;
+  height: 35px;
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
+}
+.skin-red-light .sidebar-form input[type="text"] {
+  color: #666;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-red-light .sidebar-form input[type="text"]:focus,
+.skin-red-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #fff;
+  color: #666;
+}
+.skin-red-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left-color: #fff;
+}
+.skin-red-light .sidebar-form .btn {
+  color: #999;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+}
+@media (min-width: 768px) {
+  .skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
+    border-left: 1px solid #d2d6de;
+  }
+}
+/*
  * Skin: Yellow
  * ------------
  */
@@ -613,9 +1228,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-yellow .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-yellow .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -645,11 +1257,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-yellow .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-yellow .main-header .logo:hover {
-  background: #db8b0b;
+  background-color: #db8b0b;
 }
 .skin-yellow .main-header li.user-header {
   background-color: #f39c12;
@@ -657,6 +1266,11 @@
 .skin-yellow .content-header {
   background: transparent;
 }
+.skin-yellow .wrapper,
+.skin-yellow .main-sidebar,
+.skin-yellow .left-side {
+  background-color: #222d32;
+}
 .skin-yellow .user-panel > .info,
 .skin-yellow .user-panel > .info > a {
   color: #fff;
@@ -667,9 +1281,8 @@
 }
 .skin-yellow .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-yellow .sidebar-menu > li > a:hover,
+.skin-yellow .sidebar-menu > li:hover > a,
 .skin-yellow .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -679,11 +1292,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-yellow .wrapper,
-.skin-yellow .main-sidebar,
-.skin-yellow .left-side {
-  background: #222d32;
-}
 .skin-yellow .sidebar a {
   color: #b8c7ce;
 }
@@ -708,9 +1316,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-yellow .sidebar-form input[type="text"] {
   color: #666;
@@ -735,6 +1343,161 @@
   border-bottom-left-radius: 0 !important;
 }
 /*
+ * Skin: Yellow
+ * ------------
+ */
+.skin-yellow-light .main-header .navbar {
+  background-color: #f39c12;
+}
+.skin-yellow-light .main-header .navbar .nav > li > a {
+  color: #ffffff;
+}
+.skin-yellow-light .main-header .navbar .nav > li > a:hover,
+.skin-yellow-light .main-header .navbar .nav > li > a:active,
+.skin-yellow-light .main-header .navbar .nav > li > a:focus,
+.skin-yellow-light .main-header .navbar .nav .open > a,
+.skin-yellow-light .main-header .navbar .nav .open > a:hover,
+.skin-yellow-light .main-header .navbar .nav .open > a:focus {
+  background: rgba(0, 0, 0, 0.1);
+  color: #f6f6f6;
+}
+.skin-yellow-light .main-header .navbar .sidebar-toggle {
+  color: #ffffff;
+}
+.skin-yellow-light .main-header .navbar .sidebar-toggle:hover {
+  color: #f6f6f6;
+  background: rgba(0, 0, 0, 0.1);
+}
+.skin-yellow-light .main-header .navbar .sidebar-toggle {
+  color: #fff;
+}
+.skin-yellow-light .main-header .navbar .sidebar-toggle:hover {
+  background-color: #e08e0b;
+}
+@media (max-width: 767px) {
+  .skin-yellow-light .main-header .navbar .dropdown-menu li.divider {
+    background-color: rgba(255, 255, 255, 0.1);
+  }
+  .skin-yellow-light .main-header .navbar .dropdown-menu li a {
+    color: #fff;
+  }
+  .skin-yellow-light .main-header .navbar .dropdown-menu li a:hover {
+    background: #e08e0b;
+  }
+}
+.skin-yellow-light .main-header .logo {
+  background-color: #f39c12;
+  color: #ffffff;
+  border-bottom: 0px solid transparent;
+}
+.skin-yellow-light .main-header .logo:hover {
+  background-color: #f39a0d;
+}
+.skin-yellow-light .main-header li.user-header {
+  background-color: #f39c12;
+}
+.skin-yellow-light .content-header {
+  background: transparent;
+}
+.skin-yellow-light .wrapper,
+.skin-yellow-light .main-sidebar,
+.skin-yellow-light .left-side {
+  background-color: #f9fafc;
+}
+.skin-yellow-light .content-wrapper,
+.skin-yellow-light .main-footer {
+  border-left: 1px solid #d2d6de;
+}
+.skin-yellow-light .user-panel > .info,
+.skin-yellow-light .user-panel > .info > a {
+  color: #444444;
+}
+.skin-yellow-light .sidebar-menu > li {
+  -webkit-transition: border-left-color 0.3s ease;
+  -o-transition: border-left-color 0.3s ease;
+  transition: border-left-color 0.3s ease;
+}
+.skin-yellow-light .sidebar-menu > li.header {
+  color: #848484;
+  background: #f9fafc;
+}
+.skin-yellow-light .sidebar-menu > li > a {
+  border-left: 3px solid transparent;
+  font-weight: 600;
+}
+.skin-yellow-light .sidebar-menu > li:hover > a,
+.skin-yellow-light .sidebar-menu > li.active > a {
+  color: #000000;
+  background: #f4f4f5;
+}
+.skin-yellow-light .sidebar-menu > li.active {
+  border-left-color: #f39c12;
+}
+.skin-yellow-light .sidebar-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-yellow-light .sidebar-menu > li > .treeview-menu {
+  background: #f4f4f5;
+}
+.skin-yellow-light .sidebar a {
+  color: #444444;
+}
+.skin-yellow-light .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-yellow-light .treeview-menu > li > a {
+  color: #777777;
+}
+.skin-yellow-light .treeview-menu > li.active > a,
+.skin-yellow-light .treeview-menu > li > a:hover {
+  color: #000000;
+}
+.skin-yellow-light .treeview-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-yellow-light .sidebar-form {
+  border-radius: 3px;
+  border: 1px solid #d2d6de;
+  margin: 10px 10px;
+}
+.skin-yellow-light .sidebar-form input[type="text"],
+.skin-yellow-light .sidebar-form .btn {
+  box-shadow: none;
+  background-color: #fff;
+  border: 1px solid transparent;
+  height: 35px;
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
+}
+.skin-yellow-light .sidebar-form input[type="text"] {
+  color: #666;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-yellow-light .sidebar-form input[type="text"]:focus,
+.skin-yellow-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #fff;
+  color: #666;
+}
+.skin-yellow-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left-color: #fff;
+}
+.skin-yellow-light .sidebar-form .btn {
+  color: #999;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+}
+@media (min-width: 768px) {
+  .skin-yellow-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
+    border-left: 1px solid #d2d6de;
+  }
+}
+/*
  * Skin: Purple
  * ------------
  */
@@ -753,9 +1516,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-purple .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-purple .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -785,11 +1545,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-purple .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-purple .main-header .logo:hover {
-  background: #545096;
+  background-color: #545096;
 }
 .skin-purple .main-header li.user-header {
   background-color: #605ca8;
@@ -797,6 +1554,11 @@
 .skin-purple .content-header {
   background: transparent;
 }
+.skin-purple .wrapper,
+.skin-purple .main-sidebar,
+.skin-purple .left-side {
+  background-color: #222d32;
+}
 .skin-purple .user-panel > .info,
 .skin-purple .user-panel > .info > a {
   color: #fff;
@@ -807,9 +1569,8 @@
 }
 .skin-purple .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-purple .sidebar-menu > li > a:hover,
+.skin-purple .sidebar-menu > li:hover > a,
 .skin-purple .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -819,11 +1580,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-purple .wrapper,
-.skin-purple .main-sidebar,
-.skin-purple .left-side {
-  background: #222d32;
-}
 .skin-purple .sidebar a {
   color: #b8c7ce;
 }
@@ -848,9 +1604,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-purple .sidebar-form input[type="text"] {
   color: #666;
@@ -874,3 +1630,158 @@
   border-bottom-right-radius: 2px !important;
   border-bottom-left-radius: 0 !important;
 }
+/*
+ * Skin: Purple
+ * ------------
+ */
+.skin-purple-light .main-header .navbar {
+  background-color: #605ca8;
+}
+.skin-purple-light .main-header .navbar .nav > li > a {
+  color: #ffffff;
+}
+.skin-purple-light .main-header .navbar .nav > li > a:hover,
+.skin-purple-light .main-header .navbar .nav > li > a:active,
+.skin-purple-light .main-header .navbar .nav > li > a:focus,
+.skin-purple-light .main-header .navbar .nav .open > a,
+.skin-purple-light .main-header .navbar .nav .open > a:hover,
+.skin-purple-light .main-header .navbar .nav .open > a:focus {
+  background: rgba(0, 0, 0, 0.1);
+  color: #f6f6f6;
+}
+.skin-purple-light .main-header .navbar .sidebar-toggle {
+  color: #ffffff;
+}
+.skin-purple-light .main-header .navbar .sidebar-toggle:hover {
+  color: #f6f6f6;
+  background: rgba(0, 0, 0, 0.1);
+}
+.skin-purple-light .main-header .navbar .sidebar-toggle {
+  color: #fff;
+}
+.skin-purple-light .main-header .navbar .sidebar-toggle:hover {
+  background-color: #555299;
+}
+@media (max-width: 767px) {
+  .skin-purple-light .main-header .navbar .dropdown-menu li.divider {
+    background-color: rgba(255, 255, 255, 0.1);
+  }
+  .skin-purple-light .main-header .navbar .dropdown-menu li a {
+    color: #fff;
+  }
+  .skin-purple-light .main-header .navbar .dropdown-menu li a:hover {
+    background: #555299;
+  }
+}
+.skin-purple-light .main-header .logo {
+  background-color: #605ca8;
+  color: #ffffff;
+  border-bottom: 0px solid transparent;
+}
+.skin-purple-light .main-header .logo:hover {
+  background-color: #5d59a6;
+}
+.skin-purple-light .main-header li.user-header {
+  background-color: #605ca8;
+}
+.skin-purple-light .content-header {
+  background: transparent;
+}
+.skin-purple-light .wrapper,
+.skin-purple-light .main-sidebar,
+.skin-purple-light .left-side {
+  background-color: #f9fafc;
+}
+.skin-purple-light .content-wrapper,
+.skin-purple-light .main-footer {
+  border-left: 1px solid #d2d6de;
+}
+.skin-purple-light .user-panel > .info,
+.skin-purple-light .user-panel > .info > a {
+  color: #444444;
+}
+.skin-purple-light .sidebar-menu > li {
+  -webkit-transition: border-left-color 0.3s ease;
+  -o-transition: border-left-color 0.3s ease;
+  transition: border-left-color 0.3s ease;
+}
+.skin-purple-light .sidebar-menu > li.header {
+  color: #848484;
+  background: #f9fafc;
+}
+.skin-purple-light .sidebar-menu > li > a {
+  border-left: 3px solid transparent;
+  font-weight: 600;
+}
+.skin-purple-light .sidebar-menu > li:hover > a,
+.skin-purple-light .sidebar-menu > li.active > a {
+  color: #000000;
+  background: #f4f4f5;
+}
+.skin-purple-light .sidebar-menu > li.active {
+  border-left-color: #605ca8;
+}
+.skin-purple-light .sidebar-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-purple-light .sidebar-menu > li > .treeview-menu {
+  background: #f4f4f5;
+}
+.skin-purple-light .sidebar a {
+  color: #444444;
+}
+.skin-purple-light .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-purple-light .treeview-menu > li > a {
+  color: #777777;
+}
+.skin-purple-light .treeview-menu > li.active > a,
+.skin-purple-light .treeview-menu > li > a:hover {
+  color: #000000;
+}
+.skin-purple-light .treeview-menu > li.active > a {
+  font-weight: 600;
+}
+.skin-purple-light .sidebar-form {
+  border-radius: 3px;
+  border: 1px solid #d2d6de;
+  margin: 10px 10px;
+}
+.skin-purple-light .sidebar-form input[type="text"],
+.skin-purple-light .sidebar-form .btn {
+  box-shadow: none;
+  background-color: #fff;
+  border: 1px solid transparent;
+  height: 35px;
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
+}
+.skin-purple-light .sidebar-form input[type="text"] {
+  color: #666;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-purple-light .sidebar-form input[type="text"]:focus,
+.skin-purple-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #fff;
+  color: #666;
+}
+.skin-purple-light .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left-color: #fff;
+}
+.skin-purple-light .sidebar-form .btn {
+  color: #999;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+}
+@media (min-width: 768px) {
+  .skin-purple-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {
+    border-left: 1px solid #d2d6de;
+  }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-black.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-black.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-black.css
index 9dab529..721f9ac 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-black.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-black.css
@@ -29,9 +29,6 @@
   background: #ffffff;
   color: #999999;
 }
-.skin-black .main-header > .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-black .main-header > .navbar .sidebar-toggle {
   color: #333333;
 }
@@ -57,11 +54,8 @@
   border-bottom: 0px solid transparent;
   border-right: 1px solid #eee;
 }
-.skin-black .main-header > .logo > a {
-  color: #333333;
-}
 .skin-black .main-header > .logo:hover {
-  background: #fcfcfc;
+  background-color: #fcfcfc;
 }
 @media (max-width: 767px) {
   .skin-black .main-header > .logo {
@@ -70,11 +64,8 @@
     border-bottom: 0px solid transparent;
     border-right: none;
   }
-  .skin-black .main-header > .logo > a {
-    color: #ffffff;
-  }
   .skin-black .main-header > .logo:hover {
-    background: #1f1f1f;
+    background-color: #1f1f1f;
   }
 }
 .skin-black .main-header li.user-header {
@@ -84,62 +75,59 @@
   background: transparent;
   box-shadow: none;
 }
-.skin-black .user-panel > .image > img {
-  border: 1px solid #444;
+.skin-black .wrapper,
+.skin-black .main-sidebar,
+.skin-black .left-side {
+  background-color: #222d32;
 }
 .skin-black .user-panel > .info,
 .skin-black .user-panel > .info > a {
-  color: #eee;
-}
-.skin-black .main-sidebar,
-.skin-black .left-side,
-.skin-black .wrapper {
-  background: #222;
+  color: #fff;
 }
-.skin-black .sidebar > .sidebar-menu > li.header {
-  background: #1d1d1d;
-  color: rgba(255, 255, 255, 0.4);
+.skin-black .sidebar-menu > li.header {
+  color: #4b646f;
+  background: #1a2226;
 }
-.skin-black .sidebar > .sidebar-menu > li > a {
-  margin-right: 1px;
+.skin-black .sidebar-menu > li > a {
   border-left: 3px solid transparent;
 }
-.skin-black .sidebar > .sidebar-menu > li > a:hover,
-.skin-black .sidebar > .sidebar-menu > li.active > a {
-  color: #fff;
-  background: #444;
-  border-left-color: #fff;
+.skin-black .sidebar-menu > li:hover > a,
+.skin-black .sidebar-menu > li.active > a {
+  color: #ffffff;
+  background: #1e282c;
+  border-left-color: #ffffff;
 }
-.skin-black .sidebar > .sidebar-menu > li > .treeview-menu {
-  background: #333;
+.skin-black .sidebar-menu > li > .treeview-menu {
+  margin: 0 1px;
+  background: #2c3b41;
 }
 .skin-black .sidebar a {
-  color: #eee;
+  color: #b8c7ce;
 }
 .skin-black .sidebar a:hover {
   text-decoration: none;
 }
 .skin-black .treeview-menu > li > a {
-  color: #ccc;
+  color: #8aa4af;
 }
 .skin-black .treeview-menu > li.active > a,
 .skin-black .treeview-menu > li > a:hover {
-  color: #fff;
+  color: #ffffff;
 }
 .skin-black .sidebar-form {
   border-radius: 3px;
-  border: 1px solid #3c3c3c;
+  border: 1px solid #374850;
   margin: 10px 10px;
 }
 .skin-black .sidebar-form input[type="text"],
 .skin-black .sidebar-form .btn {
   box-shadow: none;
-  background-color: #3c3c3c;
+  background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-black .sidebar-form input[type="text"] {
   color: #666;

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-blue.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-blue.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-blue.css
index db5482c..1c35c35 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-blue.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-blue.css
@@ -17,9 +17,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-blue .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-blue .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -49,11 +46,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-blue .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-blue .main-header .logo:hover {
-  background: #357ca5;
+  background-color: #357ca5;
 }
 .skin-blue .main-header li.user-header {
   background-color: #3c8dbc;
@@ -61,6 +55,11 @@
 .skin-blue .content-header {
   background: transparent;
 }
+.skin-blue .wrapper,
+.skin-blue .main-sidebar,
+.skin-blue .left-side {
+  background-color: #222d32;
+}
 .skin-blue .user-panel > .info,
 .skin-blue .user-panel > .info > a {
   color: #fff;
@@ -71,9 +70,8 @@
 }
 .skin-blue .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-blue .sidebar-menu > li > a:hover,
+.skin-blue .sidebar-menu > li:hover > a,
 .skin-blue .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -83,11 +81,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-blue .wrapper,
-.skin-blue .main-sidebar,
-.skin-blue .left-side {
-  background: #222d32;
-}
 .skin-blue .sidebar a {
   color: #b8c7ce;
 }
@@ -112,9 +105,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-blue .sidebar-form input[type="text"] {
   color: #666;
@@ -143,9 +136,6 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-blue.layout-top-nav .main-header > .logo > a {
-  color: #ffffff;
-}
 .skin-blue.layout-top-nav .main-header > .logo:hover {
-  background: #3b8ab8;
+  background-color: #3b8ab8;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-green.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-green.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-green.css
index 436c6eb..8b712d3 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-green.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-green.css
@@ -17,9 +17,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-green .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-green .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -49,11 +46,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-green .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-green .main-header .logo:hover {
-  background: #008749;
+  background-color: #008749;
 }
 .skin-green .main-header li.user-header {
   background-color: #00a65a;
@@ -61,6 +55,11 @@
 .skin-green .content-header {
   background: transparent;
 }
+.skin-green .wrapper,
+.skin-green .main-sidebar,
+.skin-green .left-side {
+  background-color: #222d32;
+}
 .skin-green .user-panel > .info,
 .skin-green .user-panel > .info > a {
   color: #fff;
@@ -71,9 +70,8 @@
 }
 .skin-green .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-green .sidebar-menu > li > a:hover,
+.skin-green .sidebar-menu > li:hover > a,
 .skin-green .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -83,11 +81,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-green .wrapper,
-.skin-green .main-sidebar,
-.skin-green .left-side {
-  background: #222d32;
-}
 .skin-green .sidebar a {
   color: #b8c7ce;
 }
@@ -112,9 +105,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-green .sidebar-form input[type="text"] {
   color: #666;

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-purple.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-purple.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-purple.css
index af7f88f..b041b2e 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-purple.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-purple.css
@@ -17,9 +17,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-purple .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-purple .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -49,11 +46,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-purple .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-purple .main-header .logo:hover {
-  background: #545096;
+  background-color: #545096;
 }
 .skin-purple .main-header li.user-header {
   background-color: #605ca8;
@@ -61,6 +55,11 @@
 .skin-purple .content-header {
   background: transparent;
 }
+.skin-purple .wrapper,
+.skin-purple .main-sidebar,
+.skin-purple .left-side {
+  background-color: #222d32;
+}
 .skin-purple .user-panel > .info,
 .skin-purple .user-panel > .info > a {
   color: #fff;
@@ -71,9 +70,8 @@
 }
 .skin-purple .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-purple .sidebar-menu > li > a:hover,
+.skin-purple .sidebar-menu > li:hover > a,
 .skin-purple .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -83,11 +81,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-purple .wrapper,
-.skin-purple .main-sidebar,
-.skin-purple .left-side {
-  background: #222d32;
-}
 .skin-purple .sidebar a {
   color: #b8c7ce;
 }
@@ -112,9 +105,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-purple .sidebar-form input[type="text"] {
   color: #666;

http://git-wip-us.apache.org/repos/asf/syncope/blob/4759d035/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-red.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-red.css b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-red.css
index 9f4cd36..cec4548 100644
--- a/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-red.css
+++ b/client/console/src/main/resources/META-INF/resources/css/AdminLTE_skins/skin-red.css
@@ -17,9 +17,6 @@
   background: rgba(0, 0, 0, 0.1);
   color: #f6f6f6;
 }
-.skin-red .main-header .navbar .navbar-custom-menu > .nav {
-  margin-right: 10px;
-}
 .skin-red .main-header .navbar .sidebar-toggle {
   color: #ffffff;
 }
@@ -49,11 +46,8 @@
   color: #ffffff;
   border-bottom: 0px solid transparent;
 }
-.skin-red .main-header .logo > a {
-  color: #ffffff;
-}
 .skin-red .main-header .logo:hover {
-  background: #d33724;
+  background-color: #d33724;
 }
 .skin-red .main-header li.user-header {
   background-color: #dd4b39;
@@ -61,6 +55,11 @@
 .skin-red .content-header {
   background: transparent;
 }
+.skin-red .wrapper,
+.skin-red .main-sidebar,
+.skin-red .left-side {
+  background-color: #222d32;
+}
 .skin-red .user-panel > .info,
 .skin-red .user-panel > .info > a {
   color: #fff;
@@ -71,9 +70,8 @@
 }
 .skin-red .sidebar-menu > li > a {
   border-left: 3px solid transparent;
-  margin-right: 1px;
 }
-.skin-red .sidebar-menu > li > a:hover,
+.skin-red .sidebar-menu > li:hover > a,
 .skin-red .sidebar-menu > li.active > a {
   color: #ffffff;
   background: #1e282c;
@@ -83,11 +81,6 @@
   margin: 0 1px;
   background: #2c3b41;
 }
-.skin-red .wrapper,
-.skin-red .main-sidebar,
-.skin-red .left-side {
-  background: #222d32;
-}
 .skin-red .sidebar a {
   color: #b8c7ce;
 }
@@ -112,9 +105,9 @@
   background-color: #374850;
   border: 1px solid transparent;
   height: 35px;
-  -webkit-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  -o-transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
-  transition: all 0.3s cubic-bezier(0.32, 1.25, 0.375, 1.15);
+  -webkit-transition: all 0.3s ease-in-out;
+  -o-transition: all 0.3s ease-in-out;
+  transition: all 0.3s ease-in-out;
 }
 .skin-red .sidebar-form input[type="text"] {
   color: #666;


[21/27] syncope git commit: Merge from master

Posted by il...@apache.org.
Merge from master


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

Branch: refs/heads/SYNCOPE-666
Commit: 46aaa9e89fa2da3ecc4208f17a4d7d443100d830
Parents: a8a4063 34ec671
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jun 9 08:15:16 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jun 9 08:15:16 2015 +0200

----------------------------------------------------------------------
 client/console/pom.xml                          |   12 +
 .../client/console/SyncopeConsoleSession.java   |    3 +-
 .../console/commons/ActionTableCheckGroup.java  |   40 +
 .../commons/AttributableDataProvider.java       |  103 ++
 .../client/console/commons/JexlHelpUtils.java   |   59 +
 .../client/console/pages/AbstractBasePage.java  |    6 +
 .../console/pages/AbstractStatusModalPage.java  |   30 +
 .../syncope/client/console/pages/BasePage.java  |   11 +-
 .../console/pages/BulkActionModalPage.java      |  166 +++
 .../pages/BulkActionResultModalPage.java        |   99 ++
 .../console/pages/ConnectorModalPage.java       |  477 +++++++
 .../console/pages/ProvisioningModalPage.java    |  253 ++++
 .../syncope/client/console/pages/Realms.java    |  177 +++
 .../client/console/pages/ResourceModalPage.java |  204 +++
 .../panels/AbstractSearchResultPanel.java       |  346 +++++
 .../client/console/panels/AccountPolicy.java    |   35 +
 .../console/panels/ActionDataTablePanel.java    |  145 +++
 .../console/panels/AjaxDataTablePanel.java      |  142 +++
 .../console/panels/AnnotatedBeanPanel.java      |   66 +
 .../syncope/client/console/panels/Any.java      |   35 +
 .../client/console/panels/Connectors.java       |  385 ++++++
 .../client/console/panels/DataTablePanel.java   |  113 ++
 .../client/console/panels/PasswordPolicy.java   |   35 +
 .../syncope/client/console/panels/Realm.java    |   49 +
 .../client/console/panels/RealmDetails.java     |   41 +
 .../console/panels/ResourceConnConfPanel.java   |  189 +++
 .../console/panels/ResourceDetailsPanel.java    |  306 +++++
 .../console/panels/ResourceMappingPanel.java    |  644 ++++++++++
 .../console/panels/ResourceSecurityPanel.java   |  186 +++
 .../client/console/panels/Resources.java        |  485 +++++++
 .../console/rest/ConnectorRestClient.java       |    6 +-
 .../client/console/rest/RealmRestClient.java    |   38 +
 .../client/console/topology/Topology.java       |  521 ++++++++
 .../client/console/topology/TopologyNode.java   |  123 ++
 .../console/topology/TopologyNodePanel.java     |  205 +++
 .../topology/TopologyReloadBehavior.java        |   61 +
 .../markup/html/ClearIndicatingAjaxButton.java  |   76 ++
 .../markup/html/ClearIndicatingAjaxLink.java    |   61 +
 .../repeater/data/table/ActionResultColumn.java |   77 ++
 .../data/table/CheckBoxGroupSelectorPanel.java  |   34 +
 .../html/repeater/data/table/CheckBoxPanel.java |   43 +
 .../repeater/data/table/CheckGroupColumn.java   |   54 +
 .../wicket/markup/html/form/ActionLink.java     |   85 ++
 .../markup/html/form/ActionLinksPanel.java      |  609 +++++++++
 .../markup/html/form/AjaxTextFieldPanel.java    |    4 +-
 .../html/form/IndicatingOnConfirmAjaxLink.java  |   58 +
 .../META-INF/resources/css/AdminLTE.css         |  602 ++++++---
 .../resources/css/AdminLTE_skins/_all-skins.css | 1203 +++++++++++++++---
 .../resources/css/AdminLTE_skins/skin-black.css |   66 +-
 .../resources/css/AdminLTE_skins/skin-blue.css  |   32 +-
 .../resources/css/AdminLTE_skins/skin-green.css |   27 +-
 .../css/AdminLTE_skins/skin-purple.css          |   27 +-
 .../resources/css/AdminLTE_skins/skin-red.css   |   27 +-
 .../css/AdminLTE_skins/skin-yellow.css          |   27 +-
 .../META-INF/resources/css/fieldstyle.css       |  191 +++
 .../META-INF/resources/css/syncopeConsole.css   |  177 ++-
 .../META-INF/resources/css/topology.css         |  160 +++
 .../META-INF/resources/js/AdminLTE-app.min.js   |    4 +-
 .../resources/META-INF/resources/js/topology.js |  244 ++++
 .../console/pages/AbstractStatusModalPage.html  |  122 ++
 .../pages/AbstractStatusModalPage.properties    |   19 +
 .../pages/AbstractStatusModalPage_it.properties |   19 +
 .../AbstractStatusModalPage_pt_BR.properties    |   19 +
 .../client/console/pages/BaseModalPage.html     |   23 +-
 .../syncope/client/console/pages/BasePage.html  |   16 +-
 .../console/pages/BulkActionModalPage.html      |   45 +
 .../pages/BulkActionModalPage.properties        |   17 +
 .../pages/BulkActionModalPage_it.properties     |   17 +
 .../pages/BulkActionModalPage_pt_BR.properties  |   17 +
 .../pages/BulkActionResultModalPage.html        |   57 +
 .../pages/BulkActionResultModalPage.properties  |   19 +
 .../BulkActionResultModalPage_it.properties     |   19 +
 .../BulkActionResultModalPage_pt_BR.properties  |   19 +
 .../console/pages/ConnectorModalPage.html       |  161 +++
 .../console/pages/ConnectorModalPage.properties |   43 +
 .../pages/ConnectorModalPage_it.properties      |   43 +
 .../pages/ConnectorModalPage_pt_BR.properties   |   43 +
 .../syncope/client/console/pages/Realms.html    |   79 ++
 .../client/console/pages/ResourceModalPage.html |   56 +
 .../console/pages/ResourceModalPage.properties  |   60 +
 .../pages/ResourceModalPage_it.properties       |   60 +
 .../pages/ResourceModalPage_pt_BR.properties    |   60 +
 .../panels/AbstractSearchResultPanel.html       |   43 +
 .../panels/AbstractSearchResultPanel.properties |   30 +
 .../AbstractSearchResultPanel_it.properties     |   30 +
 .../AbstractSearchResultPanel_pt_BR.properties  |   30 +
 .../client/console/panels/AccountPolicy.html    |   29 +
 .../console/panels/ActionDataTablePanel.html    |   45 +
 .../console/panels/AjaxDataTablePanel.html      |   47 +
 .../console/panels/AnnotatedBeanPanel.html      |   98 ++
 .../panels/AnnotatedBeanPanel.properties        |   20 +
 .../panels/AnnotatedBeanPanel_it.properties     |   20 +
 .../panels/AnnotatedBeanPanel_pt_BR.properties  |   20 +
 .../syncope/client/console/panels/Any.html      |   29 +
 .../client/console/panels/Connectors.html       |   57 +
 .../client/console/panels/Connectors.properties |   34 +
 .../console/panels/Connectors_it.properties     |   34 +
 .../console/panels/Connectors_pt_BR.properties  |   32 +
 .../client/console/panels/PasswordPolicy.html   |   29 +
 .../syncope/client/console/panels/Realm.html    |   93 ++
 .../client/console/panels/RealmDetails.html     |   45 +
 .../console/panels/ResourceConnConfPanel.html   |   40 +
 .../console/panels/ResourceDetailsPanel.html    |  137 ++
 .../console/panels/ResourceMappingPanel.html    |  114 ++
 .../console/panels/ResourceSecurityPanel.html   |   56 +
 .../panels/ResourceSecurityPanel.properties     |   19 +
 .../panels/ResourceSecurityPanel_it.properties  |   19 +
 .../ResourceSecurityPanel_pt_BR.properties      |   19 +
 .../client/console/panels/Resources.html        |   52 +
 .../client/console/panels/Resources.properties  |   34 +
 .../console/panels/Resources_it.properties      |   34 +
 .../console/panels/Resources_pt_BR.properties   |   32 +
 .../client/console/topology/Topology.html       |   52 +
 .../client/console/topology/Topology.properties |   17 +
 .../console/topology/TopologyNodePanel.html     |   67 +
 .../topology/TopologyNodePanel.properties       |   20 +
 .../topology/TopologyNodePanel_it.properties    |   20 +
 .../topology/TopologyNodePanel_pt_BR.properties |   20 +
 .../console/topology/Topology_it.properties     |   17 +
 .../console/topology/Topology_pt_BR.properties  |   17 +
 .../data/table/CheckBoxGroupSelectorPanel.html  |   21 +
 .../html/repeater/data/table/CheckBoxPanel.html |   23 +
 .../markup/html/form/ActionLinksPanel.html      |  173 +++
 .../markup/html/form/AjaxCheckBoxPanel.html     |   21 +
 .../html/form/AjaxDropDownChoicePanel.html      |   24 +
 .../markup/html/form/AjaxNumberFieldPanel.html  |   22 +
 .../markup/html/form/AjaxPalettePanel.html      |   23 +
 .../html/form/AjaxPasswordFieldPanel.html       |   22 +
 .../markup/html/form/AjaxTextFieldPanel.html    |   23 +
 .../markup/html/form/AjaxTextFieldPanel_1.html  |   23 +
 .../markup/html/form/BinaryFieldPanel.html      |   44 +
 .../form/CheckBoxMultipleChoiceFieldPanel.html  |   23 +
 .../markup/html/form/DateTextFieldPanel.html    |   22 +
 .../markup/html/form/DateTimeFieldPanel.html    |   21 +
 .../html/form/DateTimeFieldPanel.properties     |   17 +
 .../html/form/DateTimeFieldPanel_it.properties  |   17 +
 .../form/DateTimeFieldPanel_pt_BR.properties    |   17 +
 .../wicket/markup/html/form/FieldPanel.html     |   34 +
 .../wicket/markup/html/form/FieldPanel_1.html   |   34 +
 .../wicket/markup/html/form/LinkPanel.html      |   23 +
 .../wicket/markup/html/form/LinkPanel_1.html    |   23 +
 .../markup/html/form/MappingPurposePanel.html   |   31 +
 .../markup/html/form/MultiFieldPanel.html       |   35 +
 .../markup/html/form/MultiFieldPanel.properties |   22 +
 .../html/form/MultiFieldPanel_it.properties     |   22 +
 .../html/form/MultiFieldPanel_pt_BR.properties  |   22 +
 .../wicket/markup/html/form/NonI18nPalette.html |   69 +
 .../markup/html/form/SpinnerFieldPanel.html     |   29 +
 .../rest/api/service/ConnectorService.java      |    1 -
 pom.xml                                         |   13 +
 150 files changed, 12682 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/46aaa9e8/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/syncope/blob/46aaa9e8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --cc common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index c4de80a,76552e6..07fc6a4
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@@ -177,9 -176,8 +177,8 @@@ public interface ConnectorService exten
       */
      @POST
      @Path("check")
-     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
      @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
 -    boolean check(@NotNull ConnInstanceTO connInstanceTO);
 +    BooleanWrap check(@NotNull ConnInstanceTO connInstanceTO);
  
      /**
       * Reload all connector bundles and instances.

http://git-wip-us.apache.org/repos/asf/syncope/blob/46aaa9e8/pom.xml
----------------------------------------------------------------------
diff --cc pom.xml
index 805b59e,fe9519d..9011e8d
--- a/pom.xml
+++ b/pom.xml
@@@ -378,7 -379,8 +379,8 @@@ under the License
      <font-awesome.version>4.3.0</font-awesome.version>
      <ionicons.version>2.0.1</ionicons.version>
      <highlightjs.version>8.4-4</highlightjs.version>
 -    <codemirror.version>5.1</codemirror.version>
 +    <codemirror.version>5.3</codemirror.version>
+     <jsplumb.version>1.6.4</jsplumb.version>
      
      <wicket.version>7.0.0-M5</wicket.version>
      <wicket-jqueryui.version>7.0.0-M5</wicket-jqueryui.version>


[14/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties
new file mode 100644
index 0000000..1591edc
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_pt_BR.properties
@@ -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.
+displayRows=Mostrar linhas
+
+firstname=Nome
+surname=Sobrenome
+userId=Identificador do Usu\u00E1rio
+edit=Alterar
+delete=Excluir
+id=Identificador
+status=Estatus
+token=Token
+username=Nome de Usu\u00E1rio
+creationDate=Data de Cria\u00E7\u00E3o
+tokenValued=Atribu\u00EDdo
+tokenNotValued=N\u00E3o Atribu\u00EDdo

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AccountPolicy.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AccountPolicy.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AccountPolicy.html
new file mode 100644
index 0000000..26a9aae
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AccountPolicy.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
+  <body>
+    <wicket:panel>
+      <h1>Account Policy</h1>
+    </wicket:panel>
+  </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ActionDataTablePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ActionDataTablePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ActionDataTablePanel.html
new file mode 100644
index 0000000..5ad205f
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ActionDataTablePanel.html
@@ -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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <link rel="stylesheet" type="text/css" href="css/bulk.css" media="all"/>
+  </wicket:head>
+  <wicket:panel>
+
+    <form wicket:id="groupForm">
+      <span wicket:id="checkgroup">
+        <table class="ui-widget ui-widget-content table-hover" wicket:id="dataTable">[Data Table]</table>
+      </span>
+
+      <div id="actionRow" class="pageRowElement">
+        <div id="actions">
+          <div id="actionPanel"  wicket:id="actionPanelContainer" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+            <span wicket:id="actions">[Actions]</span>
+          </div>
+
+          <div id="cancelBtmForm">
+            <input type="button" wicket:id="cancel" id="cancel"
+                   class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"/>
+          </div>
+        </div>
+      </div>
+    </form>
+
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AjaxDataTablePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AjaxDataTablePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AjaxDataTablePanel.html
new file mode 100644
index 0000000..f67ba10
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AjaxDataTablePanel.html
@@ -0,0 +1,47 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <link rel="stylesheet" type="text/css" href="css/bulk.css" media="all"/>
+  </wicket:head>
+  <wicket:panel>
+    <span wicket:id="tablePanel">[Table panel]</span>
+    <div wicket:id="bulkModal" />
+
+    <wicket:fragment wicket:id="bulkAvailable">
+      <form wicket:id="groupForm">
+        <span wicket:id="checkgroup">
+          <table class="ui-widget ui-widget-content table-hover" wicket:id="dataTable">[DataTable]</table>
+        </span>
+      </form>
+      <div class="bulkAction">
+        <div class="bulkActionCell" style="width: 40px">
+          <a href="#" wicket:id="bulkActionLink">
+            <img src="img/actions/bulk.png" alt="bulk action icon"  title="Bulk action"/>
+          </a>
+        </div>
+      </div>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="bulkNotAvailable">
+      <table class="ui-widget ui-widget-content table-hover" wicket:id="dataTable">[DataTable]</table>
+    </wicket:fragment>
+
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.html
new file mode 100644
index 0000000..4d459ce
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.html
@@ -0,0 +1,98 @@
+<!--
+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>
+  <wicket:head>
+    <style>
+      div.information{
+        margin-top: 30px; 
+        border: 1px solid #DDDDDD; 
+        font-size: 8px;
+        color: #555555;
+        display: inline-table; 
+        width: 100%; 
+        clear: both; 
+        float:none;
+      }
+
+      div.infolabel{
+        margin-left: 5px; 
+        float:left; 
+        width: 150px;
+        font-weight: bold
+      }
+
+      div.infoleft{
+        float:left; 
+        display: inline-table; 
+        width: 50%
+      }
+
+      div.inforight{ 
+        display: inline-table; 
+        width: 50%
+      }
+
+      div.inforow{
+        display: inline-table;
+        width: 100%
+      }
+    </style>
+  </wicket:head>
+  <wicket:panel>
+    <div class="information">
+      <div class="infoleft">
+        <div class="infolabel"> 
+          <wicket:message key="creationDate"/>:
+        </div>
+        <div>
+          <span wicket:id="creationDate" />
+        </div>
+      </div>
+
+      <div class="inforight">
+        <div class="infolabel">
+          <wicket:message key="lastChangeDate"/>:
+        </div>
+        <div>
+          <span wicket:id="lastChangeDate" />
+        </div>
+      </div>
+
+      <div class="infoleft">
+        <div class="infolabel">
+          <wicket:message key="creator"/>:
+        </div>
+        <div>
+          <span wicket:id="creator" />
+        </div>
+      </div>
+
+      <div class="inforight">
+        <div class="infolabel">
+          <wicket:message key="lastModifier"/>:
+        </div>
+        <div>
+          <span wicket:id="lastModifier" />
+        </div>
+      </div>
+
+      <wicket:child />
+    </div>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.properties
new file mode 100644
index 0000000..54a0fcf
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.properties
@@ -0,0 +1,20 @@
+# 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.
+creationDate=Creation Date
+creator=Creator
+lastChangeDate=Last change date
+lastModifier=Last modifier

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_it.properties
new file mode 100644
index 0000000..7fae3ab
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_it.properties
@@ -0,0 +1,20 @@
+# 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.
+creationDate=Data Di Creazione
+creator=Creatore
+lastChangeDate=Data Di Ultima Modifica
+lastModifier=Ultimo Modificatore

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_pt_BR.properties
new file mode 100644
index 0000000..689436f
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnnotatedBeanPanel_pt_BR.properties
@@ -0,0 +1,20 @@
+# 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.
+creationDate=Data de Cria\u00e7\u00e3o
+creator=Criador
+lastChangeDate=Data De \u00daltima Altera\u00e7\u00e3o
+lastModifier=\u00daltima Modificador

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Any.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Any.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Any.html
new file mode 100644
index 0000000..84340b5
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Any.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
+  <body>
+    <wicket:panel>
+      <h1>ANY</h1>
+    </wicket:panel>
+  </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.html
new file mode 100644
index 0000000..d5fe13b
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.html
@@ -0,0 +1,57 @@
+<!--
+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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
+  <body>
+    <wicket:panel>
+
+      <div>
+        <div id="users-contain" class="ui-widget" style="width:inherit">
+          <span wicket:id="connectorContainer">
+            <span wicket:id="connectorDatatable">[connectors]</span>
+          </span>
+
+          <span style="float:right">
+            <form wicket:id="connectorPaginatorForm" style="display:inline">
+              <label><wicket:message key="displayRows"/></label>
+              <select class="text ui-widget-content ui-corner-all" wicket:id="rowsChooser"/>
+            </form>
+          </span>
+        </div>
+
+        <div wicket:id="createConnectorWin">[Show modal window for creating connector]</div>
+        <div wicket:id="editConnectorWin">[Show modal window for editing connector]</div>
+
+        <a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="createConnectorLink">
+          <wicket:message key="create-connector"/>
+        </a>
+      </div>
+
+      <div>
+        <a href="#" style="position: absolute; top: 4px; right:20px;" wicket:id="reloadLink">
+          <img src="img/reload_30.png" width="25" height="25"
+               alt="Reload connectors" title="title" wicket:message="title:reloadConnectors"/>
+        </a>
+      </div>    
+
+    </wicket:panel>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.properties
new file mode 100644
index 0000000..fb6b8a1
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors.properties
@@ -0,0 +1,34 @@
+# 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.
+tab1=Resources
+edit=Edit
+delete=Delete
+create-resource=Create
+propagationPriority=Propagation priority
+propagationPrimary=Propagation primary
+
+tab2=Connectors
+displayName=Display name
+version=Version
+bundleName=Bundle name
+edit=Edit
+delete=Delete
+create-connector=Create
+delete_error=Operation forbidden:the connector you're trying to delete is connected to a Resource
+connector=Connector
+reloadConnectors=Reload connectors
+confirmReloadConnectors=This request is potentially dangerous for running operations, continue?

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_it.properties
new file mode 100644
index 0000000..80a5185
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_it.properties
@@ -0,0 +1,34 @@
+# 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.
+tab1=Risorse
+edit=Modifica
+delete=Rimuovi
+create-resource=Crea
+propagationPriority=Priorit\u00e0 in propagazione
+propagationPrimary=Primaria in propagazione
+
+tab2=Connettori
+create-connector=Crea
+version=Versione
+bundleName=Bundle name
+edit=Modifica
+delete=Elimina
+delete_error=Operazione vietata: il connettore che si desidera rimuovere \u00e8 correlato ad una risorsa
+displayName=Nome visualizzato
+connector=Connettore
+reloadConnectors=Ricarica connettori
+confirmReloadConnectors=Questa richiesta \u00e8 potenzialmente dannosa per le operazioni in corso, proseguire?

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_pt_BR.properties
new file mode 100644
index 0000000..a631352
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Connectors_pt_BR.properties
@@ -0,0 +1,32 @@
+# 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.
+tab1=Recursos
+edit=Alterar
+delete=Excluir
+create-resource=Criar
+propagationPriority=Prioridade de propaga\u00e7\u00e3o
+propagationPrimary=Propaga\u00e7\u00e3o prim\u00e1ria
+
+tab2=Conectores
+displayName=Mostar
+version=Vers\u00e3o
+bundleName=Nome do Pacote
+create-connector=Criar
+delete_error=Opera\u00e7\u00e3o n\u00e3o permitida\: o conector que voc\u00ea est\u00e1 tentando excluir est\u00e1 conectado a um recurso
+connector=Conector
+reloadConnectors=Carregar Conector
+confirmReloadConnectors=Esta requis\u00e7\u00e3o \u00e9 potencialmente perigosa para opera\u00e7\u00f5es em execu\u00e7\u00e3o, prosseguir?

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/PasswordPolicy.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/PasswordPolicy.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/PasswordPolicy.html
new file mode 100644
index 0000000..5fbd41d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/PasswordPolicy.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
+  <body>
+    <wicket:panel>
+      <h1>Password Policy</h1>
+    </wicket:panel>
+  </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Realm.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Realm.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Realm.html
new file mode 100644
index 0000000..29eaae3
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Realm.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
+  <body>
+    <wicket:panel>
+      
+      <div class="tabbable tabs-left">
+        <ul class="nav nav-tabs">
+          <li class="active">
+            <a data-toggle="tab" href="#lA">Details</a>
+          </li>
+          <li>
+            <a data-toggle="tab" href="#lB">Users</a>
+          </li>
+          <li>
+            <a data-toggle="tab" href="#lC">Groups</a>
+          </li>
+          <li class="dropdown">
+            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+              ANY
+              <b class="caret"></b>
+            </a>
+            <ul class="dropdown-menu">
+              <li><a data-toggle="tab" href="#lB">Users</a></li>
+              <li><a data-toggle="tab" href="#lC">Groups</a></li>
+              <li class="divider"></li>
+              <li class="nav-header">Others</li>
+              <li><a data-toggle="tab" href="#lD">Services</a></li>
+              <li><a data-toggle="tab" href="#lE">Service Roles</a></li>
+              <li><a data-toggle="tab" href="#lF">Enactment Engines</a></li>
+              <li><a data-toggle="tab" href="#lG">Contexts</a></li>
+            </ul>
+          </li>
+          <li>
+            <a data-toggle="tab" href="#lH">Account policy</a>
+          </li>
+          <li>
+            <a data-toggle="tab" href="#lI">Password policy</a>
+          </li>
+        </ul>
+        <div class="tab-content">
+          <div id="lA" class="tab-pane active">
+            <wicket:container wicket:id="details"/>
+          </div>
+          <div id="lB" class="tab-pane">
+            <wicket:container wicket:id="users"/>
+          </div>
+          <div id="lC" class="tab-pane">
+            <wicket:container wicket:id="groups"/>
+          </div>
+          <div id="lD" class="tab-pane">
+            <wicket:container wicket:id="services"/>
+          </div>
+          <div id="lE" class="tab-pane">
+            <wicket:container wicket:id="serviceRoles"/>
+          </div>
+          <div id="lF" class="tab-pane">
+            <wicket:container wicket:id="enactmentEngine"/>
+          </div>
+          <div id="lG" class="tab-pane">
+            <wicket:container wicket:id="contexts"/>
+          </div>
+          <div id="lH" class="tab-pane">
+            <wicket:container wicket:id="accountPolicy"/>
+          </div>
+          <div id="lI" class="tab-pane">
+            <wicket:container wicket:id="passwordPolicy"/>
+          </div>
+        </div>
+      </div>
+    </wicket:panel>
+  </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html
new file mode 100644
index 0000000..b8c3d27
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
+  <body>
+    <wicket:panel>
+      <br />
+      <form data-example-id="simple-input-groups" class="bs-example bs-example-form">
+        <div class="input-group">
+          <span id="basic-addon1" class="input-group-addon">Id</span>
+          <input type="text" aria-describedby="basic-addon1" placeholder="id" class="form-control" wicket:id="id" />
+        </div>
+        <br />
+        <div class="input-group">
+          <span id="basic-addon1" class="input-group-addon">Name</span>
+          <input type="text" aria-describedby="basic-addon1" placeholder="name" class="form-control" wicket:id="name" />
+        </div>
+        <br />
+        <div class="input-group">
+          <span id="basic-addon1" class="input-group-addon">Path</span>
+          <input type="text" aria-describedby="basic-addon1" placeholder="path" class="form-control" wicket:id="path" />
+        </div>
+      </form>
+    </wicket:panel>
+  </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceConnConfPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceConnConfPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceConnConfPanel.html
new file mode 100644
index 0000000..af71505
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceConnConfPanel.html
@@ -0,0 +1,40 @@
+<!--
+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>
+    <span wicket:id="connectorPropertiesContainer">
+      <div id="formtable">
+        <div class="tablerow" wicket:id="connectorProperties">
+          <div class="tablecolumn_label medium_fixedsize">
+            <span wicket:id="connPropAttrSchema">[connPropAttrSchema]</span>
+          </div>
+          <div class="tablecolumn_field medium_dynamicsize">
+            <span wicket:id="panel">[connPropAttrValue]</span>
+          </div>
+        </div>
+      </div>
+
+      <div>
+        <a style="position: absolute; top: 2px; right:20px;" wicket:id="check">
+          <i class="fa fa-heartbeat fa-2x"></i> 
+        </a>
+      </div>
+    </span>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDetailsPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDetailsPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDetailsPanel.html
new file mode 100644
index 0000000..0b7ca7f
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceDetailsPanel.html
@@ -0,0 +1,137 @@
+<!--
+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 id="formtable">
+      <div class="tablerow alt">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="name"><wicket:message key="name"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="name">[name]</span>
+        </div>
+      </div>
+
+      <div class="tablerow">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="connector"><wicket:message key="connector"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="connector">[connector]</span>
+        </div>
+      </div>
+
+      <div class="tablerow alt">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="enforceMandatoryCondition"><wicket:message key="enforceMandatoryCondition"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="enforceMandatoryCondition">[enforceMandatoryCondition]</span>
+        </div>
+      </div>
+
+      <div class="tablerow">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="propagationPrimary"><wicket:message key="propagationPrimary"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="propagationPrimary">[propagationPrimary]</span>
+        </div>
+      </div>
+
+      <div class="tablerow alt">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="propagationPriority"><wicket:message key="propagationPriority"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="propagationPriority">[propagationPriority]</span>
+        </div>
+      </div>
+
+      <div class="tablerow">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="propagationMode"><wicket:message key="propagationMode"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="propagationMode">[propagationMode]</span>
+        </div>
+      </div>
+
+      <div class="tablerow alt">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="randomPwdIfNotProvided"><wicket:message key="randomPwdIfNotProvided"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="randomPwdIfNotProvided">[randomPwdIfNotProvided]</span>
+        </div>
+      </div>
+
+      <div class="tablerow">
+        <div class="tablecolumn_label short_dynamicsize">
+          <label for="propagationActionsClassNames"><wicket:message key="actionsClasses"/></label>
+        </div>
+        <span wicket:id="propagationActionsClassNames">
+          <span wicket:id="actionsClasses">
+            <select class="text ui-widget-content ui-corner-all" wicket:id="actionsClass"/>
+            <a wicket:id="drop"><i class="fa fa-minus"></i></a>
+            <a wicket:id="add"><i class="fa fa-plus"></i></a>
+            <br/>
+          </span>
+          <a wicket:id="first"><i class="fa fa-plus"></i></a>
+        </span>        
+      </div>
+
+      <div class="tablerow alt">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="createTraceLevel"><wicket:message key="createTraceLevel"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="createTraceLevel">[createTraceLevel]</span>
+        </div>
+      </div>
+
+      <div class="tablerow">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="updateTraceLevel"><wicket:message key="updateTraceLevel"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="updateTraceLevel">[updateTraceLevel]</span>
+        </div>
+      </div>
+
+      <div class="tablerow alt">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="deleteTraceLevel"><wicket:message key="deleteTraceLevel"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="deleteTraceLevel">[deleteTraceLevel]</span>
+        </div>
+      </div>
+
+      <div class="tablerow">
+        <div class="tablecolumn_label medium_fixedsize">
+          <label for="syncTraceLevel"><wicket:message key="syncTraceLevel"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="syncTraceLevel">[syncTraceLevel]</span>
+        </div>
+      </div>
+    </div>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
new file mode 100644
index 0000000..0e145bb
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
@@ -0,0 +1,114 @@
+<!--
+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="table-responsive no-padding">
+      <table id="mappings"
+             class="table table-hover"
+             style="font-size: 1em;margin-top:2px;"
+             wicket:id="mappingContainer">
+        <tbody>
+          <tr>
+            <th><wicket:message key="delete"/></th>
+            <th><wicket:message key="entity"/></th>
+            <th><wicket:message key="intMappingTypes"/></th>
+            <th><wicket:message key="intAttrNames"/></th>
+            <th><wicket:message key="extAttrNames"/></th>
+            <th><wicket:message key="mandatoryCondition"/>
+              <a class="help" wicket:id="questionMarkJexlHelp" href="#" alt="Click to help" title="Click to help"><i class="fa fa-question-circle"></i>
+
+                <span wicket:id="jexlHelp" class="help">
+                  <wicket:message key="jexl_info"/>
+                  <ul>
+                    <li><wicket:message key="jexl_ex1"/></li>
+                    <li><wicket:message key="jexl_ex2"/></li>
+                  </ul>
+                  <a href="#" wicket:id="jexlLink" target="_blank"><wicket:message key="jexl_syntax_url"/></a>
+                </span>
+              </a>
+            </th>
+            <th><wicket:message key="accountId"/></th>
+            <th><label wicket:id="passwordLabel"/></th>
+            <th><wicket:message key="purpose"/></th>
+          </tr>
+          <tr wicket:id="mappings">
+            <td>
+              <input type="checkbox" class="text ui-widget-content ui-corner-all"  wicket:id="toRemove"/>
+            </td>
+            <td>
+              <span wicket:id="entities">[entities]</span>
+            </td>
+            <td>
+              <span wicket:id="intMappingTypes">[intMappingTypes]</span>
+            </td>
+            <td>
+              <span wicket:id="intAttrNames">[intAttrNames]</span>
+            </td>
+            <td>
+              <span wicket:id="extAttrName">[extAttrName]</span>
+            </td>
+            <td>
+              <span wicket:id="mandatoryCondition">[mandatoryCondition]</span>
+            </td>
+            <td>
+              <span wicket:id="accountId">[accountId]</span>
+            </td>
+            <td>
+              <span wicket:id="password">[password]</span>
+            </td>
+            <td>
+              <span wicket:id="purpose">
+                <span wicket:id="purposeActions">[purpose]</span>
+              </span>
+            </td>
+          </tr>
+        </tbody>
+
+        <tfoot>
+          <tr>
+            <td colspan="7" style="padding: 5px">
+              <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
+                     wicket:id="addMappingBtn" />
+            </td>
+          </tr>
+        </tfoot>
+      </table>
+
+      <table id="accountLinkTable"
+             class="table"
+             style="font-size: 1em;margin-top:2px;"
+             wicket:id="accountLinkContainer">
+        <tbody>
+          <tr>
+            <th width="10%" align="left"><wicket:message key="enable"/></th>
+            <th align="left"><wicket:message key="accountLink"/></th>
+          </tr>
+          <tr>
+            <td width="10%">
+              <span wicket:id="accountLinkCheckbox">[accountLinkCheckbox]</span>
+            </td>
+            <td>
+              <span wicket:id="accountLink">[accountLink]</span>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html
new file mode 100644
index 0000000..ddabe05
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html
@@ -0,0 +1,56 @@
+<!--
+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 id="formtable" wicket:id="security">
+      <div class="tablerow alt">
+        <div class="tablecolumn_label short_dynamicsize">
+          <label for="passwordPolicy"><wicket:message key="passwordPolicy"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="passwordPolicy">
+            [panel for dynamic input type markup]
+          </span>
+        </div>
+      </div>
+
+      <div class="tablerow">
+        <div class="tablecolumn_label short_dynamicsize">
+          <label for="accountPolicy"><wicket:message key="accountPolicy"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="accountPolicy">
+            [panel for dynamic input type markup]
+          </span>
+        </div>
+      </div>
+
+      <div class="tablerow alt">
+        <div class="tablecolumn_label short_dynamicsize">
+          <label for="syncPolicy"><wicket:message key="syncPolicy"/></label>
+        </div>
+        <div class="tablecolumn_field medium_dynamicsize">
+          <span wicket:id="syncPolicy">
+            [panel for dynamic input type markup]
+          </span>
+        </div>
+      </div>
+    </div>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties
new file mode 100644
index 0000000..f7fd440
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties
@@ -0,0 +1,19 @@
+# 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.
+passwordPolicy = Password Policy
+accountPolicy = Account Policy
+syncPolicy = Sync Policy

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties
new file mode 100644
index 0000000..f7fd440
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties
@@ -0,0 +1,19 @@
+# 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.
+passwordPolicy = Password Policy
+accountPolicy = Account Policy
+syncPolicy = Sync Policy

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties
new file mode 100644
index 0000000..3278665
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties
@@ -0,0 +1,19 @@
+# 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.
+passwordPolicy = Pol\u00edtica de Senha
+accountPolicy = Pol\u00edtica de Conta
+syncPolicy = Pol\u00edtica de Sincroniza\u00e7\u00e3o

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
new file mode 100644
index 0000000..3d02b33
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
@@ -0,0 +1,52 @@
+<!--
+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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
+  <body>
+    <wicket:panel>
+
+      <div>
+        <div id="users-contain" class="ui-widget" style="width:inherit">
+          <span wicket:id="resourceContainer">
+            <span wicket:id="resourceDatatable">[resources]</span>
+          </span>
+
+          <span style="float:right">
+            <form wicket:id="resourcePaginatorForm" style="display:inline">
+              <label><wicket:message key="displayRows"/></label>
+              <select class="text ui-widget-content ui-corner-all" wicket:id="rowsChooser"/>
+            </form>
+          </span>
+        </div>
+
+        <div wicket:id="statusModal">[Show modal window for provisioning status]</div>
+        <div wicket:id="createResourceWin">[Show modal window for creating resource]</div>
+        <div wicket:id="editResourceWin">[Show modal window for editing resource]</div>
+        <div wicket:id="editConnectorWin">[Show modal window for editing connector]</div>
+
+        <a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="createResourceLink">
+          <wicket:message key="create-resource"/>
+        </a>
+      </div>
+
+    </wicket:panel>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
new file mode 100644
index 0000000..fb6b8a1
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
@@ -0,0 +1,34 @@
+# 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.
+tab1=Resources
+edit=Edit
+delete=Delete
+create-resource=Create
+propagationPriority=Propagation priority
+propagationPrimary=Propagation primary
+
+tab2=Connectors
+displayName=Display name
+version=Version
+bundleName=Bundle name
+edit=Edit
+delete=Delete
+create-connector=Create
+delete_error=Operation forbidden:the connector you're trying to delete is connected to a Resource
+connector=Connector
+reloadConnectors=Reload connectors
+confirmReloadConnectors=This request is potentially dangerous for running operations, continue?

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
new file mode 100644
index 0000000..80a5185
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
@@ -0,0 +1,34 @@
+# 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.
+tab1=Risorse
+edit=Modifica
+delete=Rimuovi
+create-resource=Crea
+propagationPriority=Priorit\u00e0 in propagazione
+propagationPrimary=Primaria in propagazione
+
+tab2=Connettori
+create-connector=Crea
+version=Versione
+bundleName=Bundle name
+edit=Modifica
+delete=Elimina
+delete_error=Operazione vietata: il connettore che si desidera rimuovere \u00e8 correlato ad una risorsa
+displayName=Nome visualizzato
+connector=Connettore
+reloadConnectors=Ricarica connettori
+confirmReloadConnectors=Questa richiesta \u00e8 potenzialmente dannosa per le operazioni in corso, proseguire?

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
new file mode 100644
index 0000000..a631352
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
@@ -0,0 +1,32 @@
+# 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.
+tab1=Recursos
+edit=Alterar
+delete=Excluir
+create-resource=Criar
+propagationPriority=Prioridade de propaga\u00e7\u00e3o
+propagationPrimary=Propaga\u00e7\u00e3o prim\u00e1ria
+
+tab2=Conectores
+displayName=Mostar
+version=Vers\u00e3o
+bundleName=Nome do Pacote
+create-connector=Criar
+delete_error=Opera\u00e7\u00e3o n\u00e3o permitida\: o conector que voc\u00ea est\u00e1 tentando excluir est\u00e1 conectado a um recurso
+connector=Conector
+reloadConnectors=Carregar Conector
+confirmReloadConnectors=Esta requis\u00e7\u00e3o \u00e9 potencialmente perigosa para opera\u00e7\u00f5es em execu\u00e7\u00e3o, prosseguir?

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.html b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.html
new file mode 100644
index 0000000..bc68d99
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.html
@@ -0,0 +1,52 @@
+  <!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <script type="text/javascript" src="webjars/jsplumb/${jsplumb.version}/dom.jsPlumb-${jsplumb.version}-min.js"></script>
+    <script type="text/javascript" src="webjars/jquery-cookie/${jquery-cookie.version}/jquery.cookie.js"></script>
+    <script type="text/javascript" src="js/topology.js"></script>
+    <link href="css/topology.css" rel="stylesheet"/>
+  </wicket:head>
+  <wicket:extend>
+    <div id="zoom" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+      <span wicket:id="zoom">[Actions]</span>
+    </div>
+    <div id="topology">
+      <div id="drawing">
+        <div class="window topology_root" wicket:id="syncope" onmouseup="refreshPosition(this)">[syncope]</div>
+        <span wicket:id="connectorServers">
+          <div class="window topology_cs" wicket:id="cs" onmouseup="refreshPosition(this)">[resource]</div>
+        </span>
+        <span wicket:id="conn1">
+          <div class="window topology_conn" wicket:id="conn" onmouseup="refreshPosition(this)">[resource]</div>
+        </span>
+        <span wicket:id="conn2">
+          <div class="window topology_conn" wicket:id="conn" onmouseup="refreshPosition(this)">[resource]</div>
+        </span>
+        <span wicket:id="resources">
+          <span wicket:id="resources">
+            <div class="window topology_res" wicket:id="res" onmouseup="refreshPosition(this)">[resource]</div>
+          </span>
+        </span>
+        <span wicket:id="jsPlace"></span>
+      </div>
+    </div>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.properties
new file mode 100644
index 0000000..14e381d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology.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.
+missingEntitlement=MISSING ENTITLEMENT: CONNECTOR_READ

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.html
new file mode 100644
index 0000000..6b23d8f
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<!--
+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="node-action-link btn-group">
+      <a href="javascript:void(0);" data-toggle="dropdown">
+        <i class="fa fa-sliders"></i>
+      </a>
+      <wicket:container wicket:id="actions" />
+    </div>
+
+    <p class="text-center text-primary" wicket:id="label"/>
+
+    <span wicket:id="timer" />
+
+    <wicket:fragment wicket:id="connectorWithResourceActions">
+      <div wicket:id="createWin">[createWin]</div>
+      <div wicket:id="editWin">[editWin]</div>
+      <ul role="menu" class="dropdown-menu">
+        <li><a href="#"><i class="fa fa-plus"></i></a></li>
+        <li><a href="#"><i class="fa fa-pencil"></i></a></li>
+      </ul>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="connectorWithNoResourceActions">
+      <div wicket:id="createWin">[createWin]</div>
+      <div wicket:id="editWin">[editWin]</div>
+      <ul role="menu" class="dropdown-menu">
+        <li><a href="#"><i class="fa fa-plus"></i></a></li>
+        <li><a href="#"><i class="fa fa-minus"></i></a></li>
+        <li><a href="#"><i class="fa fa-pencil"></i></a></li>
+      </ul>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="resourceActions">
+      <div wicket:id="editWin">[editWin]</div>
+      <ul role="menu" class="dropdown-menu">
+        <li><a href="#" wicket:id="delete"><i class="fa fa-minus"></i></a></li>
+        <li><a href="#" wicket:id="edit"><i class="fa fa-pencil"></i></a></li>
+      </ul>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="syncopeActions">
+      <div wicket:id="createWin">[createWin]</div>
+      <ul role="menu" class="dropdown-menu">
+        <li><a href="#"><i class="fa fa-plus"></i></a></li>
+      </ul>
+    </wicket:fragment>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.properties
new file mode 100644
index 0000000..e0c2918
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel.properties
@@ -0,0 +1,20 @@
+# 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.
+connector.new=New connector
+resource.new=New resource
+connector.edit=Edit connector {0}
+resource.edit=Edit resource {0}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_it.properties
new file mode 100644
index 0000000..be33d41
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_it.properties
@@ -0,0 +1,20 @@
+# 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.
+connector.new=Nuovo connettore
+resource.new=Nuova risorsa
+connector.edit=Modifica connettore {0}
+resource.edit=Modifica risorsa {0}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_pt_BR.properties
new file mode 100644
index 0000000..48ce11e
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyNodePanel_pt_BR.properties
@@ -0,0 +1,20 @@
+# 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.
+connector.new=Novo conector
+resource.new=Novo recurso
+connector.edit=Alterar conector {0}
+resource.edit=Alterar recurso {0}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_it.properties
new file mode 100644
index 0000000..5a3d4c8
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_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.
+missingEntitlement=ENTITLEMENT MANCANTE: CONNECTOR_READ

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_pt_BR.properties
new file mode 100644
index 0000000..14e381d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/Topology_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.
+missingEntitlement=MISSING ENTITLEMENT: CONNECTOR_READ

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.html
new file mode 100644
index 0000000..fde1840
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.html
@@ -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.
+-->
+<wicket:panel>
+   <input wicket:id="groupselector" type="checkbox"/>
+</wicket:panel>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.html
new file mode 100644
index 0000000..23156a2
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.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:panel>
+    <input wicket:id="check" type="checkbox"/>
+  </wicket:panel>
+</html>


[26/27] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
deleted file mode 100644
index 755b2d1..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
+++ /dev/null
@@ -1,485 +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.panels;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.PreferenceManager;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.pages.ConnectorModalPage;
-import org.apache.syncope.client.console.pages.ProvisioningModalPage;
-import org.apache.syncope.client.console.pages.ResourceModalPage;
-import org.apache.syncope.client.console.rest.ConnectorRestClient;
-import org.apache.syncope.client.console.rest.ResourceRestClient;
-import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.LinkPanel;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.Page;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.event.IEvent;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-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.ISortableDataProvider;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.DropDownChoice;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.markup.repeater.Item;
-import org.apache.wicket.model.AbstractReadOnlyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.StringResourceModel;
-import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Resources WebPage.
- */
-public class Resources extends Panel {
-
-    private static final long serialVersionUID = -3789252860990261728L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(Resources.class);
-
-    private static final int WIN_HEIGHT = 600;
-
-    private static final int WIN_WIDTH = 1100;
-
-    @SpringBean
-    private PreferenceManager prefMan;
-
-    @SpringBean
-    private ResourceRestClient resourceRestClient;
-
-    private final ModalWindow createResourceWin;
-
-    private final ModalWindow editResourceWin;
-
-    private final int resourcePaginatorRows;
-
-    private WebMarkupContainer resourceContainer;
-
-    private final ModalWindow editConnectorWin;
-
-    /**
-     * Modal window to be used for user status management.
-     */
-    protected final ModalWindow statusmodal = new ModalWindow("statusModal");
-
-    /**
-     * Schemas to be shown modal window height.
-     */
-    private static final int STATUS_MODAL_WIN_HEIGHT = 500;
-
-    /**
-     * Schemas to be shown modal window width.
-     */
-    private static final int STATUS_MODAL_WIN_WIDTH = 700;
-
-    @SpringBean
-    private ConnectorRestClient connectorRestClient;
-
-    private final PageReference pageRef;
-
-    public Resources(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-
-        createResourceWin = new ModalWindow("createResourceWin");
-        add(createResourceWin);
-
-        editResourceWin = new ModalWindow("editResourceWin");
-        add(editResourceWin);
-
-        editConnectorWin = new ModalWindow("editConnectorWin");
-        add(editConnectorWin);
-
-        statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
-        statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
-        statusmodal.setCookieName("status-modal");
-        add(statusmodal);
-
-        resourcePaginatorRows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_RESOURCES_PAGINATOR_ROWS);
-
-        setupResources();
-    }
-
-    private void setupResources() {
-        List<IColumn<ResourceTO, String>> columns = new ArrayList<>();
-
-        columns.add(new PropertyColumn<ResourceTO, String>(new StringResourceModel("key", this, null), "key", "key"));
-
-        columns.add(new AbstractColumn<ResourceTO, String>(
-                new StringResourceModel("connector", this, null, "connector")) {
-
-                    private static final long serialVersionUID = 8263694778917279290L;
-
-                    @Override
-                    public void populateItem(final Item<ICellPopulator<ResourceTO>> cellItem, final String componentId,
-                            final IModel<ResourceTO> rowModel) {
-
-                        final AjaxLink<String> editLink = new ClearIndicatingAjaxLink<String>("link", pageRef) {
-
-                            private static final long serialVersionUID = -7978723352517770644L;
-
-                            @Override
-                            protected void onClickInternal(final AjaxRequestTarget target) {
-
-                                editConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                                    private static final long serialVersionUID = -7834632442532690940L;
-
-                                    @Override
-                                    public Page createPage() {
-                                        return new ConnectorModalPage(Resources.this.pageRef,
-                                                editConnectorWin,
-                                                connectorRestClient.read(rowModel.getObject().getConnectorId()));
-                                    }
-                                });
-
-                                editConnectorWin.show(target);
-                            }
-                        };
-                        editLink.add(new Label("linkTitle", rowModel.getObject().getConnectorDisplayName()));
-
-                        LinkPanel editConnPanel = new LinkPanel(componentId);
-                        editConnPanel.add(editLink);
-
-                        cellItem.add(editConnPanel);
-
-                        MetaDataRoleAuthorizationStrategy.authorize(editConnPanel, ENABLE, Entitlement.CONNECTOR_READ);
-                    }
-                });
-
-        columns.add(new AbstractColumn<ResourceTO, String>(
-                new StringResourceModel("propagationPrimary", this, null)) {
-
-                    private static final long serialVersionUID = -3503023501954863131L;
-
-                    @Override
-                    public void populateItem(final Item<ICellPopulator<ResourceTO>> item,
-                            final String componentId, final IModel<ResourceTO> model) {
-
-                        item.add(new Label(componentId, ""));
-                        item.add(new AttributeModifier("class", new Model<>(
-                                                Boolean.toString(model.getObject().isPropagationPrimary()))));
-                    }
-
-                    @Override
-                    public String getCssClass() {
-                        return "narrowcolumn";
-                    }
-                });
-
-        columns.add(new PropertyColumn<ResourceTO, String>(new StringResourceModel(
-                "propagationPriority", this, null), "propagationPriority", "propagationPriority") {
-
-                    private static final long serialVersionUID = 1L;
-
-                    @Override
-                    public String getCssClass() {
-                        return "narrowcolumn";
-                    }
-                });
-
-        columns.add(new AbstractColumn<ResourceTO, String>(new StringResourceModel("actions", this, null, "")) {
-
-            private static final long serialVersionUID = 2054811145491901166L;
-
-            @Override
-            public String getCssClass() {
-                return "action";
-            }
-
-            @Override
-            public void populateItem(final Item<ICellPopulator<ResourceTO>> cellItem, final String componentId,
-                    final IModel<ResourceTO> model) {
-
-                final ResourceTO resourceTO = model.getObject();
-
-                final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, pageRef);
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        statusmodal.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new ProvisioningModalPage<>(
-                                        pageRef, statusmodal, model.getObject(), UserTO.class);
-                            }
-                        });
-
-                        statusmodal.show(target);
-                    }
-                }, ActionLink.ActionType.MANAGE_USERS, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-
-                        statusmodal.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new ProvisioningModalPage<>(
-                                        pageRef, statusmodal, model.getObject(), GroupTO.class);
-                            }
-                        });
-
-                        statusmodal.show(target);
-                    }
-                }, ActionLink.ActionType.MANAGE_GROUPS, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        resourceTO.setUsyncToken(null);
-                        resourceTO.setRsyncToken(null);
-                        try {
-                            resourceRestClient.update(resourceTO);
-                            info(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (SyncopeClientException e) {
-                            error(getString(Constants.ERROR) + ":" + e.getMessage());
-
-                            LOG.error("While resetting sync token from " + resourceTO.getKey(), e);
-                        }
-
-                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
-                        target.add(resourceContainer);
-                    }
-                }, ActionLink.ActionType.RESET, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        editResourceWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new ResourceModalPage(pageRef, editResourceWin, resourceTO, false);
-                            }
-                        });
-
-                        editResourceWin.show(target);
-                    }
-                }, ActionLink.ActionType.EDIT, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        try {
-                            resourceRestClient.delete(resourceTO.getKey());
-                            info(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (SyncopeClientException e) {
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
-
-                            LOG.error("While deleting resource " + resourceTO.getKey(), e);
-                        }
-
-                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
-                        target.add(resourceContainer);
-                    }
-                }, ActionLink.ActionType.DELETE, "Resources");
-
-                cellItem.add(panel);
-            }
-        });
-
-        final AjaxDataTablePanel<ResourceTO, String> table = new AjaxDataTablePanel<>(
-                "resourceDatatable",
-                columns,
-                (ISortableDataProvider<ResourceTO, String>) new ResourcesProvider(),
-                resourcePaginatorRows,
-                Arrays.asList(new ActionLink.ActionType[] { ActionLink.ActionType.DELETE }),
-                resourceRestClient,
-                "key",
-                "Resources",
-                pageRef);
-
-        resourceContainer = new WebMarkupContainer("resourceContainer");
-        resourceContainer.add(table);
-        resourceContainer.setOutputMarkupId(true);
-
-        add(resourceContainer);
-
-        ((BasePage) pageRef.getPage()).setWindowClosedCallback(createResourceWin, resourceContainer);
-        ((BasePage) pageRef.getPage()).setWindowClosedCallback(editResourceWin, resourceContainer);
-
-        createResourceWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        createResourceWin.setInitialHeight(WIN_HEIGHT);
-        createResourceWin.setInitialWidth(WIN_WIDTH);
-        createResourceWin.setCookieName("create-res-modal");
-
-        editResourceWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        editResourceWin.setInitialHeight(WIN_HEIGHT);
-        editResourceWin.setInitialWidth(WIN_WIDTH);
-        editResourceWin.setCookieName("edit-res-modal");
-
-        editConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        editConnectorWin.setInitialHeight(WIN_HEIGHT);
-        editConnectorWin.setInitialWidth(WIN_WIDTH);
-        editConnectorWin.setCookieName("edit-conn-modal");
-
-        AjaxLink<Void> createResourceLink
-                = new ClearIndicatingAjaxLink<Void>("createResourceLink", pageRef) {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
-                        createResourceWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                final ResourceModalPage windows = new ResourceModalPage(Resources.this.pageRef,
-                                        editResourceWin, new ResourceTO(), true);
-                                return windows;
-                            }
-                        });
-
-                        createResourceWin.show(target);
-                    }
-                };
-
-        MetaDataRoleAuthorizationStrategy.authorize(createResourceLink, ENABLE, Entitlement.RESOURCE_CREATE);
-
-        add(createResourceLink);
-
-        @SuppressWarnings("rawtypes")
-        final Form paginatorForm = new Form("resourcePaginatorForm");
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        final DropDownChoice rowsChooser = new DropDownChoice("rowsChooser", new PropertyModel(this,
-                "resourcePaginatorRows"), prefMan.getPaginatorChoices());
-
-        rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                prefMan.set(getRequest(), getResponse(), Constants.PREF_RESOURCES_PAGINATOR_ROWS,
-                        String.valueOf(resourcePaginatorRows));
-
-                table.setItemsPerPage(resourcePaginatorRows);
-                target.add(resourceContainer);
-            }
-        });
-
-        paginatorForm.add(rowsChooser);
-        add(paginatorForm);
-    }
-
-    class ResourcesProvider extends SortableDataProvider<ResourceTO, String> {
-
-        private static final long serialVersionUID = -9055916672926643975L;
-
-        private final SortableDataProviderComparator<ResourceTO> comparator;
-
-        public ResourcesProvider() {
-            super();
-            //Default sorting
-            setSort("key", SortOrder.ASCENDING);
-            comparator = new SortableDataProviderComparator<>(this);
-        }
-
-        @Override
-        public Iterator<ResourceTO> iterator(final long first, final long count) {
-            List<ResourceTO> list = resourceRestClient.getAll();
-
-            Collections.sort(list, comparator);
-
-            return list.subList((int) first, (int) first + (int) count).iterator();
-        }
-
-        @Override
-        public long size() {
-            return resourceRestClient.getAll().size();
-        }
-
-        @Override
-        public IModel<ResourceTO> model(final ResourceTO resource) {
-            return new AbstractReadOnlyModel<ResourceTO>() {
-
-                private static final long serialVersionUID = 8952474152465381634L;
-
-                @Override
-                public ResourceTO getObject() {
-                    return resource;
-                }
-            };
-        }
-    }
-
-    @Override
-    public void onEvent(final IEvent<?> event) {
-        if (event.getPayload() instanceof AbstractSearchResultPanel.EventDataWrapper) {
-            ((AbstractSearchResultPanel.EventDataWrapper) event.getPayload()).getTarget().add(resourceContainer);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index 5535c7b..3298d3f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -28,11 +28,11 @@ 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.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.springframework.beans.BeanUtils;
@@ -196,8 +196,8 @@ public class ConnectorRestClient extends BaseRestClient {
         return schemaNames;
     }
 
-    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final ConnInstanceTO connectorTO) {
-        List<ConnIdObjectClassTO> result = Collections.emptyList();
+    public List<ConnIdObjectClass> getSupportedObjectClasses(final ConnInstanceTO connectorTO) {
+        List<ConnIdObjectClass> result = Collections.emptyList();
         try {
             result = getService(ConnectorService.class).getSupportedObjectClasses(connectorTO.getKey(), connectorTO);
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 ef490e2..a146857 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
@@ -25,6 +25,7 @@ import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
@@ -119,31 +120,34 @@ public class GroupRestClient extends AbstractAnyRestClient {
         return getService(GroupService.class).bulk(action);
     }
 
-    public void unlink(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public void unlink(final String etag, final long groupKey, final List<StatusBean> statuses) {
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            service.bulkDeassociation(groupId, ResourceDeassociationActionType.UNLINK,
+            service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(GroupService.class);
         }
     }
 
-    public void link(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public void link(final String etag, final long groupKey, final List<StatusBean> statuses) {
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            service.bulkAssociation(groupId, ResourceAssociationActionType.LINK,
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class));
+
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+            service.bulkAssociation(groupKey, ResourceAssociationActionType.LINK, associationMod);
+
             resetClient(GroupService.class);
         }
     }
 
-    public BulkActionResult deprovision(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult deprovision(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupId, ResourceDeassociationActionType.DEPROVISION,
+            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -152,24 +156,27 @@ public class GroupRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult provision(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult provision(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkAssociation(groupId, ResourceAssociationActionType.PROVISION,
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class)).
+
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+
+            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }
         return result;
     }
 
-    public BulkActionResult unassign(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult unassign(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupId, ResourceDeassociationActionType.UNASSIGN,
+            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -178,14 +185,18 @@ public class GroupRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult assign(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult assign(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkAssociation(groupId, ResourceAssociationActionType.ASSIGN,
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class)).
+
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+
+            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
+
             resetClient(GroupService.class);
         }
         return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index 64daf50..bfe6385 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@ -122,22 +122,22 @@ public class UserRestClient extends AbstractAnyRestClient {
         return getService(ResourceService.class).readConnObject(resourceName, AnyTypeKind.USER.name(), id);
     }
 
-    public void suspend(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void suspend(final String etag, final long userKey, final List<StatusBean> statuses) {
         StatusMod statusMod = StatusUtils.buildStatusMod(statuses, false);
         statusMod.setType(StatusMod.ModType.SUSPEND);
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.status(userId, statusMod);
+            service.status(userKey, statusMod);
             resetClient(UserService.class);
         }
     }
 
-    public void reactivate(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void reactivate(final String etag, final long userKey, final List<StatusBean> statuses) {
         StatusMod statusMod = StatusUtils.buildStatusMod(statuses, true);
         statusMod.setType(StatusMod.ModType.REACTIVATE);
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.status(userId, statusMod);
+            service.status(userKey, statusMod);
             resetClient(UserService.class);
         }
     }
@@ -147,34 +147,34 @@ public class UserRestClient extends AbstractAnyRestClient {
         return getService(UserService.class).bulk(action);
     }
 
-    public void unlink(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void unlink(final String etag, final long userKey, final List<StatusBean> statuses) {
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.bulkDeassociation(userId, ResourceDeassociationActionType.UNLINK,
+            service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(UserService.class);
         }
     }
 
-    public void link(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void link(final String etag, final long userKey, final List<StatusBean> statuses) {
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
 
-            final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
-            service.bulkAssociation(userId, ResourceAssociationActionType.LINK, associationMod);
+            service.bulkAssociation(userKey, ResourceAssociationActionType.LINK, associationMod);
 
             resetClient(UserService.class);
         }
     }
 
-    public BulkActionResult deprovision(final String etag, final long userId, final List<StatusBean> statuses) {
+    public BulkActionResult deprovision(final String etag, final long userKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userId, ResourceDeassociationActionType.DEPROVISION,
+            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -183,32 +183,31 @@ public class UserRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult provision(final String etag, final long userId,
+    public BulkActionResult provision(final String etag, final long userKey,
             final List<StatusBean> statuses, final boolean changepwd, final String password) {
 
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
 
-            final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).
-                    getResourceNames(),
-                    ResourceKey.class));
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userId, ResourceAssociationActionType.PROVISION, associationMod).
+            result = service.bulkAssociation(userKey, ResourceAssociationActionType.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }
         return result;
     }
 
-    public BulkActionResult unassign(final String etag, final long userId, final List<StatusBean> statuses) {
+    public BulkActionResult unassign(final String etag, final long userKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userId, ResourceDeassociationActionType.UNASSIGN,
+            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -217,21 +216,20 @@ public class UserRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult assign(final String etag, final long userId,
+    public BulkActionResult assign(final String etag, final long userKey,
             final List<StatusBean> statuses, final boolean changepwd, final String password) {
 
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
 
-            final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).
-                    getResourceNames(),
-                    ResourceKey.class));
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userId, ResourceAssociationActionType.ASSIGN, associationMod).
+            result = service.bulkAssociation(userKey, ResourceAssociationActionType.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
index 013fa3a..8f6cc5c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
@@ -37,19 +37,16 @@ public class ActionResultColumn<T, S> extends AbstractColumn<T, S> {
 
     private static final long serialVersionUID = 7955560320949560716L;
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ActionResultColumn.class);
 
     private final BulkActionResult results;
 
-    private final String idFieldName;
+    private final String keyFieldName;
 
-    public ActionResultColumn(final BulkActionResult results, final String idFieldName) {
+    public ActionResultColumn(final BulkActionResult results, final String keyFieldName) {
         super(new Model<String>());
         this.results = results;
-        this.idFieldName = idFieldName;
+        this.keyFieldName = keyFieldName;
     }
 
     @Override
@@ -65,10 +62,10 @@ public class ActionResultColumn<T, S> extends AbstractColumn<T, S> {
     @Override
     public void populateItem(final Item<ICellPopulator<T>> item, final String componentId, final IModel<T> rowModel) {
         try {
-            final PropertyDescriptor propDesc = BeanUtils.getPropertyDescriptor(rowModel.getObject().getClass(),
-                    idFieldName);
-            final Object id = propDesc.getReadMethod().invoke(rowModel.getObject(), new Object[0]);
-            final Status status = id == null ? null : results.getResultMap().get(id.toString());
+            PropertyDescriptor propDesc =
+                    BeanUtils.getPropertyDescriptor(rowModel.getObject().getClass(), keyFieldName);
+            Object id = propDesc.getReadMethod().invoke(rowModel.getObject(), new Object[0]);
+            Status status = id == null ? null : results.getResults().get(id.toString());
             item.add(new Label(componentId, status == null ? Status.SUCCESS : status.toString()));
         } catch (Exception e) {
             LOG.error("Errore retrieving target id value", e);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
index 8a8eb3f..789919b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
@@ -28,7 +28,7 @@ extAttrNames=External attributes
 intMappingTypes=Internal mapping types
 entity=Entity
 groupSchema=Group Schema
-accountId=AccountId
+connObjectKey=ConnObjectKey
 mandatoryCondition=Mandatory
 password=Password
 purpose=Purpose
@@ -39,9 +39,9 @@ intAttrNames=Internal attributes
 enforceMandatoryCondition=Enforce mandatory condition
 fieldName=Field name
 
-accountIdValidation=There must be exactly one AccountId
+connObjectKeyValidation=There must be exactly one ConnObjectKey
 propagationMode=Propagation mode
-accountLink=Account link
+connObjectLink=ConnObjectLink
 enable=Enable
 
 createTraceLevel=Create trace level

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
index b98b3ae..54179a5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
@@ -28,7 +28,7 @@ extAttrNames=Attributi esterni
 intMappingTypes=Tipo mapping interno
 entity=Entit&agrave;
 groupSchema=Schema Gruppo
-accountId=AccountId
+connObjectKey=ConnObjectKey
 mandatoryCondition=Obbligatorio
 password=Password
 purpose=Scopo
@@ -39,9 +39,9 @@ intAttrNames=Attributi interni
 enforceMandatoryCondition=Abilita mandatory condition
 fieldName=Nome campo
 
-accountIdValidation=Deve essere definito esattamente un AccountId
+connObjectKeyValidation=Deve essere definito esattamente un ConnObjectKey
 propagationMode=Modalit\u00e0 di propagazione
-accountLink=Account link
+connObjectLink=ConnObjectLink
 enable=Abilita
 
 createTraceLevel=Livello di tracciamento delle creazioni

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
index a91df81..45c3616 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
@@ -28,7 +28,7 @@ extAttrNames=Atributos Externos
 intMappingTypes=Tipos internos de mapeamentos
 entity=Entidade
 groupSchema=Esquema de Grupo
-accountId=Identificador da Conta
+connObjectKey=ConnObjectKey
 mandatoryCondition=Obrigat\u00f3rio
 password=Senha
 purpose=Prop\u00f3sito
@@ -39,9 +39,9 @@ intAttrNames=Atributos internos
 enforceMandatoryCondition=Aplicar condi\u00e7\u00e3o obrigat\u00f3ria
 fieldName=Nome do Campo
 
-accountIdValidation=Precisa ser exatamente um Identificador de Conta
+connObjectKeyValidation=Precisa ser exatamente um ConnObjectKey
 propagationMode=Modo de propaga\u00e7\u00e3o
-accountLink=Link de Conta
+connObjectLink=ConnObjectLink
 enable=Habilitado
 
 createTraceLevel=Criar n\u00edvel de trace

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
index 0e145bb..fe6c4ef 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
@@ -43,7 +43,7 @@ under the License.
                 </span>
               </a>
             </th>
-            <th><wicket:message key="accountId"/></th>
+            <th><wicket:message key="connObjectKey"/></th>
             <th><label wicket:id="passwordLabel"/></th>
             <th><wicket:message key="purpose"/></th>
           </tr>
@@ -67,7 +67,7 @@ under the License.
               <span wicket:id="mandatoryCondition">[mandatoryCondition]</span>
             </td>
             <td>
-              <span wicket:id="accountId">[accountId]</span>
+              <span wicket:id="connObjectKey">[connObjectKey]</span>
             </td>
             <td>
               <span wicket:id="password">[password]</span>
@@ -90,21 +90,21 @@ under the License.
         </tfoot>
       </table>
 
-      <table id="accountLinkTable"
+      <table id="connObjectLinkTable"
              class="table"
              style="font-size: 1em;margin-top:2px;"
-             wicket:id="accountLinkContainer">
+             wicket:id="connObjectLinkContainer">
         <tbody>
           <tr>
             <th width="10%" align="left"><wicket:message key="enable"/></th>
-            <th align="left"><wicket:message key="accountLink"/></th>
+            <th align="left"><wicket:message key="connObjectLink"/></th>
           </tr>
           <tr>
             <td width="10%">
-              <span wicket:id="accountLinkCheckbox">[accountLinkCheckbox]</span>
+              <span wicket:id="connObjectLinkCheckbox">[connObjectLinkCheckbox]</span>
             </td>
             <td>
-              <span wicket:id="accountLink">[accountLink]</span>
+              <span wicket:id="connObjectLink">[connObjectLink]</span>
             </td>
           </tr>
         </tbody>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
deleted file mode 100644
index 3d02b33..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
+++ /dev/null
@@ -1,52 +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.
--->
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
-  <body>
-    <wicket:panel>
-
-      <div>
-        <div id="users-contain" class="ui-widget" style="width:inherit">
-          <span wicket:id="resourceContainer">
-            <span wicket:id="resourceDatatable">[resources]</span>
-          </span>
-
-          <span style="float:right">
-            <form wicket:id="resourcePaginatorForm" style="display:inline">
-              <label><wicket:message key="displayRows"/></label>
-              <select class="text ui-widget-content ui-corner-all" wicket:id="rowsChooser"/>
-            </form>
-          </span>
-        </div>
-
-        <div wicket:id="statusModal">[Show modal window for provisioning status]</div>
-        <div wicket:id="createResourceWin">[Show modal window for creating resource]</div>
-        <div wicket:id="editResourceWin">[Show modal window for editing resource]</div>
-        <div wicket:id="editConnectorWin">[Show modal window for editing connector]</div>
-
-        <a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="createResourceLink">
-          <wicket:message key="create-resource"/>
-        </a>
-      </div>
-
-    </wicket:panel>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
deleted file mode 100644
index fb6b8a1..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
+++ /dev/null
@@ -1,34 +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.
-tab1=Resources
-edit=Edit
-delete=Delete
-create-resource=Create
-propagationPriority=Propagation priority
-propagationPrimary=Propagation primary
-
-tab2=Connectors
-displayName=Display name
-version=Version
-bundleName=Bundle name
-edit=Edit
-delete=Delete
-create-connector=Create
-delete_error=Operation forbidden:the connector you're trying to delete is connected to a Resource
-connector=Connector
-reloadConnectors=Reload connectors
-confirmReloadConnectors=This request is potentially dangerous for running operations, continue?

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
deleted file mode 100644
index 80a5185..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
+++ /dev/null
@@ -1,34 +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.
-tab1=Risorse
-edit=Modifica
-delete=Rimuovi
-create-resource=Crea
-propagationPriority=Priorit\u00e0 in propagazione
-propagationPrimary=Primaria in propagazione
-
-tab2=Connettori
-create-connector=Crea
-version=Versione
-bundleName=Bundle name
-edit=Modifica
-delete=Elimina
-delete_error=Operazione vietata: il connettore che si desidera rimuovere \u00e8 correlato ad una risorsa
-displayName=Nome visualizzato
-connector=Connettore
-reloadConnectors=Ricarica connettori
-confirmReloadConnectors=Questa richiesta \u00e8 potenzialmente dannosa per le operazioni in corso, proseguire?

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
deleted file mode 100644
index a631352..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
+++ /dev/null
@@ -1,32 +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.
-tab1=Recursos
-edit=Alterar
-delete=Excluir
-create-resource=Criar
-propagationPriority=Prioridade de propaga\u00e7\u00e3o
-propagationPrimary=Propaga\u00e7\u00e3o prim\u00e1ria
-
-tab2=Conectores
-displayName=Mostar
-version=Vers\u00e3o
-bundleName=Nome do Pacote
-create-connector=Criar
-delete_error=Opera\u00e7\u00e3o n\u00e3o permitida\: o conector que voc\u00ea est\u00e1 tentando excluir est\u00e1 conectado a um recurso
-connector=Conector
-reloadConnectors=Carregar Conector
-confirmReloadConnectors=Esta requis\u00e7\u00e3o \u00e9 potencialmente perigosa para opera\u00e7\u00f5es em execu\u00e7\u00e3o, prosseguir?

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
index c981739..b744dc1 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
@@ -33,6 +33,7 @@ import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.builders.ListQueryBuilder;
 import org.apache.syncope.client.lib.builders.AnyListQueryBuilder;
 import org.apache.syncope.client.lib.builders.AnySearchQueryBuilder;
+import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.OrderByClauseBuilder;
 import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
@@ -89,6 +90,15 @@ public class SyncopeClient {
     }
 
     /**
+     * Returns a new instance of {@link AnyObjectFiqlSearchConditionBuilder}, for assisted building of FIQL queries.
+     *
+     * @return default instance of {@link AnyObjectFiqlSearchConditionBuilder}
+     */
+    public static AnyObjectFiqlSearchConditionBuilder getAnyObjectSearchConditionBuilder() {
+        return new AnyObjectFiqlSearchConditionBuilder();
+    }
+
+    /**
      * Returns a new instance of {@link OrderByClauseBuilder}, for assisted building of {@link orderby} clauses.
      *
      * @return default instance of {@link OrderByClauseBuilder}
@@ -119,8 +129,7 @@ public class SyncopeClient {
 
     /**
      * Returns a new instance of {@link AnySearchQueryBuilder}, for assisted building of some service's
-     * {@code search()}
-     * arguments.
+     * {@code search()} arguments.
      *
      * @return default instance of {@link AnySearchQueryBuilder}
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
index 62e4bbe..afd29e9 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
@@ -45,6 +45,7 @@ public class AnyListQueryBuilder extends ListQueryBuilder {
         if (instance.getRealms() == null) {
             instance.setRealms(new ArrayList<String>());
         }
+        instance.getRealms().add(realm);
 
         return this;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java
index e5fcb85..f84e65a 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.common.lib.mod;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.HashSet;
 import java.util.Set;
@@ -144,6 +145,7 @@ public abstract class AnyMod extends AbstractBaseBean {
     /**
      * @return true is all backing collections are empty.
      */
+    @JsonIgnore
     public boolean isEmpty() {
         return plainAttrsToUpdate.isEmpty() && plainAttrsToRemove.isEmpty()
                 && derAttrsToAdd.isEmpty() && derAttrsToRemove.isEmpty()

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
index 9279e72..0ace0b5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
@@ -49,6 +49,7 @@ public abstract class AbstractFiqlSearchConditionBuilder extends FiqlSearchCondi
         return new Builder(properties);
     }
 
+    @Override
     public SyncopeProperty is(final String property) {
         return newBuilderInstance().is(property);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
new file mode 100644
index 0000000..67e7e15
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.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.common.lib.search;
+
+import java.util.Map;
+import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+
+/**
+ * Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
+ * any objects in Syncope.
+ */
+public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
+
+    public AnyObjectFiqlSearchConditionBuilder() {
+        super();
+    }
+
+    public AnyObjectFiqlSearchConditionBuilder(final Map<String, String> properties) {
+        super(properties);
+    }
+
+    @Override
+    protected Builder newBuilderInstance() {
+        return new Builder(properties);
+    }
+
+    @Override
+    public AnyObjectProperty is(final String property) {
+        return newBuilderInstance().is(property);
+    }
+
+    public CompleteCondition type(final String type) {
+        return newBuilderInstance().is(SpecialAttr.TYPE.toString()).equalTo(type);
+    }
+
+    protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder
+            implements AnyObjectProperty, CompleteCondition {
+
+        public Builder(final Map<String, String> properties) {
+            super(properties);
+        }
+
+        public Builder(final Builder parent) {
+            super(parent);
+        }
+
+        @Override
+        public AnyObjectProperty is(final String property) {
+            Builder b = new Builder(this);
+            b.result = property;
+            return b;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
new file mode 100644
index 0000000..c675712
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
@@ -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.
+ */
+package org.apache.syncope.common.lib.search;
+
+public interface AnyObjectProperty extends SyncopeProperty {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
index 9877267..551a0ad 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
@@ -25,6 +25,7 @@ import org.apache.commons.collections4.Predicate;
 public enum SpecialAttr {
 
     NULL("$null"),
+    TYPE("$type"),
     RESOURCES("$resources"),
     GROUPS("$groups"),
     ROLES("$roles");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
deleted file mode 100644
index c562b69..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
+++ /dev/null
@@ -1,74 +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.common.lib.to;
-
-import javax.xml.bind.annotation.XmlEnum;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-/**
- * Mimic ConnId's ObjectClass information.
- */
-@XmlRootElement(name = "connIdObjectClass")
-@XmlType
-public class ConnIdObjectClassTO extends AbstractBaseBean {
-
-    private static final long serialVersionUID = 5802458031138859994L;
-
-    @XmlEnum
-    public enum DefaultType {
-
-        ACCOUNT("__ACCOUNT__"),
-        GROUP("__GROUP__");
-
-        private final String specialName;
-
-        private DefaultType(final String specialName) {
-            this.specialName = specialName;
-        }
-
-        public String getSpecialName() {
-            return specialName;
-        }
-    }
-
-    public static final ConnIdObjectClassTO ACCOUNT = new ConnIdObjectClassTO(DefaultType.ACCOUNT.getSpecialName());
-
-    public static final ConnIdObjectClassTO GROUP = new ConnIdObjectClassTO(DefaultType.GROUP.getSpecialName());
-
-    private String type;
-
-    public ConnIdObjectClassTO() {
-        super();
-    }
-
-    public ConnIdObjectClassTO(final String type) {
-        super();
-        this.type = type;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(final String type) {
-        this.type = type;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
index 92be8e1..c573278 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
@@ -61,7 +61,7 @@ public class MappingTO extends AbstractBaseBean {
     protected boolean addConnObjectKeyItem(final MappingItemTO connObjectItem) {
         if (IntMappingType.UserVirtualSchema == connObjectItem.getIntMappingType()
                 || IntMappingType.GroupVirtualSchema == connObjectItem.getIntMappingType()
-                || IntMappingType.AnyVirtualSchema == connObjectItem.getIntMappingType()
+                || IntMappingType.AnyObjectVirtualSchema == connObjectItem.getIntMappingType()
                 || IntMappingType.Password == connObjectItem.getIntMappingType()) {
 
             throw new IllegalArgumentException("Virtual attributes cannot be set as connObjectKey");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
index 3537bc5..4588a36 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
@@ -53,10 +53,10 @@ public enum IntMappingType {
     // -------------------------
     // Any attribute types (the same in AnyMappingType)
     // -------------------------
-    AnyPlainSchema(AnyTypeKind.ANY_OBJECT),
-    AnyDerivedSchema(AnyTypeKind.ANY_OBJECT),
-    AnyVirtualSchema(AnyTypeKind.ANY_OBJECT),
-    AnyKey(AnyTypeKind.ANY_OBJECT);
+    AnyObjectPlainSchema(AnyTypeKind.ANY_OBJECT),
+    AnyObjectDerivedSchema(AnyTypeKind.ANY_OBJECT),
+    AnyObjectVirtualSchema(AnyTypeKind.ANY_OBJECT),
+    AnyObjectKey(AnyTypeKind.ANY_OBJECT);
 
     private final AnyTypeKind anyTypeKind;
 
@@ -119,7 +119,7 @@ public enum IntMappingType {
     public static Set<IntMappingType> getEmbedded() {
         return EnumSet.of(IntMappingType.UserKey, IntMappingType.Username, IntMappingType.Password,
                 IntMappingType.GroupKey, IntMappingType.GroupName, IntMappingType.GroupOwnerSchema,
-                IntMappingType.AnyKey);
+                IntMappingType.AnyObjectKey);
     }
 
     /**
@@ -192,10 +192,10 @@ public enum IntMappingType {
      */
     private enum AnyMappingType {
 
-        AnyPlainSchema,
-        AnyDerivedSchema,
-        AnyVirtualSchema,
-        AnyKey;
+        AnyObjectPlainSchema,
+        AnyObjectDerivedSchema,
+        AnyObjectVirtualSchema,
+        AnyObjectKey;
 
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.java b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.java
new file mode 100644
index 0000000..868b3f1
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.java
@@ -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.
+ */
+package org.apache.syncope.common.lib.wrap;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "connIdObjectClass")
+@XmlType
+public class ConnIdObjectClass extends AbstractWrappable<String> {
+
+    private static final long serialVersionUID = 613925852330408531L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
new file mode 100644
index 0000000..b460b54
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
@@ -0,0 +1,49 @@
+/*
+ * 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.common.rest.api.service;
+
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.MatrixParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+
+/**
+ * REST operations for anyObjects.
+ */
+@Path("anyObjects")
+public interface AnyObjectService extends AnyService<AnyObjectTO, AnyObjectMod> {
+
+    /**
+     * Returns a paged list of existing any objects matching the given query, for the given type.
+     *
+     * @param type any type
+     * @param listQuery query conditions
+     * @return paged list of existing any objects matching the given query, for the given type
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    PagedResult<AnyObjectTO> list(@MatrixParam("type") String type, @BeanParam AnyListQuery listQuery);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
new file mode 100644
index 0000000..90fbf7d
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -0,0 +1,191 @@
+/*
+ * 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.common.rest.api.service;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.model.wadl.Description;
+import org.apache.cxf.jaxrs.model.wadl.Descriptions;
+import org.apache.cxf.jaxrs.model.wadl.DocTarget;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+
+public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSService {
+
+    /**
+     * Reads the any object matching the provided key.
+     *
+     * @param key key of any object to be read
+     * @return any object with matching id
+     */
+    @GET
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    TO read(@NotNull @PathParam("key") Long key);
+
+    /**
+     * Returns a paged list of existing any objects matching the given query.
+     *
+     * @param listQuery query conditions
+     * @return paged list of existing any objects matching the given query
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    PagedResult<TO> list(@BeanParam AnyListQuery listQuery);
+
+    /**
+     * Returns a paged list of any objects matching the given query.
+     *
+     * @param searchQuery query conditions
+     * @return paged list of any objects matching the given query
+     */
+    @GET
+    @Path("search")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    PagedResult<TO> search(@BeanParam AnySearchQuery searchQuery);
+
+    /**
+     * Creates a new any object.
+     *
+     * @param anyTO any object to be created
+     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created any object as well as the any
+     * object itself enriched with propagation status information - {@link AnyTO} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>Location</tt> header of created any object as well as the "
+                + "any object itself enriched with propagation status information - "
+                + "<tt>AnyTO</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response create(@NotNull TO anyTO);
+
+    /**
+     * Updates any object matching the provided key.
+     *
+     * @param key key of any object to be updated
+     * @param anyMod modification to be applied to any object matching the provided key
+     * @return <tt>Response</tt> object featuring the updated any object enriched with propagation status information
+     * - {@link AnyTO} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring the updated any object enriched with propagation status information - "
+                + "<tt>AnyTO</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response update(@NotNull @PathParam("key") Long key, @NotNull MOD anyMod);
+
+    /**
+     * Deletes any object matching provided key.
+     *
+     * @param key key of any object to be deleted
+     * @return <tt>Response</tt> object featuring the deleted any object enriched with propagation status information
+     * - {@link AnyTO} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring the deleted any object enriched with propagation status information - "
+                + "<tt>AnyTO</tt> as <tt>Entity</tt>")
+    })
+    @DELETE
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response delete(@NotNull @PathParam("key") Long key);
+
+    /**
+     * Executes resource-related operations on given any object.
+     *
+     * @param key any object id.
+     * @param type resource association action type
+     * @param resourceNames external resources to be used for propagation-related operations
+     * @return <tt>Response</tt> object featuring
+     * {@link BulkActionResult} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Path("{key}/deassociate/{type}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response bulkDeassociation(
+            @NotNull @PathParam("key") Long key,
+            @NotNull @PathParam("type") ResourceDeassociationActionType type,
+            @NotNull List<ResourceKey> resourceNames);
+
+    /**
+     * Executes resource-related operations on given any object.
+     *
+     * @param key any object id.
+     * @param type resource association action type
+     * @param associationMod external resources to be used for propagation-related operations
+     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Path("{key}/associate/{type}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response bulkAssociation(
+            @NotNull @PathParam("key") Long key,
+            @NotNull @PathParam("type") ResourceAssociationActionType type,
+            @NotNull ResourceAssociationMod associationMod);
+
+    /**
+     * Executes the provided bulk action.
+     *
+     * @param bulkAction list of any object ids against which the bulk action will be performed.
+     * @return Bulk action result
+     */
+    @POST
+    @Path("bulk")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    BulkActionResult bulk(@NotNull BulkAction bulkAction);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index 07fc6a4..e0c240f 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@ -38,11 +38,11 @@ import org.apache.cxf.jaxrs.model.wadl.DocTarget;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.wrap.BooleanWrap;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
 
 /**
  * REST operations for connector bundles and instances.
@@ -100,7 +100,7 @@ public interface ConnectorService extends JAXRSService {
     @Path("{key}/supportedObjectClasses")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<ConnIdObjectClassTO> getSupportedObjectClasses(
+    List<ConnIdObjectClass> getSupportedObjectClasses(
             @NotNull @PathParam("key") Long key,
             @NotNull ConnInstanceTO connInstanceTO);
 


[17/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
new file mode 100644
index 0000000..e0b9066
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
@@ -0,0 +1,205 @@
+/*
+ * 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.topology;
+
+import java.text.MessageFormat;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.ResourceModalPage;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+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.model.ResourceModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TopologyNodePanel extends Panel {
+
+    private static final long serialVersionUID = -8775095410207013913L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(TopologyNodePanel.class);
+
+    private static final int RESOURCE_MODAL_WIN_HEIGHT = 600;
+
+    private static final int RESOURCE_MODAL_WIN_WIDTH = 800;
+
+    public TopologyNodePanel(
+            final String id, final TopologyNode node, final PageReference pageRef, final BaseRestClient restClient) {
+        super(id);
+
+        final String resourceName = node.getDisplayName().length() > 20
+                ? node.getDisplayName().subSequence(0, 19) + "..."
+                : node.getDisplayName();
+
+        add(new Label("label", resourceName));
+
+        final String title;
+
+        switch (node.getKind()) {
+            case SYNCOPE:
+                title = "";
+                add(getSyncopeFragment(node, (ResourceRestClient) restClient, pageRef));
+                break;
+            case CONNECTOR_SERVER:
+                title = node.getDisplayName();
+                add(getConnectorServerFragment(node, (ResourceRestClient) restClient, pageRef));
+                break;
+            case CONNECTOR:
+                title = (StringUtils.isBlank(node.getConnectionDisplayName())
+                        ? "" : node.getConnectionDisplayName() + ":") + node.getDisplayName();
+                add(getConnectorFragment(node, (ResourceRestClient) restClient, pageRef));
+                break;
+            default:
+                title = node.getDisplayName().length() > 20 ? node.getDisplayName() : "";
+                add(getResurceFragment(node, (ResourceRestClient) restClient, pageRef));
+        }
+
+        if (StringUtils.isNotEmpty(title)) {
+            add(AttributeModifier.append("data-original-title", title));
+        }
+
+        this.setMarkupId(node.getDisplayName());
+    }
+
+    private Fragment getSyncopeFragment(
+            final TopologyNode node, final ResourceRestClient restClient, final PageReference pageRef) {
+        final Fragment fragment = new Fragment("actions", "syncopeActions", this);
+
+        final ModalWindow createWin = new ModalWindow("createWin");
+        fragment.add(createWin);
+
+        createWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        createWin.setInitialHeight(RESOURCE_MODAL_WIN_HEIGHT);
+        createWin.setInitialWidth(RESOURCE_MODAL_WIN_WIDTH);
+        createWin.setTitle(new ResourceModel("connector.new"));
+        createWin.setCookieName("connector-modal");
+
+        return fragment;
+    }
+
+    private Fragment getConnectorServerFragment(
+            final TopologyNode node, final ResourceRestClient restClient, final PageReference pageRef) {
+        final Fragment fragment = new Fragment("actions", "syncopeActions", this);
+
+        final ModalWindow createWin = new ModalWindow("createWin");
+        fragment.add(createWin);
+
+        createWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        createWin.setInitialHeight(RESOURCE_MODAL_WIN_HEIGHT);
+        createWin.setInitialWidth(RESOURCE_MODAL_WIN_WIDTH);
+        createWin.setCookieName("connector-modal");
+        createWin.setTitle(new ResourceModel("connector.new"));
+
+        return fragment;
+    }
+
+    private Fragment getConnectorFragment(
+            final TopologyNode node, final ResourceRestClient restClient, final PageReference pageRef) {
+        final Fragment fragment = new Fragment("actions", "connectorWithNoResourceActions", this);
+
+        final ModalWindow createWin = new ModalWindow("createWin");
+        fragment.add(createWin);
+
+        createWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        createWin.setInitialHeight(RESOURCE_MODAL_WIN_HEIGHT);
+        createWin.setInitialWidth(RESOURCE_MODAL_WIN_WIDTH);
+        createWin.setCookieName("resource-modal");
+        createWin.setTitle(new ResourceModel("resource.new"));
+
+        final ModalWindow editWin = new ModalWindow("editWin");
+        fragment.add(editWin);
+
+        editWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        editWin.setInitialHeight(RESOURCE_MODAL_WIN_HEIGHT);
+        editWin.setInitialWidth(RESOURCE_MODAL_WIN_WIDTH);
+        editWin.setCookieName("connector-modal");
+        editWin.setTitle(MessageFormat.format(getString("connector.edit"), node.getKey()));
+
+        return fragment;
+    }
+
+    private Fragment getResurceFragment(
+            final TopologyNode node, final ResourceRestClient restClient, final PageReference pageRef) {
+        final Fragment fragment = new Fragment("actions", "resourceActions", this);
+
+        final ModalWindow editWin = new ModalWindow("editWin");
+        fragment.add(editWin);
+
+        editWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        editWin.setInitialHeight(RESOURCE_MODAL_WIN_HEIGHT);
+        editWin.setInitialWidth(RESOURCE_MODAL_WIN_WIDTH);
+        editWin.setCookieName("resource-modal");
+        editWin.setTitle(MessageFormat.format(getString("resource.edit"), node.getKey()));
+
+        final AjaxLink<String> delete = new IndicatingAjaxLink<String>("delete") {
+
+            private static final long serialVersionUID = 3776750333491622263L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    restClient.delete(node.getKey().toString());
+                    target.appendJavaScript(String.format("jsPlumb.remove('%s');", node.getDisplayName()));
+                    info(getString(Constants.OPERATION_SUCCEEDED));
+                } catch (SyncopeClientException e) {
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    LOG.error("While deleting resource {}", node.getKey(), e);
+                }
+            }
+        };
+        fragment.add(delete);
+
+        final AjaxLink<String> edit = new IndicatingAjaxLink<String>("edit") {
+
+            private static final long serialVersionUID = 3776750333491622263L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                editWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        return new ResourceModalPage(
+                                pageRef,
+                                editWin,
+                                restClient.read(node.getKey().toString()),
+                                false);
+                    }
+                });
+
+                editWin.show(target);
+            }
+        };
+        fragment.add(edit);
+
+        return fragment;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyReloadBehavior.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyReloadBehavior.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyReloadBehavior.java
new file mode 100644
index 0000000..434c7ea
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyReloadBehavior.java
@@ -0,0 +1,61 @@
+/*
+ * 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.topology;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnLoadHeaderItem;
+
+public class TopologyReloadBehavior extends Behavior {
+
+    private static final long serialVersionUID = 1L;
+
+    private final String source;
+
+    private final String target;
+
+    private final TopologyNode.Status status;
+
+    public TopologyReloadBehavior(final String source, final String target, final TopologyNode.Status status) {
+        this.source = source;
+        this.target = target;
+        this.status = status;
+    }
+
+    @Override
+    public void renderHead(final Component component, final IHeaderResponse response) {
+
+        switch (status) {
+            case UNKNOWN:
+                response.render(OnLoadHeaderItem.forScript(String.format("unknown('%s', '%s')", source, target)));
+                break;
+            case REACHABLE:
+                response.render(OnLoadHeaderItem.forScript(String.format("enable('%s', '%s')", source, target)));
+                break;
+            case UNREACHABLE:
+                response.render(OnLoadHeaderItem.forScript(String.format("disable('%s', '%s')", source, target)));
+                break;
+            default:
+                response.render(OnLoadHeaderItem.forScript(String.format("failure('%s', '%s')", source, target)));
+            // remove subtree
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..37cc455
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java
@@ -0,0 +1,76 @@
+/*
+ * 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.syncope.client.console.pages.BasePage;
+import org.apache.wicket.Page;
+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;
+
+    private boolean reloadFeebackPanel = true;
+
+    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) {
+        this.reloadFeebackPanel = reloadFeedbackPanel;
+        return this;
+    }
+
+    @Override
+    protected final void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+        super.onSubmit(target, form);
+
+        Page page = pageRef.getPage();
+        if (reloadFeebackPanel && page instanceof BasePage) {
+            target.add(((BasePage) page).getFeedbackPanel());
+        }
+        onSubmitInternal(target, form);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..e052846
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java
@@ -0,0 +1,61 @@
+/*
+ * 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.syncope.client.console.pages.BasePage;
+import org.apache.wicket.Page;
+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;
+    }
+
+    public ClearIndicatingAjaxLink(final String id, final IModel<T> model, final PageReference pageRef) {
+        super(id, model);
+        this.pageRef = pageRef;
+    }
+
+    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) {
+        Page page = pageRef.getPage();
+        if (reloadFeedbackPanel && page instanceof BasePage) {
+            target.add(((BasePage) page).getFeedbackPanel());
+        }
+        onClickInternal(target);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
new file mode 100644
index 0000000..013fa3a
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table;
+
+import java.beans.PropertyDescriptor;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.BulkActionResult.Status;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+
+public class ActionResultColumn<T, S> extends AbstractColumn<T, S> {
+
+    private static final long serialVersionUID = 7955560320949560716L;
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(ActionResultColumn.class);
+
+    private final BulkActionResult results;
+
+    private final String idFieldName;
+
+    public ActionResultColumn(final BulkActionResult results, final String idFieldName) {
+        super(new Model<String>());
+        this.results = results;
+        this.idFieldName = idFieldName;
+    }
+
+    @Override
+    public String getCssClass() {
+        return "bulkResultColumn";
+    }
+
+    @Override
+    public Component getHeader(final String componentId) {
+        return new Label(componentId, new ResourceModel("bulkActionResultLabel", "Result"));
+    }
+
+    @Override
+    public void populateItem(final Item<ICellPopulator<T>> item, final String componentId, final IModel<T> rowModel) {
+        try {
+            final PropertyDescriptor propDesc = BeanUtils.getPropertyDescriptor(rowModel.getObject().getClass(),
+                    idFieldName);
+            final Object id = propDesc.getReadMethod().invoke(rowModel.getObject(), new Object[0]);
+            final Status status = id == null ? null : results.getResultMap().get(id.toString());
+            item.add(new Label(componentId, status == null ? Status.SUCCESS : status.toString()));
+        } catch (Exception e) {
+            LOG.error("Errore retrieving target id value", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.java
new file mode 100644
index 0000000..8f880b7
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxGroupSelectorPanel.java
@@ -0,0 +1,34 @@
+/*
+ * 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.extensions.markup.html.repeater.data.table;
+
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.CheckGroupSelector;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class CheckBoxGroupSelectorPanel<T> extends Panel {
+
+    private static final long serialVersionUID = 4062106303929176865L;
+
+    public CheckBoxGroupSelectorPanel(final String componentId, final CheckGroup<T> group) {
+
+        super(componentId);
+        add(new CheckGroupSelector("groupselector", group));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.java
new file mode 100644
index 0000000..6270a0f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckBoxPanel.java
@@ -0,0 +1,43 @@
+/*
+ * 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.extensions.markup.html.repeater.data.table;
+
+import org.apache.syncope.client.console.commons.ActionTableCheckGroup;
+import org.apache.wicket.markup.html.form.Check;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+
+public class CheckBoxPanel<T> extends Panel {
+
+    private static final long serialVersionUID = 4062106303929176865L;
+
+    private final Check<T> check;
+
+    public CheckBoxPanel(final String componentId, final IModel<T> model, final CheckGroup<T> checkGroup) {
+        super(componentId, model);
+        this.check = new Check<>("check", model, checkGroup);
+        if (checkGroup instanceof ActionTableCheckGroup) {
+            boolean checkable = ((ActionTableCheckGroup<T>) checkGroup).isCheckable(model.getObject());
+            this.check.setEnabled(checkable);
+            this.check.setVisible(checkable);
+        }
+        add(this.check);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckGroupColumn.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckGroupColumn.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckGroupColumn.java
new file mode 100644
index 0000000..6a9dcd6
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/CheckGroupColumn.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+public class CheckGroupColumn<T, S> extends AbstractColumn<T, S> {
+
+    private static final long serialVersionUID = 7955560320949560715L;
+
+    private final CheckGroup<T> group;
+
+    public CheckGroupColumn(final CheckGroup<T> checkGroup) {
+        super(new Model<String>());
+        this.group = checkGroup;
+    }
+
+    @Override
+    public String getCssClass() {
+        return "checkGroupColumn";
+    }
+
+    @Override
+    public Component getHeader(final String componentId) {
+        return new CheckBoxGroupSelectorPanel<>(componentId, group);
+    }
+
+    @Override
+    public void populateItem(final Item<ICellPopulator<T>> item, final String componentId, final IModel<T> rowModel) {
+        item.add(new CheckBoxPanel<>(componentId, rowModel, group));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..71bcc0f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -0,0 +1,85 @@
+/*
+ * 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.markup.html.form;
+
+import java.io.Serializable;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+public abstract class ActionLink implements Serializable {
+
+    private static final long serialVersionUID = 7031329706998320639L;
+
+    private boolean reloadFeedbackPanel = true;
+
+    public enum ActionType {
+
+        CREATE("create"),
+        EDIT("read"),
+        USER_TEMPLATE("read"),
+        GROUP_TEMPLATE("read"),
+        RESET("update"),
+        ENABLE("update"),
+        SEARCH("read"),
+        DELETE("delete"),
+        EXECUTE("execute"),
+        DRYRUN("execute"),
+        CLAIM("claim"),
+        SELECT("read"),
+        EXPORT("read"),
+        SUSPEND("update"),
+        REACTIVATE("update"),
+        RELOAD("reload"),
+        CHANGE_VIEW("changeView"),
+        UNLINK("update"),
+        LINK("update"),
+        UNASSIGN("update"),
+        ASSIGN("update"),
+        DEPROVISION("update"),
+        PROVISION("update"),
+        MANAGE_RESOURCES("update"),
+        MANAGE_USERS("update"),
+        MANAGE_GROUPS("update"),
+        ZOOM_IN("zoomin"),
+        ZOOM_OUT("zoomout");
+
+        private final String actionId;
+
+        private ActionType(final String actionId) {
+            this.actionId = actionId;
+        }
+
+        public String getActionId() {
+            return actionId;
+        }
+    }
+
+    public abstract void onClick(final AjaxRequestTarget target);
+
+    public void postClick() {
+    }
+
+    public boolean feedbackPanelAutomaticReload() {
+        return reloadFeedbackPanel;
+    }
+
+    public ActionLink feedbackPanelAutomaticReload(final boolean reloadFeedbackPanel) {
+        this.reloadFeedbackPanel = reloadFeedbackPanel;
+        return this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..433f9f5
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
@@ -0,0 +1,609 @@
+/*
+ * 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.markup.html.form;
+
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.IndicatingOnConfirmAjaxLink;
+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.markup.html.panel.Fragment;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+
+/**
+ * This empty class must exist because there not seems to be alternative to provide specialized HTML for edit links.
+ */
+public class ActionLinksPanel extends Panel {
+
+    private static final long serialVersionUID = 322966537010107771L;
+
+    private final PageReference pageRef;
+
+    public ActionLinksPanel(final String componentId, final IModel<?> model, final PageReference pageRef) {
+        super(componentId, model);
+        this.pageRef = pageRef;
+
+        super.add(new Fragment("panelClaim", "emptyFragment", this));
+        super.add(new Fragment("panelManageResources", "emptyFragment", this));
+        super.add(new Fragment("panelManageUsers", "emptyFragment", this));
+        super.add(new Fragment("panelManageGroups", "emptyFragment", this));
+        super.add(new Fragment("panelCreate", "emptyFragment", this));
+        super.add(new Fragment("panelEdit", "emptyFragment", this));
+        super.add(new Fragment("panelReset", "emptyFragment", this));
+        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("panelSearch", "emptyFragment", this));
+        super.add(new Fragment("panelDelete", "emptyFragment", this));
+        super.add(new Fragment("panelExecute", "emptyFragment", this));
+        super.add(new Fragment("panelDryRun", "emptyFragment", this));
+        super.add(new Fragment("panelSelect", "emptyFragment", this));
+        super.add(new Fragment("panelExport", "emptyFragment", this));
+        super.add(new Fragment("panelSuspend", "emptyFragment", this));
+        super.add(new Fragment("panelReactivate", "emptyFragment", this));
+        super.add(new Fragment("panelReload", "emptyFragment", this));
+        super.add(new Fragment("panelChangeView", "emptyFragment", this));
+        super.add(new Fragment("panelUnlink", "emptyFragment", this));
+        super.add(new Fragment("panelLink", "emptyFragment", this));
+        super.add(new Fragment("panelUnassign", "emptyFragment", this));
+        super.add(new Fragment("panelAssign", "emptyFragment", this));
+        super.add(new Fragment("panelDeprovision", "emptyFragment", this));
+        super.add(new Fragment("panelProvision", "emptyFragment", this));
+        super.add(new Fragment("panelZoomIn", "emptyFragment", this));
+        super.add(new Fragment("panelZoomOut", "emptyFragment", this));
+
+    }
+
+    public ActionLinksPanel add(
+            final ActionLink link, final ActionLink.ActionType type, final String entitlements) {
+
+        return addWithRoles(link, type, entitlements, true);
+    }
+
+    public ActionLinksPanel add(
+            final ActionLink link, final ActionLink.ActionType type, final String entitlement, final boolean enabled) {
+
+        return addWithRoles(link, type, entitlement, enabled);
+    }
+
+    public ActionLinksPanel addWithRoles(
+            final ActionLink link, final ActionLink.ActionType type, final String entitlements) {
+
+        return addWithRoles(link, type, entitlements, true);
+    }
+
+    public ActionLinksPanel addWithRoles(
+            final ActionLink link, final ActionLink.ActionType type, final String entitlements, final boolean enabled) {
+
+        Fragment fragment = null;
+
+        switch (type) {
+
+            case CLAIM:
+                fragment = new Fragment("panelClaim", "fragmentClaim", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("claimLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case MANAGE_RESOURCES:
+                fragment = new Fragment("panelManageResources", "fragmentManageResources", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageResourcesLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610291L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case MANAGE_USERS:
+                fragment = new Fragment("panelManageUsers", "fragmentManageUsers", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageUsersLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610292L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case MANAGE_GROUPS:
+                fragment = new Fragment("panelManageGroups", "fragmentManageGroups", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageGroupsLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610293L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case CREATE:
+                fragment = new Fragment("panelCreate", "fragmentCreate", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("createLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case RESET:
+                fragment = new Fragment("panelReset", "fragmentReset", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("resetLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610290L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                });
+                break;
+
+            case EDIT:
+                fragment = new Fragment("panelEdit", "fragmentEdit", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("editLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case USER_TEMPLATE:
+                fragment = new Fragment("panelUserTemplate", "fragmentUserTemplate", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("userTemplateLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case GROUP_TEMPLATE:
+                fragment = new Fragment("panelGroupTemplate", "fragmentGroupTemplate", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("groupTemplateLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case ENABLE:
+                fragment = new Fragment("panelEnable", "fragmentEnable", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("enableLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case SEARCH:
+                fragment = new Fragment("panelSearch", "fragmentSearch", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("searchLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case EXECUTE:
+                fragment = new Fragment("panelExecute", "fragmentExecute", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("executeLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case DRYRUN:
+                fragment = new Fragment("panelDryRun", "fragmentDryRun", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("dryRunLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case DELETE:
+                fragment = new Fragment("panelDelete", "fragmentDelete", this);
+
+                fragment.addOrReplace(new IndicatingOnConfirmAjaxLink<Void>("deleteLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+
+                break;
+
+            case SELECT:
+                fragment = new Fragment("panelSelect", "fragmentSelect", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("selectLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+
+                break;
+
+            case EXPORT:
+                fragment = new Fragment("panelExport", "fragmentExport", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("exportLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case SUSPEND:
+                fragment = new Fragment("panelSuspend", "fragmentSuspend", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("suspendLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610291L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case REACTIVATE:
+                fragment = new Fragment("panelReactivate", "fragmentReactivate", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("reactivateLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610292L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case RELOAD:
+                fragment = new Fragment("panelReload", "fragmentReload", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("reloadLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610293L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case CHANGE_VIEW:
+                fragment = new Fragment("panelChangeView", "fragmentChangeView", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("changeViewLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610292L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case UNLINK:
+                fragment = new Fragment("panelUnlink", "fragmentUnlink", this);
+
+                fragment.addOrReplace(
+                        new IndicatingOnConfirmAjaxLink<Void>("unlinkLink", pageRef, "confirmUnlink") {
+
+                            private static final long serialVersionUID = -6957616042924610293L;
+
+                            @Override
+                            protected void onClickInternal(final AjaxRequestTarget target) {
+                                link.onClick(target);
+                            }
+                        }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case LINK:
+                fragment = new Fragment("panelLink", "fragmentLink", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("linkLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610303L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case UNASSIGN:
+                fragment = new Fragment("panelUnassign", "fragmentUnassign", this);
+
+                fragment.addOrReplace(
+                        new IndicatingOnConfirmAjaxLink<Void>("unassignLink", pageRef, "confirmUnassign") {
+
+                            private static final long serialVersionUID = -6957616042924610294L;
+
+                            @Override
+                            protected void onClickInternal(final AjaxRequestTarget target) {
+                                link.onClick(target);
+                            }
+                        }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case ASSIGN:
+                fragment = new Fragment("panelAssign", "fragmentAssign", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("assignLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610304L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case DEPROVISION:
+                fragment = new Fragment("panelDeprovision", "fragmentDeprovision", this);
+
+                fragment.addOrReplace(
+                        new IndicatingOnConfirmAjaxLink<Void>("deprovisionLink", pageRef, "confirmDeprovision") {
+
+                            private static final long serialVersionUID = -6957616042924610295L;
+
+                            @Override
+                            protected void onClickInternal(final AjaxRequestTarget target) {
+                                link.onClick(target);
+                            }
+                        }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+
+            case PROVISION:
+                fragment = new Fragment("panelProvision", "fragmentProvision", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("provisionLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610305L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+            case ZOOM_IN:
+                fragment = new Fragment("panelZoomIn", "fragmentZoomIn", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("zoomInLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610305L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+            case ZOOM_OUT:
+                fragment = new Fragment("panelZoomOut", "fragmentZoomOut", this);
+
+                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("zoomOutLink", pageRef) {
+
+                    private static final long serialVersionUID = -6957616042924610305L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        link.onClick(target);
+                    }
+                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()));
+                break;
+            default:
+            // do nothing
+        }
+
+        if (fragment != null) {
+            fragment.setEnabled(enabled);
+            MetaDataRoleAuthorizationStrategy.authorize(fragment, ENABLE, entitlements);
+            super.addOrReplace(fragment);
+        }
+
+        return this;
+    }
+
+    public void remove(final ActionLink.ActionType type) {
+        switch (type) {
+            case CLAIM:
+                super.addOrReplace(new Fragment("panelClaim", "emptyFragment", this));
+                break;
+
+            case MANAGE_RESOURCES:
+                super.addOrReplace(new Fragment("panelManageResources", "emptyFragment", this));
+                break;
+
+            case MANAGE_USERS:
+                super.addOrReplace(new Fragment("panelManageUsers", "emptyFragment", this));
+                break;
+
+            case MANAGE_GROUPS:
+                super.addOrReplace(new Fragment("panelManageGroups", "emptyFragment", this));
+                break;
+
+            case CREATE:
+                super.addOrReplace(new Fragment("panelCreate", "emptyFragment", this));
+                break;
+
+            case EDIT:
+                super.addOrReplace(new Fragment("panelEdit", "emptyFragment", this));
+                break;
+
+            case USER_TEMPLATE:
+                super.addOrReplace(new Fragment("panelUserTemplate", "emptyFragment", this));
+                break;
+
+            case SEARCH:
+                super.addOrReplace(new Fragment("panelSearch", "emptyFragment", this));
+                break;
+
+            case EXECUTE:
+                super.addOrReplace(new Fragment("panelExecute", "emptyFragment", this));
+                break;
+
+            case DRYRUN:
+                super.addOrReplace(new Fragment("panelDryRun", "emptyFragment", this));
+                break;
+
+            case DELETE:
+                super.addOrReplace(new Fragment("panelDelete", "emptyFragment", this));
+                break;
+
+            case SELECT:
+                super.addOrReplace(new Fragment("panelSelect", "emptyFragment", this));
+                break;
+
+            case EXPORT:
+                super.addOrReplace(new Fragment("panelExport", "emptyFragment", this));
+                break;
+
+            case SUSPEND:
+                super.addOrReplace(new Fragment("panelSuspend", "emptyFragment", this));
+                break;
+
+            case REACTIVATE:
+                super.addOrReplace(new Fragment("panelReactivate", "emptyFragment", this));
+                break;
+
+            case RELOAD:
+                super.addOrReplace(new Fragment("panelReload", "emptyFragment", this));
+                break;
+
+            case CHANGE_VIEW:
+                super.addOrReplace(new Fragment("panelChangeView", "emptyFragment", this));
+                break;
+
+            case UNLINK:
+                super.addOrReplace(new Fragment("panelUnlink", "emptyFragment", this));
+                break;
+
+            case LINK:
+                super.addOrReplace(new Fragment("panelLink", "emptyFragment", this));
+                break;
+
+            case UNASSIGN:
+                super.addOrReplace(new Fragment("panelUnassign", "emptyFragment", this));
+                break;
+
+            case ASSIGN:
+                super.addOrReplace(new Fragment("panelAssign", "emptyFragment", this));
+                break;
+
+            case DEPROVISION:
+                super.addOrReplace(new Fragment("panelDeprovision", "emptyFragment", this));
+                break;
+
+            case PROVISION:
+                super.addOrReplace(new Fragment("panelProvision", "emptyFragment", this));
+                break;
+            case ZOOM_IN:
+                super.addOrReplace(new Fragment("panelZoomIn", "emptyFragment", this));
+                break;
+            case ZOOM_OUT:
+                super.addOrReplace(new Fragment("panelZoomOut", "emptyFragment", this));
+                break;
+            default:
+            // do nothing
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.java
index 6854fb0..df8e808 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxTextFieldPanel.java
@@ -53,7 +53,7 @@ public class AjaxTextFieldPanel extends FieldPanel<String> implements Cloneable
             protected Iterator<String> getChoices(final String input) {
                 final Pattern pattern = Pattern.compile(".*" + Pattern.quote(input) + ".*", Pattern.CASE_INSENSITIVE);
 
-                final List<String> result = new ArrayList<String>();
+                final List<String> result = new ArrayList<>();
 
                 for (String choice : choices) {
                     if (pattern.matcher(choice).matches()) {
@@ -64,7 +64,7 @@ public class AjaxTextFieldPanel extends FieldPanel<String> implements Cloneable
                 return result.iterator();
             }
         };
-        add(field.setLabel(new Model<String>(name)).setOutputMarkupId(true));
+        add(field.setLabel(new Model<>(name)).setOutputMarkupId(true));
 
         if (!isReadOnly()) {
             field.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java
new file mode 100644
index 0000000..86db915
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java
@@ -0,0 +1,58 @@
+/*
+ * 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.Component;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+
+public abstract class IndicatingOnConfirmAjaxLink<T> extends ClearIndicatingAjaxLink<T> {
+
+    private static final long serialVersionUID = 2228670850922265663L;
+
+    private final String msg;
+
+    public IndicatingOnConfirmAjaxLink(final String id, final PageReference pageRef) {
+        this(id, pageRef, "confirmDelete");
+    }
+
+    public IndicatingOnConfirmAjaxLink(final String id, final PageReference pageRef, final String msg) {
+        super(id, pageRef);
+        this.msg = msg;
+    }
+
+    @Override
+    protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+        super.updateAjaxAttributes(attributes);
+
+        final AjaxCallListener ajaxCallListener = new AjaxCallListener() {
+
+            private static final long serialVersionUID = 7160235486520935153L;
+
+            @Override
+            public CharSequence getPrecondition(final Component component) {
+                return "if (!confirm('"
+                        + getString(IndicatingOnConfirmAjaxLink.this.msg)
+                        + "')) {return false;} else {return true;}";
+            }
+        };
+        attributes.getAjaxCallListeners().add(ajaxCallListener);
+    }
+}


[10/27] syncope git commit: Merge from 1_2_X

Posted by il...@apache.org.
Merge from 1_2_X


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

Branch: refs/heads/SYNCOPE-666
Commit: a6bcbd4650b66a160d6150df36c7d3df39d59165
Parents: 8f25b25 bcf3b43
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jun 8 14:47:19 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jun 8 14:47:19 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a6bcbd46/pom.xml
----------------------------------------------------------------------
diff --cc pom.xml
index d316c03,a32149c..f2d75af
--- a/pom.xml
+++ b/pom.xml
@@@ -634,75 -682,74 +634,75 @@@ under the License
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
-         <version>1.8.5</version>
 -        <version>${aspectj.version}</version>
++        <version>1.8.6</version>
        </dependency>
 -
 +      
        <dependency>
 -        <groupId>javax.ws.rs</groupId>
 -        <artifactId>javax.ws.rs-api</artifactId>
 -        <version>${jax-rs.version}</version>
 +        <groupId>commons-io</groupId>
 +        <artifactId>commons-io</artifactId>
 +        <version>${commons-io.version}</version>
        </dependency>
 -
 -      <!-- CXF -->
        <dependency>
 -        <groupId>org.apache.cxf</groupId>
 -        <artifactId>cxf-rt-frontend-jaxrs</artifactId>
 -        <version>${cxf.version}</version>
 +        <groupId>commons-codec</groupId>
 +        <artifactId>commons-codec</artifactId>
 +        <version>${commons-codec.version}</version>
        </dependency>
        <dependency>
 -        <groupId>org.apache.cxf</groupId>
 -        <artifactId>cxf-rt-rs-extension-providers</artifactId>
 -        <version>${cxf.version}</version>
 +        <groupId>org.apache.commons</groupId>
 +        <artifactId>commons-jexl</artifactId>
 +        <version>${commons-jexl.version}</version>
        </dependency>
        <dependency>
 -        <groupId>org.apache.cxf</groupId>
 -        <artifactId>cxf-rt-rs-extension-search</artifactId>
 -        <version>${cxf.version}</version>
 +        <groupId>org.apache.commons</groupId>
 +        <artifactId>commons-lang3</artifactId>
 +        <version>${commons-lang.version}</version>
        </dependency>
        <dependency>
 -        <groupId>org.apache.cxf</groupId>
 -        <artifactId>cxf-rt-frontend-jaxws</artifactId>
 -        <version>${cxf.version}</version>
 +        <groupId>org.apache.commons</groupId>
 +        <artifactId>commons-collections4</artifactId>
 +        <version>${commons-collection.version}</version>
        </dependency>
 +            
        <dependency>
 -        <groupId>org.apache.cxf</groupId>
 -        <artifactId>cxf-rt-rs-service-description</artifactId>
 -        <version>${cxf.version}</version>
 +        <groupId>net.tirasa.connid</groupId>
 +        <artifactId>connector-framework</artifactId>
 +        <version>${connid.version}</version>
        </dependency>
        <dependency>
 -        <groupId>org.apache.cxf</groupId>
 -        <artifactId>cxf-rt-rs-client</artifactId>
 -        <version>${cxf.version}</version>
 -      </dependency>      
 -      <!-- /CXF -->
 -
 +        <groupId>net.tirasa.connid</groupId>
 +        <artifactId>connector-framework-internal</artifactId>
 +        <version>${connid.version}</version>
 +      </dependency>
        <dependency>
 -        <groupId>com.fasterxml.jackson.core</groupId>
 -        <artifactId>jackson-core</artifactId>
 -        <version>${jackson.version}</version>
 +        <groupId>net.tirasa.connid</groupId>
 +        <artifactId>slf4j-logging</artifactId>
 +        <version>${connid.version}</version>
        </dependency>
 +      
        <dependency>
 -        <groupId>com.fasterxml.jackson.core</groupId>
 -        <artifactId>jackson-databind</artifactId>
 -        <version>${jackson.version}</version>
 +        <groupId>org.codehaus.groovy</groupId>
 +        <artifactId>groovy-all</artifactId>
 +        <version>${groovy.version}</version>
        </dependency>
 +
        <dependency>
 -        <groupId>com.fasterxml.jackson.core</groupId>
 -        <artifactId>jackson-annotations</artifactId>
 -        <version>${jackson.version}</version>
 +        <groupId>com.h2database</groupId>
 +        <artifactId>h2</artifactId>
 +        <version>${h2.version}</version>
        </dependency>
 +
        <dependency>
 -        <groupId>com.fasterxml.jackson.jaxrs</groupId>
 -        <artifactId>jackson-jaxrs-json-provider</artifactId>
 -        <version>${jackson.version}</version>
 +        <groupId>org.apache.directory.server</groupId>
 +        <artifactId>apacheds-all</artifactId>
 +        <version>2.0.0-M20</version>
        </dependency>
 +      
        <dependency>
 -        <groupId>com.fasterxml.jackson.module</groupId>
 -        <artifactId>jackson-module-afterburner</artifactId>
 -        <version>${jackson.version}</version>
 +        <groupId>org.jasypt</groupId>
 +        <artifactId>jasypt</artifactId>
 +        <version>${jasypt.version}</version>
        </dependency>
 -
 +      
        <dependency>
          <groupId>org.quartz-scheduler</groupId>
          <artifactId>quartz</artifactId>


[05/27] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/SYNCOPE-666
Commit: e3e57dfb95462da33bc07f6a5549f58157c86461
Parents: 4759d03 eb99e24
Author: fmartelli <fa...@gmail.com>
Authored: Thu May 21 09:14:29 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu May 21 09:14:29 2015 +0200

----------------------------------------------------------------------
 .../core/logic/AbstractSubjectLogic.java        | 40 +++++++++++------
 .../apache/syncope/core/logic/UserLogic.java    |  2 +-
 .../src/test/resources/content.xml              | 10 ++++-
 .../core/provisioning/api/job/JobNamer.java     |  4 +-
 .../java/job/SpringBeanJobFactory.java          | 17 -------
 .../core/reference/AuthenticationITCase.java    | 47 +++++++++-----------
 .../fit/core/reference/UserWorkflowITCase.java  |  2 +-
 pom.xml                                         |  2 +-
 8 files changed, 62 insertions(+), 62 deletions(-)
----------------------------------------------------------------------



[22/27] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
new file mode 100644
index 0000000..e2b339a
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
@@ -0,0 +1,126 @@
+/*
+ * 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.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyObjectITCase extends AbstractITCase {
+
+    public static AnyObjectTO getSampleTO(final String location) {
+        AnyObjectTO anyObjectTO = new AnyObjectTO();
+        anyObjectTO.setRealm(SyncopeConstants.ROOT_REALM);
+        anyObjectTO.setType("PRINTER");
+        anyObjectTO.getPlainAttrs().add(attrTO("location", location + getUUIDString()));
+
+        anyObjectTO.getResources().add(RESOURCE_NAME_DBSCRIPTED);
+        return anyObjectTO;
+    }
+
+    @Test
+    public void create() {
+        AnyObjectTO anyObjectTO = getSampleTO("create");
+
+        anyObjectTO = createAnyObject(anyObjectTO);
+        assertNotNull(anyObjectTO);
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
+        assertNotNull(connObjectTO);
+        assertNotNull(connObjectTO.getPlainAttrMap().get("location"));
+        assertEquals(anyObjectTO.getPlainAttrMap().get("location"), connObjectTO.getPlainAttrMap().get("location"));
+    }
+
+    @Test
+    public void delete() {
+        try {
+            anyObjectService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        AnyObjectTO anyObjectTO = getSampleTO("deletable");
+        anyObjectTO.setRealm("/even");
+
+        anyObjectTO = createAnyObject(anyObjectTO);
+        assertNotNull(anyObjectTO);
+
+        AnyObjectTO deletedAnyObject = deleteAnyObject(anyObjectTO.getKey());
+        assertNotNull(deletedAnyObject);
+
+        try {
+            anyObjectService.read(deletedAnyObject.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        PagedResult<AnyObjectTO> anyObjectTOs = anyObjectService.list("PRINTER", SyncopeClient.getAnyListQueryBuilder().
+                realm(SyncopeConstants.ROOT_REALM).build());
+        assertNotNull(anyObjectTOs);
+        assertTrue(anyObjectTOs.getResult().size() >= 2);
+        for (AnyObjectTO anyObjectTO : anyObjectTOs.getResult()) {
+            assertNotNull(anyObjectTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        AnyObjectTO anyObjectTO = anyObjectService.read(1L);
+
+        assertNotNull(anyObjectTO);
+        assertNotNull(anyObjectTO.getPlainAttrs());
+        assertFalse(anyObjectTO.getPlainAttrs().isEmpty());
+    }
+
+    @Test
+    public void update() {
+        AnyObjectTO anyObjectTO = getSampleTO("update");
+        anyObjectTO = createAnyObject(anyObjectTO);
+
+        assertEquals(1, anyObjectTO.getPlainAttrs().size());
+
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(anyObjectTO.getKey());
+        String newLocation = "new" + getUUIDString();
+        anyObjectMod.getPlainAttrsToUpdate().add(attrMod("location", newLocation));
+
+        anyObjectTO = updateAnyObject(anyObjectMod);
+
+        assertEquals(newLocation, anyObjectTO.getPlainAttrMap().get("location").getValues().get(0));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
new file mode 100644
index 0000000..4dbb796
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
@@ -0,0 +1,117 @@
+/*
+ * 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.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyTypeClassITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
+        assertNotNull(minimalGroup);
+
+        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
+        assertFalse(minimalGroup.getDerSchemas().isEmpty());
+        assertFalse(minimalGroup.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void list() {
+        List<AnyTypeClassTO> list = anyTypeClassService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getPlainSchemas().add("firstname");
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertTrue(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+
+        newClass.getDerSchemas().add("cn");
+        anyTypeClassService.update(newClass.getKey(), newClass);
+
+        newClass = anyTypeClassService.read(newClass.getKey());
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertFalse(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+
+        anyTypeClassService.delete(newClass.getKey());
+
+        try {
+            anyTypeClassService.read(newClass.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteSchema() {
+        PlainSchemaTO newSchema = new PlainSchemaTO();
+        newSchema.setKey("newSchema" + getUUIDString());
+        newSchema.setType(AttrSchemaType.Date);
+        createSchema(SchemaType.PLAIN, newSchema);
+
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getPlainSchemas().add(newSchema.getKey());
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+        assertTrue(newClass.getPlainSchemas().contains(newSchema.getKey()));
+
+        schemaService.delete(SchemaType.PLAIN, newSchema.getKey());
+
+        newClass = anyTypeClassService.read(newClass.getKey());
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().contains(newSchema.getKey()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
new file mode 100644
index 0000000..01da6f8
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
@@ -0,0 +1,169 @@
+/*
+ * 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.fit.core.reference;
+
+import static org.apache.syncope.fit.core.reference.AbstractITCase.getUUIDString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyTypeITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        AnyTypeTO userType = anyTypeService.read(AnyTypeKind.USER.name());
+        assertNotNull(userType);
+        assertEquals(AnyTypeKind.USER, userType.getKind());
+        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
+        assertFalse(userType.getClasses().isEmpty());
+
+        AnyTypeTO groupType = anyTypeService.read(AnyTypeKind.GROUP.name());
+        assertNotNull(groupType);
+        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
+        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
+        assertFalse(groupType.getClasses().isEmpty());
+
+        AnyTypeTO otherType = anyTypeService.read("PRINTER");
+        assertNotNull(otherType);
+        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
+        assertEquals("PRINTER", otherType.getKey());
+    }
+
+    @Test
+    public void list() {
+        List<AnyTypeTO> list = anyTypeService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        newType.getClasses().add("generic membership");
+        newType.getClasses().add("csv");
+
+        Response response = anyTypeService.create(newType);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newType = getObject(response.getLocation(), AnyTypeService.class, AnyTypeTO.class);
+        assertNotNull(newType);
+        assertEquals(2, newType.getClasses().size());
+        assertTrue(newType.getClasses().contains("generic membership"));
+        assertTrue(newType.getClasses().contains("csv"));
+
+        newType.getClasses().remove("generic membership");
+        anyTypeService.update(newType.getKey(), newType);
+
+        newType = anyTypeService.read(newType.getKey());
+        assertNotNull(newType);
+        assertEquals(1, newType.getClasses().size());
+        assertTrue(newType.getClasses().contains("csv"));
+
+        anyTypeService.delete(newType.getKey());
+
+        try {
+            anyTypeService.read(newType.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidKind() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.USER);
+        try {
+            anyTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidName() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("group");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        try {
+            anyTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteInvalid() {
+        try {
+            anyTypeService.delete(AnyTypeKind.USER.name());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteTypeClass() {
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getDerSchemas().add("cn");
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+
+        AnyTypeTO other = anyTypeService.read("PRINTER");
+        assertNotNull(other);
+
+        other.getClasses().add(newClass.getKey());
+        anyTypeService.update(other.getKey(), other);
+
+        other = anyTypeService.read(other.getKey());
+        assertNotNull(other);
+        assertTrue(other.getClasses().contains(newClass.getKey()));
+
+        anyTypeClassService.delete(newClass.getKey());
+
+        other = anyTypeService.read(other.getKey());
+        assertNotNull(other);
+        assertFalse(other.getClasses().contains(newClass.getKey()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
index 1136f02..2616d4a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
@@ -40,7 +40,6 @@ import org.apache.commons.io.IOUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnPoolConfTO;
 import org.apache.syncope.common.lib.to.MappingItemTO;
@@ -53,6 +52,7 @@ import org.apache.syncope.common.lib.types.ConnConfPropSchema;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.identityconnectors.common.security.GuardedString;
@@ -88,7 +88,7 @@ public class ConnectorITCase extends AbstractITCase {
             }
 
             connidSoapVersion = props.getProperty("connid.soap.version");
-            connidDbTableVersion = props.getProperty("connid.db.table.version");
+            connidDbTableVersion = props.getProperty("connid.database.version");
 
             testJDBCURL = props.getProperty("testdb.url");
         } catch (Exception e) {
@@ -557,11 +557,13 @@ public class ConnectorITCase extends AbstractITCase {
         ConnInstanceTO ldap = connectorService.read(105L);
         assertNotNull(ldap);
 
-        List<ConnIdObjectClassTO> objectClasses = connectorService.getSupportedObjectClasses(ldap.getKey(), ldap);
+        List<ConnIdObjectClass> objectClasses = connectorService.getSupportedObjectClasses(ldap.getKey(), ldap);
         assertNotNull(objectClasses);
         assertEquals(2, objectClasses.size());
-        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
-        assertTrue(objectClasses.contains(ConnIdObjectClassTO.GROUP));
+        assertTrue(objectClasses.contains(
+                ConnIdObjectClass.getInstance(ConnIdObjectClass.class, ObjectClass.ACCOUNT_NAME)));
+        assertTrue(objectClasses.contains(
+                ConnIdObjectClass.getInstance(ConnIdObjectClass.class, ObjectClass.GROUP_NAME)));
 
         ConnInstanceTO csv = connectorService.read(104L);
         assertNotNull(csv);
@@ -569,7 +571,8 @@ public class ConnectorITCase extends AbstractITCase {
         objectClasses = connectorService.getSupportedObjectClasses(csv.getKey(), csv);
         assertNotNull(objectClasses);
         assertEquals(1, objectClasses.size());
-        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+        assertTrue(objectClasses.contains(
+                ConnIdObjectClass.getInstance(ConnIdObjectClass.class, ObjectClass.ACCOUNT_NAME)));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
index 017f802..f16ee21 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
@@ -44,6 +44,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.ReferenceMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.BulkActionResult;
@@ -68,7 +69,6 @@ import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.GroupService;
 import org.junit.FixMethodOrder;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
@@ -92,7 +92,6 @@ public class GroupITCase extends AbstractITCase {
     }
 
     @Test
-    @Ignore
     public void create() {
         GroupTO groupTO = getSampleTO("lastGroup");
         groupTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
@@ -351,9 +350,9 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.LINK,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
+        assertNotNull(groupService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.LINK, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -406,9 +405,10 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.ASSIGN,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
+                ResourceAssociationActionType.ASSIGN, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -456,9 +456,10 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
+                ResourceAssociationActionType.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -482,9 +483,10 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION,
-                CollectionWrapper.wrap("resource-ldap", ResourceKey.class)).
+                ResourceAssociationActionType.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
index 3f1eb0a..6011c93 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
@@ -29,6 +29,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.RoleTO;
@@ -44,25 +45,25 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchUser() {
         // LIKE
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().
                         is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        for (UserTO user : matchedUsers.getResult()) {
+        for (UserTO user : matchingUsers.getResult()) {
             assertNotNull(user);
         }
 
         // ISNULL
-        matchedUsers = userService.search(
+        matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        Collection<UserTO> found = CollectionUtils.select(matchedUsers.getResult(), new Predicate<UserTO>() {
+        Collection<UserTO> found = CollectionUtils.select(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -98,14 +99,14 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchByGroup() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(1L).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -121,14 +122,14 @@ public class SearchITCase extends AbstractITCase {
         group = createGroup(group);
         assertNotNull(group);
 
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(group.getKey()).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -139,14 +140,14 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchByRole() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(3L).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -163,14 +164,14 @@ public class SearchITCase extends AbstractITCase {
         role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
         assertNotNull(role);
 
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(role.getKey()).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -181,14 +182,14 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchUserByResourceName() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -242,27 +243,47 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void nested() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
-        assertNotNull(matchedUsers);
+        assertNotNull(matchingUsers);
 
-        assertFalse(matchedUsers.getResult().isEmpty());
-        for (UserTO user : matchedUsers.getResult()) {
+        assertFalse(matchingUsers.getResult().isEmpty());
+        for (UserTO user : matchingUsers.getResult()) {
             assertNotNull(user);
         }
     }
 
     @Test
+    public void searchByType() {
+        PagedResult<AnyObjectTO> matching = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").query()).build());
+        assertNotNull(matching);
+
+        assertFalse(matching.getResult().isEmpty());
+        for (AnyObjectTO printer : matching.getResult()) {
+            assertNotNull(printer);
+        }
+
+        matching = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("UNEXISTING").query()).build());
+        assertNotNull(matching);
+
+        assertTrue(matching.getResult().isEmpty());
+    }
+
+    @Test
     public void orderBy() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
                 orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
-        assertNotNull(matchedUsers);
+        assertNotNull(matchingUsers);
 
-        assertFalse(matchedUsers.getResult().isEmpty());
-        for (UserTO user : matchedUsers.getResult()) {
+        assertFalse(matchingUsers.getResult().isEmpty());
+        for (UserTO user : matchingUsers.getResult()) {
             assertNotNull(user);
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index ee02b26..939919f 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -37,6 +37,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
@@ -44,6 +45,7 @@ import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.SyncPolicyTO;
 import org.apache.syncope.common.lib.to.SyncTaskTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
@@ -353,6 +355,49 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     }
 
     @Test
+    public void reconcileFromScriptedSQL() {
+        // 0. reset sync token
+        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
+        ProvisionTO provision = resource.getProvision("PRINTER");
+        assertNotNull(provision);
+
+        provision.setSyncToken(null);
+        resourceService.update(resource.getKey(), resource);
+
+        // 1. create printer on external resource
+        AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync");
+        anyObjectTO = createAnyObject(anyObjectTO);
+        assertNotNull(anyObjectTO);
+
+        // 2. unlink any existing printer and delete from Syncope (printer is now only on external resource)
+        PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+                        is("location").equalTo("sync*").query()).build());
+        assertTrue(matchingPrinters.getSize() > 0);
+        for (AnyObjectTO printer : matchingPrinters.getResult()) {
+            anyObjectService.bulkDeassociation(printer.getKey(),
+                    ResourceDeassociationActionType.UNLINK,
+                    CollectionWrapper.wrap(RESOURCE_NAME_DBSCRIPTED, ResourceKey.class));
+            anyObjectService.delete(printer.getKey());
+        }
+
+        // 3. synchronize
+        execProvisioningTask(28L, 50, false);
+
+        // 4. verify that printer was re-created in Syncope
+        matchingPrinters = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+                        is("location").equalTo("sync*").query()).build());
+        assertTrue(matchingPrinters.getSize() > 0);
+
+        // 5. verify that synctoken was updated
+        assertNotNull(
+                resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
+    }
+
+    @Test
     public void issueSYNCOPE68() {
         //-----------------------------
         // Create a new user ... it should be updated applying sync policy

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index c0ab43d..bd6b4aa 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -1909,8 +1909,8 @@ public class UserITCase extends AbstractITCase {
         try {
             resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
-        } catch (Exception e) {
-            assertNotNull(e);
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9011e8d..f8506d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -321,12 +321,12 @@ under the License.
 
     <connid.version>1.4.1.0</connid.version>
     <connid.soap.version>1.3.0</connid.soap.version>
-    <connid.db.table.version>2.2.2</connid.db.table.version>
+    <connid.database.version>2.2.2</connid.database.version>
     <connid.csvdir.version>0.8.2</connid.csvdir.version>
     <connid.ldap.version>1.4.0</connid.ldap.version>
     <connid.ad.version>1.2.3</connid.ad.version>
 
-    <cxf.version>3.1.0</cxf.version>
+    <cxf.version>3.1.2-SNAPSHOT</cxf.version>
 
     <camel.version>2.15.2</camel.version>	
 
@@ -1126,8 +1126,13 @@ under the License.
               <dependency>
                 <groupId>net.tirasa.connid.bundles.db</groupId>
                 <artifactId>net.tirasa.connid.bundles.db.table</artifactId>
-                <version>${connid.db.table.version}</version>
+                <version>${connid.database.version}</version>
               </dependency>   
+              <dependency>
+                <groupId>net.tirasa.connid.bundles.db</groupId>
+                <artifactId>net.tirasa.connid.bundles.db.scriptedsql</artifactId>
+                <version>${connid.database.version}</version>
+              </dependency>  
               <artifactItem>
                 <groupId>net.tirasa.connid.bundles</groupId>
                 <artifactId>net.tirasa.connid.bundles.ldap</artifactId>


[23/27] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
index 98a23a6..2d6c6e4 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
@@ -19,98 +19,23 @@
 package org.apache.syncope.core.rest.cxf.service;
 
 import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
-import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.wrap.ResourceKey;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 import org.apache.syncope.common.rest.api.service.GroupService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.logic.GroupLogic;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class GroupServiceImpl extends AbstractServiceImpl implements GroupService {
+public class GroupServiceImpl extends AbstractAnyService<GroupTO, GroupMod> implements GroupService {
 
     @Autowired
     private GroupLogic logic;
 
     @Override
-    public Response create(final GroupTO groupTO) {
-        GroupTO created = logic.create(groupTO);
-        return createResponse(created.getKey(), created);
-    }
-
-    @Override
-    public Response delete(final Long groupKey) {
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        GroupTO deleted = logic.delete(groupKey);
-        return modificationResponse(deleted);
-    }
-
-    @Override
-    public PagedResult<GroupTO> list(final AnyListQuery listQuery) {
-        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        return buildPagedResult(
-                logic.list(
-                        listQuery.getPage(),
-                        listQuery.getSize(),
-                        getOrderByClauses(listQuery.getOrderBy()),
-                        listQuery.getRealms()),
-                listQuery.getPage(),
-                listQuery.getSize(),
-                logic.count(listQuery.getRealms()));
-    }
-
-    @Override
-    public GroupTO read(final Long groupKey) {
-        return logic.read(groupKey);
-    }
-
-    @Override
-    public PagedResult<GroupTO> search(final AnySearchQuery searchQuery) {
-        CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        SearchCond cond = getSearchCond(searchQuery.getFiql());
-        return buildPagedResult(
-                logic.search(
-                        cond,
-                        searchQuery.getPage(),
-                        searchQuery.getSize(),
-                        getOrderByClauses(searchQuery.getOrderBy()),
-                        searchQuery.getRealms()),
-                searchQuery.getPage(),
-                searchQuery.getSize(),
-                logic.searchCount(cond, searchQuery.getRealms()));
+    protected AbstractAnyLogic<GroupTO, GroupMod> getAnyLogic() {
+        return logic;
     }
 
     @Override
@@ -118,126 +43,4 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
         return logic.own();
     }
 
-    @Override
-    public Response update(final Long groupKey, final GroupMod groupMod) {
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        groupMod.setKey(groupKey);
-        GroupTO updated = logic.update(groupMod);
-        return modificationResponse(updated);
-    }
-
-    @Override
-    public Response bulkDeassociation(
-            final Long groupKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
-
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        GroupTO updated;
-        switch (type) {
-            case UNLINK:
-                updated = logic.unlink(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case UNASSIGN:
-                updated = logic.unassign(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case DEPROVISION:
-                updated = logic.deprovision(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            default:
-                updated = logic.read(groupKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceDeassociationActionType.UNLINK) {
-            for (ResourceKey resourceName : resourceNames) {
-                result.getResults().put(resourceName.getElement(),
-                        updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public Response bulkAssociation(
-            final Long groupKey, final ResourceAssociationActionType type, final List<ResourceKey> resourceNames) {
-
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        GroupTO updated;
-        switch (type) {
-            case LINK:
-                updated = logic.link(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case ASSIGN:
-                updated = logic.assign(groupKey, CollectionWrapper.unwrap(resourceNames), false, null);
-                break;
-
-            case PROVISION:
-                updated = logic.provision(groupKey, CollectionWrapper.unwrap(resourceNames), false, null);
-                break;
-
-            default:
-                updated = logic.read(groupKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceAssociationActionType.LINK) {
-            for (ResourceKey resourceName : resourceNames) {
-                result.getResults().put(resourceName.getElement(),
-                        updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult result = new BulkActionResult();
-
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
-            for (String groupKey : bulkAction.getTargets()) {
-                try {
-                    result.getResults().put(
-                            String.valueOf(logic.delete(Long.valueOf(groupKey)).getKey()),
-                            BulkActionResult.Status.SUCCESS);
-                } catch (Exception e) {
-                    LOG.error("Error performing delete for group {}", groupKey, e);
-                    result.getResults().put(groupKey, BulkActionResult.Status.FAILURE);
-                }
-            }
-        } else {
-            LOG.warn("Unsupported bulk action: {}", bulkAction.getOperation());
-        }
-
-        return result;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
index 192b4e0..391aea8 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
@@ -18,44 +18,33 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
-import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
-import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.wrap.ResourceKey;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.logic.UserLogic;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class UserServiceImpl extends AbstractServiceImpl implements UserService {
+public class UserServiceImpl extends AbstractAnyService<UserTO, UserMod> implements UserService {
 
     @Autowired
     private UserLogic logic;
 
     @Override
-    public Response getUsername(final Long userKey) {
+    protected AbstractAnyLogic<UserTO, UserMod> getAnyLogic() {
+        return logic;
+    }
+
+    @Override
+    public Response getUsername(final Long key) {
         return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
-                header(RESTHeaders.USERNAME, logic.getUsername(userKey)).
+                header(RESTHeaders.USERNAME, logic.getUsername(key)).
                 build();
     }
 
@@ -73,237 +62,13 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
     }
 
     @Override
-    public Response delete(final Long userKey) {
-        UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        UserTO deleted = logic.delete(userKey);
-        return modificationResponse(deleted);
-    }
-
-    @Override
-    public PagedResult<UserTO> list(final AnyListQuery listQuery) {
-        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        return buildPagedResult(
-                logic.list(
-                        listQuery.getPage(),
-                        listQuery.getSize(),
-                        getOrderByClauses(listQuery.getOrderBy()),
-                        listQuery.getRealms()),
-                listQuery.getPage(),
-                listQuery.getSize(),
-                logic.count(listQuery.getRealms()));
-    }
-
-    @Override
-    public UserTO read(final Long userKey) {
-        return logic.read(userKey);
-    }
-
-    @Override
-    public PagedResult<UserTO> search(final AnySearchQuery searchQuery) {
-        CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        SearchCond cond = getSearchCond(searchQuery.getFiql());
-        return buildPagedResult(
-                logic.search(
-                        cond,
-                        searchQuery.getPage(),
-                        searchQuery.getSize(),
-                        getOrderByClauses(searchQuery.getOrderBy()),
-                        searchQuery.getRealms()),
-                searchQuery.getPage(),
-                searchQuery.getSize(),
-                logic.searchCount(cond, searchQuery.getRealms()));
-    }
-
-    @Override
-    public Response update(final Long userKey, final UserMod userMod) {
-        UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        userMod.setKey(userKey);
-        UserTO updated = logic.update(userMod);
-        return modificationResponse(updated);
-    }
-
-    @Override
-    public Response status(final Long userKey, final StatusMod statusMod) {
-        UserTO user = logic.read(userKey);
+    public Response status(final Long key, final StatusMod statusMod) {
+        UserTO user = logic.read(key);
 
         checkETag(user.getETagValue());
 
-        statusMod.setKey(userKey);
+        statusMod.setKey(key);
         UserTO updated = logic.status(statusMod);
         return modificationResponse(updated);
     }
-
-    @Override
-    public Response bulkDeassociation(
-            final Long userKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
-
-        final UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        UserTO updated;
-        switch (type) {
-            case UNLINK:
-                updated = logic.unlink(userKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case UNASSIGN:
-                updated = logic.unassign(userKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case DEPROVISION:
-                updated = logic.deprovision(userKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            default:
-                updated = logic.read(userKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceDeassociationActionType.UNLINK) {
-            for (ResourceKey resourceName : resourceNames) {
-                result.getResults().put(
-                        resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public Response bulkAssociation(
-            final Long userKey, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) {
-
-        final UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        UserTO updated;
-        switch (type) {
-            case LINK:
-                updated = logic.link(
-                        userKey,
-                        CollectionWrapper.unwrap(associationMod.getTargetResources()));
-                break;
-
-            case ASSIGN:
-                updated = logic.assign(
-                        userKey,
-                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
-                        associationMod.isChangePwd(),
-                        associationMod.getPassword());
-                break;
-
-            case PROVISION:
-                updated = logic.provision(
-                        userKey,
-                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
-                        associationMod.isChangePwd(),
-                        associationMod.getPassword());
-                break;
-
-            default:
-                updated = logic.read(userKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceAssociationActionType.LINK) {
-            for (ResourceKey resourceName : associationMod.getTargetResources()) {
-                result.getResults().put(resourceName.getElement(),
-                        updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult result = new BulkActionResult();
-
-        switch (bulkAction.getOperation()) {
-            case DELETE:
-                for (String key : bulkAction.getTargets()) {
-                    try {
-                        result.getResults().put(
-                                String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
-                                BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing delete for user {}", key, e);
-                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            case SUSPEND:
-                for (String key : bulkAction.getTargets()) {
-                    StatusMod statusMod = new StatusMod();
-                    statusMod.setKey(Long.valueOf(key));
-                    statusMod.setType(StatusMod.ModType.SUSPEND);
-                    try {
-                        result.getResults().put(
-                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing suspend for user {}", key, e);
-                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            case REACTIVATE:
-                for (String key : bulkAction.getTargets()) {
-                    StatusMod statusMod = new StatusMod();
-                    statusMod.setKey(Long.valueOf(key));
-                    statusMod.setType(StatusMod.ModType.REACTIVATE);
-                    try {
-                        result.getResults().put(
-                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing reactivate for user {}", key, e);
-                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            default:
-        }
-
-        return result;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
index 3520a4a..4359e7b 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
@@ -56,6 +56,9 @@ public class CamelRouteLoader implements SyncopeLoader {
     @javax.annotation.Resource(name = "groupRoutes")
     private ResourceWithFallbackLoader groupRoutesLoader;
 
+    @javax.annotation.Resource(name = "anyObjectRoutes")
+    private ResourceWithFallbackLoader anyObjectRoutesLoader;
+
     @Autowired
     private DataSource dataSource;
 
@@ -76,6 +79,7 @@ public class CamelRouteLoader implements SyncopeLoader {
             if (!loaded) {
                 loadRoutes(userRoutesLoader.getResource(), AnyTypeKind.USER);
                 loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
+                loadRoutes(anyObjectRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
                 loaded = true;
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
new file mode 100644
index 0000000..ae29501
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
@@ -0,0 +1,163 @@
+/*
+ * 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.core.provisioning.camel;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.PollingConsumer;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+
+public class CamelAnyObjectProvisioningManager
+        extends AbstractCamelProvisioningManager implements AnyObjectProvisioningManager {
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> create(final AnyObjectTO any) {
+        return create(any, Collections.<String>emptySet());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Pair<Long, List<PropagationStatus>> create(
+            final AnyObjectTO anyObjectTO, final Set<String> excludedResources) {
+
+        PollingConsumer pollingConsumer = getConsumer("direct:createAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("excludedResources", excludedResources);
+
+        sendMessage("direct:createAnyObject", anyObjectTO, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Pair.class);
+    }
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> update(final AnyObjectMod anyMod) {
+        return update(anyMod, Collections.<String>emptySet());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Pair<Long, List<PropagationStatus>> update(
+            final AnyObjectMod anyMod, final Set<String> excludedResources) {
+
+        PollingConsumer pollingConsumer = getConsumer("direct:updateAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("excludedResources", excludedResources);
+
+        sendMessage("direct:updateAnyObject", anyMod, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Pair.class);
+    }
+
+    @Override
+    public List<PropagationStatus> delete(final Long anyObjectObjectKey) {
+        return delete(anyObjectObjectKey, Collections.<String>emptySet());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deleteAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("excludedResources", excludedResources);
+
+        sendMessage("direct:deleteAnyObject", anyObjectKey, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+    @Override
+    public Long unlink(final AnyObjectMod anyObjectMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:unlinkAnyObjectPort");
+
+        sendMessage("direct:unlinkAnyObject", anyObjectMod);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Long.class);
+    }
+
+    @Override
+    public Long link(final AnyObjectMod anyObjectMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:linkAnyObjectPort");
+
+        sendMessage("direct:linkAnyObject", anyObjectMod);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Long.class);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deprovisionAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("resources", resources);
+
+        sendMessage("direct:deprovisionAnyObject", anyObjectKey, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
new file mode 100644
index 0000000..2f2e41e
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.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.core.provisioning.camel.processor;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectCreateProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyObjectCreateProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
+        AnyObjectTO any = exchange.getProperty("any", AnyObjectTO.class);
+        Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+        List<PropagationTask> tasks =
+                propagationManager.getAnyObjectCreateTasks(created, any.getVirAttrs(), excludedResource);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(new ImmutablePair<>(created.getResult(), propagationReporter.getStatuses()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
new file mode 100644
index 0000000..d1c9243
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
@@ -0,0 +1,83 @@
+/*
+ * 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.core.provisioning.camel.processor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectDeleteProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyObjectDeleteProcessor.class);
+
+    @Autowired
+    protected AnyObjectWorkflowAdapter gwfAdapter;
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Override
+    public void process(final Exchange exchange) throws Exception {
+        Long anyKey = exchange.getIn().getBody(Long.class);
+        AnyObject anyObject = anyObjectDAO.find(anyKey);
+        @SuppressWarnings("unchecked")
+        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
+
+        List<PropagationTask> tasks = new ArrayList<>();
+
+        if (anyObject != null) {
+            // Generate propagation tasks for deleting this anyObject from resources
+            tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey(), excludedResources));
+        }
+
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.setProperty("statuses", propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
new file mode 100644
index 0000000..c56ab90
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.core.provisioning.camel.processor;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectDeprovisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserDeprovisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        Long anyObjectKey = exchange.getIn().getBody(Long.class);
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+
+        Collection<String> noPropResourceNames = CollectionUtils.removeAll(anyObject.getResourceNames(), resources);
+
+        List<PropagationTask> tasks =
+                propagationManager.getAnyObjectDeleteTasks(anyObjectKey, new HashSet<>(resources), noPropResourceNames);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
new file mode 100644
index 0000000..2979e97
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
@@ -0,0 +1,90 @@
+/*
+ * 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.core.provisioning.camel.processor;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectUpdateProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserUpdateProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected VirAttrHandler virtAttrHandler;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
+        AnyObjectMod anyObjectMod = exchange.getProperty("anyMod", AnyObjectMod.class);
+        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(updated,
+                anyObjectMod.getVirAttrsToRemove(), anyObjectMod.getVirAttrsToUpdate(), excludedResources);
+        if (tasks.isEmpty()) {
+            // SYNCOPE-459: take care of user virtual attributes ...
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+                    updated.getResult(),
+                    AnyTypeKind.GROUP,
+                    anyObjectMod.getVirAttrsToRemove(),
+                    anyObjectMod.getVirAttrsToUpdate());
+            tasks.addAll(!propByResVirAttr.isEmpty()
+                    ? propagationManager.getAnyObjectUpdateTasks(updated, null, null, null)
+                    : Collections.<PropagationTask>emptyList());
+        }
+
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(new ImmutablePair<>(updated.getResult(), propagationReporter.getStatuses()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
new file mode 100644
index 0000000..de4df0b
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
@@ -0,0 +1,121 @@
+<?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
+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.
+-->
+<routes>
+     
+  <route id="createAnyObject">
+    <from uri="direct:createAnyObject"/>
+    <setProperty propertyName="any">
+      <simple>${body}</simple>
+    </setProperty>
+    <doTry>
+      <bean ref="awfAdapter" method="create(${body})"/>
+      <process ref="anyObjectCreateProcessor"/>
+      <to uri="direct:createAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:createAnyObjectPort"/>
+      </doCatch>
+    </doTry>
+  </route>
+         
+  <route id="updateAnyObject">
+    <from uri="direct:updateAnyObject"/>
+    <setProperty propertyName="anyMod">
+      <simple>${body}</simple>
+    </setProperty>
+    <doTry>
+      <bean ref="awfAdapter" method="update(${body})"/>
+      <process ref="anyObjectUpdateProcessor"/>
+      <to uri="direct:updateAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:updateAnyObjectPort"/>
+      </doCatch>
+    </doTry>
+  </route>
+
+  <route id="deleteAnyObject">
+    <from uri="direct:deleteAnyObject"/>
+    <doTry>
+      <process ref="anyObjectDeleteProcessor"/>
+      <bean ref="awfAdapter" method="delete(${body})"/>
+      <setBody>
+        <simple>${property.statuses}</simple>
+      </setBody>
+      <to uri="direct:deleteAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:deleteAnyObjectPort"/>
+      </doCatch>
+    </doTry>
+  </route>
+
+  <route id="unlinkAnyObject">
+    <from uri="direct:unlinkAnyObject"/>
+    <doTry>
+      <bean ref="awfAdapter" method="update(${body})"/>
+      <setBody>
+        <simple>${body.getResult}</simple>
+      </setBody>
+      <to uri="direct:unlinkAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:unlinkAnyObjectPort"/>
+      </doCatch>
+    </doTry>            
+  </route>
+        
+  <route id="linkAnyObject">
+    <from uri="direct:linkAnyObject"/>
+    <doTry>
+      <bean ref="awfAdapter" method="update(${body})"/>
+      <setBody>
+        <simple>${body.getResult}</simple>
+      </setBody>
+      <to uri="direct:linkAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:linkAnyObjectPort"/>
+      </doCatch>
+    </doTry>            
+  </route>
+        
+  <route id="deprovisionAnyObject">
+    <from uri="direct:deprovisionAnyObject"/>            
+    <process ref="anyObjectDeprovisionProcessor"/>
+    <to uri="direct:deprovisionAnyObjectPort"/>              
+  </route>
+    
+</routes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
index 5061502..aa843ca 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
@@ -17,5 +17,5 @@
 camel.directory=${conf.directory}
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
-anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
+anyObjectProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelAnObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
index 8eec14d..d334d75 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
@@ -33,7 +33,11 @@ under the License.
     <property name="primary" value="file:${camel.directory}/groupRoutes.xml"/>
     <property name="fallback" value="classpath:groupRoutes.xml"/>
   </bean>
-    
+  <bean id="anyObjectRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${camel.directory}/anyObjectRoutes.xml"/>
+    <property name="fallback" value="classpath:anyObjectRoutes.xml"/>
+  </bean>
+      
   <context:component-scan base-package="org.apache.syncope.core.provisioning.camel"/>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/pom.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index bfae2f4..679eee6 100644
--- a/fit/build-tools/pom.xml
+++ b/fit/build-tools/pom.xml
@@ -85,10 +85,16 @@ under the License.
     <dependency>
       <groupId>net.tirasa.connid.bundles.db</groupId>
       <artifactId>net.tirasa.connid.bundles.db.table</artifactId>
-      <version>${connid.db.table.version}</version>
+      <version>${connid.database.version}</version>
       <scope>runtime</scope>
     </dependency>
-    
+    <dependency>
+      <groupId>net.tirasa.connid.bundles.db</groupId>
+      <artifactId>net.tirasa.connid.bundles.db.scriptedsql</artifactId>
+      <version>${connid.database.version}</version>
+      <scope>runtime</scope>
+    </dependency>
+        
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
index 37adbd3..67567ec 100644
--- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
@@ -49,7 +49,8 @@ public class ConnIdStartStopListener implements ServletContextListener {
 
         for (String bundleFile : new String[] {
             "testconnectorserver.soap.bundle",
-            "testconnectorserver.db.bundle",
+            "testconnectorserver.dbtable.bundle",
+            "testconnectorserver.scriptedsql.bundle",
             "testconnectorserver.csvdir.bundle",
             "testconnectorserver.ldap.bundle" }) {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/resources/buildToolsContext.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/buildToolsContext.xml b/fit/build-tools/src/main/resources/buildToolsContext.xml
index 2b63ed6..e0f5678 100644
--- a/fit/build-tools/src/main/resources/buildToolsContext.xml
+++ b/fit/build-tools/src/main/resources/buildToolsContext.xml
@@ -45,8 +45,11 @@ under the License.
   <bean id="testconnectorserver.soap.bundle" class="java.lang.String">
     <constructor-arg value="net.tirasa.connid.bundles.soap-${connid.soap.version}.jar"/>
   </bean>  
-  <bean id="testconnectorserver.db.bundle" class="java.lang.String">
-    <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.db.table.version}.jar"/>
+  <bean id="testconnectorserver.dbtable.bundle" class="java.lang.String">
+    <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.database.version}.jar"/>
+  </bean>  
+  <bean id="testconnectorserver.scriptedsql.bundle" class="java.lang.String">
+    <constructor-arg value="net.tirasa.connid.bundles.db.scriptedsql-${connid.database.version}.jar"/>
   </bean>  
   <bean id="testconnectorserver.csvdir.bundle" class="java.lang.String">
     <constructor-arg value="net.tirasa.connid.bundles.csvdir-${connid.csvdir.version}.jar"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/resources/testdb.sql
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/testdb.sql b/fit/build-tools/src/main/resources/testdb.sql
index ff4dd47..9202a87 100644
--- a/fit/build-tools/src/main/resources/testdb.sql
+++ b/fit/build-tools/src/main/resources/testdb.sql
@@ -37,10 +37,16 @@ INSERT INTO test2 VALUES ('verdi', 'password321', 'true');
 
 -- this table is for issueSYNCOPE230
 DROP TABLE testsync IF EXISTS;
-CREATE TABLE TESTSYNC (
+CREATE TABLE testsync (
 id NUMBER(10) PRIMARY KEY,
 username VARCHAR(80),
 surname VARCHAR(80),
 email VARCHAR(80));
 
 INSERT INTO testsync VALUES (965, 'issuesyncope230', 'Surname', 'syncope230@syncope.apache.org');
+
+DROP TABLE testPRINTER IF EXISTS;
+CREATE TABLE testPRINTER (
+id NUMBER(10) PRIMARY KEY,
+location VARCHAR(80),
+lastModification TIMESTAMP);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/connid.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/connid.properties b/fit/core-reference/src/main/resources/connid.properties
index a18252f..22ed0a8 100644
--- a/fit/core-reference/src/main/resources/connid.properties
+++ b/fit/core-reference/src/main/resources/connid.properties
@@ -20,5 +20,5 @@ connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}
 ## for test only
 testdb.url=${testdb.url}
 connid.soap.version=${connid.soap.version}
-connid.db.table.version=${connid.db.table.version}
+connid.database.version=${connid.database.version}
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy
new file mode 100644
index 0000000..52c10f9
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends us the following:
+// connection : SQL connection
+// action: String correponding to the action ("CREATE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// id: The entry identifier (OpenICF "Name" atribute. (most often matches the uid)
+// attributes: an Attribute Map, containg the <String> attribute name as a key
+// and the <List> attribute value(s) as value.
+// password: password string, clear text
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+
+def sql = new Sql(connection);
+
+switch ( objectClass ) {
+case "__PRINTER__":
+  sql.execute("INSERT INTO TESTPRINTER (id, location, lastmodification) values (?,?,?)",
+    [
+      id,
+      attributes.get("location").get(0),
+      new Date()
+    ])
+  break
+
+default:
+  id;
+}
+
+return id;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy
new file mode 100644
index 0000000..cdd7f5b
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("DELETE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// options: a handler to the OperationOptions Map
+// uid: String for the unique id that specifies the object to delete
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+assert uid != null
+
+switch ( objectClass ) {
+case "__PRINTER__":
+  sql.execute("DELETE FROM TESTPRINTER where id= ?",[uid])
+  break
+
+default:
+  uid;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy
new file mode 100644
index 0000000..50f8a8a
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+import org.identityconnectors.framework.common.objects.AttributeInfo;
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags;
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder;
+import org.identityconnectors.framework.common.objects.ObjectClassInfo;
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder;
+
+// Parameters:
+// The connector sends the following:
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+// This sample shows how to create 3 basic ObjectTypes: __ACCOUNT__, __GROUP__ and organization.
+// Each of them contains one required attribute and normal String attributes
+
+
+log.info("Entering " + action + " Script");
+
+idAIB = new AttributeInfoBuilder("id", String.class);
+idAIB.setRequired(true);
+
+orgAttrsInfo = new HashSet<AttributeInfo>();
+orgAttrsInfo.add(idAIB.build());
+orgAttrsInfo.add(AttributeInfoBuilder.build("location", String.class));
+// Create the organization Object class
+ObjectClassInfo ociOrg = new ObjectClassInfoBuilder().setType("__PRINTER__").addAllAttributeInfo(orgAttrsInfo).build();
+builder.defineObjectClass(ociOrg);
+
+log.info("Schema script done");
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy
new file mode 100644
index 0000000..cc0dd65
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used.
+//
+// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+log.info("Entering " + action + " Script");
+
+def sql = new Sql(connection);
+def result = []
+def where = "";
+
+if (query != null)  {
+  // Need to handle the __UID__ in queries
+  if (query.get("left").equalsIgnoreCase("__UID__") && objectClass.equalsIgnoreCase("__PRINTER__")) {
+    query.put("left","id")
+  }
+  
+  // We can use Groovy template engine to generate our custom SQL queries
+  def engine = new groovy.text.SimpleTemplateEngine();
+
+  def whereTemplates = [
+    CONTAINS:' WHERE $left ${not ? "NOT " : ""}LIKE "%$right%"',
+    ENDSWITH:' WHERE $left ${not ? "NOT " : ""}LIKE "%$right"',
+    STARTSWITH:' WHERE $left ${not ? "NOT " : ""}LIKE "$right%"',
+    EQUALS:' WHERE $left ${not ? "<>" : "="} \'$right\'',
+    GREATERTHAN:' WHERE $left ${not ? "<=" : ">"} "$right"',
+    GREATERTHANOREQUAL:' WHERE $left ${not ? "<" : ">="} "$right"',
+    LESSTHAN:' WHERE $left ${not ? ">=" : "<"} "$right"',
+    LESSTHANOREQUAL:' WHERE $left ${not ? ">" : "<="} "$right"'
+  ]
+
+  def wt = whereTemplates.get(query.get("operation"));
+  def binding = [left:query.get("left"),right:query.get("right"),not:query.get("not")];
+  def template = engine.createTemplate(wt).make(binding);
+  where = template.toString();
+  log.ok("Search WHERE clause is: "+ where)
+}
+
+switch ( objectClass ) {
+case "__PRINTER__":
+  sql.eachRow("SELECT * FROM TESTPRINTER " + where, 
+    {result.add([__UID__:it.id, __NAME__:it.id, location:it.location])} );
+  break
+
+default:
+  result;
+}
+
+return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy
new file mode 100644
index 0000000..6060870
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SYNC" or "GET_LATEST_SYNC_TOKEN" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map (null if action = "GET_LATEST_SYNC_TOKEN")
+// token: a handler to an Object representing the sync token (null if action = "GET_LATEST_SYNC_TOKEN")
+//
+//
+// Returns:
+// if action = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known
+// sync token for the corresponding ObjectClass
+// 
+// if action = "SYNC":
+// A list of Maps . Each map describing one update:
+// Map should look like the following:
+//
+// [
+// "token": <Object> token object (could be Integer, Date, String) , [!! could be null]
+// "operation":<String> ("CREATE_OR_UPDATE"|"DELETE")  will always default to CREATE_OR_DELETE ,
+// "uid":<String> uid  (uid of the entry) ,
+// "previousUid":<String> prevuid (This is for rename ops) ,
+// "password":<String> password (optional... allows to pass clear text password if needed),
+// "attributes":Map<String,List> of attributes name/values
+// ]
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+if (action.equalsIgnoreCase("GET_LATEST_SYNC_TOKEN")) {
+  switch (objectClass) {
+  case "__PRINTER__":
+    row = sql.firstRow("SELECT lastmodification FROM TESTPRINTER ORDER BY lastmodification DESC");
+    log.ok("Get Latest Sync Token script: last token is: " + row["lastmodification"])
+    break;
+    
+  default:
+    row = null;
+  }
+
+  return row == null ? null : row["lastmodification"].getTime();
+} else if (action.equalsIgnoreCase("SYNC")) {
+  def result = [];
+  def lastmodification = null;
+  if (token != null) {
+    lastmodification = new Date(token);
+  } else {
+    lastmodification = new Date(0);
+  }
+
+  switch (objectClass) {
+  case "__PRINTER__":    
+    sql.eachRow("SELECT * FROM TESTPRINTER WHERE lastmodification > ${lastmodification}",
+      {
+        result.add([
+            operation:"CREATE_OR_UPDATE", 
+            uid:it.id.toString(), 
+            token:it.lastmodification.getTime(), 
+            attributes:[
+              __UID__:it.id.toString(),
+              __NAME__:it.id.toString(),
+              id:it.id.toString(),
+              location:it.location
+            ]
+          ]);
+      }
+    )
+    break;
+  }
+  
+  log.ok("Sync script: found " + result.size() + " events to sync");
+  return result;
+} else {
+  log.error("Sync script: action '" + action + "' is not implemented in this script");
+  return null;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy
new file mode 100644
index 0000000..5b8f4b5
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("TEST" here)
+// log: a handler to the Log facility
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+sql.eachRow("select * from TESTPRINTER", { println it.uid} );
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy
new file mode 100644
index 0000000..f3155cb
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends us the following:
+// connection : SQL connection
+//
+// action: String correponding to the action (UPDATE/ADD_ATTRIBUTE_VALUES/REMOVE_ATTRIBUTE_VALUES)
+//   - UPDATE : For each input attribute, replace all of the current values of that attribute
+//     in the target object with the values of that attribute.
+//   - ADD_ATTRIBUTE_VALUES: For each attribute that the input set contains, add to the current values
+//     of that attribute in the target object all of the values of that attribute in the input set.
+//   - REMOVE_ATTRIBUTE_VALUES: For each attribute that the input set contains, remove from the current values
+//     of that attribute in the target object any value that matches one of the values of the attribute from the input set.
+
+// log: a handler to the Log facility
+//
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+//
+// uid: a String representing the entry uid
+//
+// attributes: an Attribute Map, containg the <String> attribute name as a key
+// and the <List> attribute value(s) as value.
+//
+// password: password string, clear text (only for UPDATE)
+//
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+
+switch (action) {
+case "UPDATE":
+  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)])
+    
+    return attributes.get("__NAME__").get(0);
+  }
+  break
+
+case "ADD_ATTRIBUTE_VALUES":
+  break
+
+
+default:
+  sql
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
index 8cfec8b..efe1b16 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
@@ -35,11 +35,13 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
 import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AbstractPolicyTO;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
@@ -48,6 +50,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
 import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
 import org.apache.syncope.common.rest.api.service.AnyTypeService;
 import org.apache.syncope.common.rest.api.service.CamelRouteService;
@@ -141,6 +144,8 @@ public abstract class AbstractITCase {
 
     protected static final String RESOURCE_NAME_CREATE_NONE = "ws-target-resource-create-none";
 
+    protected static final String RESOURCE_NAME_DBSCRIPTED = "resource-db-scripted";
+
     protected static String ANONYMOUS_UNAME;
 
     protected static String ANONYMOUS_KEY;
@@ -155,6 +160,8 @@ public abstract class AbstractITCase {
 
     protected static RealmService realmService;
 
+    protected static AnyObjectService anyObjectService;
+
     protected static RoleService roleService;
 
     protected static UserService userService;
@@ -226,6 +233,7 @@ public abstract class AbstractITCase {
         anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
         anyTypeService = adminClient.getService(AnyTypeService.class);
         realmService = adminClient.getService(RealmService.class);
+        anyObjectService = adminClient.getService(AnyObjectService.class);
         roleService = adminClient.getService(RoleService.class);
         userService = adminClient.getService(UserService.class);
         userSelfService = adminClient.getService(UserSelfService.class);
@@ -287,8 +295,8 @@ public abstract class AbstractITCase {
         return userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
     }
 
-    protected UserTO deleteUser(final Long id) {
-        return userService.delete(id).readEntity(UserTO.class);
+    protected UserTO deleteUser(final Long key) {
+        return userService.delete(key).readEntity(UserTO.class);
     }
 
     public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) {
@@ -322,6 +330,25 @@ public abstract class AbstractITCase {
         return getObject(response.getLocation(), RoleService.class, RoleTO.class);
     }
 
+    protected AnyObjectTO createAnyObject(final AnyObjectTO anyObjectTO) {
+        Response response = anyObjectService.create(anyObjectTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return getObject(response.getLocation(), AnyObjectService.class, AnyObjectTO.class);
+    }
+
+    protected AnyObjectTO updateAnyObject(final AnyObjectMod anyObjectMod) {
+        return anyObjectService.update(anyObjectMod.getKey(), anyObjectMod).readEntity(AnyObjectTO.class);
+    }
+
+    protected AnyObjectTO deleteAnyObject(final Long key) {
+        return anyObjectService.delete(key).readEntity(AnyObjectTO.class);
+    }
+
     protected GroupTO createGroup(final GroupTO groupTO) {
         Response response = groupService.create(groupTO);
         if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
@@ -337,8 +364,8 @@ public abstract class AbstractITCase {
         return groupService.update(groupMod.getKey(), groupMod).readEntity(GroupTO.class);
     }
 
-    protected GroupTO deleteGroup(final Long id) {
-        return groupService.delete(id).readEntity(GroupTO.class);
+    protected GroupTO deleteGroup(final Long key) {
+        return groupService.delete(key).readEntity(GroupTO.class);
     }
 
     @SuppressWarnings("unchecked")


[07/27] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/SYNCOPE-666
Commit: 7610c62da3df9863a33c7c047537fd26d95c5577
Parents: 84c2d7b 8ea1e6a
Author: fmartelli <fa...@gmail.com>
Authored: Thu May 28 08:40:07 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu May 28 08:40:07 2015 +0200

----------------------------------------------------------------------
 .../client/console/panels/AbstractSearchPanel.java   |  1 +
 .../java/sync/GroupSyncResultHandlerImpl.java        |  7 ++-----
 .../java/sync/UserSyncResultHandlerImpl.java         | 15 +++++++--------
 pom.xml                                              |  2 +-
 4 files changed, 11 insertions(+), 14 deletions(-)
----------------------------------------------------------------------



[18/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..b00bc1b
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
@@ -0,0 +1,644 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.JexlHelpUtils;
+import org.apache.syncope.client.console.panels.ResourceConnConfPanel.ConnConfModEvent;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDecoratedCheckbox;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.MappingPurposePanel;
+import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+/**
+ * Resource mapping panel.
+ */
+public class ResourceMappingPanel extends Panel {
+
+    private static final long serialVersionUID = -7982691107029848579L;
+
+    /**
+     * Mapping field style sheet.
+     */
+    private static final String FIELD_STYLE = "ui-widget-content ui-corner-all short_fixedsize";
+
+    /**
+     * Mapping field style sheet.
+     */
+    private static final String DEF_FIELD_STYLE = "ui-widget-content ui-corner-all";
+
+    /**
+     * Mapping field style sheet.
+     */
+    private static final String SHORT_FIELD_STYLE = "ui-widget-content ui-corner-all veryshort_fixedsize";
+
+    /**
+     * Schema rest client.
+     */
+    @SpringBean
+    private SchemaRestClient schemaRestClient;
+
+    /**
+     * ConnInstance rest client.
+     */
+    @SpringBean
+    private ConnectorRestClient connRestClient;
+
+    /**
+     * Resource schema name.
+     */
+    private final List<String> schemaNames;
+
+    /**
+     * Add mapping button.
+     */
+    private final AjaxButton addMappingBtn;
+
+    /**
+     * All mappings.
+     */
+    private final ListView<MappingItemTO> mappings;
+
+    /**
+     * External resource to be updated.
+     */
+    private final ResourceTO resourceTO;
+
+    /**
+     * User / group.
+     */
+    private final AttributableType attrType;
+
+    /**
+     * Mapping container.
+     */
+    private final WebMarkupContainer mappingContainer;
+
+    /**
+     * AccountLink container.
+     */
+    private final WebMarkupContainer accountLinkContainer;
+
+    private final AjaxCheckBoxPanel accountLinkCheckbox;
+
+    private MappingTO getMapping() {
+        MappingTO result = null;
+
+        if (AttributableType.USER == this.attrType) {
+            if (this.resourceTO.getUmapping() == null) {
+                this.resourceTO.setUmapping(new MappingTO());
+            }
+            result = this.resourceTO.getUmapping();
+        }
+        if (AttributableType.GROUP == this.attrType) {
+            if (this.resourceTO.getGmapping() == null) {
+                this.resourceTO.setGmapping(new MappingTO());
+            }
+            result = this.resourceTO.getGmapping();
+        }
+
+        return result;
+    }
+
+    /**
+     * Attribute Mapping Panel.
+     *
+     * @param id panel id
+     * @param resourceTO external resource
+     * @param attrType USER / GROUP
+     */
+    public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AttributableType attrType) {
+        super(id);
+        setOutputMarkupId(true);
+
+        this.resourceTO = resourceTO;
+        this.attrType = attrType;
+
+        this.mappingContainer = new WebMarkupContainer("mappingContainer");
+        this.mappingContainer.setOutputMarkupId(true);
+        add(this.mappingContainer);
+
+        this.accountLinkContainer = new WebMarkupContainer("accountLinkContainer");
+        this.accountLinkContainer.setOutputMarkupId(true);
+        add(this.accountLinkContainer);
+
+        if (this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0) {
+            schemaNames = getSchemaNames(this.resourceTO.getConnectorId(), this.resourceTO.getConnConfProperties());
+
+            setEnabled();
+        } else {
+            schemaNames = Collections.<String>emptyList();
+        }
+
+        final WebMarkupContainer jexlHelp = JexlHelpUtils.getJexlHelpWebContainer("jexlHelp");
+
+        AjaxLink<Void> questionMarkJexlHelp = JexlHelpUtils.getAjaxLink(jexlHelp, "questionMarkJexlHelp");
+        mappingContainer.add(questionMarkJexlHelp);
+        questionMarkJexlHelp.add(jexlHelp);
+
+        final Label passwordLabel = new Label("passwordLabel", new ResourceModel("password"));
+        mappingContainer.add(passwordLabel);
+        if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
+            passwordLabel.setVisible(false);
+        }
+
+        Collections.sort(getMapping().getItems(), new Comparator<MappingItemTO>() {
+
+            @Override
+            public int compare(final MappingItemTO left, final MappingItemTO right) {
+                int compared;
+                if (left == null && right == null) {
+                    compared = 0;
+                } else if (left == null) {
+                    compared = 1;
+                } else if (right == null) {
+                    compared = -1;
+                } else if (left.getPurpose() == MappingPurpose.BOTH && right.getPurpose() != MappingPurpose.BOTH) {
+                    compared = -1;
+                } else if (left.getPurpose() != MappingPurpose.BOTH && right.getPurpose() == MappingPurpose.BOTH) {
+                    compared = 1;
+                } else if (left.getPurpose() == MappingPurpose.PROPAGATION
+                        && (right.getPurpose() == MappingPurpose.SYNCHRONIZATION || right.getPurpose()
+                        == MappingPurpose.NONE)) {
+                    compared = -1;
+                } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION
+                        && right.getPurpose() == MappingPurpose.PROPAGATION) {
+                    compared = 1;
+                } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION
+                        && right.getPurpose() == MappingPurpose.NONE) {
+                    compared = -1;
+                } else if (left.getPurpose() == MappingPurpose.NONE
+                        && right.getPurpose() != MappingPurpose.NONE) {
+                    compared = 1;
+                } else if (left.isAccountid()) {
+                    compared = -1;
+                } else if (right.isAccountid()) {
+                    compared = 1;
+                } else if (left.isPassword()) {
+                    compared = -1;
+                } else if (right.isPassword()) {
+                    compared = 1;
+                } else {
+                    compared = left.getIntAttrName().compareTo(right.getIntAttrName());
+                }
+                return compared;
+            }
+        });
+
+        mappings = new ListView<MappingItemTO>("mappings", getMapping().getItems()) {
+
+            private static final long serialVersionUID = 4949588177564901031L;
+
+            @Override
+            protected void populateItem(final ListItem<MappingItemTO> item) {
+                final MappingItemTO mapItem = item.getModelObject();
+                if (mapItem.getPurpose() == null) {
+                    mapItem.setPurpose(MappingPurpose.BOTH);
+                }
+
+                AttributableType entity = null;
+                if (mapItem.getIntMappingType() != null) {
+                    entity = mapItem.getIntMappingType().getAttributableType();
+                }
+
+                final List<IntMappingType> attrTypes = new ArrayList<IntMappingType>(getAttributeTypes(entity));
+
+                item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) {
+
+                    private static final long serialVersionUID = 7170946748485726506L;
+
+                    @Override
+                    protected void onUpdate(final AjaxRequestTarget target) {
+                        int index = -1;
+                        for (int i = 0; i < getMapping().getItems().size() && index == -1; i++) {
+                            if (mapItem.equals(getMapping().getItems().get(i))) {
+                                index = i;
+                            }
+                        }
+
+                        if (index != -1) {
+                            getMapping().getItems().remove(index);
+                            item.getParent().removeAll();
+                            target.add(ResourceMappingPanel.this);
+                        }
+                    }
+
+                    @Override
+                    protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+                        super.updateAjaxAttributes(attributes);
+
+                        final AjaxCallListener ajaxCallListener = new AjaxCallListener() {
+
+                            private static final long serialVersionUID = 7160235486520935153L;
+
+                            @Override
+                            public CharSequence getPrecondition(final Component component) {
+                                return "if (!confirm('" + getString("confirmDelete") + "')) return false;";
+                            }
+                        };
+                        attributes.getAjaxCallListeners().add(ajaxCallListener);
+                    }
+                });
+
+                final AjaxDropDownChoicePanel<String> intAttrNames =
+                        new AjaxDropDownChoicePanel<String>("intAttrNames", getString("intAttrNames"),
+                                new PropertyModel<String>(mapItem, "intAttrName"), false);
+                intAttrNames.setChoices(schemaNames);
+                intAttrNames.setRequired(true);
+                intAttrNames.setStyleSheet(FIELD_STYLE);
+                intAttrNames.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+                    private static final long serialVersionUID = -1107858522700306810L;
+
+                    @Override
+                    protected void onUpdate(final AjaxRequestTarget target) {
+                    }
+                });
+                item.add(intAttrNames);
+
+                final AjaxDropDownChoicePanel<IntMappingType> intMappingTypes =
+                        new AjaxDropDownChoicePanel<IntMappingType>("intMappingTypes",
+                                new ResourceModel("intMappingTypes", "intMappingTypes").getObject(),
+                                new PropertyModel<IntMappingType>(mapItem, "intMappingType"));
+                intMappingTypes.setRequired(true);
+                intMappingTypes.setChoices(attrTypes);
+                intMappingTypes.setStyleSheet(FIELD_STYLE);
+                item.add(intMappingTypes);
+
+                final AjaxDropDownChoicePanel<AttributableType> entitiesPanel =
+                        new AjaxDropDownChoicePanel<AttributableType>("entities",
+                                new ResourceModel("entities", "entities").getObject(), new Model<AttributableType>(
+                                        entity));
+                entitiesPanel.setChoices(attrType == AttributableType.GROUP
+                        ? Collections.<AttributableType>singletonList(AttributableType.GROUP)
+                        : Arrays.asList(AttributableType.values()));
+                entitiesPanel.setStyleSheet(DEF_FIELD_STYLE);
+                entitiesPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+                    private static final long serialVersionUID = -1107858522700306810L;
+
+                    @Override
+                    protected void onUpdate(final AjaxRequestTarget target) {
+                        attrTypes.clear();
+                        attrTypes.addAll(getAttributeTypes(entitiesPanel.getModelObject()));
+                        intMappingTypes.setChoices(attrTypes);
+
+                        intAttrNames.setChoices(Collections.<String>emptyList());
+
+                        target.add(intMappingTypes.getField());
+                        target.add(intAttrNames.getField());
+                    }
+                });
+                item.add(entitiesPanel);
+
+                final FieldPanel<String> extAttrNames = new AjaxTextFieldPanel("extAttrName",
+                        new ResourceModel("extAttrNames", "extAttrNames").getObject(),
+                        new PropertyModel<String>(mapItem, "extAttrName"));
+                ((AjaxTextFieldPanel) extAttrNames).setChoices(schemaNames);
+
+                boolean required = false;
+                if (mapItem.isPassword()) {
+                    ((AjaxTextFieldPanel) extAttrNames).setModelObject(null);
+                } else {
+                    required = true;
+                }
+                extAttrNames.setRequired(required);
+                extAttrNames.setEnabled(required);
+                extAttrNames.setStyleSheet(FIELD_STYLE);
+                item.add(extAttrNames);
+
+                final AjaxTextFieldPanel mandatory = new AjaxTextFieldPanel("mandatoryCondition",
+                        new ResourceModel("mandatoryCondition", "mandatoryCondition").getObject(),
+                        new PropertyModel<String>(mapItem, "mandatoryCondition"));
+                mandatory.setChoices(Arrays.asList(new String[] { "true", "false" }));
+                mandatory.setStyleSheet(SHORT_FIELD_STYLE);
+                item.add(mandatory);
+
+                final AjaxCheckBoxPanel accountId = new AjaxCheckBoxPanel("accountId",
+                        new ResourceModel("accountId", "accountId").getObject(),
+                        new PropertyModel<Boolean>(mapItem, "accountid"));
+                accountId.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+                    private static final long serialVersionUID = -1107858522700306810L;
+
+                    @Override
+                    protected void onUpdate(final AjaxRequestTarget target) {
+                        if (accountId.getModelObject()) {
+                            mapItem.setMandatoryCondition("true");
+                            mandatory.setEnabled(false);
+                        } else {
+                            mapItem.setMandatoryCondition("false");
+                            mandatory.setEnabled(true);
+                        }
+                        target.add(mandatory);
+                    }
+                });
+                item.add(accountId);
+
+                final AjaxCheckBoxPanel password = new AjaxCheckBoxPanel("password",
+                        new ResourceModel("password", "password").getObject(),
+                        new PropertyModel<Boolean>(mapItem, "password"));
+                password.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+                    private static final long serialVersionUID = -1107858522700306810L;
+
+                    @Override
+                    protected void onUpdate(final AjaxRequestTarget target) {
+                        extAttrNames.setEnabled(!mapItem.isAccountid() && !password.getModelObject());
+                        extAttrNames.setModelObject(null);
+                        extAttrNames.setRequired(!password.getModelObject());
+                        target.add(extAttrNames);
+
+                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
+                        target.add(accountId);
+                    }
+                });
+                item.add(password);
+                if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
+                    password.setVisible(false);
+                }
+
+                final WebMarkupContainer purpose = new WebMarkupContainer("purpose");
+                purpose.setOutputMarkupId(Boolean.TRUE);
+
+                final MappingPurposePanel panel = new MappingPurposePanel("purposeActions",
+                        new PropertyModel<MappingPurpose>(mapItem, "purpose"), purpose);
+
+                purpose.add(panel);
+
+                item.add(purpose);
+
+                intMappingTypes.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+                    private static final long serialVersionUID = -1107858522700306810L;
+
+                    @Override
+                    protected void onUpdate(final AjaxRequestTarget target) {
+                        setAttrNames(intMappingTypes.getModelObject(), intAttrNames);
+                        target.add(intAttrNames);
+
+                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
+                        target.add(accountId);
+                    }
+                });
+
+                setAttrNames(mapItem.getIntMappingType(), intAttrNames);
+                setAccountId(mapItem.getIntMappingType(), accountId, password);
+            }
+        };
+
+        mappings.setReuseItems(true);
+        mappingContainer.add(mappings);
+
+        addMappingBtn = new IndicatingAjaxButton("addMappingBtn", new ResourceModel("add")) {
+
+            private static final long serialVersionUID = -4804368561204623354L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                getMapping().getItems().add(new MappingItemTO());
+                target.add(ResourceMappingPanel.this);
+            }
+        };
+        addMappingBtn.setDefaultFormProcessing(false);
+        addMappingBtn.setEnabled(this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0);
+        mappingContainer.add(addMappingBtn);
+
+        boolean accountLinkEnabled = false;
+        if (getMapping().getAccountLink() != null) {
+            accountLinkEnabled = true;
+        }
+        accountLinkCheckbox = new AjaxCheckBoxPanel("accountLinkCheckbox",
+                new ResourceModel("accountLinkCheckbox", "accountLinkCheckbox").getObject(),
+                new Model<Boolean>(Boolean.valueOf(accountLinkEnabled)));
+        accountLinkCheckbox.setEnabled(true);
+
+        accountLinkContainer.add(accountLinkCheckbox);
+
+        final AjaxTextFieldPanel accountLink = new AjaxTextFieldPanel("accountLink",
+                new ResourceModel("accountLink", "accountLink").getObject(),
+                new PropertyModel<String>(getMapping(), "accountLink"));
+        accountLink.setEnabled(accountLinkEnabled);
+        accountLinkContainer.add(accountLink);
+
+        accountLinkCheckbox.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                if (accountLinkCheckbox.getModelObject()) {
+                    accountLink.setEnabled(Boolean.TRUE);
+                    accountLink.setModelObject("");
+                } else {
+                    accountLink.setEnabled(Boolean.FALSE);
+                    accountLink.setModelObject("");
+                }
+
+                target.add(accountLink);
+            }
+        });
+    }
+
+    private List<String> getSchemaNames(final Long connectorId, final Set<ConnConfProperty> conf) {
+        final ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+        connInstanceTO.setKey(connectorId);
+        connInstanceTO.getConfiguration().addAll(conf);
+
+        return connRestClient.getSchemaNames(connInstanceTO);
+    }
+
+    private void setEnabled() {
+        final ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+        connInstanceTO.setKey(this.resourceTO.getConnectorId());
+        connInstanceTO.getConfiguration().addAll(this.resourceTO.getConnConfProperties());
+
+        List<ConnIdObjectClassTO> objectClasses = connRestClient.getSupportedObjectClasses(connInstanceTO);
+
+        boolean enabled = objectClasses.isEmpty()
+                || (AttributableType.USER == attrType && objectClasses.contains(ConnIdObjectClassTO.ACCOUNT))
+                || (AttributableType.GROUP == attrType && objectClasses.contains(ConnIdObjectClassTO.GROUP));
+        this.mappingContainer.setEnabled(enabled);
+        this.mappingContainer.setVisible(enabled);
+        this.accountLinkContainer.setEnabled(enabled);
+        this.accountLinkContainer.setVisible(enabled);
+
+        if (!enabled) {
+            getMapping().getItems().clear();
+            getMapping().setAccountLink(null);
+            if (this.accountLinkCheckbox != null) {
+                this.accountLinkCheckbox.setModelObject(null);
+            }
+        }
+    }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if (event.getPayload() instanceof ConnConfModEvent) {
+            final AjaxRequestTarget target = ((ConnConfModEvent) event.getPayload()).getTarget();
+
+            final List<ConnConfProperty> conf = ((ConnConfModEvent) event.getPayload()).getConfiguration();
+
+            mappings.removeAll();
+
+            addMappingBtn.setEnabled(resourceTO.getConnectorId() != null && resourceTO.getConnectorId() > 0);
+
+            schemaNames.clear();
+            schemaNames.addAll(getSchemaNames(resourceTO.getConnectorId(), new HashSet<ConnConfProperty>(conf)));
+
+            setEnabled();
+
+            target.add(this);
+        }
+    }
+
+    /**
+     * Set attribute names for a drop down choice list.
+     *
+     * @param type attribute type.
+     * @param toBeUpdated drop down choice to be updated.
+     */
+    private void setAttrNames(final IntMappingType type, final AjaxDropDownChoicePanel<String> toBeUpdated) {
+        toBeUpdated.setRequired(true);
+        toBeUpdated.setEnabled(true);
+
+        if (type == null || type.getAttributableType() == null) {
+            toBeUpdated.setChoices(Collections.<String>emptyList());
+        } else {
+            switch (type) {
+                // user attribute names
+                case UserPlainSchema:
+                case GroupPlainSchema:
+                case MembershipPlainSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getPlainSchemaNames(type.getAttributableType()));
+                    break;
+
+                case UserDerivedSchema:
+                case GroupDerivedSchema:
+                case MembershipDerivedSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getDerSchemaNames(type.getAttributableType()));
+                    break;
+
+                case UserVirtualSchema:
+                case GroupVirtualSchema:
+                case MembershipVirtualSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getVirSchemaNames(type.getAttributableType()));
+                    break;
+
+                case UserId:
+                case Password:
+                case Username:
+                case GroupId:
+                case GroupName:
+                default:
+                    toBeUpdated.setRequired(false);
+                    toBeUpdated.setEnabled(false);
+                    toBeUpdated.setChoices(Collections.<String>emptyList());
+            }
+        }
+    }
+
+    /**
+     * Enable/Disable accountId checkbox.
+     *
+     * @param type attribute type.
+     * @param accountId accountId checkbox.
+     * @param password password checkbox.
+     */
+    private void setAccountId(final IntMappingType type, final AjaxCheckBoxPanel accountId,
+            final AjaxCheckBoxPanel password) {
+
+        if (type != null && type.getAttributableType() != null) {
+            switch (type) {
+                case UserVirtualSchema:
+                case GroupVirtualSchema:
+                case MembershipVirtualSchema:
+                // Virtual accountId is not permitted
+                case Password:
+                    // AccountId cannot be derived from password.
+                    accountId.setReadOnly(true);
+                    accountId.setModelObject(false);
+                    break;
+
+                default:
+                    if (password.getModelObject()) {
+                        accountId.setReadOnly(true);
+                        accountId.setModelObject(false);
+                    } else {
+                        accountId.setReadOnly(false);
+                    }
+            }
+        }
+    }
+
+    /**
+     * Get all attribute types from a selected attribute type.
+     *
+     * @param entity entity.
+     * @return all attribute types.
+     */
+    private List<IntMappingType> getAttributeTypes(final AttributableType entity) {
+        final List<IntMappingType> res = new ArrayList<>();
+
+        if (entity != null) {
+            res.addAll(IntMappingType.getAttributeTypes(AttributableType.valueOf(entity.name())));
+        }
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
new file mode 100644
index 0000000..15d2fe8
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.syncope.client.console.rest.PolicyRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class ResourceSecurityPanel extends Panel {
+
+    private static final long serialVersionUID = -7982691107029848579L;
+
+    @SpringBean
+    private PolicyRestClient policyRestClient;
+
+    private IModel<Map<Long, String>> passwordPolicies = null;
+
+    private IModel<Map<Long, String>> accountPolicies = null;
+
+    private IModel<Map<Long, String>> syncPolicies = null;
+
+    public ResourceSecurityPanel(final String id, final ResourceTO resourceTO) {
+
+        super(id);
+
+        setOutputMarkupId(true);
+
+        passwordPolicies = new LoadableDetachableModel<Map<Long, String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected Map<Long, String> load() {
+                Map<Long, String> res = new HashMap<>();
+                for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.PASSWORD)) {
+                    res.put(policyTO.getKey(), policyTO.getDescription());
+                }
+                return res;
+            }
+        };
+
+        accountPolicies = new LoadableDetachableModel<Map<Long, String>>() {
+
+            private static final long serialVersionUID = -2012833443695917883L;
+
+            @Override
+            protected Map<Long, String> load() {
+                Map<Long, String> res = new HashMap<>();
+                for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.ACCOUNT)) {
+                    res.put(policyTO.getKey(), policyTO.getDescription());
+                }
+                return res;
+            }
+        };
+
+        syncPolicies = new LoadableDetachableModel<Map<Long, String>>() {
+
+            private static final long serialVersionUID = -2012833443695917883L;
+
+            @Override
+            protected Map<Long, String> load() {
+                Map<Long, String> res = new HashMap<>();
+                for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.SYNC)) {
+                    res.put(policyTO.getKey(), policyTO.getDescription());
+                }
+                return res;
+            }
+        };
+
+        final WebMarkupContainer securityContainer = new WebMarkupContainer("security");
+
+        securityContainer.setOutputMarkupId(true);
+        add(securityContainer);
+
+        // -------------------------------
+        // Password policy specification
+        // -------------------------------
+        final AjaxDropDownChoicePanel<Long> passwordPolicy = new AjaxDropDownChoicePanel<Long>("passwordPolicy",
+                new ResourceModel("passwordPolicy", "passwordPolicy").getObject(), new PropertyModel<Long>(resourceTO,
+                        "passwordPolicy"));
+
+        passwordPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.PASSWORD));
+
+        passwordPolicy.setChoices(new ArrayList<>(passwordPolicies.getObject().keySet()));
+
+        ((DropDownChoice<?>) passwordPolicy.getField()).setNullValid(true);
+
+        securityContainer.add(passwordPolicy);
+        // -------------------------------
+
+        // -------------------------------
+        // Account policy specification
+        // -------------------------------
+        final AjaxDropDownChoicePanel<Long> accountPolicy = new AjaxDropDownChoicePanel<Long>("accountPolicy",
+                new ResourceModel("accountPolicy", "accountPolicy").getObject(), new PropertyModel<Long>(resourceTO,
+                        "accountPolicy"));
+
+        accountPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.ACCOUNT));
+
+        accountPolicy.setChoices(new ArrayList<Long>(accountPolicies.getObject().keySet()));
+
+        ((DropDownChoice<?>) accountPolicy.getField()).setNullValid(true);
+
+        securityContainer.add(accountPolicy);
+        // -------------------------------
+
+        // -------------------------------
+        // Sync policy specification
+        // -------------------------------
+        final AjaxDropDownChoicePanel<Long> syncPolicy = new AjaxDropDownChoicePanel<Long>("syncPolicy",
+                new ResourceModel("syncPolicy", "syncPolicy").getObject(), new PropertyModel<Long>(resourceTO,
+                        "syncPolicy"));
+
+        syncPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.SYNC));
+
+        syncPolicy.setChoices(new ArrayList<Long>(syncPolicies.getObject().keySet()));
+
+        ((DropDownChoice<?>) syncPolicy.getField()).setNullValid(true);
+
+        securityContainer.add(syncPolicy);
+        // -------------------------------
+    }
+
+    private class PolicyRenderer extends ChoiceRenderer<Long> {
+
+        private static final long serialVersionUID = 8060500161321947000L;
+
+        private PolicyType type;
+
+        public PolicyRenderer(final PolicyType type) {
+            super();
+            this.type = type;
+        }
+
+        @Override
+        public Object getDisplayValue(final Long object) {
+            switch (type) {
+                case ACCOUNT:
+                    return accountPolicies.getObject().get(object);
+                case PASSWORD:
+                    return passwordPolicies.getObject().get(object);
+                case SYNC:
+                    return syncPolicies.getObject().get(object);
+                default:
+                    return "";
+            }
+        }
+
+        @Override
+        public String getIdValue(final Long object, final int index) {
+            return String.valueOf(object != null
+                    ? object
+                    : 0L);
+        }
+    };
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
new file mode 100644
index 0000000..755b2d1
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
@@ -0,0 +1,485 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.PreferenceManager;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.pages.ConnectorModalPage;
+import org.apache.syncope.client.console.pages.ProvisioningModalPage;
+import org.apache.syncope.client.console.pages.ResourceModalPage;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.LinkPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+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.ISortableDataProvider;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.StringResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resources WebPage.
+ */
+public class Resources extends Panel {
+
+    private static final long serialVersionUID = -3789252860990261728L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(Resources.class);
+
+    private static final int WIN_HEIGHT = 600;
+
+    private static final int WIN_WIDTH = 1100;
+
+    @SpringBean
+    private PreferenceManager prefMan;
+
+    @SpringBean
+    private ResourceRestClient resourceRestClient;
+
+    private final ModalWindow createResourceWin;
+
+    private final ModalWindow editResourceWin;
+
+    private final int resourcePaginatorRows;
+
+    private WebMarkupContainer resourceContainer;
+
+    private final ModalWindow editConnectorWin;
+
+    /**
+     * Modal window to be used for user status management.
+     */
+    protected final ModalWindow statusmodal = new ModalWindow("statusModal");
+
+    /**
+     * Schemas to be shown modal window height.
+     */
+    private static final int STATUS_MODAL_WIN_HEIGHT = 500;
+
+    /**
+     * Schemas to be shown modal window width.
+     */
+    private static final int STATUS_MODAL_WIN_WIDTH = 700;
+
+    @SpringBean
+    private ConnectorRestClient connectorRestClient;
+
+    private final PageReference pageRef;
+
+    public Resources(final String id, final PageReference pageRef) {
+        super(id);
+        this.pageRef = pageRef;
+
+        createResourceWin = new ModalWindow("createResourceWin");
+        add(createResourceWin);
+
+        editResourceWin = new ModalWindow("editResourceWin");
+        add(editResourceWin);
+
+        editConnectorWin = new ModalWindow("editConnectorWin");
+        add(editConnectorWin);
+
+        statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
+        statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
+        statusmodal.setCookieName("status-modal");
+        add(statusmodal);
+
+        resourcePaginatorRows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_RESOURCES_PAGINATOR_ROWS);
+
+        setupResources();
+    }
+
+    private void setupResources() {
+        List<IColumn<ResourceTO, String>> columns = new ArrayList<>();
+
+        columns.add(new PropertyColumn<ResourceTO, String>(new StringResourceModel("key", this, null), "key", "key"));
+
+        columns.add(new AbstractColumn<ResourceTO, String>(
+                new StringResourceModel("connector", this, null, "connector")) {
+
+                    private static final long serialVersionUID = 8263694778917279290L;
+
+                    @Override
+                    public void populateItem(final Item<ICellPopulator<ResourceTO>> cellItem, final String componentId,
+                            final IModel<ResourceTO> rowModel) {
+
+                        final AjaxLink<String> editLink = new ClearIndicatingAjaxLink<String>("link", pageRef) {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            protected void onClickInternal(final AjaxRequestTarget target) {
+
+                                editConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                                    private static final long serialVersionUID = -7834632442532690940L;
+
+                                    @Override
+                                    public Page createPage() {
+                                        return new ConnectorModalPage(Resources.this.pageRef,
+                                                editConnectorWin,
+                                                connectorRestClient.read(rowModel.getObject().getConnectorId()));
+                                    }
+                                });
+
+                                editConnectorWin.show(target);
+                            }
+                        };
+                        editLink.add(new Label("linkTitle", rowModel.getObject().getConnectorDisplayName()));
+
+                        LinkPanel editConnPanel = new LinkPanel(componentId);
+                        editConnPanel.add(editLink);
+
+                        cellItem.add(editConnPanel);
+
+                        MetaDataRoleAuthorizationStrategy.authorize(editConnPanel, ENABLE, Entitlement.CONNECTOR_READ);
+                    }
+                });
+
+        columns.add(new AbstractColumn<ResourceTO, String>(
+                new StringResourceModel("propagationPrimary", this, null)) {
+
+                    private static final long serialVersionUID = -3503023501954863131L;
+
+                    @Override
+                    public void populateItem(final Item<ICellPopulator<ResourceTO>> item,
+                            final String componentId, final IModel<ResourceTO> model) {
+
+                        item.add(new Label(componentId, ""));
+                        item.add(new AttributeModifier("class", new Model<>(
+                                                Boolean.toString(model.getObject().isPropagationPrimary()))));
+                    }
+
+                    @Override
+                    public String getCssClass() {
+                        return "narrowcolumn";
+                    }
+                });
+
+        columns.add(new PropertyColumn<ResourceTO, String>(new StringResourceModel(
+                "propagationPriority", this, null), "propagationPriority", "propagationPriority") {
+
+                    private static final long serialVersionUID = 1L;
+
+                    @Override
+                    public String getCssClass() {
+                        return "narrowcolumn";
+                    }
+                });
+
+        columns.add(new AbstractColumn<ResourceTO, String>(new StringResourceModel("actions", this, null, "")) {
+
+            private static final long serialVersionUID = 2054811145491901166L;
+
+            @Override
+            public String getCssClass() {
+                return "action";
+            }
+
+            @Override
+            public void populateItem(final Item<ICellPopulator<ResourceTO>> cellItem, final String componentId,
+                    final IModel<ResourceTO> model) {
+
+                final ResourceTO resourceTO = model.getObject();
+
+                final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, pageRef);
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        statusmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new ProvisioningModalPage<>(
+                                        pageRef, statusmodal, model.getObject(), UserTO.class);
+                            }
+                        });
+
+                        statusmodal.show(target);
+                    }
+                }, ActionLink.ActionType.MANAGE_USERS, "Resources");
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+
+                        statusmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new ProvisioningModalPage<>(
+                                        pageRef, statusmodal, model.getObject(), GroupTO.class);
+                            }
+                        });
+
+                        statusmodal.show(target);
+                    }
+                }, ActionLink.ActionType.MANAGE_GROUPS, "Resources");
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        resourceTO.setUsyncToken(null);
+                        resourceTO.setRsyncToken(null);
+                        try {
+                            resourceRestClient.update(resourceTO);
+                            info(getString(Constants.OPERATION_SUCCEEDED));
+                        } catch (SyncopeClientException e) {
+                            error(getString(Constants.ERROR) + ":" + e.getMessage());
+
+                            LOG.error("While resetting sync token from " + resourceTO.getKey(), e);
+                        }
+
+                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
+                        target.add(resourceContainer);
+                    }
+                }, ActionLink.ActionType.RESET, "Resources");
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        editResourceWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new ResourceModalPage(pageRef, editResourceWin, resourceTO, false);
+                            }
+                        });
+
+                        editResourceWin.show(target);
+                    }
+                }, ActionLink.ActionType.EDIT, "Resources");
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        try {
+                            resourceRestClient.delete(resourceTO.getKey());
+                            info(getString(Constants.OPERATION_SUCCEEDED));
+                        } catch (SyncopeClientException e) {
+                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+
+                            LOG.error("While deleting resource " + resourceTO.getKey(), e);
+                        }
+
+                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
+                        target.add(resourceContainer);
+                    }
+                }, ActionLink.ActionType.DELETE, "Resources");
+
+                cellItem.add(panel);
+            }
+        });
+
+        final AjaxDataTablePanel<ResourceTO, String> table = new AjaxDataTablePanel<>(
+                "resourceDatatable",
+                columns,
+                (ISortableDataProvider<ResourceTO, String>) new ResourcesProvider(),
+                resourcePaginatorRows,
+                Arrays.asList(new ActionLink.ActionType[] { ActionLink.ActionType.DELETE }),
+                resourceRestClient,
+                "key",
+                "Resources",
+                pageRef);
+
+        resourceContainer = new WebMarkupContainer("resourceContainer");
+        resourceContainer.add(table);
+        resourceContainer.setOutputMarkupId(true);
+
+        add(resourceContainer);
+
+        ((BasePage) pageRef.getPage()).setWindowClosedCallback(createResourceWin, resourceContainer);
+        ((BasePage) pageRef.getPage()).setWindowClosedCallback(editResourceWin, resourceContainer);
+
+        createResourceWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        createResourceWin.setInitialHeight(WIN_HEIGHT);
+        createResourceWin.setInitialWidth(WIN_WIDTH);
+        createResourceWin.setCookieName("create-res-modal");
+
+        editResourceWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        editResourceWin.setInitialHeight(WIN_HEIGHT);
+        editResourceWin.setInitialWidth(WIN_WIDTH);
+        editResourceWin.setCookieName("edit-res-modal");
+
+        editConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        editConnectorWin.setInitialHeight(WIN_HEIGHT);
+        editConnectorWin.setInitialWidth(WIN_WIDTH);
+        editConnectorWin.setCookieName("edit-conn-modal");
+
+        AjaxLink<Void> createResourceLink
+                = new ClearIndicatingAjaxLink<Void>("createResourceLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        createResourceWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                final ResourceModalPage windows = new ResourceModalPage(Resources.this.pageRef,
+                                        editResourceWin, new ResourceTO(), true);
+                                return windows;
+                            }
+                        });
+
+                        createResourceWin.show(target);
+                    }
+                };
+
+        MetaDataRoleAuthorizationStrategy.authorize(createResourceLink, ENABLE, Entitlement.RESOURCE_CREATE);
+
+        add(createResourceLink);
+
+        @SuppressWarnings("rawtypes")
+        final Form paginatorForm = new Form("resourcePaginatorForm");
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        final DropDownChoice rowsChooser = new DropDownChoice("rowsChooser", new PropertyModel(this,
+                "resourcePaginatorRows"), prefMan.getPaginatorChoices());
+
+        rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                prefMan.set(getRequest(), getResponse(), Constants.PREF_RESOURCES_PAGINATOR_ROWS,
+                        String.valueOf(resourcePaginatorRows));
+
+                table.setItemsPerPage(resourcePaginatorRows);
+                target.add(resourceContainer);
+            }
+        });
+
+        paginatorForm.add(rowsChooser);
+        add(paginatorForm);
+    }
+
+    class ResourcesProvider extends SortableDataProvider<ResourceTO, String> {
+
+        private static final long serialVersionUID = -9055916672926643975L;
+
+        private final SortableDataProviderComparator<ResourceTO> comparator;
+
+        public ResourcesProvider() {
+            super();
+            //Default sorting
+            setSort("key", SortOrder.ASCENDING);
+            comparator = new SortableDataProviderComparator<>(this);
+        }
+
+        @Override
+        public Iterator<ResourceTO> iterator(final long first, final long count) {
+            List<ResourceTO> list = resourceRestClient.getAll();
+
+            Collections.sort(list, comparator);
+
+            return list.subList((int) first, (int) first + (int) count).iterator();
+        }
+
+        @Override
+        public long size() {
+            return resourceRestClient.getAll().size();
+        }
+
+        @Override
+        public IModel<ResourceTO> model(final ResourceTO resource) {
+            return new AbstractReadOnlyModel<ResourceTO>() {
+
+                private static final long serialVersionUID = 8952474152465381634L;
+
+                @Override
+                public ResourceTO getObject() {
+                    return resource;
+                }
+            };
+        }
+    }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if (event.getPayload() instanceof AbstractSearchResultPanel.EventDataWrapper) {
+            ((AbstractSearchResultPanel.EventDataWrapper) event.getPayload()).getTarget().add(resourceContainer);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index a093dbd..d5c133b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -125,14 +125,14 @@ public class ConnectorRestClient extends BaseRestClient {
     }
 
     private Set<ConnConfProperty> filterProperties(final Set<ConnConfProperty> properties) {
-        Set<ConnConfProperty> newProperties = new HashSet<ConnConfProperty>();
+        Set<ConnConfProperty> newProperties = new HashSet<>();
 
         for (ConnConfProperty property : properties) {
             ConnConfProperty prop = new ConnConfProperty();
             prop.setSchema(property.getSchema());
             prop.setOverridable(property.isOverridable());
 
-            final List<Object> parsed = new ArrayList<Object>();
+            final List<Object> parsed = new ArrayList<>();
             if (property.getValues() != null) {
                 for (Object obj : property.getValues()) {
                     if (obj != null && !obj.toString().isEmpty()) {
@@ -179,7 +179,7 @@ public class ConnectorRestClient extends BaseRestClient {
     }
 
     public List<String> getSchemaNames(final ConnInstanceTO connectorTO) {
-        List<String> schemaNames = new ArrayList<String>();
+        List<String> schemaNames = new ArrayList<>();
         try {
             List<PlainSchemaTO> response = getService(ConnectorService.class).
                     getSchemaNames(connectorTO.getKey(), connectorTO, false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
new file mode 100644
index 0000000..06cba4d
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
@@ -0,0 +1,38 @@
+/*
+ * 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.rest;
+
+import java.util.List;
+
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.rest.api.service.RealmService;
+import org.springframework.stereotype.Component;
+
+/**
+ * Console client for invoking Rest Group's services.
+ */
+@Component
+public class RealmRestClient extends BaseRestClient {
+
+    private static final long serialVersionUID = -8549081557283519638L;
+
+    public List<RealmTO> list() {
+        return getService(RealmService.class).list();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..0b49f12
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -0,0 +1,521 @@
+/*
+ * 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.topology;
+
+import static org.apache.syncope.client.console.topology.TopologyNode.Status.FAILURE;
+import static org.apache.syncope.client.console.topology.TopologyNode.Status.REACHABLE;
+import static org.apache.syncope.client.console.topology.TopologyNode.Status.UNKNOWN;
+import static org.apache.syncope.client.console.topology.TopologyNode.Status.UNREACHABLE;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.time.Duration;
+
+public class Topology extends BasePage {
+
+    private static final long serialVersionUID = -1100228004207271272L;
+
+    private static final String CONNECTOR_SERVER_LOCATION_PREFIX = "connid://";
+
+    private final int origX = 3100;
+
+    private final int origY = 2800;
+
+    private final LoadableDetachableModel<List<ResourceTO>> resModel
+            = new LoadableDetachableModel<List<ResourceTO>>() {
+
+                private static final long serialVersionUID = 5275935387613157431L;
+
+                @Override
+                protected List<ResourceTO> load() {
+                    final List<ResourceTO> result = resourceRestClient.getAll();
+                    return result;
+                }
+            };
+
+    private final LoadableDetachableModel<Pair<List<ConnInstanceTO>, List<ConnInstanceTO>>> connModel
+            = new LoadableDetachableModel<Pair<List<ConnInstanceTO>, List<ConnInstanceTO>>>() {
+
+                private static final long serialVersionUID = 5275935387613157432L;
+
+                @Override
+                protected Pair<List<ConnInstanceTO>, List<ConnInstanceTO>> load() {
+                    final List<ConnInstanceTO> level1 = new ArrayList<>();
+                    final List<ConnInstanceTO> level2 = new ArrayList<>();
+
+                    for (ConnInstanceTO conn : connectorRestClient.getAllConnectors()) {
+                        if (conn.getLocation().startsWith(CONNECTOR_SERVER_LOCATION_PREFIX)) {
+                            level2.add(conn);
+                        } else {
+                            level1.add(conn);
+                        }
+                    }
+
+                    return Pair.of(level1, level2);
+                }
+            };
+
+    private final LoadableDetachableModel<List<URI>> csModel = new LoadableDetachableModel<List<URI>>() {
+
+        private static final long serialVersionUID = 5275935387613157433L;
+
+        @Override
+        protected List<URI> load() {
+            final List<URI> locations = new ArrayList<>();
+
+            for (String location : SyncopeConsoleSession.get().getSyncopeTO().getConnIdLocations()) {
+                if (location.startsWith(CONNECTOR_SERVER_LOCATION_PREFIX)) {
+                    locations.add(URI.create(location));
+                }
+            }
+
+            return locations;
+        }
+    };
+
+    public Topology() {
+        // -----------------------------------------
+        // Add Zoom panel
+        // -----------------------------------------
+        final ActionLinksPanel zoomActionPanel = new ActionLinksPanel("zoom", new Model<String>(), getPageReference());
+        add(zoomActionPanel);
+
+        zoomActionPanel.add(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                target.appendJavaScript("zoomIn($('#drawing')[0]);");
+            }
+
+        }, ActionLink.ActionType.ZOOM_IN, Entitlement.RESOURCE_LIST).add(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                target.appendJavaScript("zoomOut($('#drawing')[0]);");
+            }
+        }, ActionLink.ActionType.ZOOM_OUT, Entitlement.RESOURCE_LIST);
+        // -----------------------------------------
+
+        final WebMarkupContainer jsPlace = new WebMarkupContainer("jsPlace");
+
+        // -----------------------------------------
+        // Add Syncope (root topologynode)
+        // -----------------------------------------
+        final TopologyNode syncopeTopologyNode = new TopologyNode("Syncope", "Syncope", TopologyNode.Kind.SYNCOPE);
+        syncopeTopologyNode.setX(origX);
+        syncopeTopologyNode.setY(origY);
+
+        final URI uri = WebClient.client(SyncopeConsoleSession.get().getService(SyncopeService.class)).getBaseURI();
+        syncopeTopologyNode.setHost(uri.getHost());
+        syncopeTopologyNode.setPort(uri.getPort());
+
+        add(topologyNodePanel("syncope", syncopeTopologyNode, null, false));
+
+        final Map<String, Map<String, TopologyNode>> connections = new HashMap<>();
+        final Map<String, TopologyNode> syncopeConnections = new HashMap<>();
+        connections.put(syncopeTopologyNode.getDisplayName(), syncopeConnections);
+
+        // required to retrieve parent positions
+        final Map<String, TopologyNode> servers = new HashMap<>();
+        final Map<String, TopologyNode> connectors = new HashMap<>();
+            // -----------------------------------------
+
+        // -----------------------------------------
+        // Add Connector Servers
+        // -----------------------------------------
+        final ListView<URI> connectorServers = new ListView<URI>("connectorServers", csModel) {
+
+            private static final long serialVersionUID = 6978621871488360380L;
+
+            private final int size = csModel.getObject().size() + 1;
+
+            @Override
+            protected void populateItem(final ListItem<URI> item) {
+                int kx = size >= 4 ? 800 : (200 * size);
+
+                int x = (int) Math.round(origX + kx * Math.cos(Math.PI + Math.PI * (item.getIndex() + 1) / size));
+                int y = (int) Math.round(origY + 100 * Math.sin(Math.PI + Math.PI * (item.getIndex() + 1) / size));
+
+                final URI location = item.getModelObject();
+                final String url = location.toASCIIString();
+
+                final TopologyNode topologynode = new TopologyNode(url, url, TopologyNode.Kind.CONNECTOR_SERVER);
+
+                topologynode.setHost(location.getHost());
+                topologynode.setPort(location.getPort());
+                topologynode.setX(x);
+                topologynode.setY(y);
+
+                servers.put(topologynode.getDisplayName(), topologynode);
+
+                item.add(topologyNodePanel("cs", topologynode, syncopeTopologyNode, false));
+
+                syncopeConnections.put(url, topologynode);
+                connections.put(url, new HashMap<String, TopologyNode>());
+            }
+        };
+
+        connectorServers.setOutputMarkupId(true);
+        add(connectorServers);
+            // -----------------------------------------
+
+        // -----------------------------------------
+        // Add Connector Intances (first level)
+        // -----------------------------------------
+        final ListView<ConnInstanceTO> conn1
+                = new ListView<ConnInstanceTO>("conn1", connModel.getObject().getLeft()) {
+
+                    private static final long serialVersionUID = 6978621871488360381L;
+
+                    private final int size = connModel.getObject().getLeft().size() + 1;
+
+                    @Override
+                    protected void populateItem(final ListItem<ConnInstanceTO> item) {
+                        int kx = size >= 6 ? 800 : (130 * size);
+
+                        int x = (int) Math.round(origX + kx * Math.cos(Math.PI * (item.getIndex() + 1) / size));
+                        int y = (int) Math.round(origY + 100 * Math.sin(Math.PI * (item.getIndex() + 1) / size));
+
+                        final ConnInstanceTO conn = item.getModelObject();
+                        final TopologyNode topologynode = new TopologyNode(
+                                Long.valueOf(conn.getKey()), conn.getDisplayName(), TopologyNode.Kind.CONNECTOR);
+                        topologynode.setConnectinDisplayName(conn.getBundleName());
+                        topologynode.setX(x);
+                        topologynode.setY(y);
+
+                        connectors.put(topologynode.getDisplayName(), topologynode);
+
+                        item.add(topologyNodePanel("conn", topologynode, syncopeTopologyNode, true));
+
+                        if (conn.getLocation().startsWith(CONNECTOR_SERVER_LOCATION_PREFIX)) {
+                            final Map<String, TopologyNode> remoteConnections;
+
+                            if (connections.containsKey(conn.getLocation())) {
+                                remoteConnections = connections.get(conn.getLocation());
+                            } else {
+                                remoteConnections = new HashMap<>();
+                                connections.put(conn.getLocation(), remoteConnections);
+                            }
+                            remoteConnections.put(conn.getDisplayName(), topologynode);
+                        } else {
+                            syncopeConnections.put(conn.getDisplayName(), topologynode);
+                        }
+                    }
+                };
+
+        conn1.setOutputMarkupId(true);
+        add(conn1);
+            // -----------------------------------------
+
+        // -----------------------------------------
+        // Add Connector Intances (second level)
+        // -----------------------------------------
+        final ListView<ConnInstanceTO> conn2
+                = new ListView<ConnInstanceTO>("conn2", connModel.getObject().getRight()) {
+
+                    private static final long serialVersionUID = 6978621871488360381L;
+
+                    private final int size = connModel.getObject().getRight().size() + 1;
+
+                    @Override
+                    protected void populateItem(final ListItem<ConnInstanceTO> item) {
+                        final ConnInstanceTO conn = item.getModelObject();
+
+                        final TopologyNode parent = servers.get(conn.getLocation());
+
+                        int kx = size >= 6 ? 800 : (130 * size);
+
+                        int x = (int) Math.round((parent == null ? origX : parent.getX())
+                                + kx * Math.cos(Math.PI + Math.PI * (item.getIndex() + 1) / size));
+                        int y = (int) Math.round((parent == null ? origY : parent.getY())
+                                + 100 * Math.sin(Math.PI + Math.PI * (item.getIndex() + 1) / size));
+
+                        final TopologyNode topologynode = new TopologyNode(
+                                Long.valueOf(conn.getKey()), conn.getDisplayName(), TopologyNode.Kind.CONNECTOR);
+                        topologynode.setConnectinDisplayName(conn.getBundleName());
+                        topologynode.setX(x);
+                        topologynode.setY(y);
+
+                        connectors.put(topologynode.getDisplayName(), topologynode);
+
+                        item.add(topologyNodePanel("conn", topologynode, parent, true));
+
+                        if (conn.getLocation().startsWith(CONNECTOR_SERVER_LOCATION_PREFIX)) {
+                            final Map<String, TopologyNode> remoteConnections;
+
+                            if (connections.containsKey(conn.getLocation())) {
+                                remoteConnections = connections.get(conn.getLocation());
+                            } else {
+                                remoteConnections = new HashMap<>();
+                                connections.put(conn.getLocation(), remoteConnections);
+                            }
+                            remoteConnections.put(conn.getDisplayName(), topologynode);
+                        } else {
+                            syncopeConnections.put(conn.getDisplayName(), topologynode);
+                        }
+                    }
+                };
+
+        conn2.setOutputMarkupId(true);
+        add(conn2);
+            // -----------------------------------------
+
+        // -----------------------------------------
+        // Add Resources
+        // -----------------------------------------
+        final List<String> connToBeProcessed = new ArrayList<>();
+        for (ResourceTO resourceTO : resModel.getObject()) {
+            final TopologyNode topologynode = new TopologyNode(
+                    resourceTO.getKey(), resourceTO.getKey(), TopologyNode.Kind.RESOURCE);
+            topologynode.setX(origX);
+            topologynode.setY(origY);
+
+            final Map<String, TopologyNode> remoteConnections;
+
+            if (connections.containsKey(resourceTO.getConnectorDisplayName())) {
+                remoteConnections = connections.get(resourceTO.getConnectorDisplayName());
+            } else {
+                remoteConnections = new HashMap<>();
+                connections.put(resourceTO.getConnectorDisplayName(), remoteConnections);
+            }
+
+            remoteConnections.put(topologynode.getDisplayName(), topologynode);
+
+            if (!connToBeProcessed.contains(resourceTO.getConnectorDisplayName())) {
+                connToBeProcessed.add(resourceTO.getConnectorDisplayName());
+            }
+        }
+
+        final ListView<String> resources = new ListView<String>("resources", connToBeProcessed) {
+
+            private static final long serialVersionUID = 697862187148836038L;
+
+            @Override
+            protected void populateItem(final ListItem<String> item) {
+                final String connectorDisplayName = item.getModelObject();
+
+                final ListView<TopologyNode> innerListView = new ListView<TopologyNode>("resources",
+                        new ArrayList<>(connections.get(connectorDisplayName).values())) {
+
+                            private static final long serialVersionUID = 1L;
+
+                            private final int size = getModelObject().size() + 1;
+
+                            @Override
+                            protected void populateItem(final ListItem<TopologyNode> item) {
+                                final TopologyNode topologynode = item.getModelObject();
+                                final TopologyNode parent = connectors.get(connectorDisplayName);
+
+                                final double k;
+
+                                if (parent == null || parent.getY() < syncopeTopologyNode.getY()) {
+                                    k = Math.PI;
+                                } else {
+                                    k = 0.0;
+                                }
+
+                                int kx = size >= 16 ? 800 : (48 * size);
+                                int ky = size < 4 ? 100 : size < 6 ? 350 : 750;
+
+                                int x = (int) Math.round((parent == null ? origX : parent.getX())
+                                        + kx * Math.cos(k + Math.PI * (item.getIndex() + 1) / size));
+                                int y = (int) Math.round((parent == null ? origY : parent.getY())
+                                        + ky * Math.sin(k + Math.PI * (item.getIndex() + 1) / size));
+
+                                topologynode.setX(x);
+                                topologynode.setY(y);
+
+                                final Panel panel = new TopologyNodePanel(
+                                        "res", topologynode, getPageReference(), resourceRestClient);
+                                panel.setMarkupId(topologynode.getDisplayName());
+                                panel.setOutputMarkupId(true);
+                                item.add(topologyNodePanel("res", topologynode, parent, true));
+                            }
+                        };
+
+                innerListView.setOutputMarkupId(true);
+                item.add(innerListView);
+            }
+        };
+
+        resources.setOutputMarkupId(true);
+        add(resources);
+            // -----------------------------------------
+
+        // -----------------------------------------
+        // Create connections
+        // -----------------------------------------
+        jsPlace.add(new Behavior() {
+
+            private static final long serialVersionUID = 2661717818979056044L;
+
+            @Override
+            public void renderHead(final Component component, final IHeaderResponse response) {
+                final StringBuilder jsPlumbConf = new StringBuilder();
+                jsPlumbConf.append(String.format(Locale.US, "activate(%.2f);", 0.68f));
+
+                for (String str : createConnections(connections)) {
+                    jsPlumbConf.append(str);
+                }
+
+                response.render(OnDomReadyHeaderItem.forScript(jsPlumbConf.toString()));
+            }
+        });
+
+        jsPlace.setOutputMarkupId(true);
+        add(jsPlace);
+        // -----------------------------------------
+    }
+
+    @Override
+    public String getAjaxIndicatorMarkupId() {
+        return StringUtils.EMPTY;
+    }
+
+    private List<String> createConnections(final Map<String, Map<String, TopologyNode>> targets) {
+        List<String> list = new ArrayList<>();
+
+        for (Map.Entry<String, Map<String, TopologyNode>> source : targets.entrySet()) {
+            for (Map.Entry<String, TopologyNode> target : source.getValue().entrySet()) {
+                list.add(String.format("jsPlumb.connect({source:'%s',target:'%s'},def);",
+                        source.getKey(),
+                        target.getKey()));
+            }
+        }
+        return list;
+    }
+
+    private Panel topologyNodePanel(
+            final String id, final TopologyNode node, final TopologyNode parent, final boolean active) {
+        final Panel panel = new TopologyNodePanel(id, node, getPageReference(), resourceRestClient);
+        panel.setMarkupId(node.getDisplayName());
+        panel.setOutputMarkupId(true);
+
+        panel.add(new Behavior() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public void renderHead(final Component component, final IHeaderResponse response) {
+                response.render(OnDomReadyHeaderItem.forScript(String.format("setPosition('%s', %d, %d)",
+                        node.getDisplayName(), node.getX(), node.getY())));
+            }
+        });
+
+        final WebMarkupContainer timer = new WebMarkupContainer("timer");
+        timer.setOutputMarkupId(true);
+        panel.add(timer);
+
+        if (active) {
+            timer.add(new AbstractAjaxTimerBehavior(Duration.seconds(2)) {
+
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                protected void onTimer(final AjaxRequestTarget target) {
+                    final List<TopologyReloadBehavior> behaviors = panel.getBehaviors(TopologyReloadBehavior.class);
+                    for (TopologyReloadBehavior behavior : behaviors) {
+                        panel.remove(behavior);
+                    }
+
+                    TopologyNode.Status status;
+
+                    final FutureTask<TopologyNode.Status> future = new FutureTask<>(
+                            new Callable<TopologyNode.Status>() {
+
+                                @Override
+                                public TopologyNode.Status call() throws Exception {
+                                    switch (node.getKind()) {
+                                        case CONNECTOR:
+                                            final ConnInstanceTO connector = connectorRestClient.
+                                            read(Long.class.cast(node.getKey()));
+                                            return connectorRestClient.check(connector) ? REACHABLE : UNREACHABLE;
+                                        case RESOURCE:
+                                            final ResourceTO resource = resourceRestClient.
+                                            read(String.class.cast(node.getKey()));
+                                            return connectorRestClient.check(resource) ? REACHABLE : UNREACHABLE;
+                                        default:
+                                            return UNKNOWN;
+                                    }
+                                }
+                            });
+
+                    future.run();
+
+                    try {
+                        status = future.get(10, TimeUnit.SECONDS);
+                    } catch (TimeoutException te) {
+                        LOG.warn("Check connection timed out");
+                        status = UNKNOWN;
+                    } catch (InterruptedException | ExecutionException ie) {
+                        // ignore
+                        LOG.warn("Check connection failed", ie);
+                        status = FAILURE;
+                    }
+
+                    timer.add(new TopologyReloadBehavior(parent.getDisplayName(), node.getDisplayName(), status));
+
+                    if (getUpdateInterval().seconds() < 60.0) {
+                        setUpdateInterval(Duration.seconds(60));
+                    }
+
+                    target.add(timer);
+                }
+            });
+        }
+
+        return panel;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNode.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNode.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNode.java
new file mode 100644
index 0000000..f7c8aaa
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNode.java
@@ -0,0 +1,123 @@
+/*
+ * 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.topology;
+
+import java.io.Serializable;
+
+public class TopologyNode implements Serializable {
+
+    public enum Kind {
+
+        RESOURCE,
+        CONNECTOR,
+        CONNECTOR_SERVER,
+        SYNCOPE
+
+    }
+
+    public enum Status {
+
+        UNKNOWN,
+        REACHABLE,
+        UNREACHABLE,
+        FAILURE
+
+    }
+
+    private static final long serialVersionUID = -1506421230369224142L;
+
+    private final Serializable key;
+
+    private final String displayName;
+
+    private String connectionDisplayName;
+
+    private Kind kind;
+
+    private String host;
+
+    private int port;
+
+    private int x;
+
+    private int y;
+
+    public TopologyNode(final Serializable key, final String displayName, final Kind kind) {
+        this.key = key;
+        this.displayName = displayName;
+        this.kind = kind;
+    }
+
+    public Serializable getKey() {
+        return key;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public String getConnectionDisplayName() {
+        return connectionDisplayName;
+    }
+
+    public void setConnectinDisplayName(final String connectinDisplayName) {
+        this.connectionDisplayName = connectinDisplayName;
+    }
+
+    public Kind getKind() {
+        return kind;
+    }
+
+    public void setKind(final Kind kind) {
+        this.kind = kind;
+    }
+
+    public int getX() {
+        return x;
+    }
+
+    public void setX(final int x) {
+        this.x = x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    public void setY(final int y) {
+        this.y = y;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(final String host) {
+        this.host = host;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(final int port) {
+        this.port = port;
+    }
+
+}


[19/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
new file mode 100644
index 0000000..0af8a0b
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.PreferenceManager;
+import org.apache.syncope.client.console.commons.AttributableDataProvider;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.AbstractBasePage;
+import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.event.IEventSource;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractSearchResultPanel extends Panel implements IEventSource {
+
+    private static final long serialVersionUID = -9170191461250434024L;
+
+    /**
+     * Logger.
+     */
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractSearchResultPanel.class);
+
+    /**
+     * Edit modal window height.
+     */
+    private static final int EDIT_MODAL_WIN_HEIGHT = 550;
+
+    /**
+     * Edit modal window width.
+     */
+    private static final int EDIT_MODAL_WIN_WIDTH = 800;
+
+    /**
+     * Schemas to be shown modal window height.
+     */
+    private static final int DISPLAYATTRS_MODAL_WIN_HEIGHT = 550;
+
+    /**
+     * Schemas to be shown modal window width.
+     */
+    private static final int DISPLAYATTRS_MODAL_WIN_WIDTH = 550;
+
+    /**
+     * Schemas to be shown modal window height.
+     */
+    private static final int STATUS_MODAL_WIN_HEIGHT = 500;
+
+    /**
+     * Schemas to be shown modal window width.
+     */
+    private static final int STATUS_MODAL_WIN_WIDTH = 700;
+
+    /**
+     * Application preferences.
+     */
+    @SpringBean
+    protected PreferenceManager prefMan;
+
+    protected final AbstractSubjectRestClient restClient;
+
+    /**
+     * Number of rows per page.
+     */
+    private final int rows;
+
+    /**
+     * Container used to refresh table.
+     */
+    protected final WebMarkupContainer container;
+
+    /**
+     * Feedback panel specified by the caller.
+     */
+    protected final NotificationPanel feedbackPanel;
+
+    /**
+     * Specify if results are about a filtered search or not. Using this attribute it is possible to use this panel to
+     * show results about user list and user search.
+     */
+    private final boolean filtered;
+
+    /**
+     * Filter used in case of filtered search.
+     */
+    private String fiql;
+
+    /**
+     * Result table.
+     */
+    private AjaxDataTablePanel<AbstractAttributableTO, String> resultTable;
+
+    /**
+     * Data provider used to search for users.
+     */
+    private AttributableDataProvider dataProvider;
+
+    /**
+     * Modal window to be used for user profile editing. Global visibility is required ...
+     */
+    protected final ModalWindow editmodal = new ModalWindow("editModal");
+
+    /**
+     * Modal window to be used for attributes choosing to display in tables.
+     */
+    protected final ModalWindow displaymodal = new ModalWindow("displayModal");
+
+    /**
+     * Modal window to be used for user status management.
+     */
+    protected final ModalWindow statusmodal = new ModalWindow("statusModal");
+
+    /**
+     * Owner page.
+     */
+    protected final AbstractBasePage page;
+
+    protected <T extends AbstractAttributableTO> AbstractSearchResultPanel(final String id, final boolean filtered,
+            final String fiql, final PageReference pageRef, final AbstractSubjectRestClient restClient) {
+
+        super(id);
+
+        setOutputMarkupId(true);
+
+        this.page = (AbstractBasePage) pageRef.getPage();
+
+        this.filtered = filtered;
+        this.fiql = fiql;
+        this.feedbackPanel = page.getFeedbackPanel();
+
+        this.restClient = restClient;
+
+        editmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        editmodal.setInitialHeight(EDIT_MODAL_WIN_HEIGHT);
+        editmodal.setInitialWidth(EDIT_MODAL_WIN_WIDTH);
+        editmodal.setCookieName("edit-modal");
+        add(editmodal);
+
+        displaymodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        displaymodal.setInitialHeight(DISPLAYATTRS_MODAL_WIN_HEIGHT);
+        displaymodal.setInitialWidth(DISPLAYATTRS_MODAL_WIN_WIDTH);
+        displaymodal.setCookieName("display-modal");
+        add(displaymodal);
+
+        statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
+        statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
+        statusmodal.setCookieName("status-modal");
+        add(statusmodal);
+
+        // Container for user search result
+        container = new WebMarkupContainer("container");
+        container.setOutputMarkupId(true);
+        add(container);
+
+        rows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_USERS_PAGINATOR_ROWS);
+    }
+
+    protected void initResultTable() {
+        // ---------------------------
+        // Result table initialization
+        // ---------------------------
+        updateResultTable(false);
+        // ---------------------------
+
+        // ---------------------------
+        // Rows-per-page selector
+        // ---------------------------
+        final Form<?> paginatorForm = new Form<>("paginator");
+        container.add(paginatorForm);
+
+        final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
+                "rowsChooser", new PropertyModel<Integer>(this, "rows"), prefMan.getPaginatorChoices());
+
+        rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                prefMan.set(getRequest(), getResponse(), Constants.PREF_USERS_PAGINATOR_ROWS, String.valueOf(rows));
+
+                final EventDataWrapper data = new EventDataWrapper();
+                data.setTarget(target);
+                data.setRows(rows);
+
+                send(getParent(), Broadcast.BREADTH, data);
+            }
+        });
+        paginatorForm.add(rowsChooser);
+        // ---------------------------
+
+        setWindowClosedReloadCallback(statusmodal);
+        setWindowClosedReloadCallback(editmodal);
+        setWindowClosedReloadCallback(displaymodal);
+    }
+
+    public void search(final String fiql, final AjaxRequestTarget target) {
+        this.fiql = fiql;
+        dataProvider.setFIQL(fiql);
+        target.add(container);
+    }
+
+    private void updateResultTable(final boolean create) {
+        updateResultTable(create, rows);
+    }
+
+    private void updateResultTable(final boolean create, final int rows) {
+        dataProvider = new AttributableDataProvider(restClient, rows, filtered);
+        dataProvider.setFIQL(fiql);
+
+        final int currentPage = resultTable != null
+                ? (create
+                        ? (int) resultTable.getPageCount() - 1
+                        : (int) resultTable.getCurrentPage())
+                : 0;
+
+        resultTable = new AjaxDataTablePanel<>(
+                "resultTable",
+                getColumns(),
+                dataProvider,
+                rows,
+                getBulkActions(),
+                restClient,
+                "key",
+                getPageId(),
+                page.getPageReference());
+
+        resultTable.setCurrentPage(currentPage);
+
+        resultTable.setOutputMarkupId(true);
+
+        container.addOrReplace(resultTable);
+    }
+
+    protected abstract List<IColumn<AbstractAttributableTO, String>> getColumns();
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if (event.getPayload() instanceof EventDataWrapper) {
+            final EventDataWrapper data = (EventDataWrapper) event.getPayload();
+
+            if (data.getRows() < 1) {
+                updateResultTable(data.isCreate());
+            } else {
+                updateResultTable(data.isCreate(), data.getRows());
+            }
+
+            data.getTarget().add(container);
+        }
+    }
+
+    private void setWindowClosedReloadCallback(final ModalWindow window) {
+        window.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                final EventDataWrapper data = new EventDataWrapper();
+                data.setTarget(target);
+                data.setRows(rows);
+
+                send(getParent(), Broadcast.BREADTH, data);
+
+                if (page.isModalResult()) {
+                    // reset modal result
+                    page.setModalResult(false);
+                    // set operation succeeded
+                    getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+                    // refresh feedback panel
+                    feedbackPanel.refresh(target);
+                }
+            }
+        });
+    }
+
+    public static class EventDataWrapper {
+
+        private AjaxRequestTarget target;
+
+        private boolean create;
+
+        private int rows;
+
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+
+        public void setTarget(final AjaxRequestTarget target) {
+            this.target = target;
+        }
+
+        public boolean isCreate() {
+            return create;
+        }
+
+        public void setCreate(final boolean create) {
+            this.create = create;
+        }
+
+        public int getRows() {
+            return rows;
+        }
+
+        public void setRows(final int rows) {
+            this.rows = rows;
+        }
+    }
+
+    protected abstract <T extends AbstractAttributableTO> Collection<ActionLink.ActionType> getBulkActions();
+
+    protected abstract String getPageId();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java
new file mode 100644
index 0000000..60aae41
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.wicket.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AccountPolicy extends Panel {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AccountPolicy.class);
+
+    public AccountPolicy(final String id) {
+        super(id);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..80d05a1
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.commons.ActionTableCheckGroup;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
+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.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class ActionDataTablePanel<T, S> extends DataTablePanel<T, S> {
+
+    private static final long serialVersionUID = -8826989026203543957L;
+
+    private static final String CANCEL = "cancel";
+
+    private final Form<T> bulkActionForm;
+
+    private final ActionLinksPanel 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) {
+
+        super(id);
+
+        this.pageRef = pageRef;
+
+        bulkActionForm = new Form<>("groupForm");
+        add(bulkActionForm);
+
+        group = new ActionTableCheckGroup<T>("checkgroup", model) {
+
+            private static final long serialVersionUID = -8667764190925075389L;
+
+            @Override
+            public boolean isCheckable(final T element) {
+                return isElementEnabled(element);
+            }
+        };
+        group.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -151291731388673682L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                // triggers AJAX form submit
+            }
+        });
+        bulkActionForm.add(group);
+
+        columns.add(0, new CheckGroupColumn<T, S>(group));
+        dataTable = new AjaxFallbackDefaultDataTable<>("dataTable", columns, dataProvider, rowsPerPage);
+        group.add(dataTable);
+
+        final WebMarkupContainer actionPanelContainer = new WebMarkupContainer("actionPanelContainer");
+        bulkActionForm.add(actionPanelContainer);
+
+        actionPanel = new ActionLinksPanel("actions", new Model(), pageRef);
+        actionPanelContainer.add(actionPanel);
+
+        if (dataTable.getRowCount() == 0) {
+            actionPanelContainer.add(new AttributeModifier("style", "display: none"));
+        }
+
+        bulkActionForm.add(new ClearIndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL), pageRef) {
+
+            private static final long serialVersionUID = -2341391430136818025L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                // ignore
+            }
+        }.setVisible(false).setEnabled(false));
+    }
+
+    public void addAction(final ActionLink action, final ActionType type, final String entitlements) {
+        actionPanel.add(action, type, entitlements);
+    }
+
+    public void addAction(final ActionLink action, final ActionType type, final String pageId, final boolean enabled) {
+        actionPanel.add(action, type, pageId, enabled);
+    }
+
+    public void addCancelButton(final ModalWindow window) {
+
+        final AjaxButton cancel = new ClearIndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL), pageRef) {
+
+            private static final long serialVersionUID = -2341391430136818025L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                window.close(target);
+            }
+        }.feedbackPanelAutomaticReload(false);
+
+        cancel.setDefaultFormProcessing(false);
+        bulkActionForm.addOrReplace(cancel);
+    }
+
+    public Collection<T> getModelObject() {
+        return group.getModelObject();
+    }
+
+    public boolean isElementEnabled(final T element) {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..563bd17
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel.EventDataWrapper;
+import org.apache.syncope.client.console.pages.AbstractBasePage;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.pages.BulkActionModalPage;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Fragment;
+
+public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
+
+    private static final long serialVersionUID = -7264400471578272966L;
+
+    public AjaxDataTablePanel(
+            final String id,
+            final List<IColumn<T, S>> columns,
+            final ISortableDataProvider<T, S> dataProvider,
+            final int rowsPerPage,
+            final Collection<ActionLink.ActionType> actions,
+            final BaseRestClient bulkActionExecutor,
+            final String itemIdField,
+            final String pageId,
+            final PageReference pageRef) {
+
+        super(id);
+
+        final ModalWindow bulkModalWin = new ModalWindow("bulkModal");
+        bulkModalWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        bulkModalWin.setInitialHeight(600);
+        bulkModalWin.setInitialWidth(900);
+        bulkModalWin.setCookieName("bulk-modal");
+        add(bulkModalWin);
+
+        bulkModalWin.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487149L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                final EventDataWrapper data = new EventDataWrapper();
+                data.setTarget(target);
+                data.setRows(rowsPerPage);
+
+                send(pageRef.getPage(), Broadcast.BREADTH, data);
+
+                final AbstractBasePage page = (AbstractBasePage) pageRef.getPage();
+
+                if (page.isModalResult()) {
+                    // reset modal result
+                    page.setModalResult(false);
+                    // set operation succeeded
+                    getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+                    // refresh feedback panel
+                    target.add(page.getFeedbackPanel());
+                }
+            }
+        });
+
+        Fragment fragment = new Fragment("tablePanel", "bulkAvailable", this);
+        add(fragment);
+
+        Form<T> bulkActionForm = new Form<>("groupForm");
+        fragment.add(bulkActionForm);
+
+        group = new CheckGroup<>("checkgroup", model);
+        group.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -151291731388673682L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                // triggers AJAX form submit
+            }
+        });
+        bulkActionForm.add(group);
+
+        columns.add(0, new CheckGroupColumn<T, S>(group));
+        dataTable = new AjaxFallbackDefaultDataTable<>("dataTable", columns, dataProvider, rowsPerPage);
+        group.add(dataTable);
+
+        fragment.add(new ClearIndicatingAjaxButton("bulkActionLink", bulkActionForm, pageRef) {
+
+            private static final long serialVersionUID = 382302811235019988L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                bulkModalWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690941L;
+
+                    @Override
+                    public Page createPage() {
+                        return new BulkActionModalPage<>(
+                                bulkModalWin,
+                                group.getModelObject(),
+                                columns,
+                                actions,
+                                bulkActionExecutor,
+                                itemIdField,
+                                pageId);
+                    }
+                });
+
+                bulkModalWin.show(target);
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
new file mode 100644
index 0000000..e809263
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.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.panels;
+
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+
+public class AnnotatedBeanPanel extends Panel {
+
+    private static final long serialVersionUID = 4228064224811390809L;
+
+    public <T extends AbstractAttributableTO> AnnotatedBeanPanel(
+            final String id, final AbstractAnnotatedBean sysInfoTO) {
+
+        super(id);
+
+        // ------------------------
+        // Creation date
+        // ------------------------
+        add(new Label("creationDate", new Model<>(sysInfoTO.getCreationDate() != null
+                ? SyncopeConsoleSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+        // ------------------------
+
+        // ------------------------
+        // Last change date
+        // ------------------------
+        add(new Label("lastChangeDate", new Model<>(sysInfoTO.getLastChangeDate() != null
+                ? SyncopeConsoleSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+        // ------------------------
+
+        // ------------------------
+        // Creator
+        // ------------------------
+        add(new Label("creator", new Model<>(sysInfoTO.getCreator() != null
+                ? sysInfoTO.getCreator() : "")));
+        // ------------------------
+
+        // ------------------------
+        // Last modifier
+        // ------------------------
+        add(new Label("lastModifier", new Model<>(sysInfoTO.getLastModifier() != null
+                ? sysInfoTO.getLastModifier() : "")));
+        // ------------------------
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java
new file mode 100644
index 0000000..8d99606
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.wicket.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Any extends Panel {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(Any.class);
+
+    public Any(final String id) {
+        super(id);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
new file mode 100644
index 0000000..18f28d7
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import static org.apache.wicket.Component.ENABLE;
+import static org.apache.wicket.Component.RENDER;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.PreferenceManager;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.pages.ConnectorModalPage;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+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.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.wicket.Component;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+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.ISortableDataProvider;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.StringResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resources WebPage.
+ */
+public class Connectors extends Panel {
+
+    private static final long serialVersionUID = -3789252860990261728L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(Connectors.class);
+
+    private static final int WIN_HEIGHT = 600;
+
+    private static final int WIN_WIDTH = 1100;
+
+    @SpringBean
+    private ConnectorRestClient connectorRestClient;
+
+    @SpringBean
+    private PreferenceManager prefMan;
+
+    private final ModalWindow createConnectorWin;
+
+    private final ModalWindow editConnectorWin;
+
+    private final int connectorPaginatorRows;
+
+    private WebMarkupContainer connectorContainer;
+
+    /**
+     * Modal window to be used for user status management.
+     */
+    protected final ModalWindow statusmodal = new ModalWindow("statusModal");
+
+    /**
+     * Schemas to be shown modal window height.
+     */
+    private static final int STATUS_MODAL_WIN_HEIGHT = 500;
+
+    /**
+     * Schemas to be shown modal window width.
+     */
+    private static final int STATUS_MODAL_WIN_WIDTH = 700;
+
+    private final PageReference pageRef;
+
+    public Connectors(final String id, final PageReference pageRef) {
+        super(id);
+        this.pageRef = pageRef;
+
+        createConnectorWin = new ModalWindow("createConnectorWin");
+        add(createConnectorWin);
+
+        editConnectorWin = new ModalWindow("editConnectorWin");
+        add(editConnectorWin);
+
+        statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
+        statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
+        statusmodal.setCookieName("status-modal");
+        add(statusmodal);
+
+        AjaxLink<Void> reloadLink = new ClearIndicatingAjaxLink<Void>("reloadLink", pageRef) {
+
+            private static final long serialVersionUID = 3109256773218160485L;
+
+            @Override
+            protected void onClickInternal(final AjaxRequestTarget target) {
+                try {
+                    connectorRestClient.reload();
+                    info(getString(Constants.OPERATION_SUCCEEDED));
+                } catch (Exception e) {
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                }
+                ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
+                target.add(connectorContainer);
+            }
+
+            @Override
+            protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+                super.updateAjaxAttributes(attributes);
+
+                final AjaxCallListener ajaxCallListener = new AjaxCallListener() {
+
+                    private static final long serialVersionUID = 7160235486520935153L;
+
+                    @Override
+                    public CharSequence getPrecondition(final Component component) {
+                        return "if (!confirm('" + getString("confirmReloadConnectors") + "')) "
+                                + "{return false;} else {return true;}";
+                    }
+                };
+                attributes.getAjaxCallListeners().add(ajaxCallListener);
+            }
+        };
+        MetaDataRoleAuthorizationStrategy.authorize(reloadLink, ENABLE, Entitlement.CONNECTOR_RELOAD);
+        add(reloadLink);
+
+        connectorPaginatorRows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_CONNECTORS_PAGINATOR_ROWS);
+
+        setupConnectors();
+    }
+
+    private void setupConnectors() {
+        List<IColumn<ConnInstanceTO, String>> columns = new ArrayList<>();
+
+        columns.add(new PropertyColumn<ConnInstanceTO, String>(
+                new StringResourceModel("key", this, null), "key", "key"));
+        columns.add(new PropertyColumn<ConnInstanceTO, String>(
+                new StringResourceModel("name", this, null), "connectorName", "connectorName"));
+        columns.add(new PropertyColumn<ConnInstanceTO, String>(
+                new StringResourceModel("displayName", this, null), "displayName", "displayName"));
+        columns.add(new PropertyColumn<ConnInstanceTO, String>(
+                new StringResourceModel("bundleName", this, null), "bundleName", "bundleName"));
+        columns.add(new PropertyColumn<ConnInstanceTO, String>(
+                new StringResourceModel("version", this, null), "version", "version"));
+        columns.add(new AbstractColumn<ConnInstanceTO, String>(new StringResourceModel("actions", this, null, "")) {
+
+            private static final long serialVersionUID = 2054811145491901166L;
+
+            @Override
+            public String getCssClass() {
+                return "action";
+            }
+
+            @Override
+            public void populateItem(final Item<ICellPopulator<ConnInstanceTO>> cellItem, final String componentId,
+                    final IModel<ConnInstanceTO> model) {
+
+                final ConnInstanceTO connectorTO = model.getObject();
+
+                final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, pageRef);
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        editConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new ConnectorModalPage(Connectors.this.pageRef,
+                                        editConnectorWin,
+                                        connectorTO);
+                            }
+                        });
+
+                        editConnectorWin.show(target);
+                    }
+                }, ActionLink.ActionType.EDIT, "Connectors");
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        try {
+                            connectorRestClient.delete(connectorTO.getKey());
+                            info(getString(Constants.OPERATION_SUCCEEDED));
+                        } catch (SyncopeClientException e) {
+                            error(getString(Constants.ERROR) + ": " + e.getMessage());
+
+                            LOG.error("While deleting connector " + connectorTO.getKey(), e);
+                        }
+
+                        target.add(connectorContainer);
+                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
+                    }
+                }, ActionLink.ActionType.DELETE, "Connectors");
+
+                cellItem.add(panel);
+            }
+        });
+
+        final AjaxDataTablePanel<ConnInstanceTO, String> table = new AjaxDataTablePanel<>(
+                "connectorDatatable",
+                columns,
+                (ISortableDataProvider<ConnInstanceTO, String>) new ConnectorsProvider(),
+                connectorPaginatorRows,
+                Arrays.asList(new ActionLink.ActionType[] { ActionLink.ActionType.DELETE }),
+                connectorRestClient,
+                "key",
+                "Connectors",
+                pageRef);
+
+        connectorContainer = new WebMarkupContainer("connectorContainer");
+        connectorContainer.add(table);
+        connectorContainer.setOutputMarkupId(true);
+
+        MetaDataRoleAuthorizationStrategy.authorize(connectorContainer, RENDER, Entitlement.CONNECTOR_LIST);
+
+        add(connectorContainer);
+
+        ((BasePage) pageRef.getPage()).setWindowClosedCallback(createConnectorWin, connectorContainer);
+        ((BasePage) pageRef.getPage()).setWindowClosedCallback(editConnectorWin, connectorContainer);
+
+        createConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        createConnectorWin.setInitialHeight(WIN_HEIGHT);
+        createConnectorWin.setInitialWidth(WIN_WIDTH);
+        createConnectorWin.setCookieName("create-conn-modal");
+
+        editConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        editConnectorWin.setInitialHeight(WIN_HEIGHT);
+        editConnectorWin.setInitialWidth(WIN_WIDTH);
+        editConnectorWin.setCookieName("edit-conn-modal");
+
+        AjaxLink<Void> createConnectorLink
+                = new ClearIndicatingAjaxLink<Void>("createConnectorLink", pageRef) {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    protected void onClickInternal(final AjaxRequestTarget target) {
+                        createConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                ConnectorModalPage form = new ConnectorModalPage(
+                                        pageRef, editConnectorWin, new ConnInstanceTO());
+                                return form;
+                            }
+                        });
+
+                        createConnectorWin.show(target);
+                    }
+                };
+
+        MetaDataRoleAuthorizationStrategy.authorize(createConnectorLink, ENABLE, Entitlement.CONNECTOR_CREATE);
+
+        add(createConnectorLink);
+
+        @SuppressWarnings("rawtypes")
+        Form paginatorForm = new Form("connectorPaginatorForm");
+
+        MetaDataRoleAuthorizationStrategy.authorize(paginatorForm, RENDER, Entitlement.CONNECTOR_LIST);
+
+        final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
+                "rowsChooser",
+                new PropertyModel<Integer>(this,
+                        "connectorPaginatorRows"),
+                prefMan.getPaginatorChoices());
+
+        rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                prefMan.set(getRequest(), getResponse(), Constants.PREF_CONNECTORS_PAGINATOR_ROWS,
+                        String.valueOf(connectorPaginatorRows));
+                table.setItemsPerPage(connectorPaginatorRows);
+
+                target.add(connectorContainer);
+            }
+        });
+
+        paginatorForm.add(rowsChooser);
+        add(paginatorForm);
+    }
+
+    private class ConnectorsProvider extends SortableDataProvider<ConnInstanceTO, String> {
+
+        private static final long serialVersionUID = 4445909568349448518L;
+
+        private final SortableDataProviderComparator<ConnInstanceTO> comparator;
+
+        public ConnectorsProvider() {
+            super();
+            //Default sorting
+            setSort("key", SortOrder.ASCENDING);
+            comparator = new SortableDataProviderComparator<>(this);
+        }
+
+        @Override
+        public Iterator<ConnInstanceTO> iterator(final long first, final long count) {
+            List<ConnInstanceTO> list = connectorRestClient.getAllConnectors();
+
+            Collections.sort(list, comparator);
+
+            return list.subList((int) first, (int) first + (int) count).iterator();
+        }
+
+        @Override
+        public long size() {
+            return connectorRestClient.getAllConnectors().size();
+        }
+
+        @Override
+        public IModel<ConnInstanceTO> model(final ConnInstanceTO connector) {
+
+            return new AbstractReadOnlyModel<ConnInstanceTO>() {
+
+                private static final long serialVersionUID = -6033068018293569398L;
+
+                @Override
+                public ConnInstanceTO getObject() {
+                    return connector;
+                }
+            };
+        }
+    }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if (event.getPayload() instanceof AbstractSearchResultPanel.EventDataWrapper) {
+            ((AbstractSearchResultPanel.EventDataWrapper) event.getPayload()).getTarget().add(connectorContainer);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
new file mode 100644
index 0000000..1800d54
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.DataGridView;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class DataTablePanel<T, S> extends Panel {
+
+    private static final long serialVersionUID = -7264400471578272966L;
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(DataTablePanel.class);
+
+    protected CheckGroup<T> group;
+
+    protected AjaxFallbackDefaultDataTable<T, S> dataTable;
+
+    protected IModel<Collection<T>> model;
+
+    public DataTablePanel(final String id) {
+        super(id);
+
+        model = new IModel<Collection<T>>() {
+
+            private static final long serialVersionUID = 4886729136344643465L;
+
+            private final Collection<T> values = new HashSet<>();
+
+            @Override
+            public Collection<T> getObject() {
+                // Someone or something call this method to change the model: this is not the right behavior.
+                // Return a copy of the model object in order to avoid SYNCOPE-465
+                return new HashSet<>(values);
+            }
+
+            @Override
+            public void setObject(final Collection<T> selected) {
+                final Collection<T> all = getGroupModelObjects();
+                values.removeAll(all);
+                values.addAll(selected);
+            }
+
+            @Override
+            public void detach() {
+            }
+        };
+    }
+
+    public final void setCurrentPage(final long page) {
+        dataTable.setCurrentPage(page);
+    }
+
+    public final long getRowCount() {
+        return dataTable.getRowCount();
+    }
+
+    public final long getCurrentPage() {
+        return dataTable.getCurrentPage();
+    }
+
+    public final long getPageCount() {
+        return dataTable.getPageCount();
+    }
+
+    public void setItemsPerPage(final int resourcePaginatorRows) {
+        dataTable.setItemsPerPage(resourcePaginatorRows);
+    }
+
+    protected Collection<T> getGroupModelObjects() {
+        final Set<T> res = new HashSet<>();
+
+        final Component rows = group.get("dataTable:body:rows");
+        if (rows instanceof DataGridView) {
+            @SuppressWarnings("unchecked")
+            final Iterator<Item<T>> iter = ((DataGridView<T>) rows).getItems();
+
+            while (iter.hasNext()) {
+                res.add(iter.next().getModelObject());
+            }
+        }
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java
new file mode 100644
index 0000000..8bad8ff
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.wicket.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PasswordPolicy extends Panel {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(PasswordPolicy.class);
+
+    public PasswordPolicy(final String id) {
+        super(id);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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
new file mode 100644
index 0000000..f31c87c
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Realm extends Panel {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(Realm.class);
+
+    private final RealmTO realmTO;
+
+    public Realm(final String id, final RealmTO realmTO) {
+        super(id);
+        this.realmTO = realmTO;
+
+        add(new RealmDetails("details", realmTO));
+        add(new Any("users"));
+        add(new Any("groups"));
+        add(new Any("services"));
+        add(new Any("serviceRoles"));
+        add(new Any("contexts"));
+        add(new Any("enactmentEngine"));
+        add(new AccountPolicy("accountPolicy"));
+        add(new PasswordPolicy("passwordPolicy"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
new file mode 100644
index 0000000..391dba2
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.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.panels;
+
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RealmDetails extends Panel {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(RealmDetails.class);
+
+    public RealmDetails(final String id, final RealmTO realmTO) {
+        super(id);
+        add(new TextField<>("id", new PropertyModel<>(realmTO, "key")).setEnabled(false));
+        add(new TextField<>("name", new PropertyModel<>(realmTO, "name")).setEnabled(false));
+        add(new TextField<>("path", new PropertyModel<>(realmTO, "fullPath")).setEnabled(false));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
new file mode 100644
index 0000000..c1d01e0
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.client.console.pages.BaseModalPage;
+import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent;
+import org.apache.syncope.client.console.panels.ResourceDetailsPanel.DetailsModEvent;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel.MultiValueSelectorEvent;
+import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class ResourceConnConfPanel extends Panel {
+
+    private static final long serialVersionUID = -7982691107029848579L;
+
+    @SpringBean
+    private ConnectorRestClient restClient;
+
+    private final ResourceTO resourceTO;
+
+    private final boolean createFlag;
+
+    private List<ConnConfProperty> connConfProperties;
+
+    private WebMarkupContainer connConfPropContainer;
+
+    private AjaxButton check;
+
+    public ResourceConnConfPanel(final String id, final ResourceTO resourceTO, final boolean createFlag) {
+        super(id);
+        setOutputMarkupId(true);
+
+        this.createFlag = createFlag;
+        this.resourceTO = resourceTO;
+
+        connConfProperties = getConnConfProperties();
+
+        connConfPropContainer = new WebMarkupContainer("connectorPropertiesContainer");
+        connConfPropContainer.setOutputMarkupId(true);
+        add(connConfPropContainer);
+
+        /*
+         * the list of overridable connector properties
+         */
+        final ListView<ConnConfProperty> connPropView = new ConnConfPropertyListView("connectorProperties",
+                new PropertyModel<List<ConnConfProperty>>(this, "connConfProperties"),
+                false, resourceTO.getConnConfProperties());
+        connPropView.setOutputMarkupId(true);
+        connConfPropContainer.add(connPropView);
+
+        check = new IndicatingAjaxButton("check", new ResourceModel("check")) {
+
+            private static final long serialVersionUID = -4199438518229098169L;
+
+            @Override
+            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                final ResourceTO to = (ResourceTO) form.getModelObject();
+
+                if (restClient.check(to)) {
+                    info(getString("success_connection"));
+                } else {
+                    error(getString("error_connection"));
+                }
+
+                ((BaseModalPage) getPage()).getFeedbackPanel().refresh(target);
+            }
+        };
+
+        check.setEnabled(!connConfProperties.isEmpty());
+        check.setVisible(!connConfProperties.isEmpty());
+        
+        connConfPropContainer.add(check);
+    }
+
+    /**
+     * Get overridable properties.
+     *
+     * @return overridable properties.
+     */
+    private List<ConnConfProperty> getConnConfProperties() {
+        final List<ConnConfProperty> props = new ArrayList<ConnConfProperty>();
+        final Long connectorId = resourceTO.getConnectorId();
+        if (connectorId != null && connectorId > 0) {
+            for (ConnConfProperty property : restClient.getConnectorProperties(connectorId)) {
+                if (property.isOverridable()) {
+                    props.add(property);
+                }
+            }
+        }
+        if (createFlag || resourceTO.getConnConfProperties().isEmpty()) {
+            resourceTO.getConnConfProperties().clear();
+        } else {
+            Map<String, ConnConfProperty> valuedProps = new HashMap<String, ConnConfProperty>();
+            for (ConnConfProperty prop : resourceTO.getConnConfProperties()) {
+                valuedProps.put(prop.getSchema().getName(), prop);
+            }
+
+            for (int i = 0; i < props.size(); i++) {
+                if (valuedProps.containsKey(props.get(i).getSchema().getName())) {
+                    props.set(i, valuedProps.get(props.get(i).getSchema().getName()));
+                }
+            }
+        }
+
+        // re-order properties
+        Collections.sort(props);
+
+        return props;
+    }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        AjaxRequestTarget target = null;
+        if (event.getPayload() instanceof DetailsModEvent) {
+            // connector change: update properties and forward event
+            target = ((ResourceEvent) event.getPayload()).getTarget();
+
+            connConfProperties = getConnConfProperties();
+            check.setEnabled(!connConfProperties.isEmpty());
+
+            target.add(connConfPropContainer);
+        } else if (event.getPayload() instanceof MultiValueSelectorEvent) {
+            // multi value connector property change: forward event
+            target = ((MultiValueSelectorEvent) event.getPayload()).getTarget();
+        }
+
+        if (target != null) {
+            send(getPage(), Broadcast.BREADTH, new ConnConfModEvent(target, connConfProperties));
+        }
+    }
+
+    /**
+     * Connector configuration properties modification event.
+     */
+    public static class ConnConfModEvent extends ResourceEvent {
+
+        private List<ConnConfProperty> configuration;
+
+        /**
+         * Constructor.
+         *
+         * @param target request target.
+         * @param configuration connector configuration properties.
+         */
+        public ConnConfModEvent(final AjaxRequestTarget target, final List<ConnConfProperty> configuration) {
+            super(target);
+            this.configuration = configuration;
+        }
+
+        public List<ConnConfProperty> getConfiguration() {
+            return configuration;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
new file mode 100644
index 0000000..3bff23f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResourceDetailsPanel extends Panel {
+
+    private static final long serialVersionUID = -7982691107029848579L;
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(ResourceDetailsPanel.class);
+
+    @SpringBean
+    private ConnectorRestClient connRestClient;
+
+    private ConnInstanceTO connInstanceTO;
+
+    public ResourceDetailsPanel(final String id, final ResourceTO resourceTO, final List<String> actionClassNames,
+            final boolean createFlag) {
+
+        super(id);
+        setOutputMarkupId(true);
+
+        final AjaxTextFieldPanel resourceName = new AjaxTextFieldPanel("name", new ResourceModel("name", "name").
+                getObject(), new PropertyModel<String>(resourceTO, "key"));
+
+        resourceName.setEnabled(createFlag);
+        resourceName.addRequiredLabel();
+        add(resourceName);
+
+        final AjaxCheckBoxPanel enforceMandatoryCondition = new AjaxCheckBoxPanel("enforceMandatoryCondition",
+                new ResourceModel("enforceMandatoryCondition", "enforceMandatoryCondition").getObject(),
+                new PropertyModel<Boolean>(resourceTO, "enforceMandatoryCondition"));
+        add(enforceMandatoryCondition);
+
+        final AjaxCheckBoxPanel propagationPrimary = new AjaxCheckBoxPanel("propagationPrimary", new ResourceModel(
+                "propagationPrimary", "propagationPrimary").getObject(), new PropertyModel<Boolean>(resourceTO,
+                        "propagationPrimary"));
+        add(propagationPrimary);
+
+        final SpinnerFieldPanel<Integer> propagationPriority =
+                new SpinnerFieldPanel<>("propagationPriority", "propagationPriority", Integer.class,
+                        new PropertyModel<Integer>(resourceTO, "propagationPriority"), null, null);
+        add(propagationPriority);
+
+        final AjaxDropDownChoicePanel<PropagationMode> propagationMode = new AjaxDropDownChoicePanel<>(
+                "propagationMode", new ResourceModel("propagationMode", "propagationMode").getObject(),
+                new PropertyModel<PropagationMode>(resourceTO, "propagationMode"));
+        propagationMode.setChoices(Arrays.asList(PropagationMode.values()));
+        add(propagationMode);
+
+        final AjaxCheckBoxPanel randomPwdIfNotProvided = new AjaxCheckBoxPanel("randomPwdIfNotProvided",
+                new ResourceModel("randomPwdIfNotProvided", "randomPwdIfNotProvided").getObject(),
+                new PropertyModel<Boolean>(resourceTO, "randomPwdIfNotProvided"));
+        add(randomPwdIfNotProvided);
+
+        final WebMarkupContainer propagationActionsClassNames = new WebMarkupContainer("propagationActionsClassNames");
+        propagationActionsClassNames.setOutputMarkupId(true);
+        add(propagationActionsClassNames);
+
+        final AjaxLink<Void> first = new IndicatingAjaxLink<Void>("first") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
+                setVisible(false);
+                target.add(propagationActionsClassNames);
+            }
+        };
+        first.setOutputMarkupPlaceholderTag(true);
+        first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
+        propagationActionsClassNames.add(first);
+
+        final ListView<String> actionsClasses = new ListView<String>("actionsClasses",
+                new PropertyModel<List<String>>(resourceTO, "propagationActionsClassNames")) {
+
+                    private static final long serialVersionUID = 9101744072914090143L;
+
+                    @Override
+                    protected void populateItem(final ListItem<String> item) {
+                        final String className = item.getModelObject();
+
+                        final DropDownChoice<String> actionsClass = new DropDownChoice<>(
+                                "actionsClass", new Model<>(className), actionClassNames);
+                        actionsClass.setNullValid(true);
+                        actionsClass.setRequired(true);
+                        actionsClass.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+
+                            private static final long serialVersionUID = -1107858522700306810L;
+
+                            @Override
+                            protected void onUpdate(final AjaxRequestTarget target) {
+                                resourceTO.getPropagationActionsClassNames().
+                                set(item.getIndex(), actionsClass.getModelObject());
+                            }
+                        });
+                        actionsClass.setRequired(true);
+                        actionsClass.setOutputMarkupId(true);
+                        actionsClass.setRequired(true);
+                        item.add(actionsClass);
+
+                        AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target) {
+                                resourceTO.getPropagationActionsClassNames().remove(className);
+                                first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
+                                target.add(propagationActionsClassNames);
+                            }
+                        };
+                        item.add(minus);
+
+                        final AjaxLink<Void> plus = new IndicatingAjaxLink<Void>("add") {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target) {
+                                resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
+                                target.add(propagationActionsClassNames);
+                            }
+                        };
+                        plus.setOutputMarkupPlaceholderTag(true);
+                        plus.setVisible(item.getIndex() == resourceTO.getPropagationActionsClassNames().size() - 1);
+                        item.add(plus);
+                    }
+                };
+        propagationActionsClassNames.add(actionsClasses);
+
+        final AjaxDropDownChoicePanel<TraceLevel> createTraceLevel = new AjaxDropDownChoicePanel<>(
+                "createTraceLevel", new ResourceModel("createTraceLevel", "createTraceLevel").getObject(),
+                new PropertyModel<TraceLevel>(resourceTO, "createTraceLevel"));
+        createTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+        add(createTraceLevel);
+
+        final AjaxDropDownChoicePanel<TraceLevel> updateTraceLevel = new AjaxDropDownChoicePanel<>(
+                "updateTraceLevel", new ResourceModel("updateTraceLevel", "updateTraceLevel").getObject(),
+                new PropertyModel<TraceLevel>(resourceTO, "updateTraceLevel"));
+        updateTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+        add(updateTraceLevel);
+
+        final AjaxDropDownChoicePanel<TraceLevel> deleteTraceLevel = new AjaxDropDownChoicePanel<>(
+                "deleteTraceLevel", new ResourceModel("deleteTraceLevel", "deleteTraceLevel").getObject(),
+                new PropertyModel<TraceLevel>(resourceTO, "deleteTraceLevel"));
+        deleteTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+        add(deleteTraceLevel);
+
+        final AjaxDropDownChoicePanel<TraceLevel> syncTraceLevel = new AjaxDropDownChoicePanel<>(
+                "syncTraceLevel", new ResourceModel("syncTraceLevel", "syncTraceLevel").getObject(),
+                new PropertyModel<TraceLevel>(resourceTO, "syncTraceLevel"));
+        syncTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+        add(syncTraceLevel);
+
+        final IModel<List<ConnInstanceTO>> connectors = new LoadableDetachableModel<List<ConnInstanceTO>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<ConnInstanceTO> load() {
+                return connRestClient.getAllConnectors();
+            }
+        };
+
+        connInstanceTO = getConectorInstanceTO(connectors.getObject(), resourceTO);
+
+        final AjaxDropDownChoicePanel<ConnInstanceTO> conn = new AjaxDropDownChoicePanel<>("connector",
+                new ResourceModel("connector", "connector").getObject(),
+                new PropertyModel<ConnInstanceTO>(this, "connInstanceTO"));
+        conn.setChoices(connectors.getObject());
+        conn.setChoiceRenderer(new ChoiceRenderer("displayName", "key"));
+
+        conn.getField().setModel(new IModel<ConnInstanceTO>() {
+
+            private static final long serialVersionUID = -4202872830392400310L;
+
+            @Override
+            public ConnInstanceTO getObject() {
+                return connInstanceTO;
+            }
+
+            @Override
+            public void setObject(final ConnInstanceTO connector) {
+                resourceTO.setConnectorId(connector.getKey());
+                connInstanceTO = connector;
+            }
+
+            @Override
+            public void detach() {
+            }
+        });
+
+        conn.addRequiredLabel();
+        conn.setEnabled(createFlag);
+
+        conn.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                send(getPage(), Broadcast.BREADTH, new DetailsModEvent(target));
+            }
+        });
+
+        add(conn);
+    }
+
+    /**
+     * Get the connetorTO linked to the resource.
+     *
+     * @param connectorTOs list of all connectors.
+     * @param resourceTO resource.
+     * @return selected connector instance: in case of no connectors available, null; in case of new resource
+     * specification, the first on connector available
+     */
+    private ConnInstanceTO getConectorInstanceTO(final List<ConnInstanceTO> connectorTOs, final ResourceTO resourceTO) {
+        if (connectorTOs.isEmpty()) {
+            resourceTO.setConnectorId(null);
+            return null;
+        } else {
+            // use the first element as default
+            ConnInstanceTO res = connectorTOs.get(0);
+
+            for (ConnInstanceTO to : connectorTOs) {
+                if (Long.valueOf(to.getKey()).equals(resourceTO.getConnectorId())) {
+                    res = to;
+                }
+            }
+
+            // in case of no match
+            resourceTO.setConnectorId(res.getKey());
+
+            return res;
+        }
+    }
+
+    /**
+     * Connector instance modification event.
+     */
+    public static class DetailsModEvent extends ResourceEvent {
+
+        /**
+         * Constructor.
+         *
+         * @param target request target.
+         */
+        public DetailsModEvent(final AjaxRequestTarget target) {
+            super(target);
+        }
+    }
+}


[15/27] syncope git commit: [SYNCOPE-156] working with resource and connector topology

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/META-INF/resources/css/fieldstyle.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/fieldstyle.css b/client/console/src/main/resources/META-INF/resources/css/fieldstyle.css
new file mode 100644
index 0000000..23ef109
--- /dev/null
+++ b/client/console/src/main/resources/META-INF/resources/css/fieldstyle.css
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+.drop_button{
+  vertical-align: middle;
+}
+
+.add_button{
+  vertical-align: middle;
+  margin-left: 6px;
+}
+
+.date_size{
+  width: 90px;
+}
+
+.long_dynamicsize{
+  width: 80%;
+}
+
+.medium_dynamicsize{
+  width: 45%;
+}
+
+.short_dynamicsize{
+  width: 35%;
+}
+
+.long_fixedsize{
+  width: 500px;
+}
+
+.medium_fixedsize{
+  width: 300px;
+}
+
+.short_fixedsize{
+  width: 150px;
+}
+
+.veryshort_fixedsize{
+  width: 70px;
+}
+
+.all_dynamicsize{
+  width: 100%;
+}
+
+div#formtable {
+  display: table;
+  width: 100%;
+}
+
+div#formtable > span:first-of-type {
+  display: table-row-group;
+  width: 100%;
+}
+
+div.tablerow {
+  display: inline-table;
+  padding: 5px;
+  width: 99%;
+}
+
+div.tablerow.connectorProp {
+  height:22px;
+  vertical-align: middle; 
+  font-size: 12px;
+}
+
+div.tablecolumn_connPropAttr {
+  display: table-cell;
+  vertical-align: middle; 
+}
+
+div.tablerow2 {
+  display: inline-table;
+  padding: 5px 0px 5px 0px;
+  width: 99%;
+}
+
+div.alt {
+  background: #eff3ea;
+}
+
+div.tablecolumn_label{
+  display: table-cell;
+  font-size: 12px;
+  vertical-align: middle;
+  font-family: Verdana,Tahoma,sans-serif;
+  width: 30%;
+}
+
+div.tablecolumn_field{
+  display: table-cell;
+  vertical-align: middle;
+  font-family: Verdana,Tahoma,sans-serif;
+  width: 70%;
+}
+
+div.tablecolumn_check{
+  display: table-cell;
+  margin-right: 5px;
+  margin-left: 2px;
+  vertical-align: middle;
+}
+
+div.tablecolumn2_label{
+  display: table-cell;
+  font-size: 12px;
+  vertical-align: middle;
+  font-family: Verdana,Tahoma,sans-serif;
+  padding-left: 5px;
+  width: 15%;
+}
+
+div.tablecolumn2_field{
+  display: table-cell;
+  vertical-align: middle;
+  font-family: Verdana,Tahoma,sans-serif;
+  width: 35%;
+}
+
+.ui-tabs .ui-tabs-panel {
+  background: none repeat scroll 0 0 #FFFFFF;
+  border-width: 0;
+  display: block;
+  overflow: auto;
+  padding: 1em 1.4em;
+}
+
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button {
+  font-family: Verdana,Arial,sans-serif;
+  font-size: 12px;
+  padding: 2px 4px;
+}
+
+.ui-widget-header { 
+  border: 1px solid #aaaaaa
+    /*{borderColorHeader}*/; 
+  background: #cccccc
+    /*{bgColorHeader}*/ 
+    url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)
+    /*{bgImgUrlHeader}*/ 
+    50%/*{bgHeaderXPos}*/ 
+    50%/*{bgHeaderYPos}*/ 
+    repeat-x/*{bgHeaderRepeat}*/; 
+  color: #222222/*{fcHeader}*/; 
+  font-weight: bold;
+  padding: 7px 15px;
+}
+
+.ui-button { 
+  display: inline-block; 
+  position: relative; 
+  margin-right: .1em; 
+  cursor: pointer; 
+  text-align: center; 
+  zoom: 1; 
+  overflow: visible; 
+  padding: 7px 15px;
+}
+
+.ui-spinner-button {
+  cursor: default;
+  display: block;
+  font-size: 0.5em;
+  height: 50%;
+  margin: 0;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  right: 0;
+  text-align: center;
+  width: 16px;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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 12af172..1b8e565 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
@@ -17,90 +17,168 @@
  * under the License.
  */
 .feedbackPanel {
-  padding-left: 0px;
-  text-align: center;
+    padding-left: 0px;
+    text-align: center;
 }
 
 .notificationpanel_row {  
-  list-style-type: none;
+    list-style-type: none;
 }  
 
 .notificationpanel_row span {  
-  border:0 none;
+    border:0 none;
 }    
 pre {
-  white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
-  white-space: -pre-wrap; /* Opera */
-  white-space: -o-pre-wrap; /* Opera */
-  white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) http://www.w3.org/TR/css3-text/#white-space */
-  word-wrap: break-word; /* IE 5.5+ */
+    white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
+    white-space: -pre-wrap; /* Opera */
+    white-space: -o-pre-wrap; /* Opera */
+    white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) http://www.w3.org/TR/css3-text/#white-space */
+    word-wrap: break-word; /* IE 5.5+ */
 }
 
 #veil {
-  display:none;
-  position:absolute;
-  top:0;
-  left:0;
-  z-index:99999;
-  background-color:black;
-  width:100%;
-  height:20000px;
-  color:white;
-  opacity:0.3;
-  filter:alpha(opacity=30);
+    display:none;
+    position:absolute;
+    top:0;
+    left:0;
+    z-index:99999;
+    background-color:black;
+    width:100%;
+    height:20000px;
+    color:white;
+    opacity:0.3;
+    filter:alpha(opacity=30);
 }
 
 #veil img {
-  position:absolute;
-  top:300px;
-  left:50%;
-  margin-left:-75px;
-  width:150px;
+    position:absolute;
+    top:300px;
+    left:50%;
+    margin-left:-75px;
+    width:150px;
 }
 
 .block-sidebar {
-  max-height: 100%; 
-  overflow: auto; 
-  padding-top: 90px; 
-  padding-bottom: 50px; 
-  position: fixed;
+    max-height: 100%; 
+    overflow: auto; 
+    padding-top: 90px; 
+    padding-bottom: 50px; 
+    position: fixed;
 }
 
 .inner-control-sidebar {
-  position: fixed; 
-  height: auto;
+    position: fixed; 
+    height: auto;
 }
 
 .content-margin-layout {
-  margin: 0px 230px 0px 0px !important;
-  padding: 20px !important;
+    margin: 0px 230px 0px 0px !important;
+    padding: 20px !important;
 }
 
 .admin-content-page {
-  padding: 20px;
-  background: #ecf0f5
+    padding: 20px;
+    background: #ecf0f5
 }
 
 .realms {
-  min-height: 554px
+    min-height: 554px
 }
 
 .actions > li > a {
-  padding-top: 5px !important;
-  padding-bottom: 5px !important;
+    padding-top: 5px !important;
+    padding-bottom: 5px !important;
 }
 
 .block-header {
-  position: fixed;
+    position: fixed;
+    width: 100%;
+    top: 0;
+}
+
+.block-footer {
+    position: fixed;
+    width: 100%;
+    bottom: 0px;
 }
 
 .logo-pos {
-  padding-top: 4px !important;
-  overflow: visible !important;
+    padding-top: 4px !important;
+    overflow: visible !important;
+}
+
+.angle {
+    border: medium none !important;
+    cursor: pointer;
+    display: inline-table !important;
+    float: right;
+    height: 30px;
+    overflow: hidden;
+    position: relative !important;
+    right: 0;
+    top: -30px;
+    width: 25%;
+    z-index: 3;
 }
 
 @media (min-width: 768px) {
-  .main-header .logo {
-    height: 54px;
-  }
-}
\ No newline at end of file
+    .main-header .logo {
+	height: 54px;
+    }
+}
+
+.w_caption h3 {
+    font-size: 16px;
+}
+
+div.wicket-modal div.w_content_3 {
+    border: 1px solid #eee;
+    border-radius: 20px;
+    padding: 5px;
+}
+
+.tab-content {
+    margin-bottom: 10px;
+    margin-top: 10px;
+}
+
+a.help {
+  position: relative;
+  display: inline;
+  text-decoration: none;
+}
+
+a.help span {
+  position: absolute;
+  width:19em;
+  color: #000000;
+  background: whitesmoke;
+  visibility: hidden;
+  border-radius: 0px;
+  padding: 3px;
+}
+
+a.help span:after {
+  position: absolute;
+  top: 50%;
+  left: 100%;
+  margin-top: -8px;
+  width: 0;
+  height: 0;
+}
+
+a.help span {
+  visibility: visible;
+  opacity: none;
+  right: 100%;
+  top: 50%;
+  margin-right: 4px;
+  margin-top: -11px;
+  border: 1px solid black;
+  z-index: 1000000;
+}
+
+a.help span a {
+  color: #463;
+  text-decoration: none;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/META-INF/resources/css/topology.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/topology.css b/client/console/src/main/resources/META-INF/resources/css/topology.css
new file mode 100644
index 0000000..c5744cb
--- /dev/null
+++ b/client/console/src/main/resources/META-INF/resources/css/topology.css
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+.window {
+    border:1px solid #346789;
+    box-shadow: 2px 2px 19px #aaa;
+    -o-box-shadow: 2px 2px 19px #aaa;
+    -webkit-box-shadow: 2px 2px 19px #aaa;
+    -moz-box-shadow: 2px 2px 19px #aaa;
+    -moz-border-radius:0.5em;
+    border-radius:0.5em;
+    opacity:0.8;
+    filter:alpha(opacity=80);
+    width:140px; height:55px;
+    line-height:5em;
+    text-align:center;
+    z-index:20; position:absolute;
+    background-color:#eeeeef;
+    color:black;
+    font-family:helvetica;padding:0.0em;
+    font-size:0.9em;}
+
+.topology_root {
+    background-color:rgba(0,170,0,0.4);
+}
+
+.topology_cs {
+    background-color:rgba(0,100,0,0.10);
+}
+
+.topology_conn {
+    background-color:rgba(100,200,200,0.08);
+}
+
+.topology_res {
+    background-color:rgba(250,230,0,0.09);
+}
+
+.window:hover {
+    box-shadow: 2px 2px 19px #444;
+    -o-box-shadow: 2px 2px 19px #444;
+    -webkit-box-shadow: 2px 2px 19px #444;
+    -moz-box-shadow: 2px 2px 19px #444;
+    opacity:0.6;
+    filter:alpha(opacity=60);
+}
+
+.active {
+    border:1px dotted green;
+}
+.hover {
+    border:1px dotted red;
+}
+._jsPlumb_dragging { 
+    z-index:4000;
+}
+
+#drawing ._jsPlumb_overlay.component.label{
+    background-color: white;
+    border: 1px solid #346789;
+    border-radius: 0.5em 0.5em 0.5em 0.5em;
+    color: black;
+    font-size: 0.8em;
+    opacity: 0.8;
+    padding: 0.5em;
+}
+
+.aLabel {
+    background-color:white; 
+    padding:0.4em; 
+    font:12px sans-serif; 
+    color:#444;
+    z-index:21;
+    border:1px dotted gray;
+    opacity:0.8;
+    filter:alpha(opacity=80);
+    cursor: pointer;
+}
+.aLabel._jsPlumb_hover {
+    background-color:#5C96BC;
+    color:white;	
+    border:1px solid white;
+}
+
+div#topology {
+    position: relative; 
+    border: 0px; 
+    height: 800px; 
+    overflow: hidden;
+}
+
+div#drawing {
+    height: 5000px;
+    width: 5000px;
+    display: block;
+    position: relative;
+    top: -2490px;
+    left: -2270px;
+}
+
+div#zoom {
+    padding : 10px;
+    text-align: right;
+}
+
+div#zoom .fa{
+    font-size: 2em;
+    padding-right: 5px;
+}
+
+div.node-action-link {
+    clear: both;
+    display: block;
+    height: 0px;
+    padding: 3px 8px 0px 0px;
+    position: absolute;
+    right: 0;
+    top: 0;
+}
+
+div.node-action-link .fa{
+    font-size: 14px;
+    display: block !important;
+}
+
+div.node-action-link .dropdown-menu{
+    border-radius: 12px;
+    min-width: 50px;
+    width: 50px;
+}
+
+.window[data-original-title]:hover::after{
+    border: 1px solid #BBB;
+    padding: 5px 10px;
+    background: #EEE;
+    content: attr(data-original-title);
+    position: relative;
+    right: -5px;
+    top:-70px;
+    white-space: nowrap;
+    text-align: center;
+    height: 20px;
+    margin: 0px;
+    border-radius: 0.5em;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/META-INF/resources/js/topology.js
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/js/topology.js b/client/console/src/main/resources/META-INF/resources/js/topology.js
new file mode 100644
index 0000000..5592b9c
--- /dev/null
+++ b/client/console/src/main/resources/META-INF/resources/js/topology.js
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+var def = {
+    paintStyle: {
+	lineWidth: 2,
+        strokeStyle: "rgba(204,204,204, 0.3)",
+        outlineColor: "#666",
+        outlineWidth: 1
+    },
+    connectorPaintStyle:{
+	lineWidth:2
+    },
+    anchor: "AutoDefault",
+    detachable: false,
+    endpointStyle: {
+	gradient: {
+	    stops: [
+            	[0, "rgba(204,204,204, 1)" ], [1, "rgba(180, 180, 200, 1)" ]
+	    ],
+	    offset: 5.5,
+	    innerRadius: 3.5
+	},
+	radius: 3.5
+    }
+};
+
+var failedConnectorStyle = {
+    lineWidth: 2,
+    strokeStyle: "rgba(220, 220, 220, 1)",
+    outlineColor: "#666",
+    outlineWidth: 1
+};
+
+var disabledConnectorStyle = {
+    lineWidth: 2,
+    strokeStyle: "rgba(255, 69, 0, 1)",
+    outlineColor: "#666",
+    outlineWidth: 1
+};
+
+var disabledConnectorHoverStyle = {
+    strokeStyle: "#FF8C00" 
+};
+
+var failedEndpointStyle = {
+    gradient: {
+	stops: [
+	    [0, "rgba(220, 220, 220, 1)" ], [1, "rgba(180, 180, 200, 1)" ]
+	],
+	offset: 5.5,
+	innerRadius: 3.5
+    },
+    radius: 3.5
+};
+
+var disabledEndpointStyle = {
+    gradient: {
+	stops: [
+	    [0, "rgba(255, 69, 0, 1)" ], [1, "rgba(180, 180, 200, 1)" ]
+	],
+	offset: 5.5,
+	innerRadius: 3.5
+    },
+    radius: 3.5
+};
+
+var enabledConnectorStyle = {
+    lineWidth: 2,
+    strokeStyle: "rgba(65, 155, 30, 0.3)",
+    outlineColor: "#666",
+    outlineWidth: 1
+};
+
+var enabledConnectorHoverStyle = {
+    strokeStyle: "#00FF00" 
+};
+
+var enabledEndpointStyle = {
+    gradient: {
+        stops: [
+            [0, "rgba(65, 155, 30, 0.1)" ], [1, "rgba(180, 180, 200, 0.1)" ]
+        ],
+        offset: 5.5,
+        innerRadius: 3.5
+    },
+    radius: 3.5
+};
+
+function disable(sourceName, targetName){
+    jsPlumb.select({target:targetName}).setPaintStyle(disabledConnectorStyle).setHoverPaintStyle({strokeStyle: "#FF8C00" });
+    jsPlumb.selectEndpoints({element: [targetName]}).setPaintStyle(disabledEndpointStyle);
+}
+
+function enable(sourceName, targetName){
+    jsPlumb.select({target:targetName}).setPaintStyle(enabledConnectorStyle).setHoverPaintStyle({strokeStyle: "#00FF00" });
+    jsPlumb.selectEndpoints({element: [targetName]}).setPaintStyle(enabledEndpointStyle);
+}
+
+function failure(sourceName, targetName){
+    jsPlumb.select({target:targetName}).setPaintStyle(failedConnectorStyle).setHoverPaintStyle({strokeStyle: "#FFFFFF" });
+    jsPlumb.selectEndpoints({element: [targetName]}).setPaintStyle(failedEndpointStyle);
+}
+
+function unknown(sourceName, targetName){
+}
+
+function getTopology(){
+    var topology = $.cookie("topology");
+
+    if(topology == null){
+	var val = {};
+    }else{
+	var val = JSON.parse(decodeURIComponent(topology));
+    }
+
+    return val;
+}
+
+window.refreshPosition = function(element) {
+    var val = getTopology();
+    
+    var id = $(element).attr('id');
+    var left = $(element).css('left');
+    var top = $(element).css('top');
+
+    if(val[id] == null){
+	val[id] = {'top':top,'left':left};
+    }else{
+	val[id].top=top;
+	val[id].left=left;
+    }
+    
+    $.cookie("topology", JSON.stringify(val), { expires: 9999 });
+}
+
+window.setPosition = function(id, x, y) {
+    var val = getTopology();
+
+    try{
+	// We cannot use jQuery selector for id since the syntax of connector server id
+	var element = $(document.getElementById(id));
+	
+	if(val[id] == null){ 
+	    element.css("left", x + "px");
+	    element.css("top", y + "px");
+	}else{
+	    element.css("left", val[id].left);
+	    element.css("top", val[id].top);
+	}
+    }catch(err){
+	console.log("Failure setting position for ", id);
+    }
+}
+
+window.setZoom = function(el, zoom, instance, transformOrigin) {
+    transformOrigin = transformOrigin || [ 0.5, 0.5 ];
+    instance = instance || jsPlumb;
+    el = el || instance.getContainer();
+    
+    var p = [ "webkit", "moz", "ms", "o" ],
+	s = "scale(" + zoom + ")",
+	oString = (transformOrigin[0] * 100) + "% " + (transformOrigin[1] * 100) + "%";
+
+    for (var i = 0; i < p.length; i++) {
+	el.style[p[i] + "Transform"] = s;
+	el.style[p[i] + "TransformOrigin"] = oString;
+    }
+
+    el.style["transform"] = s;
+    el.style["transformOrigin"] = oString;
+
+    instance.setZoom(zoom);
+};
+
+window.zoomIn = function(el, instance, transformOrigin) {
+    var val = getTopology();
+    if(val.__zoom__ == null){
+	var zoom = 0.69;
+    }else{
+	var zoom = val.__zoom__ + 0.01;
+    }
+
+    setZoom(el, zoom, instance, transformOrigin);
+    
+    val['__zoom__']=zoom;
+    $.cookie("topology", JSON.stringify(val), { expires: 9999 });
+};
+
+window.zoomOut = function(el, instance, transformOrigin) {
+    var val = getTopology();
+    if(val.__zoom__ == null){
+	var zoom = 0.67;
+    }else{
+	var zoom = val.__zoom__ - 0.01;
+    }
+
+    setZoom(el, zoom, instance, transformOrigin);
+    
+    val['__zoom__']=zoom;
+    $.cookie("topology", JSON.stringify(val), { expires: 9999 });
+};
+
+window.activate = function(zoom){
+    jsPlumb.draggable(jsPlumb.getSelector(".window"));
+    jsPlumb.setContainer("drawing");
+
+    $("#drawing").draggable({
+	containment: 'topology',
+	cursor: 'move'
+    });
+
+    var val = getTopology();
+    if(val.__zoom__ == null){
+	setZoom($("#drawing")[0], zoom);
+    }else{
+	setZoom($("#drawing")[0], val.__zoom__);
+    }
+}
+
+jsPlumb.importDefaults({
+    Connector : [ "Straight" ],
+    DragOptions: {
+	cursor: "pointer",
+	zIndex: 2000
+    },
+    HoverClass: "connector-hover"
+});
+

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.html
new file mode 100644
index 0000000..0c43c4b
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.html
@@ -0,0 +1,122 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <link rel="stylesheet" type="text/css" href="css/bulk.css" media="all"/>
+    <style>
+      #dataTableSpan{
+        display:  block;
+        clear:  both;
+        float: none;
+        margin: 10px;
+        padding-top: 10px;
+      }
+
+      #dataTableSpan table{
+        width: 100%;
+      }
+
+      form#pwdMgtForm {
+        border: 1px solid #AAAAAA;
+        margin:10px;
+      }
+
+      div#changepwd {
+        display: inline-row;
+        margin-top: 5px;
+      }
+
+      div#changepwd div{
+        display: table-cell;
+      }
+
+      div#changepwd div#label{
+        padding-left: 5px;
+        vertical-align: middle;
+        font-family: Verdana,Arial,sans-serif;
+      }
+
+      div#password {
+        display: inline-row;
+        margin: 5px;
+      }
+
+      div#continue {
+        display: inline-row;
+        margin: 5px;
+      }
+
+      div#continue div{
+        display: table-cell;
+      }
+
+      div#cancelBtmForm {
+        padding-left: 5px;
+      }
+    </style>
+  </wicket:head>
+  <wicket:extend>
+    <p class="ui-widget ui-corner-all ui-widget-header">
+      <wicket:message key="title"/>&nbsp;<span wicket:id="displayName"/>
+    </p>
+    <span wicket:id="resourceDatatable" id="dataTableSpan">[resources]</span>
+
+    <span wicket:id="pwdMgtFields">[password management]</span>
+
+    <wicket:fragment wicket:id="pwdMgtFragment">
+      <div wicket:id="pwdMgt">
+        <form wicket:id="pwdMgtForm" id="pwdMgtForm">
+          <div id="changepwd">
+            <div id="value">
+              <span wicket:id="changepwd">[changepwd]</span>
+            </div>
+            <div id="label">
+              <label wicket:id="changePwdLabel">[Change password]</label>
+            </div>
+          </div>
+
+          <div id="password">
+            <input type="password" wicket:id="password" id="password" size="25"  style="width: 180px" title="password"/>
+          </div>
+
+          <div id="password">
+            <input type="password" wicket:id="confirm" id="confirm" size="25"  style="width: 180px" title="confirm"/>
+          </div>
+
+          <div id="continue">
+            <div id="continueBtmForm">
+              <input type="button" wicket:id="continue" id="continue"
+                     class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"/>
+            </div>
+
+            <div id="cancelBtmForm">
+              <input type="button" wicket:id="cancel" id="cancel"
+                     class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"/>
+            </div>
+          </div>
+        </form>
+      </div>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="emptyFragment">
+    </wicket:fragment>
+
+    <wicket:child />
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.properties
new file mode 100644
index 0000000..0f1fcdc
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage.properties
@@ -0,0 +1,19 @@
+# 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.
+title=Global Status
+changePwdLabel=Password propagation
+passwordMismatch=Password mismatch

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_it.properties
new file mode 100644
index 0000000..d30c99c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_it.properties
@@ -0,0 +1,19 @@
+# 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.
+title=Stato Globale
+changePwdLabel=Propagazione password
+passwordMismatch=Password non corrispondenti

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_pt_BR.properties
new file mode 100644
index 0000000..36d86e8
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/AbstractStatusModalPage_pt_BR.properties
@@ -0,0 +1,19 @@
+# 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.
+title=Estatus Global
+changePwdLabel=Password propagation
+passwordMismatch=Password mismatch

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BaseModalPage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BaseModalPage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BaseModalPage.html
index 57fc8d3..c1be88b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BaseModalPage.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BaseModalPage.html
@@ -20,17 +20,21 @@ under the License.
   <head>
     <title></title>
 
-    <link rel="stylesheet" type="text/css" href="webjars/jquery-ui/${jquery-ui.version}/themes/base/minified/jquery-ui.min.css" media="all"/>
-    <link rel="stylesheet" type="text/css" href="css/style.css" media="all"/>
-    <link rel="stylesheet" type="text/css" href="css/fieldstyle.css" media="all"/>
-
-    <script type="text/javascript" src="webjars/jquery-ui/${jquery-ui.version}/ui/minified/jquery-ui.min.js"></script>
+    <link href="webjars/bootstrap/${bootstrap.version}/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
+    <link href="webjars/bootstrap-select/${bootstrap-select.version}/dist/css/bootstrap-select.min.css" rel="stylesheet" type="text/css" />
+    <link href="webjars/font-awesome/${font-awesome.version}/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
+    <link href="webjars/ionicons/${ionicons.version}/css/ionicons.min.css" rel="stylesheet" type="text/css" />
+    <link href="css/AdminLTE.css" rel="stylesheet" type="text/css" />
+    <link href="css/AdminLTE_skins/skin-green.css" rel="stylesheet" type="text/css" />
+    <link href="css/syncopeConsole.css" rel="stylesheet" type="text/css" />
+    <link href="css/fieldstyle.css" rel="stylesheet" type="text/css" />
+
+    <script type="text/javascript" src="webjars/jquery-ui/${jquery-ui.version}/jquery-ui.min.js"></script>
+    <script type="text/javascript" src="webjars/bootstrap/${bootstrap.version}/js/bootstrap.min.js"></script>
+    <script type="text/javascript" src="webjars/bootstrap-select/${bootstrap-select.version}/dist/js/bootstrap-select.min.js"></script>
+    <script type="text/javascript" src="js/AdminLTE-app.min.js"></script>
 
     <script type="text/javascript">
-      $(function() {
-        $("#tabs").tabs();
-      });
-
       var notificationShownTimes = 0;
 
       function showNotification(componentId, messagecount) {
@@ -50,7 +54,6 @@ under the License.
   </head>
   <body onload="setTimeout('window.focus();', 0);">
     <div wicket:id="feedback"/>
-
     <wicket:child />
   </body>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
index 66fcc75..147f819 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
@@ -33,10 +33,13 @@ under the License.
     <link href="css/AdminLTE.css" rel="stylesheet" type="text/css" />
     <link href="css/AdminLTE_skins/skin-green.css" rel="stylesheet" type="text/css" />
     <link href="css/syncopeConsole.css" rel="stylesheet" type="text/css" />
+    <link href="css/fieldstyle.css" rel="stylesheet" type="text/css" />
 
+    <script type="text/javascript" src="webjars/jquery-ui/${jquery-ui.version}/jquery-ui.min.js"></script>
     <script type="text/javascript" src="webjars/bootstrap/${bootstrap.version}/js/bootstrap.min.js"></script>
     <script type="text/javascript" src="webjars/bootstrap-select/${bootstrap-select.version}/dist/js/bootstrap-select.min.js"></script>
     <script type="text/javascript" src="js/AdminLTE-app.min.js"></script>
+    
     <script type="text/javascript">
       var notificationShownTimes = 0;
       function showNotification(componentId, messagecount) {
@@ -51,7 +54,7 @@ under the License.
 
     <div class="wrapper">
 
-      <header class="main-header block-pos">
+      <header class="main-header block-header">
         <div class="logo logo-pos">
           <img src="img/logo.png"/>
         </div>
@@ -100,8 +103,8 @@ under the License.
         <section class="sidebar">
           <ul class="sidebar-menu">
             <li wicket:id="dashboardLI"><a href="#" wicket:id="dashboard"><i class="fa fa-dashboard"></i><span>Dashboard</span></a></li>
-            <li wicket:id="realmsLI"><a href="#" wicket:id="realms"><i class="fa fa-users"></i><span>Realms</span></a></li>
-            <li><a href="#"><i class="fa fa-th"></i><span>Resources</span></a></li>
+            <li wicket:id="realmsLI"><a href="#" wicket:id="realms"><i class="fa fa-folder-o"></i><span>Realms</span></a></li>
+            <li wicket:id="topologyLI"><a href="#" wicket:id="topology"><i class="fa fa-database"></i><span>Topology</span></a></li>
             <li><a href="#"><i class="fa fa-pie-chart"></i><span>Reports</span></a></li>
             <li wicket:id="configurationLI" class="treeview">
               <a href="#"><i class="fa fa-edit"></i><span>Configuration</span> <i class="fa fa-angle-left pull-right"></i></a>
@@ -131,7 +134,7 @@ under the License.
         <wicket:child />
       </div>
 
-      <footer class="main-footer">
+      <footer class="main-footer block-footer">
         <div class="pull-right hidden-xs">
           Version <label wicket:id="version"/>
         </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.html
new file mode 100644
index 0000000..9e5d497
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.html
@@ -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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <link rel="stylesheet" type="text/css" href="css/bulk.css" media="all"/>
+  </wicket:head>
+  <wicket:extend>
+    <p class="ui-widget ui-corner-all ui-widget-header"><wicket:message key="title"/></p>
+
+    <div id="selectedObjects">
+      <table class="ui-widget ui-widget-content table-hover pageRowElement" wicket:id="selectedObjects">[DataTable]</table>
+
+      <div id="actionRow" class="pageRowElement">
+        <div id="actions">
+          <div id="actionPanel" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
+            <span wicket:id="actions">[Actions]</span>
+          </div>
+
+          <div id="cancelBtmForm">
+            <form wicket:id="form">
+              <input type="button" wicket:id="cancel" id="cancel"
+                     class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"/>
+            </form>
+          </div>
+        </div>
+      </div>
+    </div>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.properties
new file mode 100644
index 0000000..bd28d80
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage.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.
+title=Bulk action

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_it.properties
new file mode 100644
index 0000000..3989422
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_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.
+title=Operazioni di gruppo

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_pt_BR.properties
new file mode 100644
index 0000000..ec07d02
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionModalPage_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.
+title=A\u00E7\u00E3o Composta

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.html
new file mode 100644
index 0000000..16dd256
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.html
@@ -0,0 +1,57 @@
+<!--
+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.
+-->
+
+<!--
+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.
+-->
+<wicket:head>
+  <link rel="stylesheet" type="text/css" href="css/bulk.css" media="all"/>
+</wicket:head>
+<wicket:extend>
+  <p class="ui-widget ui-corner-all ui-widget-header"><wicket:message key="title"/></p>
+
+<div id="selectedObjects">
+  <table class="ui-widget ui-widget-content table-hover pageRowElement" wicket:id="selectedObjects">[DataTable]</table>
+
+  <div id="actionRow" class="pageRowElement">
+    <div id="actions">
+      <div id="cancelBtmForm" style="padding: 0px">
+        <a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="close">
+          <wicket:message key="close"/>
+        </a>
+      </div>
+    </div>
+  </div>
+</div>
+</wicket:extend>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.properties
new file mode 100644
index 0000000..7ba550c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage.properties
@@ -0,0 +1,19 @@
+# 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.
+title=Bulk Action Result
+close=Close
+bulkActionResultLabel=Result

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_it.properties
new file mode 100644
index 0000000..4268c00
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_it.properties
@@ -0,0 +1,19 @@
+# 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.
+title=Risultato esecuzion Bulk Action
+close=Chiudi
+bulkActionResultLabel=Esito

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_pt_BR.properties
new file mode 100644
index 0000000..00c3a51
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/BulkActionResultModalPage_pt_BR.properties
@@ -0,0 +1,19 @@
+# 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.
+title=Resultado da A\u00E7\u00E3o Composta
+close=Fechar
+bulkActionResultLabel=Implantar

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.html
new file mode 100644
index 0000000..b85acb6
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.html
@@ -0,0 +1,161 @@
+<!--
+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>
+    <p class="ui-widget ui-corner-all ui-widget-header">
+        <span wicket:id="new"/>&nbsp;<wicket:message key="title"/>&nbsp;<span wicket:id="key"/>
+    </p>
+    <div style="margin: 5px;">
+      <form wicket:id="form">
+        <div id="tabs">
+          <ul>
+            <li class="tabs-selected"><a href="#tabs-1"><span><wicket:message key="tab1"/></span></a></li>
+            <li><a href="#tabs-2"><span><wicket:message key="tab2"/></span></a></li>
+            <li><a href="#tabs-3"><span><wicket:message key="tab3"/></span></a></li>
+          </ul>
+          <div id="tabs-1">
+            <div id="formtable">
+              <div class="tablerow alt">
+                <div class="tablecolumn_label short_dynamicsize">
+                  <label for="displayName"><wicket:message key="displayName"/></label>
+                </div>
+                <div class="tablecolumn_field short_dynamicsize">
+                  <span wicket:id="displayName">[displayName]</span>
+                </div>
+              </div>
+
+              <div class="tablerow">
+                <div class="tablecolumn_label short_dynamicsize">
+                  <label for="location"><wicket:message key="location"/></label>
+                </div>
+                <div class="tablecolumn_field short_dynamicsize">
+                  <span wicket:id="location">[location]</span>
+                </div>
+              </div>
+
+              <div class="tablerow alt">
+                <div class="tablecolumn_label short_dynamicsize">
+                  <label for="name"><wicket:message key="name"/></label>
+                </div>
+                <div class="tablecolumn_field medium_dynamicsize">
+                  <span wicket:id="connectorName">[connectorName]</span>
+                </div>
+              </div>
+
+              <div class="tablerow">
+                <div class="tablecolumn_label short_dynamicsize">
+                  <label for="version"><wicket:message key="version"/></label>
+                </div>
+                <div class="tablecolumn_field short_dynamicsize">
+                  <span wicket:id="version">[version]</span>
+                </div>
+              </div>
+            </div>
+            <div style="display: table; border: 1px solid #BBBBBB;">
+              <div class="tablerow2 alt">
+                <div class="tablecolumn2_label short_dynamicsize">
+                  <label for="connRequestTimeout"><wicket:message key="connRequestTimeout"/></label>
+                </div>
+                <div class="tablecolumn2_field short_dynamicsize">
+                  <span wicket:id="connRequestTimeout">[connRequestTimeout]</span>
+                </div>
+                <div class="tablecolumn2_label short_dynamicsize">
+                  <label for="poolMaxObjects"><wicket:message key="poolMaxObjects"/></label>
+                </div>
+                <div class="tablecolumn2_field short_dynamicsize">
+                  <span wicket:id="poolMaxObjects">[poolMaxObjects]</span>
+                </div>
+              </div>
+              <div class="tablerow2">
+                <div class="tablecolumn2_label short_dynamicsize">
+                  <label for="poolMinIdle"><wicket:message key="poolMinIdle"/></label>
+                </div>
+                <div class="tablecolumn2_field short_dynamicsize">
+                  <span wicket:id="poolMinIdle">[poolMinIdle]</span>
+                </div>
+                <div class="tablecolumn2_label short_dynamicsize">
+                  <label for="poolMaxIdle"><wicket:message key="poolMaxIdle"/></label>
+                </div>
+                <div class="tablecolumn2_field short_dynamicsize">
+                  <span wicket:id="poolMaxIdle">[poolMaxIdle]</span>
+                </div>
+              </div>
+              <div class="tablerow2 alt">
+                <div class="tablecolumn2_label short_dynamicsize">
+                  <label for="poolMaxWait"><wicket:message key="poolMaxWait"/></label>
+                </div>
+                <div class="tablecolumn2_field short_dynamicsize">
+                  <span wicket:id="poolMaxWait">[poolMaxWait]</span>
+                </div>
+                <div class="tablecolumn2_label short_dynamicsize">
+                  <label for="poolMinEvictableIdleTime"><wicket:message key="poolMinEvictableIdleTime"/></label>
+                </div>
+                <div class="tablecolumn2_field short_dynamicsize">
+                  <span wicket:id="poolMinEvictableIdleTime">[poolMinEvictableIdleTime]</span>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div id="tabs-2">
+            <div id="formtable">
+              <span wicket:id="container">
+                <div style="border-bottom: 10px">
+                  <div style="width: 40px; text-align: center; font-size: 7px">
+                    <label for="version"><wicket:message key="overridable"/></label>
+                  </div>
+                </div>
+                <form wicket:id="connectorPropForm">
+                  <div class="tablerow connectorProp" wicket:id="connectorProperties">
+                    <div class="tablecolumn_check" style="width: 27px; text-align: center; margin-right: 10px">
+                      <span wicket:id="connPropAttrOverridable">[connPropAttrOverridable]</span>
+                    </div>
+                    <div class="tablecolumn_connPropAttr">
+                      <span wicket:id="connPropAttrSchema">[connPropAttrSchema]</span>
+                    </div>
+                    <div class="tablecolumn_field veryshort_fixedsize">
+                      <span wicket:id="panel">[panel]</span>
+                    </div>
+                  </div>
+                  <div>
+                    <a style="position: absolute; top: 2px; right:20px;" wicket:id="check">
+                      <img src="img/ping.png"width="30" height="30"
+                           alt="ping" title="title" wicket:message="title:check"/>
+                    </a>
+                  </div>
+                </form>
+              </span>
+            </div>
+          </div>
+          <div id="tabs-3">
+            <span wicket:id="capabilitiesPalette"/>
+          </div>
+        </div>
+
+        <div style="margin: 20px 10px 0">
+          <input type="submit"
+                 class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
+                 wicket:id="apply"/>
+          <input type="button"
+                 class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
+                 wicket:id="cancel"/>
+        </div>
+      </form>
+    </div>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.properties
new file mode 100644
index 0000000..8500f1a
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage.properties
@@ -0,0 +1,43 @@
+# 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.
+tab1=General
+tab2=Configuration
+tab3=Capabilities
+displayName=Display name
+bundleName=Bundle name
+version=Version
+connRequestTimeout=Request timeout (sec)
+action=Action
+edit=Edit
+edit_attribute=Edit attribute
+serviceName=Service name
+endpoint=Endpoint
+title=Connector
+overridable=Overridable
+property=Property
+value=Value
+
+success_connection=Successful connection
+error_connection=Connection failure
+check=Check connection
+location=Location
+poolMaxObjects=Max objects (idle+active)
+poolMinIdle=Min idle objects
+poolMaxIdle=Max idle objects
+poolMaxWait=Max waiting time (msec)
+poolMinEvictableIdleTime=Min eviction time (msec)
+new=New

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_it.properties
new file mode 100644
index 0000000..96080c3
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_it.properties
@@ -0,0 +1,43 @@
+# 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.
+tab1=Generale
+tab2=Configurazione
+tab3=Capabilities
+bundleName=Bundle name
+version=Versione
+connRequestTimeout=Timeout richiesta (sec)
+action=Azione
+edit=Edit
+edit_attribute=Edit attribute
+serviceName=Nome servizio
+endpoint=Endpoint
+title=Connettore
+displayName=Nome visualizzato
+overridable=Sovrascrivibile
+property=Propriet\u00e0
+value=Valore
+
+success_connection=Connessione avvenuta con successo
+error_connection=Connessione non riuscita
+check=Verifica connessione
+location=Posizione
+poolMaxObjects=Max oggetti (attivi e non)
+poolMinIdle=Max oggetti attivi
+poolMaxIdle=Max oggetti inattivi
+poolMaxWait=Tempo max attesa
+poolMinEvictableIdleTime=Tempo min espulsione
+new=Nuovo

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_pt_BR.properties
new file mode 100644
index 0000000..b688216
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ConnectorModalPage_pt_BR.properties
@@ -0,0 +1,43 @@
+# 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.
+tab1=Geral
+tab2=Configura\u00e7\u00e3o
+tab3=Capacidades
+displayName=Mostrar Nome
+bundleName=Nome do Pacote
+version=Vers\u00e3o
+connRequestTimeout=Timeout da Requisi\u00e7\u00e3o (seg)
+action=A\u00e7\u00e3o
+edit=Alterar
+edit_attribute=Alterar Atributo
+serviceName=Nome de Servi\u00e7o
+endpoint=Endpoint
+title=Conector
+overridable=Alter\u00e1vel
+property=Propriedade
+value=Valor
+
+success_connection=Sucesso na Conex\u00e3o
+error_connection=Falha na Conex\u00e3o
+check=Verificar a Conex\u00e3o
+location=Localiza\u00e7\u00e3o
+poolMaxObjects=Max objects (idle+active)
+poolMinIdle=Min idle objects
+poolMaxIdle=Max idle objects
+poolMaxWait=Max waiting time (msec)
+poolMinEvictableIdleTime=Min eviction time (msec)
+new=Novo

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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 ab26a9e..8a998cc 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
@@ -22,10 +22,12 @@ under the License.
   <wicket:extend>
 
     <div class="wrapper">
-      <div class="admin-content-page content-margin-layout">
+      <div class="admin-content-page content-margin-layout" wicket:id="content">
         <div class="box box-solid box-primary">
           <div class="box-header with-border">
-            <h3 class="box-title">Realm 5</h3>
+            <h3 class="box-title">
+              <wicket:container wicket:id="header"></wicket:container>
+            </h3>
             <div class="box-tools pull-right">
               <ul class="nav navbar-nav actions">
                 <li><a href="#"><i class="fa fa-plus"></i></a></li>
@@ -35,78 +37,43 @@ under the License.
             </div><!-- /.box-tools -->
           </div><!-- /.box-header -->
           <div class="box-body">
-            <div class="realms">body</div>
+            <div class="realms">
+              <wicket:container wicket:id="body"></wicket:container>
+            </div>
           </div>
         </div>
       </div>
 
-      <!-- The Right Sidebar -->
       <aside class="control-sidebar control-sidebar-dark control-sidebar-open block-sidebar">
         <section class="sidebar">
           <ul class="sidebar-menu">
-            <li><a href="#"><i class="fa fa-dashboard"></i><span>Realm 1</span></a></li>
-            <li><a href="#"><i class="fa fa-users"></i><span>Realm 2</span></a></li>
-            <li><a href="#"><i class="fa fa-th"></i><span>Realm 3</span></a></li>
-            <li><a href="#"><i class="fa fa-pie-chart"></i><span>Realm 4</span></a></li>
-            <li class="treeview">
-              <a href="#"><i class="fa fa-edit"></i><span>Realm 5</span> <i class="fa fa-angle-left pull-right"></i></a>
-              <ul class="treeview-menu">
-                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.1</a></li>
-                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.2</a></li>
-                <li class="treeview">
-                  <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3</span> <i class="fa fa-angle-left pull-right"></i></a>
-                  <ul class="treeview-menu">
-                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.1</a></li>
-                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2</a></li>
-                    <li class="treeview">
-                      <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2</span> <i class="fa fa-angle-left pull-right"></i></a>
-                      <ul class="treeview-menu">
-                        <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.1</a></li>
-                        <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.2</a></li>
-                        <li class="treeview">
-                          <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2.3</span> <i class="fa fa-angle-left pull-right"></i></a>
-                          <ul class="treeview-menu">
-                            <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.1</a></li>
-                            <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.2</a></li>
-                            <li class="treeview">
-                              <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2.3.3</span> <i class="fa fa-angle-left pull-right"></i></a>
-                              <ul class="treeview-menu">
-                                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.1</a></li>
-                                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.2</a></li>
-                                <li class="treeview">
-                                  <a href="#"><i class="fa fa-edit"></i><span>Realm 5.3.2.3.3.3</span> <i class="fa fa-angle-left pull-right"></i></a>
-                                  <ul class="treeview-menu">
-                                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.3.1</a></li>
-                                    <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.3.2.3.3.3.2</a></li>
-                                  </ul>
-                                </li>
-                              </ul>
-                            </li>
-                          </ul>
-                        </li>
-                      </ul>
-                    </li>
-                  </ul>
-                </li>
-                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.4</a></li>
-                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.5</a></li>
-                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.6</a></li>
-                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 5.7</a></li>
-              </ul>
-            </li>
-            <li class="treeview">
-              <a href="#"><i class="fa fa-laptop"></i><span>Realm 6</span> <i class="fa fa-angle-left pull-right"></i></a>
-              <ul class="treeview-menu">
-                <li><a href="#"><i class="fa fa-circle-o"></i>Realm 6.1</a></li>
-              </ul>
-            </li>
+            <wicket:container wicket:id="list"></wicket:container>
           </ul>
         </section>
       </aside>
-      <!-- The sidebar's background -->
-      <!-- This div must placed right after the sidebar for it to work-->
       <div class="control-sidebar-bg inner-control-sidebar"></div>
     </div>
 
+    <wicket:fragment wicket:id="withChildren">
+      <li class="treeview">
+        <a href="#" wicket:id="link"><i class="fa fa-folder-o">
+          </i><span wicket:id="name">[ITEM NAME]</span>
+        </a>
+        <a haref="#" class="angle">
+          <i class="fa fa-angle-left pull-right"></i>
+        </a>
+        <ul class="treeview-menu">
+          <wicket:container wicket:id="list"></wicket:container>
+        </ul>
+      </li>
+    </wicket:fragment>
+
+    <wicket:fragment wicket:id="withoutChildren">
+      <li>
+        <a href="#" wicket:id="link">
+          <i class="fa fa-leaf"></i><span wicket:id="name">[ITEM NAME]</span>
+        </a>
+      </li>
+    </wicket:fragment>
   </wicket:extend>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.html
new file mode 100644
index 0000000..8cb22f0
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.html
@@ -0,0 +1,56 @@
+<!--
+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>
+    <form wicket:id="form">
+      <div class="tabbable tabs-left">
+        <ul class="nav nav-tabs">
+          <li class="active"><a  data-toggle="tab" href="#resource"><span><wicket:message key="resource"/></span></a></li>
+          <li><a  data-toggle="tab" href="#umapping"><span><wicket:message key="umapping"/></span></a></li>
+          <li><a  data-toggle="tab" href="#gmapping"><span><wicket:message key="gmapping"/></span></a></li>
+          <li><a  data-toggle="tab" href="#connectorProperties"><span><wicket:message key="connectorProperties"/></span></a></li>
+          <li><a  data-toggle="tab" href="#security"><span><wicket:message key="security"/></span></a></li>
+        </ul>
+        <div class="tab-content">
+          <div id="resource" class="tab-pane active">
+            <span wicket:id="details">[details]</span>
+            <span wicket:id="systeminformation">[System Information]</span>
+          </div>
+          <div id="umapping" class="tab-pane">
+            <span wicket:id="umapping">[umapping]</span>
+          </div>
+          <div id="gmapping" class="tab-pane">
+            <span wicket:id="gmapping">[gmapping]</span>
+          </div>
+          <div id="connectorProperties" class="tab-pane">
+            <span wicket:id="connconf">[connconf]</span>
+          </div>
+          <div id="security" class="tab-pane">
+            <span wicket:id="security">[security]</span>
+          </div>
+        </div>
+      </div>
+
+      <div class="modal-footer">
+        <input type="submit" class="btn btn-primary" wicket:id="apply"/>
+        <input type="button" class="btn btn-default" wicket:id="cancel"/>
+      </div> 
+    </form>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
new file mode 100644
index 0000000..8a8eb3f
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
@@ -0,0 +1,60 @@
+# 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.
+resource=Resource details
+umapping=User mapping
+connectorProperties=Connector properties
+security=Security
+required_alert=All form fields are required
+connector=Connector
+existing_resources=Existing resources
+action=Action
+edit_attribute=Edit resource
+title=Resource
+extAttrNames=External attributes
+intMappingTypes=Internal mapping types
+entity=Entity
+groupSchema=Group Schema
+accountId=AccountId
+mandatoryCondition=Mandatory
+password=Password
+purpose=Purpose
+mappingUserSchema=Mapping User Schema
+mappingGroupSchema=Mapping Group Schema
+delete=Delete
+intAttrNames=Internal attributes
+enforceMandatoryCondition=Enforce mandatory condition
+fieldName=Field name
+
+accountIdValidation=There must be exactly one AccountId
+propagationMode=Propagation mode
+accountLink=Account link
+enable=Enable
+
+createTraceLevel=Create trace level
+updateTraceLevel=Update trace level
+deleteTraceLevel=Delete trace level
+syncTraceLevel=Synchronization trace level
+propagationPriority=Propagation priority
+propagationPrimary=Propagation primary
+
+success_connection=Successful connection
+error_connection=Connection failure
+check=Check connection
+actionsClasses=Actions classes
+gmapping=Group mapping
+new=New resource
+randomPwdIfNotProvided=Generate random passwords when missing

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
new file mode 100644
index 0000000..b98b3ae
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
@@ -0,0 +1,60 @@
+# 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.
+resource=Dettagli Risorsa
+umapping=Mapping utenti
+connectorProperties=Propriet\u00e0\u00a0 Connettore
+security=Sicurezza
+required_alert=Tutti i campi sono richiesti
+connector=Connettore
+existing_resources=Risorse esistenti
+action=Azione
+edit_attribute=Modifica risorsa
+title=Risorsa
+extAttrNames=Attributi esterni
+intMappingTypes=Tipo mapping interno
+entity=Entit&agrave;
+groupSchema=Schema Gruppo
+accountId=AccountId
+mandatoryCondition=Obbligatorio
+password=Password
+purpose=Scopo
+mappingUserSchema=Mapping User Schema
+mappingGroupSchema=Mapping Group Schema
+delete=Rimuovi
+intAttrNames=Attributi interni
+enforceMandatoryCondition=Abilita mandatory condition
+fieldName=Nome campo
+
+accountIdValidation=Deve essere definito esattamente un AccountId
+propagationMode=Modalit\u00e0 di propagazione
+accountLink=Account link
+enable=Abilita
+
+createTraceLevel=Livello di tracciamento delle creazioni
+updateTraceLevel=Livello di tracciamento degli aggiornamenti
+deleteTraceLevel=Livello di tracciamento delle cancellazioni
+syncTraceLevel=Livello di tracciamento delle sincronizzazioni
+propagationPriority=Priorit\u00e0 in propagazione
+propagationPrimary=Primaria in propagazione
+
+success_connection=Connessione avvenuta con successo
+error_connection=Connessione non riuscita
+check=Verifica connessione
+actionsClasses=Classi azioni
+gmapping=Mapping gruppi
+new=Nuova risorsa
+randomPwdIfNotProvided=Genera password casuali se mancanti

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
new file mode 100644
index 0000000..a91df81
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
@@ -0,0 +1,60 @@
+# 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.
+resource=Detalhes de Recursos
+umapping=Mapeamento de usu\u00e1rios
+connectorProperties=Propriedades de Conectores
+security=Seguran\u00e7a
+required_alert=Todos os campos deste formul\u00e1rio s\u00e3o obrigat\u00f3rios
+connector=Conector
+existing_resources=Recursos Existentes
+action=A\u00e7\u00e3o
+edit_attribute=Alterar Recurso
+title=Recurso
+extAttrNames=Atributos Externos
+intMappingTypes=Tipos internos de mapeamentos
+entity=Entidade
+groupSchema=Esquema de Grupo
+accountId=Identificador da Conta
+mandatoryCondition=Obrigat\u00f3rio
+password=Senha
+purpose=Prop\u00f3sito
+mappingUserSchema=Esquema de mapeamento de usu\u00e1rio
+mappingGroupSchema=Esquema de mapeamento de grupo
+delete=Excluir
+intAttrNames=Atributos internos
+enforceMandatoryCondition=Aplicar condi\u00e7\u00e3o obrigat\u00f3ria
+fieldName=Nome do Campo
+
+accountIdValidation=Precisa ser exatamente um Identificador de Conta
+propagationMode=Modo de propaga\u00e7\u00e3o
+accountLink=Link de Conta
+enable=Habilitado
+
+createTraceLevel=Criar n\u00edvel de trace
+updateTraceLevel=Atualizar n\u00edvel de trace
+deleteTraceLevel=Excluir n\u00edvel de trace
+syncTraceLevel=N\u00edvel de trace de sincroniza\u00e7\u00e3o
+propagationPriority=Prioridade de propaga\u00e7\u00e3o
+propagationPrimary=Propaga\u00e7\u00e3o prim\u00e1ria
+
+success_connection=Conex\u00e3o com sucesso
+error_connection=Conex\u00e3o sem sucesso
+check=Verificar a conex\u00e3o
+actionsClasses=Classes de a\u00e7\u00f5es
+gmapping=Mapeamento de grupos
+new=Novo recurso
+randomPwdIfNotProvided=Gerar senhas aleat\u00f3rias quando n\u00e3o houver

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.html
new file mode 100644
index 0000000..487165b
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.html
@@ -0,0 +1,43 @@
+<!--
+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 wicket:id="container">
+      <span wicket:id="resultTable">[Table]</span>
+
+      <span style="float:right">
+        <form wicket:id="paginator" style="display:inline">
+          <label><wicket:message key="displayRows"/></label>
+          <select class="text ui-widget-content ui-corner-all" wicket:id="rowsChooser"/>
+        </form>
+      </span>
+    </div>
+
+    <div wicket:id="editModal">
+    </div>
+
+    <div wicket:id="displayModal">
+    </div>
+
+    <div wicket:id="statusModal">
+    </div>
+
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties
new file mode 100644
index 0000000..6f016a4
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.properties
@@ -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.
+displayRows=Display rows
+
+firstname=Firstname
+surname=Surname
+userId=User Id
+edit=Edit
+delete=Delete
+id=Id
+status=Status
+token=Token
+username=Username
+creationDate=Creation Date
+tokenValued=Valued
+tokenNotValued=Not valued

http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties
new file mode 100644
index 0000000..02b3b57
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AbstractSearchResultPanel_it.properties
@@ -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.
+displayRows=display rows
+
+firstname=Nome
+surname=Cognome
+userId=User Id
+edit=Edit
+delete=Rimuovi
+id=Id
+status=Stato
+token=Token
+username=Username
+creationDate=Data Creazione
+tokenValued=Valued
+tokenNotValued=Not valued