diff --git a/addons/account/static/src/js/widgets.js b/addons/account/static/src/js/widgets.js
index 054735cb60d1997a8ad0fd154a326509b7579534..852acbc3795e5efab57c8a6ba35e73669bd4472d 100644
--- a/addons/account/static/src/js/widgets.js
+++ b/addons/account/static/src/js/widgets.js
@@ -539,12 +539,12 @@ var bankStatementReconciliation = Widget.extend({
             .call("get_object_reference", ['account', 'action_bank_statement_tree'])
             .then(function (result) {
                 var action_id = result[1];
-                var breadcrumbs = self.action_manager.get_widgets();
-                var widget = _.find(breadcrumbs, function(widget){
-                    return widget.action && widget.action.id === action_id;
+                var breadcrumbs = self.action_manager.get_states();
+                var state = _.find(breadcrumbs, function(state){
+                    return state.widget.action && state.widget.action.id === action_id;
                 });
-                if (widget) {
-                    self.action_manager.select_widget(widget, 0);
+                if (state) {
+                    self.action_manager.select_state(state, 0);
                 } else {
                     self.action_manager.do_action(action_id, {
                         clear_breadcrumbs: true
diff --git a/addons/board/static/src/js/dashboard.js b/addons/board/static/src/js/dashboard.js
index fc7e12322e3af2aed302401169ddfd3bed7d8316..b2c91b23c5e3c6dbcbd31d79b12f2bd6d0e38f37 100644
--- a/addons/board/static/src/js/dashboard.js
+++ b/addons/board/static/src/js/dashboard.js
@@ -334,17 +334,24 @@ FavoriteMenu.include({
     prepare_dropdown_menu: function (filters) {
         var self = this;
         this._super(filters);
-        this.$('.favorites-menu').append(QWeb.render('SearchView.addtodashboard'));
-        var $add_to_dashboard = this.$('.add-to-dashboard');
-        this.$add_dashboard_btn = $add_to_dashboard.eq(2).find('button');
-        this.$add_dashboard_input = $add_to_dashboard.eq(1).find('input');
-        this.$add_dashboard_link = $add_to_dashboard.first();
-        var title = this.searchview.getParent().title;
-        this.$add_dashboard_input.val(title);
-        this.$add_dashboard_link.click(function () {
-            self.toggle_dashboard_menu();
+        var am = this.findAncestor(function (a) {
+            return a instanceof ActionManager;
         });
-        this.$add_dashboard_btn.click(this.proxy('add_dashboard'));
+        if (am && am.get_inner_widget() instanceof ViewManager) {
+            this.view_manager = am.get_inner_widget();
+            this.add_to_dashboard_available = true;
+            this.$('.favorites-menu').append(QWeb.render('SearchView.addtodashboard'));
+            var $add_to_dashboard = this.$('.add-to-dashboard');
+            this.$add_dashboard_btn = $add_to_dashboard.eq(2).find('button');
+            this.$add_dashboard_input = $add_to_dashboard.eq(1).find('input');
+            this.$add_dashboard_link = $add_to_dashboard.first();
+            var title = this.searchview.get_title();
+            this.$add_dashboard_input.val(title);
+            this.$add_dashboard_link.click(function () {
+                self.toggle_dashboard_menu();
+            });
+            this.$add_dashboard_btn.click(this.proxy('add_dashboard'));
+        }
     },
     toggle_dashboard_menu: function (is_open) {
         this.$add_dashboard_link
@@ -357,29 +364,24 @@ FavoriteMenu.include({
         }
     },
     close_menus: function () {
-        this.toggle_dashboard_menu(false);
+        if (this.add_to_dashboard_available) {
+            this.toggle_dashboard_menu(false);
+        }
         this._super();
     },
     add_dashboard: function () {
-        var self = this,
-            view_manager = this.findAncestor(function (a) {
-                return a instanceof ViewManager;
-            });
-        if (!view_manager.action) {
-            this.do_warn(_t("Can't find dashboard action"));
-            return;
-        }
-        var searchview = view_manager.get_searchview();
-        var search_data = searchview.build_search_data();
-        var context = new data.CompoundContext(searchview.dataset.get_context() || []);
-        var domain = new data.CompoundDomain(searchview.dataset.get_domain() || []);
+        var self = this;
+
+        var search_data = this.searchview.build_search_data(),
+            context = new data.CompoundContext(this.searchview.dataset.get_context() || []),
+            domain = new data.CompoundDomain(this.searchview.dataset.get_domain() || []);
         _.each(search_data.contexts, context.add, context);
         _.each(search_data.domains, domain.add, domain);
 
         context.add({
             group_by: pyeval.eval('groupbys', search_data.groupbys || [])
         });
-        context.add(view_manager.active_view.controller.get_context());
+        context.add(this.view_manager.active_view.controller.get_context());
         var c = pyeval.eval('context', context);
         for(var k in c) {
             if (c.hasOwnProperty(k) && /^search_default_/.test(k)) {
@@ -396,10 +398,10 @@ FavoriteMenu.include({
             .then(function (board_list) {
                 return self.rpc('/board/add_to_dashboard', {
                     menu_id: board_list[0].id,                    
-                    action_id: view_manager.action.id,
+                    action_id: self.action_id,
                     context_to_save: c,
                     domain: d,
-                    view_mode: view_manager.active_view.type,
+                    view_mode: self.view_manager.active_view.type,
                     name: name,
                 });
             }).then(function (r) {
diff --git a/addons/google_spreadsheet/static/src/js/search.js b/addons/google_spreadsheet/static/src/js/search.js
index 2736088fd8cbd354e4512014a1563b2d8e0a9a9b..030c84b1a84287b9e609622081258712fedef074 100644
--- a/addons/google_spreadsheet/static/src/js/search.js
+++ b/addons/google_spreadsheet/static/src/js/search.js
@@ -1,11 +1,13 @@
 odoo.define('google_spreadsheet.google.spreadsheet', function (require) {
 "use strict";
 
+var ActionManager = require('web.ActionManager');
 var core = require('web.core');
 var data = require('web.data');
 var FavoriteMenu = require('web.FavoriteMenu');
 var FormView = require('web.FormView');
 var pyeval = require('web.pyeval');
+var ViewManager = require('web.ViewManager');
 
 var QWeb = core.qweb;
 
@@ -27,14 +29,19 @@ FormView.include({
 FavoriteMenu.include({
     prepare_dropdown_menu: function (filters) {
         this._super(filters);
-        this.$('.favorites-menu').append(QWeb.render('SearchView.addtogooglespreadsheet'));
-        this.$('.add-to-spreadsheet').click(this.add_to_spreadsheet.bind(this));
+        var am = this.findAncestor(function(a) {
+            return a instanceof ActionManager;
+        });
+        if (am && am.get_inner_widget() instanceof ViewManager) {
+            this.view_manager = am.get_inner_widget();
+            this.$('.favorites-menu').append(QWeb.render('SearchView.addtogooglespreadsheet'));
+            this.$('.add-to-spreadsheet').click(this.add_to_spreadsheet.bind(this));
+        }
     },
     add_to_spreadsheet: function () {
         var sv_data = this.searchview.build_search_data(),
             model = this.searchview.dataset.model,
-            view_manager = this.searchview.getParent(),
-            list_view = view_manager.views.list,
+            list_view = this.view_manager.views.list,
             list_view_id = list_view ? list_view.view_id : false,
             context = this.searchview.dataset.get_context() || [],
             compound_context = new data.CompoundContext(context),
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index 687ae228b737c3eb15164b4d3974609b0e61c074..cd6da8a4dc3171738969c9f6ed72dde82b2a86d1 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -25,6 +25,26 @@
     margin-top: -2px;
 }
 
+/* -------- Mail Wall + Control Panel --------- */
+.openerp .oe_mail_wall{
+    display: -webkit-box;
+    display: -moz-box;
+    display: -ms-flexbox;
+    display: -webkit-flex;
+    display: flex;
+    -ms-flex-direction: column;
+    -webkit-flex-direction: column;
+    flex-direction: column;
+}
+.openerp .oe_mail_wall .oe-view-manager-content{
+    -webkit-box-flex: 1;
+    -webkit-flex: 1 1 auto;
+    -ms-flex: 1 1 auto;
+    flex: 1 1 auto;
+    overflow: auto;
+    position: static;
+}
+
 /* ---------------- MESSAGES ------------------ */
 
 .openerp .oe_mail .oe_msg{
@@ -731,10 +751,6 @@
     margin-bottom: 10px;
 }
 
-.oe_mail_wall .oe-groupby-menu, .oe_mail_wall .add-to-dashboard {
-    display: none;
-}
-
 .oe-view-manager-content .oe_mail {
     display: inline-block !important;
     position: relative !important;
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index b88f254cf4e7a1ccabfdee242ad2ab81965ae753..f97d036bb2a54a20260920272aac911ecb175b51 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -171,18 +171,20 @@
         Template used to display the communication history in the wall.
         -->
     <div t-name="mail.wall" class="oe-view-manager oe_mail_wall oe_view_manager_current">
-        <div class="oe-control-panel container-fluid">
-            <div class="row">
-                <div class="col-md-6 oe-cp-title">
-                    <ol class="oe-view-title breadcrumb">
-                        <li class="active"><t t-esc="widget.action.name"/></li>
-                    </ol>
+        <div class="oe-control-panel">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col-md-6 oe-cp-title">
+                        <ol class="oe-view-title breadcrumb">
+                            <li class="active"><t t-esc="widget.action.name"/></li>
+                        </ol>
+                    </div>
+                    <div class="oe-cp-search-view col-md-6" />
                 </div>
-                <div class="oe-cp-search-view col-md-6" />
-            </div>
-            <div class="row">
-                <div class="col-sm-6 col-sm-offset-6">
-                    <div class="oe-search-options btn-group"/>
+                <div class="row">
+                    <div class="col-sm-6 col-sm-offset-6">
+                        <div class="oe-search-options btn-group"/>
+                    </div>
                 </div>
             </div>
         </div>
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 5626ccec148ba680a8ccce8dcd687b883b57586c..5181e22a2628ff964ff32b1f43659d78fcc82f9b 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -923,60 +923,74 @@
 }
 .openerp .oe_application {
   height: 100%;
-  -webkit-flex-grow: 1;
-  flex-grow: 1;
-  -ms-flex-negative: 1;
-  display: inline-block\9;
-  overflow: auto\9;
-  width: -webkit-calc(100% - 220px);
-  width: calc(100% - 220px);
-}
-.openerp .oe_application .oe_application {
-  width: 100%;
-}
-.openerp .oe-view-manager {
   width: 100%;
-  height: 100%;
+  display: -webkit-box;
+  display: -moz-box;
+  display: -ms-flexbox;
   display: -webkit-flex;
   display: flex;
+  -ms-flex-direction: column;
   -webkit-flex-direction: column;
   flex-direction: column;
 }
-.openerp .oe-view-manager .oe-view-manager-content {
+.openerp .oe_application .oe_application {
+  width: 100%;
+}
+.openerp .oe-view-manager {
+  -webkit-box-flex: 1;
+  -webkit-flex: 1 1 auto;
+  -ms-flex: 1 1 auto;
+  flex: 1 1 auto;
   overflow: auto;
-  -webkit-flex-grow: 1;
-  flex-grow: 1;
   position: relative;
 }
-.openerp .oe-view-manager .oe-view-manager-content a {
-  color: #7C7BAD;
-}
-.openerp .oe-view-manager .oe-view-manager-content > div {
+.openerp .oe-view-manager .oe-view-manager-content {
   position: absolute;
-  position: static\9;
   top: 0;
   bottom: 0;
   right: 0;
   left: 0;
+}
+.openerp .oe-view-manager .oe-view-manager-content a {
+  color: #7C7BAD;
+}
+.openerp .oe-view-manager .oe-view-manager-content > div {
+  height: 100%;
+  position: static;
   display: none;
 }
+.openerp .oe-view-manager .oe-view-manager-content .oe-view-manager-content {
+  position: static;
+}
 .openerp .oe-view-manager .oe-view-manager-content .oe-view-manager-content > div {
-  position: relative;
   display: block;
 }
 .openerp .oe-view-manager .oe-view-manager-debug {
   margin-right: 5px;
 }
+.openerp .oe-o2m-control-panel {
+  width: 100%;
+}
+.openerp .oe-o2m-control-panel .oe-cp-buttons div {
+  display: inline-block;
+  padding: 5px 5px;
+}
+.openerp .oe-o2m-control-panel .oe-cp-pager div {
+  display: inline-block;
+  padding: 5px 5px;
+}
 .openerp .oe-control-panel {
   background-color: #f0eeee;
   border-bottom: 1px solid #afafb6;
-  -webkit-flex-shrink: 0;
-  flex-shrink: 0;
-  width: 100%;
-  -webkit-user-select: none;
-  -moz-user-select: none;
+  -webkit-box-flex: 0;
+  -webkit-flex: 0 0 auto;
+  -ms-flex: 0 0 auto;
+  flex: 0 0 auto;
   user-select: none;
 }
+.openerp .oe-control-panel > .container-fluid {
+  width: 100%;
+}
 .openerp .oe-control-panel .oe-button-column {
   height: 30px;
 }
@@ -1092,7 +1106,8 @@
 }
 .openerp .oe-control-panel .oe-cp-sidebar .oe_sidebar_delete_item {
   padding: 0;
-  display: inline-block;
+  position: absolute;
+  right: 10px;
 }
 .openerp .oe-control-panel .oe-cp-sidebar .dropdown-menu li a {
   width: 100%;
@@ -1110,9 +1125,6 @@
 .openerp .oe-control-panel .oe-pager-buttons {
   min-height: 30px;
 }
-.openerp .oe_view_manager_inline > .oe-control-panel-content, .openerp .oe_view_manager_inlineview > .oe-control-panel-content {
-  display: none;
-}
 .openerp .o-modal-header > div {
   margin-left: 45%;
 }
@@ -2010,7 +2022,7 @@
   margin: 4px 7px;
 }
 .openerp .oe_form .oe-view-manager-content {
-  overflow: visible;
+  overflow: hidden;
 }
 .openerp .oe_form_editable .oe_form .oe_form_field_integer input {
   width: 6em;
@@ -3206,7 +3218,7 @@ body.oe_single_form .oe_single_form_container {
 .modal .oe_act_window.modal-body {
   padding: 0;
 }
-.modal .oe-view-manager-content > div {
+.modal .oe-view-manager-content {
   position: static !important;
 }
 
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 63ef0cd5bdbafe63ff86bb38a489b401e7dcc973..a4250f78d9166530aa2a46527ae84efd14440adf 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -801,54 +801,64 @@ $sheet-padding: 16px
         text-decoration: underline
     .oe_application
         height: 100%
-        -webkit-flex-grow: 1
-        flex-grow: 1
-        -ms-flex-negative: 1
-        display: inline-block\9
-        overflow: auto\9
-        width: -webkit-calc(100% - 220px)
-        width: calc(100% - 220px)
+        width: 100%
+        display: -webkit-box
+        display: -moz-box
+        display: -ms-flexbox
+        display: -webkit-flex
+        display: flex
+        -ms-flex-direction: column
+        -webkit-flex-direction: column
+        flex-direction: column        
         .oe_application
             width: 100%
     // }}}
     // ViewManager common {{{
     .oe-view-manager
-        width: 100%
-        height: 100%
-        display: -webkit-flex
-        display: flex
-        -webkit-flex-direction: column
-        flex-direction: column
+        -webkit-box-flex: 1
+        -webkit-flex: 1 1 auto
+        -ms-flex: 1 1 auto
+        flex: 1 1 auto
+        overflow: auto
+        position: relative
         .oe-view-manager-content
-            overflow: auto
-            -webkit-flex-grow: 1
-            flex-grow: 1
-            position: relative
+            position: absolute
+            top: 0
+            bottom: 0
+            right: 0
+            left: 0
             a
                 color: $link-color
             > div
-                position: absolute
-                position: static\9
-                top: 0
-                bottom: 0
-                right: 0
-                left: 0
+                height: 100%
+                position: static
                 display: none
             .oe-view-manager-content
+                position: static
                 > div
-                    position: relative
                     display: block
         .oe-view-manager-debug
             margin-right: 5px
+    .oe-o2m-control-panel
+        width: 100%
+        .oe-cp-buttons
+            div
+                display: inline-block
+                padding: 5px 5px
+        .oe-cp-pager
+            div
+                display: inline-block
+                padding: 5px 5px
     .oe-control-panel
         background-color: rgb(240, 238, 238)
         border-bottom: 1px solid #afafb6
-        -webkit-flex-shrink: 0
-        flex-shrink: 0
-        width: 100%
-        -webkit-user-select: none
-        -moz-user-select: none
+        -webkit-box-flex: 0
+        -webkit-flex: 0 0 auto
+        -ms-flex: 0 0 auto
+        flex: 0 0 auto
         user-select: none
+        > .container-fluid
+            width: 100%
         .oe-button-column
             height: 30px
         .dropdown-menu
@@ -950,9 +960,6 @@ $sheet-padding: 16px
 
         .oe-pager-buttons
             min-height: 30px
-    .oe_view_manager_inline, .oe_view_manager_inlineview
-        > .oe-control-panel-content
-            display: none
 
         // }}}
     // FormPopup {{{
@@ -1673,8 +1680,7 @@ $sheet-padding: 16px
             margin: 4px 7px
         // Override ViewManager overflow auto for One2Many fields
         .oe-view-manager-content
-            overflow: visible
-
+            overflow: hidden
     .oe_form_editable
         .oe_form
             .oe_form_field_integer input
@@ -2641,7 +2647,7 @@ body.oe_single_form
         margin: 0 4px 0 0
     .oe_act_window.modal-body
         padding: 0
-    .oe-view-manager-content > div
+    .oe-view-manager-content
         position: static !important
 
 @media (min-width: 768px)
diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js
index 61686dc4e7e6e44735346d7b167a8e19277052c4..8c560830493a41cdf93d1c4efa1454e3b16f4028 100644
--- a/addons/web/static/src/js/action_manager.js
+++ b/addons/web/static/src/js/action_manager.js
@@ -1,6 +1,7 @@
 odoo.define('web.ActionManager', function (require) {
 "use strict";
 
+var ControlPanel = require('web.ControlPanel');
 var core = require('web.core');
 var crash_manager = require('web.crash_manager');
 var data = require('web.data');
@@ -11,7 +12,63 @@ var session = require('web.session');
 var ViewManager = require('web.ViewManager');
 var Widget = require('web.Widget');
 
-var CompoundContext = data.CompoundContext;
+var State = core.Class.extend({
+    init: function(title, flags) {
+        this.title = title;
+        this.flags = flags;
+    },
+    enable: function() { return $.when(); },
+    disable: function() {},
+    destroy: function() {},
+    get_widget: function() {},
+    get_title: function() { return this.title; },
+    get_flags: function() { return this.flags; },
+    get_action: function() {},
+    get_active_view: function() {},
+});
+
+var WidgetState = State.extend({
+    init: function(title, flags, widget) {
+        this._super(title, flags);
+
+        this.widget = widget;
+        if (this.widget.get('title')) {
+            this.title = title;
+        } else {
+            this.widget.set('title', title);
+        }
+        this.widget.on("do_search", this, function() {
+            // active_search = this.control_panel.activate_search(view.created);
+            // call activate search on search view
+            // domain context and groupby computed are important
+        });
+    },
+    set_cp_content: function(content) { this.cp_content = content; },
+    get_cp_content: function() { return this.cp_content; },
+    get_action: function() { return this.widget.action; },
+    get_active_view: function() { return this.widget.active_view; },
+    destroy: function() { 
+        if (this.cp_content && this.cp_content.searchview) {
+            this.cp_content.searchview.destroy();
+        }
+        this.widget.destroy();
+    },
+    get_widget: function() {
+        return this.widget;
+    },
+});
+
+var FunctionState = State.extend({
+    init: function(title, flags) {
+        this._super(title, flags);
+
+        this.widget = {
+            view_stack: [{
+                controller: { get: function () { return this.title; }}
+            }]
+        };
+    }
+});
 
 var ActionManager = Widget.extend({
     template: "ActionManager",
@@ -22,9 +79,28 @@ var ActionManager = Widget.extend({
         this.webclient = parent;
         this.dialog = null;
         this.dialog_widget = null;
-        this.widgets = [];
+        this.states = [];
         this.on('history_back', this, this.proxy('history_back'));
     },
+    start: function() {
+        this._super();
+
+        // Instantiate the unique main control panel used by every widget in this.states
+        this.main_control_panel = new ControlPanel(this);
+        // Listen to event "switch_view" trigerred on the control panel when clicking
+        // on switch buttons. Forward this event to the current inner_widget
+        this.main_control_panel.on("switch_view", this, function(view_type) {
+            this.inner_widget.trigger("switch_view", view_type);
+        });
+        // Listen to event "on_breadcrumb_click" trigerred on the control panel when
+        // clicking on a part of the breadcrumbs. Call select_state for this breadcrumb.
+        this.main_control_panel.on("on_breadcrumb_click", this, function(state, index) {
+            this.select_state(state, index);
+        });
+
+        // Append the main control panel to the DOM (inside the ActionManager jQuery element)
+        this.main_control_panel.appendTo(this.$el);
+    },
     dialog_stop: function (reason) {
         if (this.dialog) {
             this.dialog.destroy(reason);
@@ -32,125 +108,150 @@ var ActionManager = Widget.extend({
         this.dialog = null;
     },
     /**
-     * Add a new widget to the action manager
+     * Add a new state to the action manager
      *
-     * widget: typically, widgets added are instance.web.ViewManager.  The action manager
+     * widget: typically, widgets added are web.ViewManager.  The action manager
      *      uses this list of widget to handle the breadcrumbs.
      * action: new action
      * options.on_reverse_breadcrumb: will be called when breadcrumb is selected
      * options.clear_breadcrumbs: boolean, if true, current widgets are destroyed
-     * options.replace_breadcrumb: boolean, if true, replace current breadcrumb
      */
-    push_widget: function(widget, action, options) {
+    push_state: function(widget, action, options) {
         var self = this,
             to_destroy,
-            old_widget = this.inner_widget;
+            old_widget = this.inner_widget,
+            old_state = this.get_current_state();
         options = options || {};
 
         if (options.clear_breadcrumbs) {
-            to_destroy = this.widgets;
-            this.widgets = [];
-        } else if (options.replace_breadcrumb) {
-            to_destroy = _.last(this.widgets);
-            this.widgets = _.initial(this.widgets);
+            to_destroy = this.states;
+            this.states = [];
         }
+        var new_state,
+            title = action.display_name || action.name;
         if (widget instanceof Widget) {
-            var title = widget.get('title') || action.display_name || action.name;
-            widget.set('title', title);
-            this.widgets.push(widget);
+            new_state = new WidgetState(title, action.flags, widget);
         } else {
-            this.widgets.push({
-                view_stack: [{
-                    controller: {get: function () {return action.display_name || action.name; }},
-                }],
-                destroy: function () {},
-            });
+            new_state = new FunctionState(title, action.flags);
         }
-        _.last(this.widgets).__on_reverse_breadcrumb = options.on_reverse_breadcrumb;
+        this.states.push(new_state);
+
+        this.get_current_state().__on_reverse_breadcrumb = options.on_reverse_breadcrumb;
         this.inner_action = action;
         this.inner_widget = widget;
-        return $.when(this.inner_widget.appendTo(this.$el)).done(function () {
-            if ((action.target !== 'inline') && (!action.flags.headless) && widget.$header) {
-                widget.$header.show();
+
+        // Sets the main ControlPanel state
+        // AAB: temporary restrict the use of main control panel to act_window actions
+        if (action.type === 'ir.actions.act_window') {
+            // if (old_state) old_state.disable();
+            // new_state.enable();
+            this.main_control_panel.set_state(new_state, old_state);
+            // Expose the ControlPanel nodes to the inner_widget only if the ControlPanel is
+            // displayed so that the inner_widget don't insert stuff in hidden nodes
+            var new_state_flags = new_state.get_flags();
+            if (!new_state_flags.headless) {
+                this.inner_widget.set_external_nodes(this.main_control_panel.get_cp_nodes());
             }
+        }
+
+        return $.when(this.inner_widget.appendTo(this.$el)).done(function () {
             if (old_widget) {
                 old_widget.$el.hide();
             }
             if (options.clear_breadcrumbs) {
-                self.clear_widgets(to_destroy);
+                self.clear_states(to_destroy);
             }
         });
     },
     get_breadcrumbs: function () {
-        return _.flatten(_.map(this.widgets, function (widget) {
-            if (widget instanceof ViewManager) {
-                return widget.view_stack.map(function (view, index) { 
+        return _.flatten(_.map(this.states, function (state) {
+            if (state.widget instanceof ViewManager) {
+                return state.widget.view_stack.map(function (view, index) {
                     return {
-                        title: view.controller.get('title') || widget.title,
+                        title: view.controller.get('title') || state.get_title(),
                         index: index,
-                        widget: widget,
+                        widget: state,
                     }; 
                 });
             } else {
-                return {title: widget.get('title'), widget: widget };
+                return { title: state.get_title(), widget: state };
             }
         }), true);
     },
     get_title: function () {
-        if (this.widgets.length === 1) {
+        if (this.states.length === 1) {
             // horrible hack to display the action title instead of "New" for the actions
             // that use a form view to edit something that do not correspond to a real model
             // for example, point of sale "Your Session" or most settings form,
-            var widget = this.widgets[0];
-            if (widget instanceof ViewManager && widget.view_stack.length === 1) {
-                return widget.title;
+            var state = this.states[0];
+            if (state.widget instanceof ViewManager && state.widget.view_stack.length === 1) {
+                return state.get_title();
             }
         }
         return _.pluck(this.get_breadcrumbs(), 'title').join(' / ');
     },
-    get_widgets: function () {
-        return this.widgets.slice(0);
+    get_states: function () {
+        return this.states;
+    },
+    get_current_state: function() {
+        return _.last(this.states);
+    },
+    get_inner_action: function() {
+        return this.inner_action;
+    },
+    get_inner_widget: function() {
+        return this.inner_widget;
     },
     history_back: function() {
-        var widget = _.last(this.widgets);
-        if (widget instanceof ViewManager) {
-            var nbr_views = widget.view_stack.length;
+        var state = this.get_current_state();
+        if (state.widget instanceof ViewManager) {
+            var nbr_views = state.widget.view_stack.length;
             if (nbr_views > 1) {
-                return this.select_widget(widget, nbr_views - 2);
+                return this.select_state(state, nbr_views - 2);
             } 
         } 
-        if (this.widgets.length > 1) {
-            widget = this.widgets[this.widgets.length - 2];
-            var index = widget.view_stack && widget.view_stack.length - 1;
-            return this.select_widget(widget, index);
+        if (this.states.length > 1) {
+            state = this.states[this.states.length - 2];
+            var index = state.widget.view_stack && state.widget.view_stack.length - 1;
+            return this.select_state(state, index);
         }
         return $.Deferred().reject();
     },
-    select_widget: function(widget, index) {
+    select_state: function(state, index) {
         var self = this;
         if (this.webclient.has_uncommitted_changes()) {
             return $.Deferred().reject();
         }
-        var widget_index = this.widgets.indexOf(widget),
-            def = $.when(widget.select_view && widget.select_view(index));
 
+        // Client widget (-> put in ClientState?)
+        if (state.__on_reverse_breadcrumb) {
+            state.__on_reverse_breadcrumb();
+        }
+        // Set the control panel new state
+        // Put in VMState?
+        // Inform the ControlPanel that the current state changed
+        self.main_control_panel.set_state(state, this.get_current_state());
+
+        var state_index = this.states.indexOf(state),
+            def = $.when(state.widget.select_view && state.widget.select_view(index));
+
+        self.clear_states(self.states.splice(state_index + 1));
+        var last_state = _.last(self.states);
+        self.inner_widget = last_state.widget;
+        // AAB: preceeding two lines probably equal to
+        // self.inner_widget = state;
         return def.done(function () {
-            if (widget.__on_reverse_breadcrumb) {
-                widget.__on_reverse_breadcrumb();
-            }
-            _.each(self.widgets.splice(widget_index + 1), function (w) {
-                w.destroy();
-            });
-            self.inner_widget = _.last(self.widgets);
             if (self.inner_widget.do_show) {
                 self.inner_widget.do_show();
             }
         });
     },
-    clear_widgets: function(widgets) {
-        _.invoke(widgets || this.widgets, 'destroy');
-        if (!widgets) {
-            this.widgets = [];
+    clear_states: function(states) {
+        _.map(states || this.states, function(state) {
+            state.destroy();
+        });
+        if (!states) {
+            this.states = [];
             this.inner_widget = null;
         }
     },
@@ -202,7 +303,7 @@ var ActionManager = Widget.extend({
         var self = this,
             action_loaded;
         if (state.action) {
-            if (_.isString(state.action) && core.action_registry.contains(state.action)) {
+            if (_.isString(state.action) && core.action_regisry.contains(state.action)) {
                 var action_client = {
                     type: "ir.actions.client",
                     tag: state.action,
@@ -300,7 +401,7 @@ var ActionManager = Widget.extend({
 
         if (action === false) {
             action = { type: 'ir.actions.act_window_close' };
-        } else if (_.isString(action) && core.action_registry.contains(action)) {
+        } else if (_.isString(action) && core.action_regisry.contains(action)) {
             var action_client = { type: "ir.actions.client", tag: action, params: {} };
             return this.do_action(action_client, options);
         } else if (_.isNumber(action) || _.isString(action)) {
@@ -318,7 +419,7 @@ var ActionManager = Widget.extend({
         core.bus.trigger('action', action);
 
         // Ensure context & domain are evaluated and can be manipulated/used
-        var ncontext = new CompoundContext(options.additional_context, action.context || {});
+        var ncontext = new data.CompoundContext(options.additional_context, action.context || {});
         action.context = pyeval.eval('context', ncontext);
         if (action.context.active_id || action.context.active_ids) {
             // Here we assume that when an `active_id` or `active_ids` is used
@@ -335,39 +436,56 @@ var ActionManager = Widget.extend({
             console.error("No type for action", action);
             return $.Deferred().reject();
         }
+
         var type = action.type.replace(/\./g,'_');
-        var popup = action.target === 'new';
-        var inline = action.target === 'inline' || action.target === 'inlineview';
-        var form = _.str.startsWith(action.view_mode, 'form');
-        action.flags = _.defaults(action.flags || {}, {
-            views_switcher : !popup && !inline,
-            search_view : !popup && !inline,
-            action_buttons : !popup && !inline,
-            sidebar : !popup && !inline,
-            pager : (!popup || !form) && !inline,
-            display_title : !popup,
-            headless: (popup || inline) && form,
-            search_disable_custom_filters: action.context && action.context.search_disable_custom_filters
-        });
         action.menu_id = options.action_menu_id;
         action.context.params = _.extend({ 'action' : action.id }, action.context.params);
         if (!(type in this)) {
             console.error("Action manager can't handle action of type " + action.type, action);
             return $.Deferred().reject();
         }
+
+        // Special case for Dashboards, this should definitively be done upstream
+        if (action.res_model === 'board.board' && action.view_mode === 'form') {
+            action.target = 'inline';
+            _.extend(action.flags, {
+                headless: true,
+                views_switcher: false,
+                display_title: false,
+                search_view: false,
+                pager: false,
+                sidebar: false,
+                action_buttons: false
+            });
+        } else {
+            var popup = action.target === 'new';
+            var inline = action.target === 'inline' || action.target === 'inlineview';
+            var form = _.str.startsWith(action.view_mode, 'form');
+            action.flags = _.defaults(action.flags || {}, {
+                views_switcher : !popup && !inline,
+                search_view : !popup && !inline,
+                action_buttons : !popup && !inline,
+                sidebar : !popup && !inline,
+                pager : (!popup || !form) && !inline,
+                display_title : !popup,
+                headless: (popup || inline) && form,
+                search_disable_custom_filters: action.context && action.context.search_disable_custom_filters
+            });
+        }
+
         return this[type](action, options);
     },
     null_action: function() {
         this.dialog_stop();
-        this.clear_widgets();
+        this.clear_states();
     },
     /**
      *
      * @param {Object} executor
      * @param {Object} executor.action original action
-     * @param {Function<instance.web.Widget>} executor.widget function used to fetch the widget instance
+     * @param {Function<web.Widget>} executor.widget function used to fetch the widget instance
      * @param {String} executor.klass CSS class to add on the dialog root, if action.target=new
-     * @param {Function<instance.web.Widget, undefined>} executor.post_process cleanup called after a widget has been added as inner_widget
+     * @param {Function<web.Widget, undefined>} executor.post_process cleanup called after a widget has been added as inner_widget
      * @param {Object} options
      * @return {*}
      */
@@ -425,14 +543,13 @@ var ActionManager = Widget.extend({
         }
         widget = executor.widget();
         this.dialog_stop(executor.action);
-        return this.push_widget(widget, executor.action, options);
+        return this.push_state(widget, executor.action, options);
     },
     ir_actions_act_window: function (action, options) {
         var self = this;
-
         return this.ir_actions_common({
             widget: function () { 
-                return new ViewManager(self, null, null, null, action); 
+                return new ViewManager(self, null, null, null, action, self.main_control_panel.get_bus());
             },
             action: action,
             klass: 'oe_act_window',
@@ -440,7 +557,7 @@ var ActionManager = Widget.extend({
     },
     ir_actions_client: function (action, options) {
         var self = this;
-        var ClientWidget = core.action_registry.get(action.tag);
+        var ClientWidget = core.action_registry.get_object(action.tag);
         if (!ClientWidget) {
             return self.do_warn("Action Error", "Could not find client action '" + action.tag + "'.");
         }
@@ -454,7 +571,11 @@ var ActionManager = Widget.extend({
         }
 
         return this.ir_actions_common({
-            widget: function () { return new ClientWidget(self, action); },
+            widget: function () {
+                // AAB: temporary fix: Hide main control panel as client actions do not use it
+                self.main_control_panel.do_hide();
+                return new ClientWidget(self, action);
+            },
             action: action,
             klass: 'oe_act_client',
         }, options).then(function () {
diff --git a/addons/web/static/src/js/control_panel.js b/addons/web/static/src/js/control_panel.js
index d5c016522f503e8a2b35d7a2b3df2a92c9c70cf6..b71aefa60f1022e0d4d2961bdb08fad59f47bc1a 100644
--- a/addons/web/static/src/js/control_panel.js
+++ b/addons/web/static/src/js/control_panel.js
@@ -5,12 +5,13 @@ var core = require('web.core');
 var Dialog = require('web.Dialog');
 var formats = require('web.formats');
 var framework = require('web.framework');
-var Model = require('web.Model');
-var pyeval = require('web.pyeval');
 var SearchView = require('web.SearchView');
 var utils = require('web.utils');
 var Widget = require('web.Widget');
 
+var QWeb = core.qweb;
+var _t = core._t;
+
 var ControlPanel = Widget.extend({
     template: 'ControlPanel',
     events: {
@@ -27,58 +28,118 @@ var ControlPanel = Widget.extend({
             this.template = template;
         }
 
-        this.view_manager = parent;
-        this.action_manager = this.view_manager.action_manager;
-        this.action = this.view_manager.action;
-        this.dataset = this.view_manager.dataset;
-        this.active_view = this.view_manager.active_view;
-        this.views = this.view_manager.views;
-        this.flags = this.view_manager.flags;
-        this.title = this.view_manager.title; // needed for Favorites of searchview
-        this.view_order = this.view_manager.view_order;
-        this.multiple_views = (this.view_order.length > 1);
+        this.bus = new core.Bus();
+        this.bus.on("setup_search_view", this, this.setup_search_view);
+        this.bus.on("update", this, this.update);
+        this.bus.on("update_breadcrumbs", this, this.update_breadcrumbs);
+        this.bus.on("render_buttons", this, this.render_buttons);
+        this.bus.on("render_switch_buttons", this, this.render_switch_buttons);
+
+        this.searchview = null;
+
+        this.flags = null;
+        this.dataset = null;
+        this.active_view = null;
+        this.title = null; // Needed for Favorites of searchview
     },
     start: function() {
-        var self = this;
-
-        // Retrieve control panel elements
+        // Retrieve ControlPanel jQuery nodes
         this.$control_panel = this.$('.oe-control-panel-content');
         this.$breadcrumbs = this.$('.oe-view-title');
-        this.$switch_buttons = this.$('.oe-cp-switch-buttons button');
+        this.$buttons = this.$('.oe-cp-buttons');
+        this.$switch_buttons = this.$('.oe-cp-switch-buttons');
         this.$title_col = this.$control_panel.find('.oe-cp-title');
         this.$search_col = this.$control_panel.find('.oe-cp-search-view');
-        // AAB: Use sidebar and pager of the ControlPanel only if it is displayed, otherwise set them
-        // to undefined to that the view uses its own elements to sidebar and pager, as follows:
-        // this.$sidebar = !this.flags.headless && this.flags.sidebar ? this.$('.oe-cp-sidebar') : undefined,
-        // this.$pager = !this.flags.headless ? this.$('.oe-cp-pager') : undefined;
-        // But rather use the following definition to keep behavior as it is for now (i.e. it does not
-        // display the pager in one2many list views)
-        this.$sidebar = this.flags.sidebar ? this.$('.oe-cp-sidebar') : undefined;
+        this.$searchview = this.$(".oe-cp-search-view");
+        this.$searchview_buttons = this.$('.oe-search-options');
         this.$pager = this.$('.oe-cp-pager');
+        this.$sidebar = this.$('.oe-cp-sidebar');
+
+        return this._super();
+    },
+    /**
+     * @return {Object} Dictionnary of ControlPanel nodes
+     */
+    get_cp_nodes: function() {
+        return {
+            $buttons: this.$buttons,
+            $switch_buttons: this.$switch_buttons,
+            $sidebar: this.$sidebar,
+            $pager: this.$pager
+        };
+    },
+    get_bus: function() {
+        return this.bus;
+    },
+    // Sets the state of the controlpanel (in the case of a viewmanager, set_state must be
+    // called before switch_mode for the controlpanel and the viewmanager to be synchronized)
+    set_state: function(state, old_state) {
+        // Detach control panel elements in which sub-elements are inserted by other widgets
+        var old_content = {
+            '$buttons': this.$buttons.contents().detach(),
+            '$switch_buttons': this.$switch_buttons.contents().detach(),
+            '$pager': this.$pager.contents().detach(),
+            '$sidebar': this.$sidebar.contents().detach(),
+            'searchview': this.searchview, // AAB: do better with searchview
+            '$searchview': this.$searchview.contents().detach(),
+            '$searchview_buttons': this.$searchview_buttons.contents().detach(),
+        };
+        if (old_state) {
+            // Store them to re-attach them if we come back to that state (e.g. using breadcrumbs)
+            old_state.set_cp_content(old_content);
+        }
+
+        this.state = state;
+        this.flags = state.get_flags();
+
+        this.flags = state.widget.flags;
+        this.active_view = state.widget.active_view;
+        this.dataset = state.widget.dataset;
+        this.title = state.widget.title; // needed for Favorites of searchview
 
         // Hide the ControlPanel in headless mode
-        if (this.flags.headless) {
-            this.$control_panel.hide();
+        this.$el.toggle(!this.flags.headless);
+
+        var content = state.get_cp_content();
+        if (content) {
+            // This state has already been rendered once
+            content.$buttons.appendTo(this.$buttons);
+            content.$switch_buttons.appendTo(this.$switch_buttons);
+            content.$pager.appendTo(this.$pager);
+            content.$sidebar.appendTo(this.$sidebar);
+            this.searchview = content.searchview;
+            content.$searchview.appendTo(this.$searchview);
+            content.$searchview_buttons.appendTo(this.$searchview_buttons);
         }
+    },
+    get_state: function() {
+        return this.state;
+    },
+    render_buttons: function(views) {
+        var self = this;
 
-        _.each(this.views, function (view) {
-            // Expose control panel elements to the views so that they can insert stuff in them
-            view.options = _.extend(view.options, {
-                $buttons : !self.flags.headless ? self.$('.oe-' + view.type + '-buttons') : undefined,
-                $sidebar : self.$sidebar,
-                $pager : self.$pager,
-            }, self.flags, self.flags[view.type], view.options);
-            // Show $buttons as views will put their own buttons inside it and show/hide them
-            if (view.options.$buttons) view.options.$buttons.show();
-            self.$('.oe-cp-switch-' + view.type).tooltip();
+        var buttons_divs = QWeb.render('ControlPanel.buttons', {views: views});
+        $(buttons_divs).appendTo(this.$buttons);
+
+        // Show each div as views will put their own buttons inside it and show/hide them
+        _.each(views, function(view) {
+            self.$('.oe-' + view.type + '-buttons').show();
         });
+    },
+    render_switch_buttons: function(views) {
+        if (views.length > 1) {
+            var self = this;
 
-        // Create the searchview
-        this.search_view_loaded = this.setup_search_view();
+            var switch_buttons = QWeb.render('ControlPanel.switch-buttons', {views: views});
+            $(switch_buttons).appendTo(this.$switch_buttons);
 
-        return this._super();
+            // Create tooltips
+            _.each(views, function(view) {
+                self.$('.oe-cp-switch-' + view.type).tooltip();
+            });
+        }
     },
-    /**
+     /**
      * Triggers an event when switch-buttons are clicked on
      */
     on_switch_buttons_click: function(event) {
@@ -87,22 +148,34 @@ var ControlPanel = Widget.extend({
     },
     /**
      * Updates its status according to the active_view
+     * @param {Object} [active_view] the current active view
+     * @param {Boolean} [search_view_hidden] true if the searchview is hidden, false otherwise
+     * @param {Array} [breadcrumbs] the breadcrumbs to display
      */
-    update: function(active_view) {
-        this.active_view = active_view;
+    update: function(active_view, search_view_hidden, breadcrumbs) {
+        this.active_view = active_view; // this.active_view only used for debug view
 
-        this.update_search_view();
-        this.update_breadcrumbs();
+        this.update_switch_buttons(active_view);
+        this.update_search_view(search_view_hidden);
+        this.update_breadcrumbs(breadcrumbs);
         this.render_debug_view();
-
-        // Update switch-buttons
-        this.$switch_buttons.removeClass('active');
-        this.$('.oe-cp-switch-' + this.active_view.type).addClass('active');
     },
-    update_breadcrumbs: function () {
+    /**
+     * Removes active class on all switch-buttons and adds it to the one of the active view
+     * @param {Object} [active_view] the active_view
+     */
+    update_switch_buttons: function(active_view) {
+        _.each(this.$switch_buttons.contents('button'), function(button) {
+            $(button).removeClass('active');
+        });
+        this.$('.oe-cp-switch-' + active_view.type).addClass('active');
+    },
+    /**
+     * Updates the breadcrumbs
+     **/
+    update_breadcrumbs: function (breadcrumbs) {
         var self = this;
-        if (!this.action_manager) return;
-        var breadcrumbs = this.action_manager.get_breadcrumbs();
+
         if (!breadcrumbs.length) return;
 
         var $breadcrumbs = breadcrumbs.map(function (bc, index) {
@@ -119,27 +192,27 @@ var ControlPanel = Widget.extend({
                     .toggleClass('active', is_last);
             if (!is_last) {
                 $bc.click(function () {
-                    self.action_manager.select_widget(bc.widget, bc.index);
+                    self.trigger("on_breadcrumb_click", bc.widget, bc.index);
                 });
             }
             return $bc;
         }
     },
     /**
-     * Sets up the search view.
+     * Sets up the search view and calls set_search_view on the widget requesting it
      *
-     * @returns {jQuery.Deferred} search view startup deferred
+     * @param {Object} [src] the widget requesting a search_view
+     * @param {Object} [action] the action (required to instantiated the SearchView)
+     * @param {Object} [dataset] the dataset (required to instantiated the SearchView)
+     * @param {Object} [flags] a dictionnary of Booleans
      */
-    setup_search_view: function() {
-        if (this.searchview) {
-            this.searchview.destroy();
-        }
-
-        var view_id = (this.action && this.action.search_view_id && this.action.search_view_id[0]) || false;
+    setup_search_view: function(src, action, dataset, flags) {
+        var self = this;
+        var view_id = (action && action.search_view_id && action.search_view_id[0]) || false;
 
         var search_defaults = {};
 
-        var context = this.action ? this.action.context : [];
+        var context = action ? action.context : [];
         _.each(context, function (value, key) {
             var match = /^search_default_(.*)$/.exec(key);
             if (match) {
@@ -148,67 +221,29 @@ var ControlPanel = Widget.extend({
         });
 
         var options = {
-            hidden: this.flags.search_view === false,
-            disable_custom_filters: this.flags.search_disable_custom_filters,
-            $buttons: this.$('.oe-search-options'),
-            action: this.action,
+            hidden: flags.search_view === false,
+            disable_custom_filters: flags.search_disable_custom_filters,
+            $buttons: this.$searchview_buttons,
+            action: action,
         };
-        this.searchview = new SearchView(this, this.dataset, view_id, search_defaults, options);
 
-        this.searchview.on('search_data', this, this.search.bind(this));
-        return this.searchview.appendTo(this.$(".oe-cp-search-view:first"));
+        // Instantiate the SearchView and append it to the DOM
+        this.searchview = new SearchView(this, dataset, view_id, search_defaults, options);
+        var search_view_loaded = this.searchview.appendTo(this.$searchview);
+        // Sets the SearchView in the widget which made the request
+        src.set_search_view(self.searchview, search_view_loaded);
     },
-    update_search_view: function() {
+    /**
+     * Updates the SearchView's visibility and extend the breadcrumbs area if the SearchView is not visible
+     * @param {Boolean} [is_hidden] visibility of the searchview
+     **/
+    update_search_view: function(is_hidden) {
         if (this.searchview) {
-            var is_hidden = this.active_view.controller.searchable === false;
             this.searchview.toggle_visibility(!is_hidden);
             this.$title_col.toggleClass('col-md-6', !is_hidden).toggleClass('col-md-12', is_hidden);
             this.$search_col.toggle(!is_hidden);
         }
     },
-    search: function(domains, contexts, groupbys) {
-        var self = this,
-            controller = this.active_view.controller,
-            action_context = this.action.context || {},
-            view_context = controller.get_context();
-        pyeval.eval_domains_and_contexts({
-            domains: [this.action.domain || []].concat(domains || []),
-            contexts: [action_context, view_context].concat(contexts || []),
-            group_by_seq: groupbys || []
-        }).done(function (results) {
-            if (results.error) {
-                self.active_search.resolve();
-                throw new Error(
-                        _.str.sprintf(_t("Failed to evaluate search criterions")+": \n%s",
-                                      JSON.stringify(results.error)));
-            }
-            self.dataset._model = new Model(
-                self.dataset.model, results.context, results.domain);
-            var groupby = results.group_by.length ?
-                          results.group_by :
-                          action_context.group_by;
-            if (_.isString(groupby)) {
-                groupby = [groupby];
-            }
-            if (!controller.grouped && !_.isEmpty(groupby)){
-                self.dataset.set_sort([]);
-            }
-            $.when(controller.do_search(results.domain, results.context, groupby || [])).then(function() {
-                self.active_search.resolve();
-            });
-        });
-    },
-    activate_search: function(view_created_def) {
-        this.active_search = $.Deferred();
-        if (this.searchview &&
-                this.flags.auto_search &&
-                this.active_view.controller.searchable !== false) {
-            $.when(this.search_view_loaded,view_created_def).done(this.searchview.do_search);
-        } else {
-            this.active_search.resolve();
-        }
-        return this.active_search;
-    },
     on_debug_changed: function (evt) {
         var self = this,
             params = $(evt.target).data(),
@@ -231,7 +266,7 @@ var ControlPanel = Widget.extend({
                 var ids = current_view.get_selected_ids();
                 if (ids.length === 1) {
                     this.dataset.call('get_metadata', [ids]).done(function(result) {
-                        var dialog = new Dialog(this, {
+                        new Dialog(this, {
                             title: _.str.sprintf(_t("Metadata (%s)"), self.dataset.model),
                             size: 'medium',
                             buttons: {
diff --git a/addons/web/static/src/js/view_manager.js b/addons/web/static/src/js/view_manager.js
index 0474f0e127be0287a5347d840e9afbab41140d6d..94af0912907207f4f2c2afbfe73a6096fdab074e 100644
--- a/addons/web/static/src/js/view_manager.js
+++ b/addons/web/static/src/js/view_manager.js
@@ -1,21 +1,13 @@
 odoo.define('web.ViewManager', function (require) {
 "use strict";
 
-var ControlPanel = require('web.ControlPanel');
 var core = require('web.core');
 var data = require('web.data');
-var Dialog = require('web.Dialog');
-var formats = require('web.formats');
-var framework = require('web.framework');
 var Model = require('web.Model');
 var pyeval = require('web.pyeval');
-var utils = require('web.utils');
-var SearchView = require('web.SearchView');
-var session = require('web.session');
 var Widget = require('web.Widget');
 
 var _t = core._t;
-var QWeb = core.qweb;
 
 var ViewManager = Widget.extend({
     template: "ViewManager",
@@ -23,25 +15,14 @@ var ViewManager = Widget.extend({
      * @param {Object} [dataset] null object (... historical reasons)
      * @param {Array} [views] List of [view_id, view_type]
      * @param {Object} [flags] various boolean describing UI state
+     * @param {Object} [cp_bus] Bus to allow communication with ControlPanel
      */
-    init: function(parent, dataset, views, flags, action) {
+    init: function(parent, dataset, views, flags, action, cp_bus) {
         if (action) {
             flags = action.flags || {};
             if (!('auto_search' in flags)) {
                 flags.auto_search = action.auto_search !== false;
             }
-            if (action.res_model === 'board.board' && action.view_mode === 'form') {
-                action.target = 'inline';
-                // Special case for Dashboards
-                _.extend(flags, {
-                    views_switcher : false,
-                    display_title : false,
-                    search_view : false,
-                    pager : false,
-                    sidebar : false,
-                    action_buttons : false
-                });
-            }
             this.action = action;
             this.action_manager = parent;
             dataset = new data.DataSetSearch(this, action.res_model, action.context, action.domain);
@@ -62,6 +43,7 @@ var ViewManager = Widget.extend({
         this.active_view = null;
         this.registry = core.view_registry;
         this.title = this.action && this.action.name;
+        this.cp_bus = cp_bus;
 
         _.each(views, function (view) {
             var view_type = view[1] || view.view_type,
@@ -81,10 +63,8 @@ var ViewManager = Widget.extend({
             self.views[view_type] = view_descr;
         });
 
-        // Instantiate ControlPanel
-        this.control_panel = new ControlPanel(self);
-        // Listen to event 'switch_view' trigerred when clicking on switch-buttons
-        this.control_panel.on('switch_view', this, function(view_type) {
+        // Listen to event 'switch_view' indicating that the VM must now display view wiew_type
+        this.on('switch_view', this, function(view_type) {
             if (view_type === 'form' && this.active_view && this.active_view.type === 'form') {
                 this._display_view(view_type);
             } else {
@@ -114,17 +94,85 @@ var ViewManager = Widget.extend({
 
         this.$el.addClass("oe_view_manager_" + ((this.action && this.action.target) || 'current'));
 
-        // Insert ControlPanel in the DOM
-        var cp_loaded = this.control_panel.prependTo(this.$el);
-        var main_view_loaded = this.switch_mode(default_view, null, default_options);
+        if (this.cp_bus) {
+            // Tell the ControlPanel to setup its search view
+            this.search_view_loaded = $.Deferred();
+            this.cp_bus.trigger('setup_search_view', this, this.action, this.dataset, this.flags);
+            $.when(this.search_view_loaded).then(function() {
+                self.searchview.on('search_data', self, self.search);
+            });
+
+            // Tell the ControlPanel to render and append the (switch-)buttons to the DOM
+            this.cp_bus.trigger('render_buttons', this.views);
+            this.cp_bus.trigger('render_switch_buttons', this.view_order);
+        }
+
+        _.each(this.views, function (view) {
+            // Expose buttons, sidebar and pager elements to the views so that they can insert stuff in them
+            view.options = _.extend(view.options, {
+                $buttons : self.$ext_buttons ? self.$ext_buttons.find('.oe-' + view.type + '-buttons') : undefined,
+                $sidebar : self.$ext_sidebar,
+                $pager : self.$ext_pager,
+            }, self.flags, self.flags[view.type], view.options);
+        });
+
+        // Switch to the default_view to load it
+        this.main_view_loaded = this.switch_mode(default_view, null, default_options);
 
-        return $.when(main_view_loaded, cp_loaded);
+        return $.when(self.main_view_loaded, this.search_view_loaded);
+    },
+    /**
+     * Sets the external nodes in which the ViewManager and its views should insert elements
+     * @param {Object} [nodes] a dictionnary of jQuery nodes
+     */
+    set_external_nodes: function(nodes) {
+        this.$ext_buttons = nodes.$buttons;
+        this.$ext_sidebar = nodes.$sidebar;
+        this.$ext_pager = nodes.$pager;
     },
     /**
-     * Needed for dashboard.js to add Favorites to Dashboard
+     * Executed by the ControlPanel when the searchview requested by this ViewManager is loaded
+     * @param {Widget} [searchview] the SearchView
+     * @param {Deferred} [search_view_loaded_def] will be resolved when the SearchView is loaded
      */
-    get_searchview: function() {
-        return this.control_panel.searchview;
+    set_search_view: function(searchview, search_view_loaded_def) {
+        this.searchview = searchview;
+        this.search_view_loaded = search_view_loaded_def;
+    },
+    /**
+     * Executed on event "search_data" thrown by the SearchView
+     */
+    search: function(domains, contexts, groupbys) {
+        var self = this,
+            controller = this.active_view.controller, // AAB: Correct view must be loaded here
+            action_context = this.action.context || {},
+            view_context = controller.get_context();
+        pyeval.eval_domains_and_contexts({
+            domains: [this.action.domain || []].concat(domains || []),
+            contexts: [action_context, view_context].concat(contexts || []),
+            group_by_seq: groupbys || []
+        }).done(function (results) {
+            if (results.error) {
+                self.active_search.resolve();
+                throw new Error(
+                        _.str.sprintf(_t("Failed to evaluate search criterions")+": \n%s",
+                                      JSON.stringify(results.error)));
+            }
+            self.dataset._model = new Model(
+                self.dataset.model, results.context, results.domain);
+            var groupby = results.group_by.length
+                        ? results.group_by
+                        : action_context.group_by;
+            if (_.isString(groupby)) {
+                groupby = [groupby];
+            }
+            if (!controller.grouped && !_.isEmpty(groupby)){
+                self.dataset.set_sort([]);
+            }
+            $.when(controller.do_search(results.domain, results.context, groupby || [])).then(function() {
+                self.active_search.resolve();
+            });
+        });
     },
     get_default_view: function() {
         return this.flags.default_view || this.view_order[0].type;
@@ -147,15 +195,22 @@ var ViewManager = Widget.extend({
             if (this.active_view.controller) this.active_view.controller.do_hide();
             if (this.active_view.$container) this.active_view.$container.hide();
         }
-        this.active_view = this.control_panel.active_view = view;
+        this.active_view = view;
 
         if (!view.created) {
             view.created = this.create_view.bind(this)(view, view_options);
         }
-        // Tell the ControlPanel to call do_search on its searchview
-        var active_search = this.control_panel.activate_search(view.created);
 
-        return $.when(view.created, active_search).done(function () {
+        // Call do_search on the searchview to compute domains, contexts and groupbys
+        if (this.searchview &&
+                this.flags.auto_search &&
+                view.controller.searchable !== false) {
+            this.active_search = $.Deferred();
+            $.when(this.search_view_loaded, view.created).done(function() {
+                self.searchview.do_search();
+            });
+        }
+        return $.when(view.created, this.active_search).done(function () {
             self._display_view(view_options);
             self.trigger('switch_mode', view_type, no_store, view_options);
         });
@@ -165,17 +220,21 @@ var ViewManager = Widget.extend({
         this.active_view.$container.show();
         $.when(this.active_view.controller.do_show(view_options)).done(function () {
             // Tell the ControlPanel to update its elemnts
-            self.control_panel.update(self.active_view);
+            if (self.cp_bus) {
+                var search_view_hidden = self.active_view.controller.searchable === false;
+                var breadcrumbs = self.action_manager.get_breadcrumbs();
+                self.cp_bus.trigger("update", self.active_view, search_view_hidden, breadcrumbs);
+            }
         });
     },
     create_view: function(view, view_options) {
         var self = this,
-            View = this.registry.get_object(view.type),
+            View = this.registry.get(view.type),
             options = _.clone(view.options),
             view_loaded = $.Deferred();
 
-        if (view.type === "form" && ((this.action && (this.action.target === 'new' || this.action.target === 'inline')) ||
-                (view_options && view_options.mode === 'edit'))) {
+        if (view.type === "form" && ((this.action && (this.action.target === 'new' || this.action.target === 'inline'))
+                || (view_options && view_options.mode === 'edit'))) {
             options.initial_mode = 'edit';
         }
         var controller = new View(this, this.dataset, view.view_id, options),
@@ -193,7 +252,10 @@ var ViewManager = Widget.extend({
             if (self.action_manager) self.action_manager.trigger('history_back');
         });
         controller.on("change:title", this, function() {
-            self.control_panel.update_breadcrumbs();
+            if (self.cp_bus) {
+                var breadcrumbs = self.action_manager.get_breadcrumbs();
+                self.cp_bus.trigger("update_breadcrumbs", breadcrumbs);
+            }
         });
         controller.on('view_loaded', this, function () {
             view_loaded.resolve();
diff --git a/addons/web/static/src/js/views/search_menus.js b/addons/web/static/src/js/views/search_menus.js
index 54d83ba8f78a67b0f00ae8b692747ba7d4808ab6..0860c8aa553f98034c843a13a78b1c0fd7618398 100644
--- a/addons/web/static/src/js/views/search_menus.js
+++ b/addons/web/static/src/js/views/search_menus.js
@@ -37,7 +37,7 @@ return Widget.extend({
         this.$save_name = this.$('.oe-save-name');
         this.$inputs = this.$save_name.find('input');
         this.$divider = this.$('.divider');
-        this.$inputs.eq(0).val(this.searchview.getParent().title);
+        this.$inputs.eq(0).val(this.searchview.get_title());
         var $shared_filter = this.$inputs.eq(1),
             $default_filter = this.$inputs.eq(2);
         $shared_filter.click(function () {$default_filter.prop('checked', false);});
diff --git a/addons/web/static/src/js/views/search_view.js b/addons/web/static/src/js/views/search_view.js
index af18bdea9aca8fb8c00742c6af4fec06bbcb2045..6e78e69b46622532c59502e5ab097fdb593f0571 100644
--- a/addons/web/static/src/js/views/search_view.js
+++ b/addons/web/static/src/js/views/search_view.js
@@ -376,6 +376,7 @@ var SearchView = Widget.extend(/** @lends instance.web.SearchView# */{
         this.query = undefined;
         this.dataset = dataset;
         this.view_id = view_id;
+        this.title = options.action && options.action.name;
         this.search_fields = [];
         this.filters = [];
         this.groupbys = [];
@@ -411,6 +412,9 @@ var SearchView = Widget.extend(/** @lends instance.web.SearchView# */{
             .toggleClass('fa-caret-up', this.visible_filters);
         return this.alive($.when(this._super(), this.alive(load_view).then(this.view_loaded.bind(this))));
     },
+    get_title: function() {
+        return this.title;
+    },
     view_loaded: function (r) {
         var custom_filters_ready;
         this.fields_view_get = r;
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 3758aec3366a54399a03f22f3f32614756550685..d148ce2f17a90039409cf07ddf7134bbce1c2fb5 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -225,7 +225,6 @@
                         </td>
                     </tr>
                     <tr>
-                        <td><label for="backup_pwd">Master Password:</label></td>
                         <td><input type="password" name="backup_pwd" class="required" /></td>
                     </tr>
                 </table>
@@ -470,42 +469,45 @@
 <div t-name="ActionManager" class="oe_application" />
 
 <t t-name="ControlPanel">
-    <div class="oe-control-panel container-fluid">
-        <div class="row">
-            <div class="col-md-6 oe-cp-title">
-                <div t-if="widget.debug" class="oe_debug_view btn-group btn-group-sm"/>
-                <ol class="oe-view-title breadcrumb" t-if="widget.flags.display_title !== false">
-                </ol>
-            </div>
-            <div class="oe-cp-search-view col-md-6" />
-        </div>
-        <div class="row">
-            <div class="col-md-6 oe-button-column">
-                <div class="oe-cp-buttons">
-                    <t t-foreach="widget.views" t-as="view">
-                        <div t-attf-class="oe-#{view}-buttons"/>
-                    </t>
+    <div class="oe-control-panel">
+        <div class="container-fluid">
+            <div class="row">
+                <div class="col-md-6 oe-cp-title">
+                    <div t-if="widget.debug" class="oe_debug_view btn-group btn-group-sm"/>
+                    <ol class="oe-view-title breadcrumb">
+                    </ol>
                 </div>
-                <div class="oe-cp-sidebar"></div>
+                <div class="oe-cp-search-view col-md-6" />
             </div>
-            <div class="col-md-6">
-                <div class="oe-search-options btn-group"/>
-                <div class="oe-right-toolbar">
-                    <div class="oe-cp-pager"></div>
-                    <t t-if="widget.multiple_views">
-                        <div class="oe-cp-switch-buttons btn-group btn-group-sm">
-                            <t t-foreach="widget.view_order" t-as="view">
-                                <button type="button" t-attf-class="btn btn-default fa oe-cp-switch-#{view.type}" t-att-data-view-type="view.type" t-att-title="view.label">
-                                </button>
-                            </t>
-                        </div>
-                    </t>
+            <div class="row">
+                <div class="col-md-6 oe-button-column">
+                    <div class="oe-cp-buttons"></div>
+                    <div class="oe-cp-sidebar"></div>
+                </div>
+                <div class="col-md-6">
+                    <div class="oe-search-options btn-group"/>
+                    <div class="oe-right-toolbar">
+                        <div class="oe-cp-pager"></div>
+                        <div class="oe-cp-switch-buttons btn-group btn-group-sm"></div>
+                    </div>
                 </div>
             </div>
         </div>
     </div>
 </t>
 
+<t t-name="ControlPanel.buttons">
+    <t t-foreach="views" t-as="view">
+        <div t-attf-class="oe-#{view}-buttons"/>
+    </t>
+</t>
+
+<t t-name="ControlPanel.switch-buttons">
+    <t t-foreach="views" t-as="view">
+        <button type="button" t-attf-class="btn btn-default fa oe-cp-switch-#{view.type}" t-att-data-view-type="view.type" t-att-title="view.label"/>
+    </t>
+</t>
+
 <div t-name="ViewManager" class="oe-view-manager">
     <div class="oe-view-manager-content">
         <t t-foreach="widget.views" t-as="view">