diff --git a/FEATURES/59497 b/FEATURES/59497
new file mode 100644
index 0000000000000000000000000000000000000000..daecd729c3c6399d141b7e4eb18e263bf266fb6f
--- /dev/null
+++ b/FEATURES/59497
@@ -0,0 +1,10 @@
+        '59497' =>
+            ['Label' => $this->_('Sélection multiple de notices pour impression, export et sauvegarde'),
+             'Desc' => $this->_('Ajoutez librement des notices dans une sélection temporaire'),
+             'Image' => '',
+             'Video' => 'https://youtu.be/9vFTH2NcdGk',
+             'Category' => $this->_('Recherche'),
+             'Right' => function($feature_description, $user) {return true;},
+             'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=S%C3%A9lection_de_notices_dans_un_r%C3%A9sultat_de_recherche',
+             'Test' => '',
+             'Date' => '2018-09-25'],
\ No newline at end of file
diff --git a/VERSIONS_WIP/59497 b/VERSIONS_WIP/59497
new file mode 100644
index 0000000000000000000000000000000000000000..c750530d00e0bccb2411cda97005f3c07e9eb685
--- /dev/null
+++ b/VERSIONS_WIP/59497
@@ -0,0 +1 @@
+ - ticket #59497 : Sélection multiple de notices pour impression, export et sauvegarde
\ No newline at end of file
diff --git a/application/modules/opac/controllers/PanierController.php b/application/modules/opac/controllers/PanierController.php
index b5e5e366dcd432de5e1ee147c75d8d1634089c57..d32ce2de1e9e11f7f34387b53c7ad02ddc87deb9 100644
--- a/application/modules/opac/controllers/PanierController.php
+++ b/application/modules/opac/controllers/PanierController.php
@@ -97,34 +97,37 @@ class PanierController extends ZendAfi_Controller_Action {
 
 
   public function addAction() {
-    $this->_prepareAdd($this->view->url(['controller' => 'panier',
-                                         'action' => 'add']),
-                       function() {
-                                     return $this->_redirect($this->view->absoluteUrl(['action' => 'index',
-                                                                                       'render' => null,
-                                                                                       'id_panier' => null]));
-                                   });
+    $this->_addFormAndSave(['controller' => 'panier',
+                            'action' => 'add'],
+
+                           ['controller' => 'panier',
+                            'action' => 'index',
+                            'render' => null,
+                            'id_panier' => null]);
   }
 
 
   public function addAjaxAction() {
-    $this->_prepareAdd($this->view->url(['controller' => 'panier',
-                                         'action' => 'add-ajax']),
-                       function() {
-                                     return $this->_redirect($this->view->absoluteUrl(['action' => 'add-record-ajax',
-                                                                                       'render' => null,
-                                                                                       'id_panier' => null]));
-                                   });
+    $after_save_url = ['controller' => 'panier',
+                       'action' => $this->_getParam('selection') ? 'add-selection' : 'add-record-ajax',
+                       'render' => null,
+                       'selection' => null,
+                       'id_panier' => null];
+
+    $this->_addFormAndSave(['controller' => 'panier',
+                            'action' => 'add-ajax'],
+
+                           $after_save_url);
   }
 
 
-  protected function _prepareAdd($action, $callback) {
+  protected function _addFormAndSave($action, $after_save_url) {
     $this->view->titre = $this->view->_('Créer un panier');
     $this->view->form = ZendAfi_Form_Panier::newWith($this->_request->getParams());
-    $this->view->form->setAction($action);
+    $this->view->form->setAction($this->view->url($action));
 
     if($this->saveModelWithForm(Class_PanierNotice::newForUser($this->_user), $this->view->form)) {
-      call_user_func($callback);
+      $this->_redirect($this->view->url($after_save_url));
     }
   }
 
@@ -158,9 +161,14 @@ class PanierController extends ZendAfi_Controller_Action {
 
   public function switchAjaxAction() {
     return $this->_switchAndRedirect('switch-ajax',
-                                     $this->view->absoluteUrl(['action' => 'add-record-ajax',
-                                                               'render' => null,
-                                                               'id_panier' => null]));
+
+                                     ['controller' => 'panier',
+                                      'action' => ($this->_getParam('selection')
+                                                   ? 'add-selection'
+                                                   : 'add-record-ajax'),
+                                      'render' => null,
+                                      'selection' => null,
+                                      'id_panier' => null]);
   }
 
 
@@ -184,7 +192,7 @@ class PanierController extends ZendAfi_Controller_Action {
     }
 
     return $url
-      ? $this->_redirect($url)
+      ? $this->_redirect($this->view->url($url))
       : $this->_redirectClose($this->_getReferer());
   }
 
@@ -200,6 +208,30 @@ class PanierController extends ZendAfi_Controller_Action {
   }
 
 
+  public function addSelectionAction() {
+    $this->view->titre = $this->_('Mettre la sélection dans un panier');
+
+    if(!$this->_user)
+      return $this->_forward('popup-login', 'auth', 'opac', ['redirect' => $this->view->url()]);
+
+    $this->view->panier = $panier = $this->_user->getPanierCourant();
+
+    if (!$this->_request->isPost())
+      return;
+
+    $records = Class_Notice::findAllBy(['id_notice' => (new Class_RecordSelection)->values()]);
+    array_map(function($record) use($panier) { $panier->addNotice($record); },
+              $records);
+
+    $panier->save();
+    $panier->index();
+
+    $this->_helper->notify($this->_('Sélection ajoutée dans le panier "%s"', $panier->getLibelle()));
+
+    $this->_redirectClose($this->_getReferer());
+  }
+
+
   public function addRecordAjaxAction() {
     $this->view->titre = $popup_title = $this->_('Ajouter un document dans un panier');
 
diff --git a/application/modules/opac/controllers/RechercheController.php b/application/modules/opac/controllers/RechercheController.php
index 849d7061d867fd21072d1af7f8627698f766627c..86188d06a74153d603f06d076e68f1de217d9d61 100644
--- a/application/modules/opac/controllers/RechercheController.php
+++ b/application/modules/opac/controllers/RechercheController.php
@@ -39,7 +39,7 @@ class RechercheController extends ZendAfi_Controller_Action {
 
 
   public function getPlugins() {
-    return ['ZendAfi_Controller_Plugin_Printer_ModelFusion',
+    return ['ZendAfi_Controller_Plugin_Printer_SearchResult',
             'ZendAfi_Controller_Plugin_Mailer_SearchResult'];
   }
 
@@ -140,7 +140,13 @@ class RechercheController extends ZendAfi_Controller_Action {
     if ('atom' == $this->_getParam('format', ''))
       return $this->_renderAtomResult($search_result);
 
-    $this->preferences['liste_format'] = $this->_getParam('liste_format', $this->preferences['liste_format']);
+    $this->preferences['liste_format'] = $this->_getParam('liste_format',
+                                                          $this->preferences['liste_format']);
+
+    if (Class_AdminVar::isModuleEnabled('ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION')) {
+      $this->preferences['display_add_to_cart'] = false;
+      $this->preferences['display_select_record'] = true;
+    }
 
     $this->view->titre = $this->getTitreRechercheSimple($criteres_recherche);
 
diff --git a/application/modules/opac/controllers/RecordsController.php b/application/modules/opac/controllers/RecordsController.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d3530daeedc9c26ae0029b43405527ffdf5e649
--- /dev/null
+++ b/application/modules/opac/controllers/RecordsController.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class RecordsController extends ZendAfi_Controller_Action {
+  protected $_selection;
+
+  public function preDispatch() {
+    parent::preDispatch();
+    $this->_selection = new Class_RecordSelection();
+  }
+
+
+  public function selectToggleAction() {
+    $this->_selection->toggle(Class_Notice::find($this->_getParam('id')));
+    $this->_helper->json(['count' => $this->_selection->count()]);
+  }
+
+
+  public function selectClearAction() {
+    $this->_selection->clear();
+    $this->_helper->json(['count' => $this->_selection->count()]);
+  }
+
+
+  public function selectPageAction() {
+    $this->_selection->addAll($this
+                              ->_helper
+                              ->searchRecords()
+                              ->fetchRecords());
+    $this->_helper->json(['count' => $this->_selection->count()]);
+  }
+
+
+  public function selectAllAction() {
+    $this->_selection->addAllIds($this
+                                 ->_helper
+                                 ->searchRecords()
+                                 ->fetchAllRecordsIds());
+    $this->_helper->json(['count' => $this->_selection->count()]);
+  }
+
+
+  public function selectViewAction() {
+
+  }
+}
diff --git a/application/modules/opac/views/scripts/panier/add-record-ajax.phtml b/application/modules/opac/views/scripts/panier/add-record-ajax.phtml
index a5174c12336d80d4c1e279c4eea5ffb4e9639db8..28a5e0ef3b7d89ca783d90d104ddd9e93cb44cb0 100644
--- a/application/modules/opac/views/scripts/panier/add-record-ajax.phtml
+++ b/application/modules/opac/views/scripts/panier/add-record-ajax.phtml
@@ -20,7 +20,7 @@ echo $this->tag('div',
                            $this->_('Ajouter %s au panier %s ?',
                                     $this->tag('b',  $this->notice->getTitrePrincipal()),
                                     $this->tag('b', $this->panier->getLibelle())),
-                ['class' => 'center'])
+                           ['class' => 'center'])
                 . $actions);
 
 
diff --git a/application/modules/opac/views/scripts/panier/add-selection.phtml b/application/modules/opac/views/scripts/panier/add-selection.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..16548345ae66b638107bc8a03a5a13242dbf0178
--- /dev/null
+++ b/application/modules/opac/views/scripts/panier/add-selection.phtml
@@ -0,0 +1,32 @@
+<?php
+$actions = $this->tag('div', $this->tagAnchor($this->url(['controller' => 'panier',
+                                                          'action' => 'add-ajax',
+                                                          'selection' => '1']),
+                                              $this->_('Nouveau panier'),
+                                              ['class' => 'bouton',
+                                               'data-popup' => 'true']) .
+
+                      $this->tagAnchor($this->url(['controller' => 'panier',
+                                                   'action' => 'switch-ajax',
+                                                   'id_panier' => $this->panier->getId(),
+                                                   'selection' => '1']),
+                                       $this->_('Changer de panier'),
+                                       ['class' => 'bouton',
+                                        'data-popup' => 'true']),
+                      ['class' => 'boutons']);
+
+echo $this->tag('div',
+                $this->tag('p',
+                           $this->_('Ajouter ma sélection au panier "%s" ?',
+                                    $this->panier->getLibelle()),
+                           ['class' => 'center'])
+                                     . $actions);
+
+echo $this->renderForm(ZendAfi_Form::newWith([])
+                     ->setAction($this->url(['controller'=>'panier',
+                                             'action'=>'add-selection',
+                                             'id_panier'=>$this->panier->getId()],
+                                            null,
+                                            true)));
+
+?>
diff --git a/application/modules/opac/views/scripts/recherche/viewnotice.phtml b/application/modules/opac/views/scripts/recherche/viewnotice.phtml
index 5582487bd6749f03d8d7d0f718fe0870564dba87..86b0313a47c2e7802f37905cdfee8154d9a1b1f2 100644
--- a/application/modules/opac/views/scripts/recherche/viewnotice.phtml
+++ b/application/modules/opac/views/scripts/recherche/viewnotice.phtml
@@ -18,9 +18,13 @@ $script_loader = Class_ScriptLoader::getInstance()
     ['title' => $this->_('Retourner au résultat de recherche'),
      'class' => 'retour']);
 
-  echo $this->tagPrintLink((new Class_Entity())
-         ->setModels([$this->notice])
-         ->setStrategy('Notice_View'));
+  echo Class_ModeleFusion::canPrintRecordInProfile(Class_Profil::getCurrentProfil())
+    ? $this->tagAnchor(['controller' => 'recherche',
+                        'action' => 'print'],
+                       $this->_('Imprimer'),
+                       ['title' => $this->_('Imprimer "%s"', $this->notice->getTitrePrincipal()),
+                        'target' => '_blank'])
+    : '';
 
 	echo $this->tagAnchor($this->url_panier,
 												$this->_('Ajouter au panier'),
diff --git a/library/Class/AdminVar.php b/library/Class/AdminVar.php
index c401ec3d770e5428c4f77a8784f83471b034fc94..af9aca4a2baad7a2ee738ec4cbeaf83a90d6d44a 100644
--- a/library/Class/AdminVar.php
+++ b/library/Class/AdminVar.php
@@ -241,18 +241,27 @@ class Class_AdminVarLoader extends Storm_Model_Loader {
 
 
   protected function _getSearchVars() {
-    return ['SEARCH_PAGINATE_POSITION' => Class_AdminVar_Meta::newCombo($this->_('Position de la pagination en résultat de recherche'),
-                                                                        ['options' => ['selectOptions' => ['label' => $this->_('Position'),
-                                                                                                           'multioptions' => ['BOTTOM' => 'en bas', 'TOP' => 'en haut', 'BOTH' => 'en haut et en bas']]]]),
-            'EXTENDED_SEARCH' => Class_AdminVar_Meta::newOnOff($this->_('Etendre automatiquement le résultat de recherche en rajoutant des "OU" entre les mots saisis'), ['value' => 1]),
-            'AFFICHER_DISPONIBILITE_SUR_RECHERCHE' => Class_AdminVar_Meta::newOnOff($this->_('Activation de la disponibilite dans le resultat de recherche au survol de la couverture du document, calculé en temps réel.')),
-            'AFFICHER_DISPONIBILITE_SUR_RECHERCHE_MODE_FACETTE' => Class_AdminVar_Meta::newOnOff($this->_('Activation de la disponibilite dans le resultat de recherche. Calculé grâce à la facette "En rayon".')),
-            'SEARCH_ALSO_IN' => Class_AdminVar_Meta::newMultiInput($this->_('Liste des sites de recherche élargie (la chaine \'%s\' dans l\'url sera remplacée par le terme de recherche)'),
-                                                                   [ 'options' => ['fields' => [['name' => 'site_label', 'label' => $this->_('Nom du site')],
-                                                                                                ['name' => 'site_url', 'label' => $this->_('Url de recherche')] ]]]),
-            'NOM_DOMAINE' => Class_AdminVar_Meta::newDefault($this->_('Nom de domaine principal de l\'OPAC, ex: monopac.macommune.fr')),
-
-            'CUSTOM_SEARCH_FORM' => Class_AdminVar_Meta::newOnOff($this->_('Activer les formulaires de recherche configurables'))->bePrivate()];
+    return
+      [
+       'SEARCH_PAGINATE_POSITION' => Class_AdminVar_Meta::newCombo($this->_('Position de la pagination en résultat de recherche'),
+                                        ['options' => ['selectOptions' => ['label' => $this->_('Position'),
+                                                                           'multioptions' => ['BOTTOM' => 'en bas',
+                                                                                              'TOP' => 'en haut',
+                                                                                              'BOTH' => 'en haut et en bas']]]]),
+
+       'EXTENDED_SEARCH' => Class_AdminVar_Meta::newOnOff($this->_('Etendre automatiquement le résultat de recherche en rajoutant des "OU" entre les mots saisis'),
+                                                          ['value' => 1]),
+
+       'AFFICHER_DISPONIBILITE_SUR_RECHERCHE' => Class_AdminVar_Meta::newOnOff($this->_('Activation de la disponibilite dans le resultat de recherche au survol de la couverture du document, calculé en temps réel.')),
+       'AFFICHER_DISPONIBILITE_SUR_RECHERCHE_MODE_FACETTE' => Class_AdminVar_Meta::newOnOff($this->_('Activation de la disponibilite dans le resultat de recherche. Calculé grâce à la facette "En rayon".')),
+       'SEARCH_ALSO_IN' => Class_AdminVar_Meta::newMultiInput($this->_('Liste des sites de recherche élargie (la chaine \'%s\' dans l\'url sera remplacée par le terme de recherche)'),
+                                                              [ 'options' => ['fields' => [['name' => 'site_label', 'label' => $this->_('Nom du site')],
+                                                                                           ['name' => 'site_url', 'label' => $this->_('Url de recherche')] ]]]),
+       'NOM_DOMAINE' => Class_AdminVar_Meta::newDefault($this->_('Nom de domaine principal de l\'OPAC, ex: monopac.macommune.fr')),
+
+       'CUSTOM_SEARCH_FORM' => Class_AdminVar_Meta::newOnOff($this->_('Activer les formulaires de recherche configurables'))->bePrivate(),
+       'ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION' => Class_AdminVar_Meta::newOnOff($this->_('Activer la sélection multiple de notices dans le résultat de recherche'))
+      ];
   }
 
 
diff --git a/library/Class/CollectionFusion.php b/library/Class/CollectionFusion.php
index a480dd02718b43bc7b0a250ebfe588501c10b930..912975af979e71a3749d897592c1274a2de9a665 100644
--- a/library/Class/CollectionFusion.php
+++ b/library/Class/CollectionFusion.php
@@ -25,7 +25,7 @@ class Class_CollectionFusion extends Storm_Model_Abstract{
 
 
   public function __construct($elements) {
-    $this->_elements=$elements;
+    $this->_elements = array_filter($elements);
   }
 
 
@@ -38,4 +38,3 @@ class Class_CollectionFusion extends Storm_Model_Abstract{
     return '<div style="brackground:red;padding:50px;width:100%;height:100%;"></div>';
   }
 }
-?>
\ No newline at end of file
diff --git a/library/Class/CriteresRecherche.php b/library/Class/CriteresRecherche.php
index f735b5ae7e25ad5fcf4a8ec138780db0a3214503..6005e19285bd216aad980be17d858a8c8d2feff4 100644
--- a/library/Class/CriteresRecherche.php
+++ b/library/Class/CriteresRecherche.php
@@ -128,7 +128,8 @@ class Class_CriteresRecherche {
                         'fil',
                         'bib_select',
                         'serie',
-                        'from']);
+                        'from',
+                        'selection']);
   }
 
 
@@ -266,6 +267,7 @@ class Class_CriteresRecherche {
   public function getFiltres() {
     $filtres = [];
     if (!$this->isRecherchePanier()
+        && !$this->isSelection()
         && !$this->isRechercheCatalogueEmpty()
         && $this->_profil) {
       $filtres = array_merge($filtres,
@@ -385,6 +387,13 @@ class Class_CriteresRecherche {
   }
 
 
+  public function getSelection() {
+    return $this->isSelection()
+      ? new Class_RecordSelection()
+      : null;
+  }
+
+
   public function visitCatalogue($visitor, $catalogue) {
     $visitor->visitCatalogue($catalogue);
 
@@ -465,8 +474,20 @@ class Class_CriteresRecherche {
   }
 
 
-  public function isRechercheCatalogueOuPanier() {
-    return ($this->isRechercheCatalogue() || $this->isRecherchePanier());
+  public function isSelection() {
+    return (bool)$this->getParam('selection');
+  }
+
+
+  public function isEmptySelection() {
+    return $this->isSelection() && $this->getSelection()->isEmpty();
+  }
+
+
+  public function isRechercheCatalogueOuPanierOuSelection() {
+    return $this->isRechercheCatalogue()
+      || $this->isRecherchePanier()
+      || $this->isSelection();
   }
 
 
@@ -476,7 +497,7 @@ class Class_CriteresRecherche {
 
 
   public function visitPanierCatalogue($visitor) {
-    if (!$this->isRechercheCatalogueOuPanier())
+    if (!$this->isRechercheCatalogueOuPanierOuSelection())
       return $this;
 
     if ($catalogue = $this->getCatalogue()) {
@@ -489,6 +510,11 @@ class Class_CriteresRecherche {
       return $this;
     }
 
+    if ($selection = $this->getSelection()) {
+      $visitor->visitSelection($selection);
+      return $this;
+    }
+
     $visitor->setErreur($this->_('La sélection ne contient aucune notice'));
     return $this;
   }
diff --git a/library/Class/ModeleFusion.php b/library/Class/ModeleFusion.php
index fd129a3839f6a50067eeb5fbc17272fb039f6014..478fdc983a88f066546cbde476da9b5f38e28285 100644
--- a/library/Class/ModeleFusion.php
+++ b/library/Class/ModeleFusion.php
@@ -43,8 +43,20 @@ class Class_ModeleFusionLoader extends Storm_Model_Loader {
 
 
   public function getFusionForStrategy($strategy) {
-    return $this->findFirstBy(['type' => $strategy,
-                               'profil_ids' => '']);
+    return Class_ModeleFusion::findFirstBy(['type' => $strategy,
+                                            'profil_ids' => '']);
+  }
+
+
+  public function canPrintRecordsInProfile($profile) {
+    return null !== Class_ModeleFusion::getFusionForStrategyAndProfilOrDefault(Class_ModeleFusion::RECORDS_TEMPLATE,
+                                                                               $profile);
+  }
+
+
+  public function canPrintRecordInProfile($profile) {
+    return null !== Class_ModeleFusion::getFusionForStrategyAndProfilOrDefault(Class_ModeleFusion::RECORD_TEMPLATE,
+                                                                               $profile);
   }
 
 
@@ -59,14 +71,26 @@ class Class_ModeleFusionLoader extends Storm_Model_Loader {
   }
 
 
+  public function getFusionForStrategyAndProfilOrDefault($strategy, $profil) {
+    if ($model_fusion  = Class_ModeleFusion::getFusionForStrategyAndProfil($strategy,
+                                                                           $profil->getId()))
+      return $model_fusion;
+
+    return Class_ModeleFusion::getFusionForStrategy($strategy);
+  }
+
+
   public function getFusionForStrategyAndProfil($strategy,$id_profil) {
-    $models =array_filter($this->findAllBy(['type' => $strategy]),
-                          function($model) use ($id_profil) {
-                                                               if (!$ids=$model->getProfilIds())
-                                                                 return false;
-                                                               if (in_array($id_profil,explode(';',$ids)))
-                                                                 return $model;
-                                                             });
+    $models = array_filter(
+                           Class_ModeleFusion::findAllBy(['type' => $strategy]),
+                           function($model) use ($id_profil) {
+                             if (!$ids=$model->getProfilIds())
+                               return false;
+
+                             if (in_array($id_profil,explode(';',$ids)))
+                               return $model;
+                           });
+
     return reset($models);
   }
 
@@ -81,7 +105,7 @@ class Class_ModeleFusionLoader extends Storm_Model_Loader {
 
 
   public function getTemplates() {
-    if ($models= Class_ModeleFusion::findAll())
+    if ($models = Class_ModeleFusion::findAll())
       return array_filter($models, function($model)
                           {
                             return !$model->isForActivity();
@@ -128,7 +152,8 @@ class Class_ModeleFusion extends Storm_Model_Abstract {
     RECORD_TEMPLATE = 'Notice_View',
     LOANS_TEMPLATE = 'Loans_List';
 
-  protected $_table_name = 'modele_fusion',
+  protected
+    $_table_name = 'modele_fusion',
     $_loader_class = 'Class_ModeleFusionLoader',
     $_table_primary = 'id',
     $_default_attribute_values = ['nom' => '',
diff --git a/library/Class/MoteurRecherche.php b/library/Class/MoteurRecherche.php
index 2b8b62063ae00227a7b6e8f28e8b159bea7d0d37..de281f3fb37246a41eb68a4b63fa372fd8180a73 100644
--- a/library/Class/MoteurRecherche.php
+++ b/library/Class/MoteurRecherche.php
@@ -443,11 +443,17 @@ class Class_MoteurRecherche {
     if ($this->all_facettes)
       $this->setCondition("MATCH(facettes) AGAINST('" . trim($this->all_facettes)."' IN BOOLEAN MODE)");
 
-    if($this->criteres_recherche->hasEmptyDomain() && !$this->criteres_recherche->isSearchInBasket()){
+    if($this->criteres_recherche->hasEmptyDomain()
+       && !$this->criteres_recherche->isSearchInBasket()){
       return ['statut' => 'erreur',
               'erreur' => $this->_('Domaine non paramétré')];
     }
 
+    if($this->criteres_recherche->isEmptySelection()){
+      return ['statut' => 'erreur',
+              'erreur' => $this->_('La sélection courante est vide')];
+    }
+
     return self::getConditionsForRequest($this->conditions, $this->_or_conditions, $this->_filter_domain_conditions);
   }
 
@@ -682,4 +688,12 @@ class Class_MoteurRecherche {
     if ($diff = array_diff($version->getData(), $previous->getData()))
       $this->setCondition('clef_alpha in (\'' . implode('\', \'', $diff) . '\')');
   }
+
+
+  public function visitSelection($selection) {
+    if (!$selection || $selection->isEmpty())
+      return;
+
+    $this->setCondition('id_notice in (' . implode(',', $selection->values()). ')');
+  }
 }
\ No newline at end of file
diff --git a/library/Class/RecordSelection.php b/library/Class/RecordSelection.php
new file mode 100644
index 0000000000000000000000000000000000000000..2efe35dd3e63be20f397e151bde21c132fe973cd
--- /dev/null
+++ b/library/Class/RecordSelection.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Class_RecordSelection {
+
+  protected function _getSelection() {
+    return (array)Zend_Registry::get('session')->search_record_selection;
+  }
+
+
+  protected function _setSelection($values) {
+    Zend_Registry::get('session')->search_record_selection = array_keys(array_flip($values));
+    return $this;
+  }
+
+
+  public function count() {
+    return count($this->_getSelection());
+  }
+
+
+  public function isEmpty() {
+    return 0 === $this->count();
+  }
+
+
+  public function values() {
+    return $this->_getSelection();
+  }
+
+
+  public function includes($record) {
+    return in_array($record->getId(), $this->_getSelection());
+  }
+
+
+  public function remove($record) {
+    return $this->_setSelection( array_diff($this->_getSelection(),
+                                            [$record->getId()]) );
+  }
+
+
+  public function add($record) {
+    return $this->addId($record->getId());
+  }
+
+
+  public function addAll($records) {
+    $ids = array_map(function($record) { return $record->getId(); },
+                     $records);
+    return $this->addAllIds($ids);
+  }
+
+
+  public function addAllIds($ids) {
+    return $this->_setSelection(array_merge($this->_getSelection(), $ids));
+  }
+
+
+  public function addId($id) {
+    $selection = $this->_getSelection();
+    $selection []= $id;
+    return $this->_setSelection($selection);
+  }
+
+
+  public function toggle($record) {
+    if (!$record)
+      return $this;
+
+    return $this->includes($record)
+      ? $this->remove($record)
+      : $this->add($record);
+  }
+
+
+  public function clear() {
+    $this->_setSelection([]);
+  }
+}
diff --git a/library/Class/Systeme/ModulesAppli.php b/library/Class/Systeme/ModulesAppli.php
index a540518b21f3a4d40453b337cedeb69fa9469746..3ba3de66167c1967bf126177b15368167e37cd96 100644
--- a/library/Class/Systeme/ModulesAppli.php
+++ b/library/Class/Systeme/ModulesAppli.php
@@ -25,7 +25,7 @@
 class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
   const ONGLETS_KEY     = 'onglets';
   const LISTE_FORMAT_TABLEAU = 1;
-  const LISTE_FORMAT_ACCORDEON = 2;
+  const LISTE_FORMAT_LIST = 2;
   const LISTE_FORMAT_VIGNETTES = 3;
   const LISTE_FORMAT_MUR = 4;
   const LISTE_FORMAT_CHRONO = 5;
@@ -155,7 +155,6 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
   public static function getAvailableListeNoticeFormat() {
     return
       [Class_Systeme_ModulesAppli::LISTE_FORMAT_TABLEAU => 'Tableau',
-       Class_Systeme_ModulesAppli::LISTE_FORMAT_ACCORDEON => 'Liste en mode accordéon',
        Class_Systeme_ModulesAppli::LISTE_FORMAT_VIGNETTES => 'Vignettes',
        Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR => 'Mur',
        Class_Systeme_ModulesAppli::LISTE_FORMAT_CHRONO => 'Chronologique'];
@@ -165,7 +164,7 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
   public static function getAvailableListeDomainsFormat() {
     return
       [
-       Class_Systeme_ModulesAppli::LISTE_FORMAT_ACCORDEON => 'Liste',
+       Class_Systeme_ModulesAppli::LISTE_FORMAT_LIST => 'Liste',
        Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR => 'Mur'
       ];
 
diff --git a/library/Trait/SearchCriteriaVisitor.php b/library/Trait/SearchCriteriaVisitor.php
index 46c4ddbd452a8df2c87e0c50f5c6722894036571..f52cd242d2a5cc3e7c15c54ff4adbaa0fab29cb9 100644
--- a/library/Trait/SearchCriteriaVisitor.php
+++ b/library/Trait/SearchCriteriaVisitor.php
@@ -46,6 +46,7 @@ trait Trait_SearchCriteriaVisitor {
   public function setErreur($error) {}
   public function visitSearchUrl($params) {}
   public function visitPanier($panier) {}
+  public function visitSelection($selection) {}
 
   public function visitFacetteDomainForOrConditions($catalog_id) {}
   public function visitFilterOnDomain($criteria) {}
diff --git a/library/ZendAfi/Controller/Action/Helper/SearchRecords.php b/library/ZendAfi/Controller/Action/Helper/SearchRecords.php
new file mode 100644
index 0000000000000000000000000000000000000000..c23518792803e77b427639a02e683c099ea07886
--- /dev/null
+++ b/library/ZendAfi/Controller/Action/Helper/SearchRecords.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Controller_Action_Helper_SearchRecords extends Zend_Controller_Action_Helper_Abstract {
+  public function searchRecords() {
+    $criteria = (new Class_CriteresRecherche())
+      ->setParams($this->getRequest()->getParams());
+
+    return Class_MoteurRecherche::getInstance()
+      ->lancerRecherche($criteria);
+  }
+
+
+  public function direct() {
+    return $this->searchRecords();
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Plugin/Mailer/SearchResult.php b/library/ZendAfi/Controller/Plugin/Mailer/SearchResult.php
index b50076ad2ac8a213ea718f915626409cbeb09872..68f548bc915826fa00af253e429e7b1ee4278a42 100644
--- a/library/ZendAfi/Controller/Plugin/Mailer/SearchResult.php
+++ b/library/ZendAfi/Controller/Plugin/Mailer/SearchResult.php
@@ -20,21 +20,50 @@
  */
 
 
-class ZendAfi_Controller_Plugin_Mailer_SearchResult extends ZendAfi_Controller_Plugin_Mailer_ModelFusion {
+class ZendAfi_Controller_Plugin_Mailer_SearchResult
+  extends ZendAfi_Controller_Plugin_Mailer_ModelFusion {
 
   protected function _getSubject() {
+    $term = $this->_getSelection()->isEmpty()
+      ? $this->_view->tagSearchTerm($this->_getCriteria(),
+                                    function($term) { return $term; })
+      : $this->_('dans ma sélection');
+
     return $this->_('%s : Documents %s',
                     Class_Profil::getCurrentProfil()->getTitreSite(),
-                    $this->_getParam('subject', parent::_getSubject()));
+                    $term);
+  }
+
+
+  protected function _getCriteria() {
+    return (new Class_CriteresRecherche())->setParams($this->_request->getParams());
+  }
+
+
+  protected function _getSelection() {
+    return new Class_RecordSelection();
   }
 
 
   protected function _getHtml() {
-    $criteria = (new Class_CriteresRecherche())->setParams($this->_request->getParams());
+    $model_fusion = Class_ModeleFusion::getFusionForStrategyAndProfilOrDefault(Class_ModeleFusion::RECORDS_TEMPLATE,
+                                                                               Class_Profil::getCurrentProfil());
+
+    if (!$ids = $this->_getSelection()->values())
+      $ids = $this->_helper->searchRecords()->fetchAllRecordsIds();
+
+    $params = (new Class_Entity)
+      ->setStrategy($model_fusion->getType())
+      ->setModelFusion($model_fusion->getId())
+      ->setIds(implode(';', array_slice($ids, 0, 200)));
+
+    $criteria = $this->_getCriteria();
+
     return $this->_view->tag('p',
-                             $this->_view->tagAnchor(Class_Url::absolute($criteria->getUrlRetourListe(), null, true),
+                             $this->_view->tagAnchor(Class_Url::absolute($this->_getCriteria()
+                                                                         ->getUrlRetourListe(),
+                                                                         null, true),
                                                      $this->_('Voir le résultat de recherche complet')))
-      . parent::_getHtml();
-
+      . $this->_view->tagModelFusion($params);
   }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Plugin/Printer/SearchResult.php b/library/ZendAfi/Controller/Plugin/Printer/SearchResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..0037e60454dac5b03d50a3c88e87090e9be382c8
--- /dev/null
+++ b/library/ZendAfi/Controller/Plugin/Printer/SearchResult.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Controller_Plugin_Printer_SearchResult
+  extends ZendAfi_Controller_Plugin_Printer_ModelFusion {
+
+  protected function _getPrinterConfig() {
+    return $this->_getParam('id')
+      ? $this->_getOnePrinterConfig()
+      : $this->_getManyPrinterConfig();
+  }
+
+
+  protected function _getOnePrinterConfig() {
+    $model_fusion = Class_ModeleFusion::getFusionForStrategyAndProfilOrDefault(Class_ModeleFusion::RECORD_TEMPLATE,
+                                                                               Class_Profil::getCurrentProfil());
+
+    return parent::_getPrinterConfig()
+      ->setStrategy($model_fusion->getType())
+      ->setModelFusion($model_fusion->getId())
+      ->setId($this->_getParam('id'));
+  }
+
+
+  protected function _getManyPrinterConfig() {
+    $model_fusion = Class_ModeleFusion::getFusionForStrategyAndProfilOrDefault(Class_ModeleFusion::RECORDS_TEMPLATE,
+                                                                               Class_Profil::getCurrentProfil());
+
+    if (!$ids = (new Class_RecordSelection())->values())
+      $ids = $this->_helper->searchRecords()->fetchAllRecordsIds();
+
+    return parent::_getPrinterConfig()
+      ->setStrategy($model_fusion->getType())
+      ->setModelFusion($model_fusion->getId())
+      ->setIds(implode(';', array_slice($ids, 0, 200)));
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/ListeNotices.php b/library/ZendAfi/View/Helper/ListeNotices.php
index a48e848c12f5ae69045bf17a89aec989a7b661fb..9c936f1bec935f59d10c3a659d42f0cc925d79de 100644
--- a/library/ZendAfi/View/Helper/ListeNotices.php
+++ b/library/ZendAfi/View/Helper/ListeNotices.php
@@ -23,7 +23,7 @@ class ZendAfi_View_Helper_ListeNotices extends ZendAfi_View_Helper_BaseHelper {
 
   public function listeNotices($search_result) {
     $criteres_recherche = $search_result->getCriteresRecherche();
-    $notices = $search_result->getRecords();
+    $notices = $search_result->fetchRecords();
     $nombre_resultats = $search_result->getRecordsCount();
     $page = $criteres_recherche->getPage();
     $preferences = $search_result->getSettings();
@@ -63,7 +63,6 @@ class ZendAfi_View_Helper_ListeNotices extends ZendAfi_View_Helper_BaseHelper {
 
   protected function _displayList($notices, $preferences) {
     $helpers = [Class_Systeme_ModulesAppli::LISTE_FORMAT_TABLEAU => 'ListeNotices_Tableau',
-                Class_Systeme_ModulesAppli::LISTE_FORMAT_ACCORDEON => 'ListeNotices_Accordeon',
                 Class_Systeme_ModulesAppli::LISTE_FORMAT_VIGNETTES => 'ListeNotices_Vignettes',
                 Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR => 'ListeNotices_Mur',
                 Class_Systeme_ModulesAppli::LISTE_FORMAT_CHRONO => 'ListeNotices_Chrono'];
diff --git a/library/ZendAfi/View/Helper/ListeNotices/Abstract.php b/library/ZendAfi/View/Helper/ListeNotices/Abstract.php
index 6059efda377aead92cd4e45e6cfc2d65d5da69d8..79595eabf9cb1baad7bf8c6161827f3104f5c7b5 100644
--- a/library/ZendAfi/View/Helper/ListeNotices/Abstract.php
+++ b/library/ZendAfi/View/Helper/ListeNotices/Abstract.php
@@ -20,6 +20,13 @@
  */
 abstract class ZendAfi_View_Helper_ListeNotices_Abstract extends ZendAfi_View_Helper_BaseHelper {
 
+  protected function _updatePreferences($preferences) {
+    return array_merge(['liste_codes' => 'TANE',
+                        'display_add_to_cart' => true,
+                        'display_select_record' => false],
+                       $preferences);
+  }
+
   protected function _divRecord($html, $record, $class) {
     return $this->_tag('div',
                        $html,
diff --git a/library/ZendAfi/View/Helper/ListeNotices/Accordeon.php b/library/ZendAfi/View/Helper/ListeNotices/Accordeon.php
deleted file mode 100644
index 61f376f7ee82d7ca299a3ff3bddd2035c1cc78e1..0000000000000000000000000000000000000000
--- a/library/ZendAfi/View/Helper/ListeNotices/Accordeon.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
- *
- * BOKEH is free software; you can redistribute it and/or modify
- * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
- * the Free Software Foundation.
- *
- * There are special exceptions to the terms and conditions of the AGPL as it
- * is applied to this software (see README file).
- *
- * BOKEH is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
- * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
- */
-class ZendAfi_View_Helper_ListeNotices_Accordeon extends ZendAfi_View_Helper_ListeNotices_Abstract {
-  public function listeNotices_Accordeon($data, $preferences=[]) {
-    // Javascripts pour affichage localisation
-    $html ='<link rel="stylesheet" type="text/css" media="screen" href="'.URL_ADMIN_JS.'slimbox/slimbox2.css">';
-    $html.='<link rel="stylesheet" type="text/css" media="screen" href="'.URL_ADMIN_JS.'jquery_ui/css/jquery.ui.all.css">';
-    $html.='<link rel="stylesheet" type="text/css" media="screen" href="'.URL_ADMIN_JS.'rating/jquery.rating.css">';
-
-    $html.='<script type="text/javascript" src="'.URL_ADMIN_JS.'slimbox/slimbox2.js"> </script>';
-    $html.='<script type="text/javascript" src="'.URL_ADMIN_JS.'rating/jquery.rating.pack.js"> </script>';
-
-    // Notices
-    $notice_html= new Class_NoticeHtml("");
-    $lig=0;
-    foreach ($data as $notice)  {
-        $html.='<table cellspacing="0" cellpadding="3" border="0" width="100%">';
-        if($lig % 2) $style_css="listeImpaire"; else $style_css="listePaire";
-        $div_notice="N".$notice->getId();
-        $type_doc = $notice->getTypeDoc();
-        $onclick="deployer_contracter('".$div_notice."');getNoticeAjax('".$div_notice."','".$div_notice."','".$type_doc."')";
-        $html.='<tr>';
-        $html.=sprintf('<td class="%s" width="10" style="text-align:center"><img id="I'.$div_notice.'" src="'.URL_IMG.'bouton/plus_carre.gif" border="0" onclick="%s" style="cursor:pointer" alt="%s"/></td>',
-                       $style_css,
-                       $onclick,
-                       $this->translate()->_('déplier'));
-
-        $html.=sprintf('<td class="%s" width="26" style="text-align:center">%s</td>',
-                       $style_css,
-                       $this->view->iconeSupport($type_doc));
-
-        $html.='<td class="'. $style_css .'" width="100%"><a href="#" onclick="'.$onclick.'">'.$notice->getTitrePrincipal().'</a>';
-        $html.=' / '.$notice->getAuteurPrincipal().'</td>';
-        $html.='</tr>';
-
-        // container notice
-        $patience=sprintf('<table><tr><td><img border="0" src="'.URL_IMG.'patience.gif" alt="%s" /></td><td>%s...</td></tr></table>',
-                          $this->translate()->_('Chargement en cours'),
-                          $this->translate()->_('Veuillez patienter : traitement en cours'));
-
-        $html.='<tr><td colspan="10">'.$notice_html->getConteneurNotice($notice->getId()).'</td></tr>';
-        $html.='</table>';
-      }
-    return $html.='</div>';
-  }
-}
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/ListeNotices/Mur.php b/library/ZendAfi/View/Helper/ListeNotices/Mur.php
index 77fd78699552bac5d70eed5e4265da185d4b297e..7f449efbc625190a51d6bcc2e437c884f5c84b3a 100644
--- a/library/ZendAfi/View/Helper/ListeNotices/Mur.php
+++ b/library/ZendAfi/View/Helper/ListeNotices/Mur.php
@@ -22,6 +22,7 @@ class ZendAfi_View_Helper_ListeNotices_Mur extends ZendAfi_View_Helper_ListeNoti
 
   public function ListeNotices_Mur($data, $preferences=[]) {
     $this->loadScript();
+    $preferences = $this->_updatePreferences($preferences);
 
     $notices = [];
     foreach($data as $notice)
@@ -35,9 +36,7 @@ class ZendAfi_View_Helper_ListeNotices_Mur extends ZendAfi_View_Helper_ListeNoti
 
 
   protected function _notice_mur($notice, $preferences=[]) {
-    $champs = isset($preferences['liste_codes'])
-      ? $preferences['liste_codes']
-      : 'TANE';
+    $champs = $preferences['liste_codes'];
 
     $datas = [$this->_tag('span',
                           $this->view->tagAnchor($this->view->urlNotice($notice, $preferences),
@@ -63,7 +62,7 @@ class ZendAfi_View_Helper_ListeNotices_Mur extends ZendAfi_View_Helper_ListeNoti
       . $this->_tag('div',
                     implode($datas),
                    ['class' => 'titre_auteur'])
-      . $this->barreDeLien($notice);
+      . $this->barreDeLien($notice, $preferences);
 
     $html = $this->_divRecord($html, $notice, 'notice');
 
@@ -73,11 +72,12 @@ class ZendAfi_View_Helper_ListeNotices_Mur extends ZendAfi_View_Helper_ListeNoti
   }
 
 
-  protected function barreDeLien($notice){
+  protected function barreDeLien($notice, $preferences){
     $html = [$this->_usersReviews($notice),
              $this->_adminsReviews($notice),
              $this->_socialNetwork($notice),
-             $this->barreDeLienPanier($notice),
+             $this->barreDeLienPanier($notice, $preferences),
+             $this->barreDeLienSelectCheckbox($notice, $preferences),
              $this->barreDeLienReserver($notice)];
 
     return implode([$this->_recordAvailability($notice),
@@ -143,7 +143,19 @@ class ZendAfi_View_Helper_ListeNotices_Mur extends ZendAfi_View_Helper_ListeNoti
   }
 
 
-  protected function barreDeLienPanier($notice) {
-    return $this->view->tag('li', $this->view->tagAddToCart($notice));
+  protected function barreDeLienPanier($notice, $preferences) {
+    return ($preferences['display_add_to_cart'])
+      ? $this->view->tag('li',
+                         $this->view->tagAddToCart($notice),
+                         ['class' => 'add_to_cart'])
+      : '';
   }
+
+
+  protected function barreDeLienSelectCheckbox($record, $preferences) {
+    return ($preferences['display_select_record'])
+      ? $this->_tag('li', $this->view->tagSelectRecord($record))
+      : '';
+	}
+
 }
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/ListeNotices/Tableau.php b/library/ZendAfi/View/Helper/ListeNotices/Tableau.php
index 0de54e98e0faab3d31bf1308f9878eef36aa685f..652e435e8676a1326c71933a678fcbb4366801db 100644
--- a/library/ZendAfi/View/Helper/ListeNotices/Tableau.php
+++ b/library/ZendAfi/View/Helper/ListeNotices/Tableau.php
@@ -18,71 +18,93 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
+
 class ZendAfi_View_Helper_ListeNotices_Tableau extends ZendAfi_View_Helper_ListeNotices_Abstract {
   public function listeNotices_Tableau($data, $preferences=[]) {
-    $champs = isset($preferences['liste_codes'])
-      ? $preferences['liste_codes']
-      : 'TANE';
-
-    // Entête
-    $html='<table cellspacing="0" cellpadding="3" border="0" width="100%">';
-    $html.='<tr><td class="listeTitre" width="26px">&nbsp;</td>';
-    for($i=0; $i < strlen($champs); $i++)
-      {
-        $champ=Class_Codification::getInstance()->getNomChamp($champs[$i]);
-        $html.='<td class="listeTitre">'.$champ.'</td>';
-      }
-    $html.='</tr>';
-
-    // Notices
-    $lig=0;
+    $preferences = $this->_updatePreferences($preferences);
+    $codes = $this->_filterCodes($preferences['liste_codes']);
+
+    return $this->_tag('table',
+                       $this->_header($codes)
+                       . $this->_body($data, $codes),
+                       ['cellspacing' => '0',
+                        'cellpadding' => '3',
+                        'border' => '0',
+                        'width' => '100%']);
+  }
+
+
+  protected function _filterCodes($codes) {
+    return array_filter(str_split($codes),
+                        function($code) { return !in_array($code, [';', '-']); });
+  }
+
 
+  protected function _header($codes) {
+    $columns = ['<td class="listeTitre" width="26px">&nbsp;</td>'];
+    $codifications = Class_Codification::getInstance();
+    foreach($codes as $code)
+      $columns[] = $this->_tag('td', $codifications->getNomChamp($code),
+                               ['class' => 'listeTitre']);
+
+    return $this->_tag('tr', implode($columns));
+  }
+
+
+  protected function _body($data, $codes) {
+    $lig=0;
+    $rows = [];
     foreach ($data as $notice) {
-        if($lig % 2) $style_css="listeImpaire"; else $style_css="listePaire";
-        $html.='<tr>';
-        $html.=sprintf('<td class="%s" style="text-align:center">%s</td>',
-                       $style_css,
-                       $this->view->iconeSupport($notice->getTypeDoc()));
-
-        for($i=0; $i < strlen($champs); $i++)
-          {
-            $champ=$champs[$i];
-
-            if($champ=="J")
-              $html.= sprintf('<td class="%s"><a href="%s">%s</a></td>',
-                              $style_css,
-                              $this->view->urlNotice($notice),
-                              $notice->getTitrePrincipal());
-            else if($champ=="A")  {
-              $html.= sprintf('<td class="%s">%s</td>',
-                              $style_css,
-                              $this->view->notice_LienRebondAuteur($notice));
-            }
-            else {
-              if (!$value = $notice->getChampNotice($champ, $notice->getFacettes())) {
-                $html .='<td class="'. $style_css .'"></td>';
-                continue;
-              }
-
-
-              if (is_array($value))
-                $value = $value[0];
-
-              if (is_array($value) && array_key_exists('libelle',$value))
-                $value = $value['libelle'];
-
-              if (is_object($value))
-                $value = $value->renderOn($this->view);
-
-              if($champ == "N") $align='style="text-align:center"'; else $align="";
-              $html.='<td class="'. $style_css .'" '.$align.'>'.$value.'</td>';
-            }
-            $lig++;
-          }
-        $html.='</tr>';
-      }
-    $html.='</table>';
-    return $html;
+      $style = 'liste' . ((0 === $lig % 2) ? 'Impaire' : 'Paire');
+      $rows[] = $this->_record($notice, $codes, $style);
+      $lig++;
+    }
+
+    return implode($rows);
+  }
+
+
+  protected function _record($notice, $codes, $style) {
+    $columns = [$this->_td($this->view->iconeSupport($notice->getTypeDoc()),
+                           $style,
+                           ['style' => 'text-align:center'])];
+
+    foreach ($codes as $code)
+      $columns[] = $this->_field($code, $notice, $style);
+
+    return $this->_tag('tr', implode($columns));
+  }
+
+
+  protected function _field($code, $notice, $style) {
+    if ('J' === $code)
+      return $this->_td($this->_tag('a', $notice->getTitrePrincipal(),
+                                    ['href' => $this->view->urlNotice($notice)]),
+                         $style);
+
+    if ('A' === $code)
+      return $this->_td($this->view->notice_LienRebondAuteur($notice),
+                        $style);
+
+    if (!$value = $notice->getChampNotice($code, $notice->getFacettes()))
+      return $this->_td('', $style);
+
+    if (is_array($value))
+      $value = $value[0];
+
+    if (is_array($value) && array_key_exists('libelle', $value))
+      $value = $value['libelle'];
+
+    if (is_object($value))
+      $value = $value->renderOn($this->view);
+
+    return $this->_td($value, $style,
+                      ('N' === $code) ? ['style' =>  'text-align:center'] : []);
+  }
+
+
+  protected function _td($content, $style, $attribs=[]) {
+    return $this->_tag('td', $content,
+                       array_merge(['class' => $style], $attribs));
   }
 }
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/ListeNotices/Vignettes.php b/library/ZendAfi/View/Helper/ListeNotices/Vignettes.php
index cd4e51f08c0a43635ffa4067d2514cd4c8c17813..cb9b011393aabe8ac1cef6fe4dec653864407b0d 100644
--- a/library/ZendAfi/View/Helper/ListeNotices/Vignettes.php
+++ b/library/ZendAfi/View/Helper/ListeNotices/Vignettes.php
@@ -25,30 +25,35 @@ class ZendAfi_View_Helper_ListeNotices_Vignettes extends ZendAfi_View_Helper_Lis
 
 	public function listeNotices_Vignettes($data, $preferences=[]) {
 		$this->loadScript();
-		$champs = isset($preferences['liste_codes']) ? $preferences['liste_codes'] : 'TANE';
+    $preferences = $this->_updatePreferences($preferences);
 
 		$html = '';
 		foreach($data as $notice){
 			$type_doc = $notice->getTypeDoc();
-			$html .= $this->_vignetteHtml($notice, $type_doc, $champs, $preferences);
+			$html .= $this->_vignetteHtml($notice,
+                                    $type_doc,
+                                    $preferences);
 		}
 
-		return $this->_tag('div', $html, ['class' => 'liste_vignettes']);
+		return $this->_tag('div',
+                       $html,
+                       ['class' => 'liste_vignettes']);
 	}
 
 
-	protected function _vignetteHtml($notice, $type_doc, $champs, $preferences){
+	protected function _vignetteHtml($notice, $type_doc, $preferences){
 		$url_notice = $this->view->urlNotice($notice, $preferences);
 
     $html = [$this->_hold($notice),
-             $this->_cart($notice),
+             $this->_cart($notice, $preferences),
+             $this->_selectCheckbox($notice, $preferences),
              $this->_recordAvailability($notice),
              $this->_title($notice, $url_notice),
              $this->_author($notice, $url_notice),
              $this->_docType($notice, $type_doc),
              $this->_link($notice, $type_doc),
              $this->_image($notice, $preferences),
-             $this->_info($notice, $champs),
+             $this->_info($notice, $preferences),
              $this->_pcTag($notice),
              $this->_xsl($notice)];
 
@@ -74,9 +79,20 @@ class ZendAfi_View_Helper_ListeNotices_Vignettes extends ZendAfi_View_Helper_Lis
 	}
 
 
-	protected function _cart($record) {
-		return $this->_tag('div', $this->view->tagAddToCart($record),
-											 ['class' => 'vignette_lien_panier']);
+	protected function _cart($record, $preferences) {
+    return ($preferences['display_add_to_cart'])
+      ? $this->_tag('div', $this->view->tagAddToCart($record),
+                    ['class' => 'vignette_lien_panier'])
+      : '';
+	}
+
+
+  protected function _selectCheckbox($record, $preferences) {
+    return ($preferences['display_select_record'])
+      ? $this->_tag('div',
+                    $this->view->tagSelectRecord($record),
+                    ['class' => 'vignette_select_record'])
+      : '';
 	}
 
 
@@ -113,7 +129,8 @@ class ZendAfi_View_Helper_ListeNotices_Vignettes extends ZendAfi_View_Helper_Lis
 	}
 
 
-	protected function _info($record, $fields) {
+	protected function _info($record, $preferences) {
+    $fields = $preferences['liste_codes'];
 		return $this
 			->_tag('div',
 						 $this->view->notice_Entete($record,
diff --git a/library/ZendAfi/View/Helper/ModeleFusion/Link.php b/library/ZendAfi/View/Helper/ModeleFusion/Link.php
index c48e55fddd177f09584f66f96407f267243695b4..4323592464bd52eb109862f64354551a98b4754b 100644
--- a/library/ZendAfi/View/Helper/ModeleFusion/Link.php
+++ b/library/ZendAfi/View/Helper/ModeleFusion/Link.php
@@ -23,14 +23,11 @@
 class ZendAfi_View_Helper_ModeleFusion_Link  extends ZendAfi_View_Helper_BaseHelper {
 
   public function ModeleFusion_Link($instance) {
-    if(!$instance)
+    if (!$instance)
       return '';
 
-    if(!$model_fusion =
-       (($model_fusion  = Class_ModeleFusion::getFusionForStrategyAndProfil($instance->getStrategy(),
-                                                                            Class_Profil::getCurrentProfil()->getId()))
-        ? $model_fusion
-        : Class_ModeleFusion::getFusionForStrategy($instance->getStrategy())))
+    if (!$model_fusion = Class_ModeleFusion::getFusionForStrategyAndProfilOrDefault($instance->getStrategy(),
+                                                                                    Class_Profil::getCurrentProfil()))
       return '';
 
     $models = $instance->getModels();
diff --git a/library/ZendAfi/View/Helper/Search/Header.php b/library/ZendAfi/View/Helper/Search/Header.php
index 7c3424054c935de956ff0726c3444ec06c7d670a..43f4bed600be077a9e3c9250a278b40497099c01 100644
--- a/library/ZendAfi/View/Helper/Search/Header.php
+++ b/library/ZendAfi/View/Helper/Search/Header.php
@@ -40,7 +40,8 @@ class ZendAfi_View_Helper_Search_Header extends ZendAfi_View_Helper_BaseHelper {
              $this->_tagCriteria(),
              $this->_tagDomainBrowser(),
              $this->_tagSearchActions(),
-             $this->view->tagSearchExtension($this->_criteria)];
+             $this->view->tagSearchExtension($this->_criteria),
+             $this->_tagRecordSelectionCount()];
 
     return $this->_tag('div',
                        implode(
@@ -93,12 +94,6 @@ class ZendAfi_View_Helper_Search_Header extends ZendAfi_View_Helper_BaseHelper {
 
 
   protected function _tagSearchActions() {
-    $instance = (new Class_Entity())
-      ->setSubject(strip_tags($this->view->tagSearchTerm($this->_criteria)))
-      ->setModels($this->_search_result->fetchRecords())
-      ->setIds(implode(';', array_slice($this->_search_result->fetchAllRecordsIds(), 0, 200)))
-      ->setStrategy(Class_ModeleFusion::RECORDS_TEMPLATE);
-
     $actions = [$this->_tag('span',
                             $this->view->tagAnchor($this->view->url($this->_criteria->getUrlRetourRechercheInitiale(), null, true),
                                                    $this->_('Retour à la recherche initiale'),
@@ -113,13 +108,9 @@ class ZendAfi_View_Helper_Search_Header extends ZendAfi_View_Helper_BaseHelper {
 
                 $this->_tagBookmarkSearch(),
 
-                $this->_tag('span',
-                            $this->view->tagPrintLink($instance),
-                            ['class' => 'print']),
+                $this->_tagPrintLink(),
 
-                $this->_tag('span',
-                            $this->view->tagSendMail($instance),
-                            ['class' => 'mail']),
+                $this->_tagSendMail(),
     ];
 
     return $this->_tag('div',
@@ -139,8 +130,37 @@ class ZendAfi_View_Helper_Search_Header extends ZendAfi_View_Helper_BaseHelper {
   }
 
 
+  protected function _tagPrintLink() {
+    if (!Class_ModeleFusion::canPrintRecordsInProfile(Class_Profil::getCurrentProfil()))
+      return '';
+
+    return $this->_tag('span',
+                       $this->view->tagAnchor(['controller' => 'recherche',
+                                               'action' => 'print'],
+                                              $this->_('Imprimer'),
+                                              ['title' => $this->_('Imprimer le résultat'),
+                                               'target' => '_blank']),
+                       ['class' => 'print']);
+  }
+
+
+  protected function _tagSendMail() {
+    if (!Class_ModeleFusion::canPrintRecordsInProfile(Class_Profil::getCurrentProfil()))
+      return '';
+
+    return $this->_tag('span',
+                       $this->view->tagAnchor(['controller' => 'recherche',
+                                               'action' => 'send-mail'],
+                                              $this->_('Partager par email'),
+                                              ['title' => $this->_('Partager le résultat par email'),
+                                               'data-popup' => 'true']),
+                       ['class' => 'mail']);
+  }
+
+
   protected function _tagBookmarkSearch() {
-    if(!Class_AdminVar::isBookmarkSearchesReady())
+    if(!Class_AdminVar::isBookmarkSearchesReady()
+       || $this->_criteria->isSelection())
       return '';
 
     return $this->_tag('span',
@@ -151,4 +171,10 @@ class ZendAfi_View_Helper_Search_Header extends ZendAfi_View_Helper_BaseHelper {
                                                'data-popup' => true]),
                 ['class' => 'save']);
   }
+
+
+  protected function _tagRecordSelectionCount() {
+    return $this->view->getHelper('TagSelectRecord')
+                      ->tagRecordSelectionCount($this->_criteria);
+  }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/TagCriteresRecherche.php b/library/ZendAfi/View/Helper/TagCriteresRecherche.php
index 9d5bf6d22e4f0de9228b3c8af306a6b3d4fe86dc..bad61c909e0f0531f7f822a28ba2f82da75be4e3 100644
--- a/library/ZendAfi/View/Helper/TagCriteresRecherche.php
+++ b/library/ZendAfi/View/Helper/TagCriteresRecherche.php
@@ -168,6 +168,13 @@ class ZendAfi_View_Helper_TagCriteresRecherche extends ZendAfi_View_Helper_BaseH
   }
 
 
+  public function visitSelection($selection) {
+    $this
+      ->htmlAppend($this->getSuppressionImgUrlForLibelle($this->_('Sélection courante'),
+                                                         $this->_criteres_recherche->getUrlCriteresWithoutElement('selection')));
+  }
+
+
   public function visitSection($section) {
     $url = $this->_criteres_recherche->getUrlCriteresWithoutElement('section');
     $libelle = $this->_('Section: %s', Class_Codification::getInstance()->getLibelleFacette('S'.$section));
diff --git a/library/ZendAfi/View/Helper/TagSearchTerm.php b/library/ZendAfi/View/Helper/TagSearchTerm.php
index 2ef9b6202ebf4da7959e2be175e59ee791079bea..3fed54cbfb0a2b20ac7ca58e6c8287ae3e618ee6 100644
--- a/library/ZendAfi/View/Helper/TagSearchTerm.php
+++ b/library/ZendAfi/View/Helper/TagSearchTerm.php
@@ -21,46 +21,29 @@
 
 
 class ZendAfi_View_Helper_TagSearchTerm extends ZendAfi_View_Helper_BaseHelper {
-  public function tagSearchTerm($criteres_recherche) {
-    if($term = $this->_getInputOrStaticSearchTerm($criteres_recherche))
-      return $this->_('pour : %s', $this->_addClassExpressionRecherche($term));
+  public function tagSearchTerm($criteria, $decorator=null) {
+    if (!$decorator)
+      $decorator = $this->_getDefaultDecorator();
 
-    if($domain = $criteres_recherche->getCatalogue())
-      return $this->_('dans le catalogue : %s',
-                      $this->_addClassExpressionRecherche($domain->getLibelle()));
+    if ($term = $criteria->getExpressionRecherche())
+      return $this->_('pour : %s', $decorator($term));
 
-    if($selection = $criteres_recherche->getPanier())
-      return $this->_('dans le panier : %s',
-                      $this->_addClassExpressionRecherche($selection->getLibelle()));
+    if ($domain = $criteria->getCatalogue())
+      return $this->_('dans le catalogue : %s', $decorator($domain->getLibelle()));
 
-    if($serie = $criteres_recherche->getSerie())
-      return $this->_('dans la serie : %s',
-                      $this->_addClassExpressionRecherche($serie));
-
-    return '';
-  }
+    if ($selection = $criteria->getPanier())
+      return $this->_('dans le panier : %s', $decorator($selection->getLibelle()));
 
+    if ($serie = $criteria->getSerie())
+      return $this->_('dans la serie : %s', $decorator($serie));
 
-  protected function _getInputOrStaticSearchTerm($criteres_recherche) {
-    if (!Class_Profil::getCurrentProfil()->isSearchTermEditable())
-      return $this->view->escape($criteres_recherche->getExpressionRecherche());
-
-    $expression = $criteres_recherche->getExpressionRecherche();
-    $input = $this->view->formText('expressionRecherche',
-                                   $expression,
-                                   ['class' => 'expressionRecherche',
-                                    'placeholder' => $expression]);
-    return $this->view->tag('form',
-                             $input,
-                             ['method' => 'get',
-                              'style' => 'display: inline-block',
-                              'action' => $this->view->url(['expressionRecherche' => null])]);
+    return '';
   }
 
 
-  protected function _addClassExpressionRecherche($expression_recherche) {
-    return $this->_tag('div', $expression_recherche, ['class' => 'expression-recherche']);
+  protected function _getDefaultDecorator() {
+    return function($value) {
+      return $this->view->tagWrappedSearchTerm($value);
+    };
   }
-
 }
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/TagSelectRecord.php b/library/ZendAfi/View/Helper/TagSelectRecord.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f862b9011e38337327defe121ec653daa985f6b
--- /dev/null
+++ b/library/ZendAfi/View/Helper/TagSelectRecord.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_View_Helper_TagSelectRecord extends ZendAfi_View_Helper_BaseHelper {
+  public function tagSelectRecord($record) {
+    $checked = (new Class_RecordSelection())->includes($record);
+
+    $url = Class_url::relative(['module' => 'opac',
+                                'controller' => 'records',
+                                'action' => 'select-toggle',
+                                'id' => $record->getId()]);
+
+    return $this->view->formCheckbox('select_record_' . $record->getId(),
+                                     $record->getId(),
+                                     ['title' => $this->_('Sélectionner "%s" pour impression, export ou sauvegarde',
+                                                          $record->getTitrePrincipal()),
+                                      'checked' => $checked,
+                                      'onclick' => '$.get(\'' . $url  . '\', updateRecordSelectionCount)'
+                                     ]);
+  }
+
+
+  public function tagRecordSelectionCount($criteria) {
+    if (!Class_AdminVar::isModuleEnabled('ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION'))
+      return '';
+
+    Class_ScriptLoader::getInstance()
+      ->addInlineScript('function updateRecordSelectionCount(data) {'
+                        . '$(\'.record-selection span\').text(data.count); '
+                        . '}')
+      ->addJQueryReady('$(\'.record-selection > a\').click(function(event) {'
+                       . '$(event.target).parent().find(\'ul\').slideToggle();'
+                       . 'event.preventDefault();'
+                       .'})');
+
+    $record_count = (new Class_RecordSelection())->count();
+    return $this->_tag('div',
+                       $this->_tag('a',
+                                   $this->_('Sélection : ')
+                                   . $this->_tag('span',
+                                                 $record_count),
+                                   ['class' => 'bouton',
+                                    'href' => '#',
+                                    'title' => implode(' ' ,
+                                                       [$this->_('Ouvrir le menu des actions de sélection.'),
+                                                        $this->_plural($record_count,
+                                                                       'Aucune notice sélectionnée',
+                                                                       'Une notice sélectionné',
+                                                                       '%d notices sélectionnées',
+                                                                       $record_count)])])
+                       . $this->_tag('ul',
+                                     implode(array_map(function($content) { return $this->_tag('li', $content);},
+                                                       [$this->_addSelectionToCartLink(),
+                                                        $this->_selectPageLink($criteria),
+                                                        $this->_selectAllLink($criteria),
+                                                        $this->_selectViewLink($criteria),
+                                                        $this->_clearSelectionLink()]))),
+                       ['class' => 'record-selection']);
+  }
+
+
+  protected function _clearSelectionLink() {
+    Class_ScriptLoader::getInstance()
+      ->addInlineScript('function updateRecordSelectionCountAndClear(data) { '
+                        .'updateRecordSelectionCount(data);'
+                        .'$(\'input[id^=select_record_]\').prop(\'checked\', false);'
+                        .'}');
+
+    $url_clear = Class_url::relative(['module' => 'opac',
+                                      'controller' => 'records',
+                                      'action' => 'select-clear']);
+
+
+    return $this->_tag('a',
+                       $this->_('Vider la sélection'),
+                       ['href' => $url_clear,
+                        'onclick' => sprintf('$.get(\'%s\', updateRecordSelectionCountAndClear); return false',
+                                             $url_clear),
+                        'title' => $this->_('Retirer toute les notices présente dans votre sélection')]);
+  }
+
+
+  protected function _selectPageLink($criteria) {
+    Class_ScriptLoader::getInstance()
+      ->addInlineScript('function updateRecordSelectionCountAndCheckAll(data) { '
+                        .'updateRecordSelectionCount(data);'
+                        .'$(\'input[id^=select_record_]\').prop(\'checked\', true);'
+                        .'}');
+
+    $url_select_page = Class_Url::relative(array_merge($criteria->getUrlCriteresWithFacettes(),
+                                                       ['controller' => 'records',
+                                                        'action' => 'select-page']));
+
+
+    return $this->_tag('a',
+                       $this->_('Sélectionner toute la page'),
+                       ['href' => $url_select_page,
+                        'onclick' => sprintf('$.get(\'%s\', updateRecordSelectionCountAndCheckAll); return false',
+                                             $url_select_page),
+                        'title' => $this->_('Ajouter toutes les notices de la page de résultat courante dans votre sélection')
+                       ]);
+  }
+
+
+  protected function _addSelectionToCartLink() {
+    $url_add = Class_Url::relative(['controller' => 'panier',
+                                    'action' => 'add-selection']);
+
+
+    return $this->_tag('a',
+                       $this->_('Mettre dans un panier'),
+                       ['href' => $url_add,
+                        'data-popup' => 'true',
+                        'title' => $this->_('Ajouter toutes les notices de la sélection à un panier')
+                       ]);
+  }
+
+
+  protected function _selectAllLink($criteria) {
+    Class_ScriptLoader::getInstance()
+      ->addInlineScript('function updateRecordSelectionCountAndCheckAll(data) { '
+                        .'updateRecordSelectionCount(data);'
+                        .'$(\'input[id^=select_record_]\').prop(\'checked\', true);'
+                        .'}');
+
+    $url_select_page = Class_Url::relative(array_merge($criteria->getUrlCriteresWithFacettes(),
+                                                       ['controller' => 'records',
+                                                        'action' => 'select-all']));
+
+
+    return $this->_tag('a',
+                       $this->_('Sélectionner tous les résultats'),
+                       ['href' => $url_select_page,
+                        'onclick' => sprintf('$.get(\'%s\', updateRecordSelectionCountAndCheckAll); return false',
+                                             $url_select_page),
+                        'title' => $this->_('Ajouter toutes les notices du résultat dans votre sélection')
+                       ]);
+  }
+
+
+  protected function _selectViewLink($criteria) {
+    return $this->_tag('a',
+                       $this->_('Voir la sélection'),
+                       ['href' => Class_Url::relative(['controller' => 'recherche',
+                                                       'action' => 'simple',
+                                                       'tri' => $criteria->getTri(),
+                                                       'liste_format' => $criteria->getFormat(),
+                                                       'page_size' => $criteria->getPageSize(),
+                                                       'selection' => 1], null, true),
+                        'title' => $this->_('Afficher un résultat de recherche incluant uniquement les notices de votre sélection'),
+                       ]);
+  }
+}
diff --git a/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php b/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php
index 29d3a400a492078ed3826fcd2dd104325301967d..2f1d2e13ffa98add6bf7f7a024b0013559bd6b3a 100644
--- a/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php
+++ b/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php
@@ -23,7 +23,7 @@ class ZendAfi_View_Helper_TagTitreEtNombreDeResultats extends ZendAfi_View_Helpe
   public function tagTitreEtNombreDeResultats($search_result){
     $search_duration = $search_result->getDuration();
     $criteres_recherche = $search_result->getCriteresRecherche();
-    $expression_recherche = $this->view->tagSearchTerm($criteres_recherche);
+    $expression_recherche = $this->_getSearchTerm($criteres_recherche);
 
     $nombre_resultats = $search_result->getRecordsCount();
 
@@ -61,5 +61,28 @@ class ZendAfi_View_Helper_TagTitreEtNombreDeResultats extends ZendAfi_View_Helpe
   protected function _islimited($count, $limit) {
     return $limit && ($count == $limit);
   }
+
+
+  protected function _getSearchTerm($criteria) {
+    if (($term = $criteria->getExpressionRecherche())
+        && Class_Profil::getCurrentProfil()->isSearchTermEditable())
+      return $this->_('pour : %s', $this->_getInputSearchTerm($term));
+
+    return $this->view->tagSearchTerm($criteria);
+  }
+
+
+  protected function _getInputSearchTerm($term) {
+    $input = $this->view->formText('expressionRecherche',
+                                   $term,
+                                   ['class' => 'expressionRecherche',
+                                    'placeholder' => $term]);
+    $form = $this->_tag('form',
+                        $input,
+                        ['method' => 'get',
+                         'style' => 'display: inline-block',
+                         'action' => $this->view->url(['expressionRecherche' => null])]);
+
+    return $this->view->tagWrappedSearchTerm($form, false);
+  }
 }
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/TagSendMail.php b/library/ZendAfi/View/Helper/TagWrappedSearchTerm.php
similarity index 64%
rename from library/ZendAfi/View/Helper/TagSendMail.php
rename to library/ZendAfi/View/Helper/TagWrappedSearchTerm.php
index 36420ea032b081bb480dc9ab08a2e5d3ddfd03e0..b842401071df8510552111b80a8a77aa4e122450 100644
--- a/library/ZendAfi/View/Helper/TagSendMail.php
+++ b/library/ZendAfi/View/Helper/TagWrappedSearchTerm.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
  *
  * BOKEH is free software; you can redistribute it and/or modify
  * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
@@ -20,15 +20,10 @@
  */
 
 
-class ZendAfi_View_Helper_TagSendMail extends ZendAfi_View_Helper_BaseHelper {
-  public function tagSendMail($instance) {
-    $instance
-      ->setAction('send-mail')
-      ->setLink($this->_('Partager par email'))
-      ->setAttribs(['title' => $this->_('Aperçu de l\'email'),
-                    'data-popup' => 'true']);
-
-    return $this->view->ModeleFusion_Link($instance);
+class ZendAfi_View_Helper_TagWrappedSearchTerm extends ZendAfi_View_Helper_BaseHelper {
+  public function tagWrappedSearchTerm($term, $should_escape=true) {
+    return $this->_tag('div',
+                       $should_escape ? $this->view->escape($term) : $term,
+                       ['class' => 'expression-recherche']);
   }
 }
-?>
\ No newline at end of file
diff --git a/library/digital_resources/Cvs/controllers/SearchController.php b/library/digital_resources/Cvs/controllers/SearchController.php
index 88afbb895f1b1622706f249a7dc8aa4ad6092b0f..91cfd1fa1e33788af1480b8ed00f977dbd7dcf50 100644
--- a/library/digital_resources/Cvs/controllers/SearchController.php
+++ b/library/digital_resources/Cvs/controllers/SearchController.php
@@ -50,6 +50,9 @@ class Cvs_Plugin_SearchController extends Class_DigitalResource_Controller {
 
     $service = (new Cvs_Service)->setUser($user);
     $this->view->result = $service->find($query, $criteria->getPage(), $preferences['cvs_nb_result']);
+
+    $preferences['display_add_to_cart'] = false;
+    $preferences['display_select_record'] = false;
     $this->view->preferences = $preferences;
   }
 }
\ No newline at end of file
diff --git a/library/digital_resources/Cvs/tests/CvsTest.php b/library/digital_resources/Cvs/tests/CvsTest.php
index 7e3c20bd5a78d05f8abe35aaaa2f291d40b8c196..5ddc1d782ea9f55883b2bf3568a03549c6e367d3 100644
--- a/library/digital_resources/Cvs/tests/CvsTest.php
+++ b/library/digital_resources/Cvs/tests/CvsTest.php
@@ -313,6 +313,18 @@ class CvsRecordsSearchCuissonTest extends CvsSearchWithResultTestCase {
   public function resultFormatShouldBeVignetteMode() {
     $this->assertXPath('//div[@class="liste_vignettes"]');
   }
+
+
+  /** @test */
+  public function pageShouldNotIncludeLinkAddRecordAjaxOnBasket() {
+    $this->assertNotXPath('//a[contains(@href, "panier/add-record-ajax/")]');
+  }
+
+
+  /** @test */
+  public function pageShouldNotIncludeCheckboxToSelectRecord() {
+    $this->assertNotXPath('//input[@type="checkbox"]');
+  }
 }
 
 
diff --git a/public/opac/css/global.css b/public/opac/css/global.css
index 516939685e4b3a505a9418d65e655e6ab5b58f4a..9399658dc5a93d39f84b6330696aa34c1bf8d4ab 100644
--- a/public/opac/css/global.css
+++ b/public/opac/css/global.css
@@ -1558,7 +1558,23 @@ body.abonne_multimedia-hold-view .actions a {
 }
 
 
-.recherche_actions, .search_extensions {
+.record-selection > a {
+    background: url(../images/buttons/burger_dots.png) no-repeat right 5px center;
+    padding-right: 20px;
+}
+
+
+.record-selection ul {
+    position: absolute;
+    background: white;
+    margin: 0;
+    list-style: none;
+    padding: 0 5px 5px 5px;
+    display: none;
+}
+
+
+.recherche_actions, .record-selection, .search_extensions {
     margin-top: 10px;
     clear: both;
 }
@@ -2072,7 +2088,8 @@ div.suggestion-achat-liste dl{
 }
 
 
-.vignette_lien_panier { 
+.vignette_lien_panier,
+.vignette_select_record { 
     clear:both;
     float: right;
     margin-top:5px;
@@ -2493,7 +2510,7 @@ button.vodeclic_link + img {
     background: url(../images/bouton/partager.png) no-repeat center  center;
 }
 
-.barre-de-lien li:first-child+li+li+li{
+.barre-de-lien li.add_to_cart {
     background: url(../../admin/images/picto/paniers_16.png) no-repeat center  center;
 }
 
diff --git a/public/opac/images/buttons/burger_dots.png b/public/opac/images/buttons/burger_dots.png
new file mode 100644
index 0000000000000000000000000000000000000000..761e09d42436abc7021a10fd9be8a78c0a2893f8
Binary files /dev/null and b/public/opac/images/buttons/burger_dots.png differ
diff --git a/tests/application/modules/opac/controllers/PanierControllerTest.php b/tests/application/modules/opac/controllers/PanierControllerTest.php
index 18791e37ccd42f9670743f8224f32f669653cc0f..8ae056dded830f19986cc6bb28bb83303be23037 100644
--- a/tests/application/modules/opac/controllers/PanierControllerTest.php
+++ b/tests/application/modules/opac/controllers/PanierControllerTest.php
@@ -118,10 +118,11 @@ abstract class PanierControllerTestCase extends AbstractControllerTestCase {
                                         'panier_notice_catalogues' => [$panier_domaine_histoire]]))
       ->setCatalogue($this->fixture('Class_Catalogue',
                                     ['id' => 97,
-                                     'libelle' => 'histoire']))
+                                     'libelle' => 'histoire',
+                                     'indexer' => 1,
+                                     'auteur' => '1']))
       ->save();
 
-
     $panier_domaine_bd = $this->fixture('Class_PanierNoticeCatalogue',
                                         ['id' => 72]);
     $panier_domaine_bd
@@ -252,15 +253,20 @@ class PanierControllerAsSimpleUserActionTest extends PanierControllerSimpleLogge
     $this->dispatch('/opac/panier', true);
 
   }
+
+
   /** @test */
   public function panierDomaineBDShouldBeVisibleForSimpleUser() {
     $this->assertXPathCount('//td[contains(text(), "Mes BD")]', 1,$this->_response->getBody());
   }
 
+
   /** @test */
   public function forInviteShouldContainsOnePanier() {
     $this->assertXPathCount('//span[contains(text(), "Vous avez 1 panier")]', 1);
   }
+
+
   /** @test */
   public function panierDomaineSelectionJeunesseShouldNotBeVisibleForSimpleUser() {
     $this->assertNotXPathCount('//td[contains(text(), "selection jeunesse")]', 1,$this->_response->getBody());
@@ -274,9 +280,7 @@ class PanierControllerIndexAsRedacteurActionTest extends PanierControllerTestCas
     parent::setUp();
 
     $this->manon->changeRoleTo(ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL);
-
     $this->dispatch('/opac/panier', true);
-
   }
 
 
@@ -286,6 +290,7 @@ class PanierControllerIndexAsRedacteurActionTest extends PanierControllerTestCas
                                       'Vous avez 2 paniers');
   }
 
+
   /** @test */
   public function panierDomaineShouldContainLinkToCreerPanier(){
     $this->assertNotXPath('//a[contains(@href,"panier/creer-panier")]',$this->response->getBody());
@@ -320,6 +325,7 @@ class PanierControllerIndexWithPanierIdFifteenTest extends PanierControllerTestC
     $this->assertAction('index');
   }
 
+
   /** @test */
   public function panierMesBDShouldBeVisible() {
     $this->assertQueryContentContains('td', 'Mes BD');
@@ -593,6 +599,25 @@ class PanierControllerAjoutNoticeBlackSadToPanierDomaineHistoireTest extends Pan
 
 
 
+class PanierControllerAjoutNoticeBlackSadToPanierDomaineHistoirePostTest extends PanierControllerTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->manon
+      ->changeRoleTo(ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL)
+      ->setPanierCourant(Class_PanierNotice::find(38));
+    $this->postDispatch('/panier/add-record-ajax/id_notice/12', []);
+    Class_PanierNotice::clearCache();
+  }
+
+  /** @test */
+  public function cardDomainShouldBeIndexedInRecord() {
+    $this->assertContains('Q97', Class_Notice::find(12)->getFacettes());
+  }
+}
+
+
+
+
 class PanierControllerModifierTitrePanierMesRomansToMesLivresTest extends PanierControllerTestCase {
   public function setUp() {
     parent::setUp();
@@ -1076,7 +1101,7 @@ class PanierControllerAjouterNoticeDansBoitePanierTest extends AbstractControlle
   }
 
   /** @test */
-  public function contextShouldExpectation() {
+  public function postDispatchIdNotice4ShouldaddLeMontespanToMyCart() {
     $panier = $this->fixture('Class_PanierNotice',
                              ['id' => 1,
                               'titre' => 'my cart',
@@ -1793,7 +1818,7 @@ class PanierControllerSwitchAjaxPostActionTest extends PanierControllerSimpleLog
 
   /** @test */
   public function shouldRedirect() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/panier/add-record-ajax');
+    $this->assertRedirectTo('/panier/add-record-ajax');
   }
 }
 
diff --git a/tests/application/modules/opac/controllers/RechercheControllerPrintActionTest.php b/tests/application/modules/opac/controllers/RechercheControllerPrintActionTest.php
index a912af20b20c2ed63ca82f0b859f405b9fdcd747..2a493eeae163fe7de9a19f42befa25d00430478d 100644
--- a/tests/application/modules/opac/controllers/RechercheControllerPrintActionTest.php
+++ b/tests/application/modules/opac/controllers/RechercheControllerPrintActionTest.php
@@ -30,31 +30,28 @@ class RechercheControllerPrintActionLinkTest extends AbstractControllerTestCase
                                           'contenu' => '<p> {notices.each[<img src="{url_vignette}"/>  {titre_principal} <div>{article.contenu}</div>
 ]}</p>',
                                           'type' => 'Notice_List']);
-
-    $this->fixture('Class_Catalogue',
-                   ['id'=>3,
-                    'libelle' => 'Nouveautés',
-                    'auteur' => 'Paul']);
-
     $mock_sql = $this->mock()
                      ->whenCalled('fetchAll')
-                     ->with("select id_notice, facettes from notices Where MATCH(facettes) AGAINST('+(APaul)' IN BOOLEAN MODE) order by annee desc", true, false)
-                     ->answers([ [1, ''] ])
-
-                     ->whenCalled('fetchAll')
-                     ->answers([$this->fixture('Class_Notice',
-                                               ['id' => 1])->toArray()])
-                     ->beStrict();
+                     ->answers([ [1, ''] ]);
 
     Zend_Registry::set('sql', $mock_sql);
-    $this->dispatch('/recherche/simple/id_catalogue/3/id_module/9/aleatoire/1', true);
+    $this->dispatch('/recherche/simple/expressionRecherche/pomme/facettes/T3/tri/*', true);
   }
 
 
   /** @test */
-  public function printLinkShouldBePresent() {
-    $this->assertXPathContentContains('//a[contains(@href, "/recherche/print/id_catalogue/3/id_module/9/aleatoire/1/ids/1/subject/pour+%3A+/strategy/Notice_List/modele_fusion/1")][@target="_blank"]',
-                                      'Imprimer');
+  public function pageShouldContainsPrintLinkWithSearchCriteria() {
+    $this->assertXPathContentContains('//a[contains(@href, "/recherche/print/expressionRecherche/pomme/facettes/T3/tri/%2A")][@target="_blank"]',
+                                      'Imprimer',
+                                      $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function pageShouldContainsSendMailLinkWithSearchCriteria() {
+   $this->assertXPathContentContains('//a[@href="/recherche/send-mail/expressionRecherche/pomme/facettes/T3/tri/%2A"]',
+                                      'Partager par email',
+                                      $this->_response->getBody());
   }
 }
 
@@ -66,11 +63,6 @@ class RechercheControllerPrintActionWithRecordsTest extends AbstractControllerTe
   public function setUp() {
     parent::setUp();
 
-    $this->fixture('Class_ModeleFusion', ['id' => 1,
-                                          'nom' => 'recherche',
-                                          'contenu' => '<p> {notices.each[<img src="{url_vignette}"/>  <h1>{titre_principal}</h1> <div>{article.contenu}</div> <div>{resume}</div>
-]}</p>']);
-
     Class_Indexation_PseudoNotice::index( $this->fixture('Class_Article' , ['id' => 10,
                                                                             'titre' => 'pomme',
                                                                             'contenu' => '<p>blabla</p>',
@@ -84,7 +76,27 @@ class RechercheControllerPrintActionWithRecordsTest extends AbstractControllerTe
                                                                             'notice' => new Class_Notice(),
                                                                             'type_doc_id' => Class_TypeDoc::ARTICLE]));
 
-    $this->dispatch("/recherche/print/expressionRecherche/pomme/strategy/Notice_List/ids/2;1/modele_fusion/1",true);
+    $mock_sql = $this->mock()
+                     ->whenCalled('fetchAll')
+                     ->with("select id_notice, facettes from notices Where MATCH(titres, auteurs, editeur, collection, matieres, dewey) AGAINST('+(POMME POMMES POM)' IN BOOLEAN MODE) and MATCH(facettes) AGAINST('+T3' IN BOOLEAN MODE) order by (MATCH(alpha_titre) AGAINST(' POMME') * 1.5) + (MATCH(alpha_auteur) AGAINST(' POMME')) desc",
+                            true,
+                            false)
+                     ->answers([
+                                [2, ''],
+                                [1, '']
+                                ])
+                     ->beStrict();
+    Zend_Registry::set('sql', $mock_sql);
+
+    $this->fixture('Class_ModeleFusion', ['id' => 1,
+                                          'nom' => 'recherche',
+                                          'contenu' => '<p> {notices.each[<img src="{url_vignette}"/>  <h1>{titre_principal}</h1> <div>{article.contenu}</div> <div>{resume}</div>
+]}</p>',
+                                          'type' => 'Notice_List']);
+
+
+
+    $this->dispatch("/recherche/print/expressionRecherche/pomme/facettes/T3/tri/*",true);
   }
 
 
@@ -109,7 +121,7 @@ class RechercheControllerPrintActionWithRecordsTest extends AbstractControllerTe
 
   /** @test */
   public function contenuShouldContainsTransmetropolitan() {
-    $this->assertXPathContentContains("//div//h1[1]", "transmetropolitan");
+    $this->assertXPathContentContains("//h1[1]", "transmetropolitan", $this->_response->getBody());
   }
 
 
@@ -128,7 +140,7 @@ class RechercheControllerPrintActionWithRecordsTest extends AbstractControllerTe
 
 
 
-class RechercheControllerViewNoticePrintActionWithRecordsTest extends AbstractControllerTestCase {
+class RechercheControllerPrintActionViewNoticeWithRecordsTest extends AbstractControllerTestCase {
   protected $_storm_default_to_volatile = true;
 
   public function setUp() {
@@ -141,7 +153,7 @@ class RechercheControllerViewNoticePrintActionWithRecordsTest extends AbstractCo
 <div>{notice.resume} </div>
 {notice.avis[<p>{avis}</p>]}
 </p>',
-                                          'type' => 'Notice_View']);
+                                          'type' => Class_ModeleFusion::RECORD_TEMPLATE]);
 
 
     Class_Indexation_PseudoNotice::index( $this->fixture('Class_Article' , ['id' => 12,
diff --git a/tests/application/modules/opac/controllers/RechercheControllerTest.php b/tests/application/modules/opac/controllers/RechercheControllerTest.php
index d1b3bc7f4fb2a7abf8e0406cc31cc400e01c1c1d..da6e83cb7ed758fd08c3dcdf1377c90ba0b00b1e 100644
--- a/tests/application/modules/opac/controllers/RechercheControllerTest.php
+++ b/tests/application/modules/opac/controllers/RechercheControllerTest.php
@@ -18,7 +18,6 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-require_once 'AbstractControllerTestCase.php';
 
 abstract class RechercheControllerNoticeTestCase extends AbstractControllerTestCase {
   protected $_storm_default_to_volatile = true;
@@ -110,7 +109,7 @@ class RechercheControllerPrintTest extends RechercheControllerNoticeTestCase {
 {notice.avis[<p>{avis}</p>]}
 </p>',
                                           'profil_ids' => '3;4',
-                                          'type' =>'Notice_View']);
+                                          'type' => Class_ModeleFusion::RECORD_TEMPLATE]);
     Class_AdminVar::newInstanceWithId('BABELTHEQUE_JS')->setValeur('');
 
   }
@@ -1903,25 +1902,6 @@ class RechercheControllerSimpleActionWithListeFormatChronoTest extends Recherche
 
 
 
-class RechercheControllerSimpleActionWithListeFormatAccordeonTest extends RechercheControllerSimpleActionListeFormatTestCase {
-  protected $_liste_format = Class_Systeme_ModulesAppli::LISTE_FORMAT_ACCORDEON;
-
-
-  public function setUp() {
-    parent::setUp();
-    $this->dispatch('/recherche/simple/expressionRecherche/potter/facettes/T1/facette/B1/page/2', true);
-  }
-
-
-  /** @test */
-  public function ajaxToGetNotice() {
-    $this->assertXPath('//img[contains(@onclick, "getNoticeAjax")]');
-  }
-}
-
-
-
-
 class RechercheControllerSimpleActionWithListeFormatTableauTest extends RechercheControllerSimpleActionListeFormatTestCase {
   protected $_liste_format = Class_Systeme_ModulesAppli::LISTE_FORMAT_TABLEAU;
 
diff --git a/tests/library/ZendAfi/View/Helper/Accueil/DomainBrowserTest.php b/tests/library/ZendAfi/View/Helper/Accueil/DomainBrowserTest.php
index 8188ca48a247ea6236b9d0dc93516c6b2e861888..0f434f62e92a76a11c24e91f8a2e006135466118 100644
--- a/tests/library/ZendAfi/View/Helper/Accueil/DomainBrowserTest.php
+++ b/tests/library/ZendAfi/View/Helper/Accueil/DomainBrowserTest.php
@@ -80,7 +80,7 @@ class ZendAfi_View_Helper_Accueil_DomainBrowserWithRootDomainTest extends ZendAf
                                                               'preferences' => [
                                                                 'boite' => '',
                                                                 'titre' => 'Browse Jazz domain',
-                                                                'display_mode' => Class_Systeme_ModulesAppli::LISTE_FORMAT_ACCORDEON,
+                                                                'display_mode' => Class_Systeme_ModulesAppli::LISTE_FORMAT_VIGNETTES,
                                                                 'root_domain_id' => '2']]);
 
     $helper->setView(new ZendAfi_Controller_Action_Helper_View());
@@ -108,7 +108,7 @@ class ZendAfi_View_Helper_Accueil_DomainBrowserWithRootDomainTest extends ZendAf
 
 
 
-abstract class ZendAfi_View_Helper_Accueil_DomainBrowserViewAccordionTestCase extends ZendAfi_View_Helper_Accueil_DomainBrowserTestCase {
+abstract class ZendAfi_View_Helper_Accueil_DomainBrowserViewThumbnailsTestCase extends ZendAfi_View_Helper_Accueil_DomainBrowserTestCase {
   public function setUp() {
     parent::setUp();
 
@@ -116,7 +116,7 @@ abstract class ZendAfi_View_Helper_Accueil_DomainBrowserViewAccordionTestCase ex
                                                                     'division' => 1,
                                                                     'type_module' => 'DOMAIN_BROWSER',
                                                                     'preferences' => [
-                                                                                      'display_mode' => Class_Systeme_ModulesAppli::LISTE_FORMAT_ACCORDEON
+                                                                                      'display_mode' => Class_Systeme_ModulesAppli::LISTE_FORMAT_VIGNETTES
                                                                     ]]);
 
     $this->helper->setView(new ZendAfi_Controller_Action_Helper_View());
@@ -126,7 +126,7 @@ abstract class ZendAfi_View_Helper_Accueil_DomainBrowserViewAccordionTestCase ex
 
 
 
-class ZendAfi_View_Helper_Accueil_DomainBrowserViewAccordionTest extends ZendAfi_View_Helper_Accueil_DomainBrowserViewAccordionTestCase {
+class ZendAfi_View_Helper_Accueil_DomainBrowserViewThumbnailsTest extends ZendAfi_View_Helper_Accueil_DomainBrowserViewThumbnailsTestCase {
   /** @test */
   public function linkForDomainMetalShouldBePresent() {
     $this->assertXPath($this->_html, '//div[contains(@class,"domains")]//ul[@class="children"]//li//a[contains(@href, "/recherche/simple/id_catalogue/1/id_module/9/tri/annee+desc")]', $this->_html);
@@ -173,7 +173,7 @@ class ZendAfi_View_Helper_Accueil_DomainBrowserWithNoBreadcrumbSettingsTest exte
 
 
 
-class ZendAfi_View_Helper_Accueil_DomainBrowserWithDisplayModeSettingTest extends ZendAfi_View_Helper_Accueil_DomainBrowserViewAccordionTestCase {
+class ZendAfi_View_Helper_Accueil_DomainBrowserWithDisplayModeSettingTest extends ZendAfi_View_Helper_Accueil_DomainBrowserViewThumbnailsTestCase {
   public function setup() {
     parent::setup();
     $this->_html = $this->helper->getBoite();
diff --git a/tests/library/ZendAfi/View/Helper/ListeNotices/MurTest.php b/tests/library/ZendAfi/View/Helper/ListeNotices/MurTest.php
index 37d747b3deceff924a1387c4492e89390bbc2fab..f8fb8e50367d5d041d45ad138b6e10433521552a 100644
--- a/tests/library/ZendAfi/View/Helper/ListeNotices/MurTest.php
+++ b/tests/library/ZendAfi/View/Helper/ListeNotices/MurTest.php
@@ -255,7 +255,7 @@ class ZendAfi_View_Helper_ListeNotices_Mur_BarreDeLienTest extends ZendAfi_View_
 
   /** @test */
   public function barreDeLienShouldContainUrlAjoutPanier() {
-    $this->assertXPath($this->_html, '//a[contains(@href, "panier/add-record-ajax/id_notice/34")]', $this->_html);
+    $this->assertXPath($this->_html, '//li[@class="add_to_cart"]//a[contains(@href, "panier/add-record-ajax/id_notice/34")]', $this->_html);
   }
 
 
diff --git a/tests/library/ZendAfi/View/Helper/ListeNotices/TableauTest.php b/tests/library/ZendAfi/View/Helper/ListeNotices/TableauTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9bd900deaaeeda0cafab8a8fce9a83b45170350e
--- /dev/null
+++ b/tests/library/ZendAfi/View/Helper/ListeNotices/TableauTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_View_Helper_ListeNotices_TableauTest extends ViewHelperTestCase {
+  protected
+    $_storm_default_to_volatile = true,
+    $_html = '',
+    $_helper;
+
+
+  public function setUp() {
+    parent::setUp();
+    $this->_helper = new ZendAfi_View_Helper_ListeNotices_Tableau();
+    $this->_helper->setView($this->view);
+
+    $data = [$this->fixture('Class_Notice',
+                            ['id' => 42,
+                             'titre_principal' => 'Le grand livre de Beatrix Potter'])];
+
+    $this->_html = $this->_helper->listeNotices_Tableau($data, ['liste_codes' => 'J;A;F;C;N']);
+  }
+
+
+  /** @test */
+  public function pageShouldContainsTitleColumn() {
+    $this->assertXPathContentContains($this->_html, '//td[@class="listeTitre"]', 'Titre');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsBeatrixPotter() {
+    $this->assertXPathContentContains($this->_html, '//td', 'Beatrix Potter');
+  }
+}
\ No newline at end of file
diff --git a/tests/scenarios/Mailer/MailerTest.php b/tests/scenarios/Mailer/MailerTest.php
index f9938f711b9aba74e4635f0f2cbd54b1fb1abd56..7b41c6e06b4ec3ee4b94df063c392bff95bcb22c 100644
--- a/tests/scenarios/Mailer/MailerTest.php
+++ b/tests/scenarios/Mailer/MailerTest.php
@@ -41,92 +41,159 @@ abstract class MailerWithUserConnectedTestCase extends AbstractControllerTestCas
     ZendAfi_Auth::getInstance()->logUser($this->_guest);
 
     $this->fixture('Class_ModeleFusion',
-                   ['id' => 6]);
+                   ['id' => 6,
+                    'type' => Class_ModeleFusion::RECORDS_TEMPLATE,
+                    'contenu' => '{notices.each[<strong>{titre_principal}</strong>]}']);
   }
 }
 
 
 
-
-class MailerSearchResultSimpleTest extends MailerWithUserConnectedTestCase {
-
+class MailerSearchResultWarmupTest extends MailerWithUserConnectedTestCase {
   /** @test */
-  public function authLoginformShouldBePresent() {
+  public function withoutUserPageShouldContainsAuthLoginForm() {
     ZendAfi_Auth::getInstance()->clearIdentity();
-    $this->dispatch('/recherche/send-mail/expressionRecherche/il+%C3%A9tait+une+fois+dans+l%27ouest/tri/%2A/code_rebond/A26874/ids/6731%3B6877%3B6917%3B7528%3B7574%3B8648%3B11793%3B11972%3B13994%3B14010/strategy/Notice_List/modele_fusion/6', true);
-
+    $this->dispatch('/recherche/send-mail/expressionRecherche/il+%C3%A9tait+une+fois+dans+l%27ouest/tri/%2A/code_rebond/A26874', true);
     $this->assertContains('<input type=\"submit\" name=\"login\"', $this->_response->getBody());
   }
 
 
   /** @test */
-  public function subjectShouldBeIlEtaitUneFoisDansLOuest() {
-    $this->dispatch('/recherche/send-mail/expressionRecherche/il+%C3%A9tait+une+fois+dans+l%27ouest/tri/%2A/code_rebond/A26874/ids/6731%3B6877%3B6917%3B7528%3B7574%3B8648%3B11793%3B11972%3B13994%3B14010/strategy/Notice_List/modele_fusion/6/subject/il+%C3%A9tait+une+fois+dans+l%27ouest', true);
-    $this->assertXPath('//form//input[@type="text"][@value="PHP Unit : Documents il était une fois dans l\'ouest"]');
-  }
-
-
-  /** @test */
-  public function emailFromShouldBeDisplay() {
+  public function withoutUserMailpageShouldContainsSenderEmailInput() {
     $this->_guest->setMail('');
-    $this->dispatch('/recherche/send-mail/expressionRecherche/il+%C3%A9tait+une+fois+dans+l%27ouest/tri/%2A/code_rebond/A26874/ids/6731%3B6877%3B6917%3B7528%3B7574%3B8648%3B11793%3B11972%3B13994%3B14010/strategy/Notice_List/modele_fusion/6/subject/il+%C3%A9tait+une+fois+dans+l%27ouest', true);
+    $this->dispatch('/recherche/send-mail/expressionRecherche/il+%C3%A9tait+une+fois+dans+l%27ouest/tri/%2A/code_rebond/A26874', true);
     $this->assertContains('<input type=\"email\" name=\"email\"', $this->_response->getBody());
   }
 }
 
 
 
+abstract class MailerSearchResultSendMailTestCase extends MailerWithUserConnectedTestCase {
+  public function setUp() {
+    parent::setUp();
 
-class MailerSearchResultPostTest extends MailerWithUserConnectedTestCase {
+    $this->fixture('Class_Notice',
+                   ['id' => 3,
+                    'titre_principal' => 'Il était une fois dans l\'ouest']);
 
-  public function setup() {
+
+    $this->fixture('Class_Notice',
+                   ['id' => 6,
+                    'titre_principal' => 'Il était une autre fois dans l\'ouest']);
+
+    $this->mock_sql = $this->mock()
+                           ->whenCalled('fetchAll')
+                           ->answers([ [3, ''], [6, ''] ]);
+
+    Zend_Registry::set('sql', $this->mock_sql);
+  }
+}
+
+
+
+class MailerSearchResultSendMailWithoutSelectionTest extends MailerSearchResultSendMailTestCase {
+  public function setUp() {
     parent::setUp();
-    Zend_Mail::setDefaultTransport($this->_mock_transport = new MockMailTransport());
+    $this->dispatch('/recherche/send-mail/expressionRecherche/il+%C3%A9tait+une+fois+dans+l%27ouest/tri/%2A/code_rebond/A26874', true);
+  }
 
-    $this->postDispatch('/opac/recherche/send-mail',
-                        ['subject' => 'search result from libray Boutheon for "One upon a time"',
-                         'recipient' => 'gloas@afi-sa.fr',
-                         'content' => '<html><body><div>record</div></body></html>']);
+
+  /** @test */
+  public function pageShouldContainsSubjectIlEtaitUneFoisDansLOuest() {
+    $this->assertXPath('//form//input[@type="text"][@value="PHP Unit : Documents pour : il était une fois dans l\'ouest"]');
   }
 
 
   /** @test */
-  public function shouldContainsScriptToRedirect() {
-    $this->assertXPathContentContains('//script', 'location.reload()');
+  public function pageShouldContainsRecipientInput() {
+    $this->assertXPath('//form//input[@type="email"][@name="recipient"]');
   }
 
 
   /** @test */
-  public function senderShouldBeTreizeAtBdDotCom() {
-    $this->assertEquals('treize@bd.com', $this->_mock_transport->getSentMails()[0]->getFrom());
+  public function pageShouldContainsIlEtaitUneFoisDansLOuestInMergedContent() {
+    $this->assertXPathContentContains('//form//textarea[@name="content"]',
+                                      '&lt;strong&gt;Il était une fois dans l\'ouest&lt;/strong&gt;',
+                                      $this->_response->getBody());
   }
-}
 
 
+  /** @test */
+  public function pageShouldContainsIlEtaitUneAutreFoisDansLOuestInMergedContent() {
+    $this->assertXPathContentContains('//form//textarea[@name="content"]',
+                                      '&lt;strong&gt;Il était une autre fois dans l\'ouest&lt;/strong&gt;',
+                                      $this->_response->getBody());
+  }
+}
 
 
-class MailerLinkInSearchResultTest extends AbstractControllerTestCase {
-  protected $_storm_default_to_volatile = true;
 
+class MailerSearchResultSendMailWithSelectionTest extends MailerSearchResultSendMailTestCase {
   public function setUp() {
     parent::setUp();
 
-    $this->fixture('Class_ModeleFusion',
-                   ['id' => 6,
-                    'type' => 'Notice_List']);
+    Zend_Registry::get('session')->search_record_selection = [6];
+    $this->mock_sql
+      ->whenCalled('fetchAll')
+      ->with('select id_notice, facettes from notices Where id_notice in (6)',
+             true, false)
+      ->answers([ [6, '']])
+      ->beStrict();
+
+    $this->dispatch('/recherche/send-mail/expressionRecherche/il+%C3%A9tait+une+fois+dans+l%27ouest/tri/%2A/code_rebond/A26874', true);
+  }
 
-    $this->dispatch('/recherche/simple/expressionRecherche/seven+deadly+sins', true);
+
+  /** @test */
+  public function pageShouldContainsSubjectDansMaSelection() {
+    $this->assertXPath('//form//input[@type="text"][@value="PHP Unit : Documents dans ma sélection"]');
   }
 
 
   /** @test */
-  public function shareByMAilShouldBePresent() {
-    $this->assertXPath('//div//a[contains(@href,"/recherche/send-mail/expressionRecherche/seven+deadly+sins/ids/")][contains(@href,"/subject/pour+%3A+/strategy/Notice_List/modele_fusion/6")]');
+  public function pageShouldNotContainsIlEtaitUneFoisDansLOuestInMergedContent() {
+    $this->assertNotXPathContentContains('//form//textarea[@name="content"]',
+                                         '&lt;strong&gt;Il était une fois dans l\'ouest&lt;/strong&gt;',
+                                         $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function pageShouldContainsIlEtaitUneAutreFoisDansLOuestInMergedContent() {
+    $this->assertXPathContentContains('//form//textarea[@name="content"]',
+                                      '&lt;strong&gt;Il était une autre fois dans l\'ouest&lt;/strong&gt;',
+                                      $this->_response->getBody());
   }
 }
 
 
 
+class MailerSearchResultPostTest extends MailerWithUserConnectedTestCase {
+
+  public function setup() {
+    parent::setUp();
+    Zend_Mail::setDefaultTransport($this->_mock_transport = new MockMailTransport());
+
+    $this->postDispatch('/opac/recherche/send-mail',
+                        ['subject' => 'search result from libray Boutheon for "One upon a time"',
+                         'recipient' => 'gloas@afi-sa.fr',
+                         'content' => '<html><body><div>record</div></body></html>']);
+  }
+
+
+  /** @test */
+  public function shouldContainsScriptToRedirect() {
+    $this->assertXPathContentContains('//script', 'location.reload()');
+  }
+
+
+  /** @test */
+  public function senderShouldBeTreizeAtBdDotCom() {
+    $this->assertEquals('treize@bd.com', $this->_mock_transport->getSentMails()[0]->getFrom());
+  }
+}
+
+
 
 
 class MailerPopupEmailPostTest extends MailerWithUserConnectedTestCase {
diff --git a/tests/scenarios/SearchSelection/SearchSelectionTest.php b/tests/scenarios/SearchSelection/SearchSelectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cedd474ccd013c1e355f067cc54585899c45dedb
--- /dev/null
+++ b/tests/scenarios/SearchSelection/SearchSelectionTest.php
@@ -0,0 +1,611 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+abstract class SearchSelectionTestCase extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+    Class_AdminVar::set('ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION', 1);
+
+    $this->mock_sql = $this->mock()
+                           ->whenCalled('fetchAll')->answers([[8, ''], [9, ''], [10, '']])
+      ;
+    Zend_Registry::set('sql', $this->mock_sql);
+
+    Class_Profil::getCurrentProfil()
+      ->setCfgModules(['recherche' =>
+                       ['resultatsimple' =>
+                        [
+                         'liste_format' => Class_Systeme_ModulesAppli::LISTE_FORMAT_VIGNETTES,
+                         'liste_codes' => "TAN9"]]]);
+
+    $this->fixture('Class_Notice',
+                   ['id' => 8,
+                    'clef_alpha'=>'HARRY_POTTER_ROWLING_1',
+                    'titre_principal' => 'Harry Potter',
+                    'clef_oeuvre' =>'HARRY_POTTER',
+                    'url_vignette'=>'no',
+                    'url_image'=>'no',
+                    'date_creation'=> '2013-12-30']);
+
+    $this->fixture('Class_Notice',
+                   ['id' => 9,
+                    'clef_alpha'=>'MILLENIUM_LARSSON_1',
+                    'titre_principal' => 'Millenium',
+                    'clef_oeuvre' =>'MILLENIUM_LARSSON',
+                    'url_vignette'=>'no',
+                    'url_image'=>'no',
+                    'date_creation'=> '2013-12-30']);
+
+      $this->fixture('Class_Notice',
+                   ['id' => 10,
+                    'clef_alpha'=>'INTERSTELLAR_NOLAN_3',
+                    'titre_principal' => 'Interstellar',
+                    'clef_oeuvre' =>'INTERSTALLAR_NOLAN',
+                    'url_vignette'=>'no',
+                    'url_image'=>'no',
+                    'date_creation'=> '2015-11-28']);
+  }
+}
+
+
+
+class SearchSelectionNotActivatedTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    Class_AdminVar::set('ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION', 0);
+
+    $this->dispatch('/recherche/simple/expressionRecherche/*', true);
+  }
+
+
+  /** @test */
+  public function pageShouldNotContainsselectionMenu() {
+    $this->assertNotXPath('//div[@class="record-selection"]/a[text()="Sélection : "]');
+  }
+}
+
+
+
+
+class SearchSelectionWithEmptySessionTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/recherche/simple/expressionRecherche/*', true);
+  }
+
+
+  /** @test */
+  public function pageShouldNotHaveAnyCheckedCheckbox() {
+    $this->assertNotXPath('//input[@checked]');
+  }
+}
+
+
+
+
+class SearchSelectionWithSessionTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    Zend_Registry::get('session')->search_record_selection = [8, 10];
+
+    $this->dispatch('/recherche/simple/expressionRecherche/pomme/facettes/T3/page/1/liste_format/3/page_size/20/tri/alpha_titre', true);
+  }
+
+
+  /** @test */
+  public function pageShouldContainsRecordMillenium() {
+    $this->assertXPathContentContains('//div[@class="vignette_titre"]//a', 'Millenium');
+  }
+
+
+  /** @test */
+  public function pageShouldNotIncludeLinkAddRecordAjaxOnBasket() {
+    $this->assertNotXPath('//a[contains(@href, "panier/add-record-ajax/")]');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsUncheckedCheckboxToSelectMilleniumRecord() {
+    $this->assertXPath('//div[@class="vignette_select_record"]/input[@type="checkbox"][@value="9"][@name="select_record_9"][@title=\'Sélectionner "Millenium" pour impression, export ou sauvegarde\'][not(@checked)]');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsCheckedCheckboxToUnselectHarryPotterRecord() {
+    $this->assertXPath('//div[@class="vignette_select_record"]/input[@type="checkbox"][@value="8"][@name="select_record_8"][@checked]');
+  }
+
+
+  /** @test */
+  public function checkboxOnClickShouldAjaxGetRecordsSelectToggle() {
+    $url = Class_url::relative(['module' => 'opac',
+                                'controller' => 'records',
+                                'action' => 'select-toggle',
+                                'id' => 8]);
+
+    $this->assertXPath('//input[@onclick="$.get(\''. $url .'\', updateRecordSelectionCount)"]');
+  }
+
+
+  /** @test */
+  public function selectionMenuShouldContainsTwoRecordsSelected() {
+    $this->assertXPathContentContains('//div[@class="record-selection"]/a[text()="Sélection : "]/span', '2');
+  }
+
+
+  /** @test */
+  public function selectionMenuShouldContainsActionToClearSelection() {
+    $url = Class_url::relative(['module' => 'opac',
+                                'controller' => 'records',
+                                'action' => 'select-clear']);
+
+    $this->assertXPathContentContains('//div[@class="record-selection"]/ul/li/a[@href="' . $url . '"][@onclick="$.get(\'' . $url . '\', updateRecordSelectionCountAndClear); return false"]',
+                                      'Vider la sélection');
+  }
+
+
+
+  /** @test */
+  public function selectionMenuShouldContainsActionToAddToBasket() {
+    $url = Class_url::relative(['module' => 'opac',
+                                'controller' => 'panier',
+                                'action' => 'add-selection']);
+
+    $this->assertXPathContentContains('//div[@class="record-selection"]/ul/li/a[@href="' . $url . '"][@data-popup="true"]',
+                                      'Mettre dans un panier');
+  }
+
+
+  /** @test */
+  public function selectionMenuShouldContainsActionToSelectPage() {
+    $url = Class_url::relative(['module' => 'opac',
+                                'controller' => 'records',
+                                'action' => 'select-page',
+                                'expressionRecherche' => 'pomme',
+                                'tri' => 'alpha_titre',
+                                'page' => '1',
+                                'page_size' => 20,
+                                'liste_format' => 3,
+                                'facettes' => 'T3']);
+
+    $this->assertXPathContentContains('//div[@class="record-selection"]/ul/li/a[@href="' . $url . '"][@onclick="$.get(\'' . $url . '\', updateRecordSelectionCountAndCheckAll); return false"]',
+                                      'Sélectionner toute la page',
+                                      $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function selectionMenuShouldContainsActionToSelectAllResults() {
+    $url = Class_url::relative(['module' => 'opac',
+                                'controller' => 'records',
+                                'action' => 'select-all',
+                                'expressionRecherche' => 'pomme',
+                                'tri' => 'alpha_titre',
+                                'page' => '1',
+                                'page_size' => 20,
+                                'liste_format' => 3,
+                                'facettes' => 'T3']);
+
+    $this->assertXPathContentContains('//div[@class="record-selection"]/ul/li/a[@href="' . $url . '"][@onclick="$.get(\'' . $url . '\', updateRecordSelectionCountAndCheckAll); return false"]',
+                                      'Sélectionner tous les résultats',
+                                      $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function selectionMenuShouldContainsActionToViewSelection() {
+    $url = Class_url::relative(['module' => 'opac',
+                                'controller' => 'recherche',
+                                'action' => 'simple',
+                                'tri' => 'alpha_titre',
+                                'liste_format' => 3,
+                                'page_size' => 20,
+                                'selection' => 1]);
+
+    $this->assertXPathContentContains('//div[@class="record-selection"]/ul/li/a[@href="' . $url . '"]',
+                                      'Voir la sélection',
+                                      $this->_response->getBody());
+  }
+}
+
+
+
+
+class SearchSelectionSelectToggleRecordMilleniumTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    Zend_Registry::get('session')->search_record_selection = [8, 10];
+  }
+
+
+  /** @test */
+  public function toggleRecordNineShouldAddItToSession() {
+    $this->dispatch('/records/select-toggle/id/9', true);
+    $this->assertEquals([8, 10, 9],
+                        Zend_Registry::get('session')->search_record_selection);
+    return $this->_response->getBody();
+  }
+
+
+  /**
+   * @depends toggleRecordNineShouldAddItToSession
+   * @test
+   */
+  public function toggleRecordNineShouldAnswerJsonCountThree($response) {
+    $this->assertEquals(3, json_decode($response)->count);
+  }
+
+
+  /** @test */
+  public function toggleRecordHeightShouldRemoteItFromSession() {
+    $this->dispatch('/records/select-toggle/id/8', true);
+    $this->assertEquals([10],
+                        Zend_Registry::get('session')->search_record_selection);
+  }
+}
+
+
+
+class SearchSelectionSelectClearTest extends SearchSelectionTestCase {
+   public function setUp() {
+    parent::setUp();
+    Zend_Registry::get('session')->search_record_selection = [8, 10];
+    $this->dispatch('/records/select-clear', true);
+  }
+
+
+  /** @test */
+  public function recordsSelectionShouldBeEmpty() {
+    $this->assertEmpty(Zend_Registry::get('session')->search_record_selection);
+  }
+
+
+  /** @test */
+  public function answerShouldContainsCountZero() {
+    $this->assertEquals(0, json_decode($this->_response->getBody())->count);
+  }
+}
+
+
+
+
+class SearchSelectionSelectPageTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    Zend_Registry::get('session')->search_record_selection = [8, 10];
+    $this->dispatch('/records/select-page/expressionRecherche/pomme/facettes/T3/page/1/page_size/2', true);
+  }
+
+
+  /** @test */
+  public function sessionShouldContainsNine() {
+    $this->assertEquals([8, 10, 9],
+                        Zend_Registry::get('session')->search_record_selection);
+    return $this->_response->getBody();
+  }
+}
+
+
+
+class SearchSelectionSelectAllTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/records/select-all/expressionRecherche/pomme/facettes/T3/page/1/page_size/2', true);
+  }
+
+
+  /** @test */
+  public function sessionShouldContainsAll() {
+    $this->assertEquals([8, 9, 10],
+                        Zend_Registry::get('session')->search_record_selection);
+    return $this->_response->getBody();
+  }
+}
+
+
+
+class SearchSelectionSelectViewWithSelectionTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    Zend_Registry::get('session')->search_record_selection = [8, 10];
+    $this->mock_sql
+      ->whenCalled('fetchAll')
+      ->with('select id_notice, facettes from notices Where id_notice in (8,10)',
+             true, false)
+      ->answers([ [8, ''], [10, '']])
+      ->beStrict();
+
+    $this->fixture('Class_AdminVar',
+                   ['id' => 'ENABLE_BOOKMARKABLE_SEARCHES',
+                    'valeur' => 1]);
+
+    $this->dispatch('/recherche/simple/selection/1', true);
+  }
+
+
+  /** @test */
+  public function pageShouldContainsRecordMillenium() {
+    $this->assertXPathContentContains('//div[@class="vignette_titre"]//a', 'Interstellar');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsRemovableCriteriaSelectionCourante() {
+    $this->assertXPathContentContains('//div[@class="criteres_recherche"]//a', 'Sélection courante');
+  }
+
+
+  /** @test */
+  public function pageShouldNotContainsSearchSaveLink() {
+    $this->assertNotXPath('//a[contains(@href, "/bookmarked-searches/add")]');
+  }
+}
+
+
+
+class SearchSelectionSelectViewWithoutSelectionTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->mock_sql->beStrict();
+    $this->dispatch('/recherche/simple/selection/1', true);
+  }
+
+
+  /** @test */
+  public function pageShouldContainsRemovableCriteriaSelectionCourante() {
+    $this->assertXPathContentContains('//div[@class="criteres_recherche"]//a', 'Sélection courante');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsNoRecords() {
+    $this->assertXPathContentContains('//div', 'Aucun résultat trouvé');
+  }
+}
+
+
+
+
+class SearchSelectionAdminVarsTest extends Admin_AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/admin/index/adminvar', true);
+  }
+
+
+  /** @test */
+  public function pageShouldContainsAdminVarENABLE_SEARCH_MULTIPLE_RECORD_SELECTION() {
+    $this->assertXpathContentContains('//td', 'ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION');
+  }
+}
+
+
+
+class SearchSelectionAddToCartWithoutUserTest extends SearchSelectionTestCase {
+  /** @test */
+  public function withoutUserSessionShouldDisplayLoginPage() {
+    ZendAfi_Auth::getInstance()->clearIdentity();
+    $this->dispatch('/panier/add-selection', true);
+    $this->assertController('auth');
+  }
+}
+
+
+
+abstract class SearchSelectionAddToCartWithUserTestCase extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $histoire = $this->fixture('Class_Catalogue',
+                               ['id' => 97,
+                                'libelle' => 'histoire',
+                                'indexer' => 1,
+                                'auteur' => '1']);
+
+    $this->cart = $this->fixture('Class_PanierNotice',
+                                 ['id' => 15,
+                                  'id_panier' => 2,
+                                  'libelle' => 'my cart',
+                                  'date_maj' => '25/05/2010',
+                                  'notices' => '',
+                                  'user' => $this->user,
+                                  'catalogues' => [$histoire]]);
+
+    $this->user = $this->fixture('Class_Users',
+                                 ['id' => 23,
+                                  'pseudo' => 'zorn',
+                                  'nom' => 'john',
+                                  'login' => 'jzorn',
+                                  'password' => '123',
+                                  'panier_courant' => $this->cart]);
+
+    ZendAfi_Auth::getInstance()->logUser($this->user);
+  }
+}
+
+
+
+
+class SearchSelectionAddToCartTest extends SearchSelectionAddToCartWithUserTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/panier/add-selection', true);
+  }
+
+
+  /** @test */
+  public function titleShouldBeAddSelectionToCart() {
+    $this->assertXPathContentContains('//title', 'Mettre la sélection dans un panier');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsLinkAddToMyCart() {
+    $this->assertXPathContentContains('//p', 'Ajouter ma sélection au panier "my cart"');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsLinkAddToCreateCart() {
+    $this->assertXPathContentContains('//a[contains(@href, "panier/add-ajax/selection/1")]',
+                                      'Nouveau panier');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsLinkToSwitchCart() {
+    $this->assertXPathContentContains('//a[contains(@href, "panier/switch-ajax/id_panier/15/selection/1")]',
+                                      'Changer de panier');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsFormToAddSelection() {
+    $this->assertXPath('//form[contains(@action, "/panier/add-selection/id_panier/15")]');
+  }
+}
+
+
+
+
+class SearchSelectionPostAddSelectionToCartTest extends SearchSelectionAddToCartWithUserTestCase {
+  public function setUp() {
+    parent::setUp();
+    Zend_Registry::get('session')->search_record_selection = [8, 10];
+    $this->postDispatch('/panier/add-selection/id_panier/15',
+                        []);
+
+    Class_PanierNotice::clearCache();
+  }
+
+
+  /** @test */
+  public function cartShouldContainsRecordsPotterAndInterstellar() {
+    $this->assertEquals(['HARRY_POTTER_ROWLING_1', 'INTERSTELLAR_NOLAN_3'],
+                        Class_PanierNotice::find(15)->getClesNotices());
+  }
+
+
+  /** @test */
+  public function cartDomainShouldBeIndexedInRecord() {
+    $this->assertContains('Q97', Class_Notice::find(8)->getFacettes());
+  }
+}
+
+
+
+
+class SearchSelectionPostNewCartSelectionTest extends SearchSelectionAddToCartWithUserTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->postDispatch('/panier/add-ajax/selection/1',
+                        ['libelle' => 'my new selection']);
+  }
+
+
+  /** @test */
+  public function responseShouldBeARedirectToAddSelection() {
+    $this->assertRedirectTo('/panier/add-selection');
+  }
+}
+
+
+
+class SearchSelectionPostSwitchCartTest extends SearchSelectionAddToCartWithUserTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->postDispatch('/panier/switch-ajax/id_panier/2/selection/1',
+                        ['id_panier' => 15]);
+  }
+
+
+  /** @test */
+  public function responseShouldBeARedirectToAddSelection() {
+    $this->assertRedirectTo('/panier/add-selection');
+  }
+}
+
+
+
+class SearchSelectionWithSessionViewWallModeTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    Class_Profil::getCurrentProfil()
+      ->setCfgModules(['recherche' =>
+                       ['resultatsimple' =>
+                        [
+                         'liste_format' => Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR,
+                         'liste_codes' => "TAN9"]]]);
+
+    $this->dispatch('/recherche/simple/expressionRecherche/pomme/facettes/T3/page/1', true);
+  }
+
+
+  /** @test */
+  public function pageShouldContainsUCheckboxToSelectMilleniumRecord() {
+    $this->assertXPath('//ul[@class="barre-de-lien"]/li/input[@type="checkbox"][@value="9"][@name="select_record_9"]');
+  }
+
+
+  /** @test */
+  public function pageShouldNotIncludeLinkAddRecordAjaxOnBasket() {
+    $this->assertNotXPath('//a[contains(@href, "panier/add-record-ajax/")]');
+  }
+}
+
+
+
+
+class SearchSelectionPrintWithSelectionTest extends SearchSelectionTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    Zend_Registry::get('session')->search_record_selection = [8, 10];
+    $this->mock_sql
+      ->whenCalled('fetchAll')
+      ->with('select id_notice, facettes from notices Where id_notice in (8,10)',
+             true, false)
+      ->answers([ [8, ''], [10, '']])
+      ->beStrict();
+
+    $this->fixture('Class_ModeleFusion', ['id' => 1,
+                                          'nom' => 'recherche',
+                                          'contenu' => '{notices.each[<h1>{titre_principal}</h1>]}',
+                                          'type' => 'Notice_List']);
+
+    $this->dispatch('/recherche/print/expressionRecherche/pomme', true);
+  }
+
+
+  /** @test */
+  public function printPreviewShouldContainsInterstellar() {
+    $this->assertXPathContentContains('//h1', 'Interstellar', $this->_response->getBody());
+  }
+}
\ No newline at end of file