diff --git a/VERSIONS_WIP/94469 b/VERSIONS_WIP/94469
new file mode 100644
index 0000000000000000000000000000000000000000..640968ccd86c7d59601d178289d0dc86e49f76c4
--- /dev/null
+++ b/VERSIONS_WIP/94469
@@ -0,0 +1 @@
+ - ticket #94469 : Notices autorité : Ajout d'un écran de recherche / parcours des autorités
\ No newline at end of file
diff --git a/application/modules/opac/controllers/AuthorController.php b/application/modules/opac/controllers/AuthorController.php
index a234108d9922cd0abbb9307b852ed81067067890..4a53fbc214d831bb4bd47334e742f8ea740446ea 100644
--- a/application/modules/opac/controllers/AuthorController.php
+++ b/application/modules/opac/controllers/AuthorController.php
@@ -54,15 +54,9 @@ class AuthorController extends ZendAfi_Controller_Action {
 
 
   protected function _addInspectorGadget($author) {
-    if (!$ig = Zend_Controller_Front::getInstance()
-         ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget'))
-      return;
-
-    if(!$ig->isEnabled())
-      return;
-
-    $ig->addButton(new Class_Entity(['Label' => $this->_('Auteur Bokeh'),
-                                     'Content' => $this->view->renderAuthorMetadata($author)]));
+    if ($this->_isInspecting())
+      $this->_inspectorButton(new Class_Entity(['Label' => $this->_('Auteur Bokeh'),
+                                                'Content' => $this->view->renderAuthorMetadata($author)]));
   }
 
 
diff --git a/application/modules/opac/controllers/AuthoritySearchController.php b/application/modules/opac/controllers/AuthoritySearchController.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8393c1afdae6cd30d49c930415d21035b3fa4ad
--- /dev/null
+++ b/application/modules/opac/controllers/AuthoritySearchController.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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 AuthoritySearchController extends ZendAfi_Controller_Action {
+  public function indexAction() {
+    $tree_roots = $this->_getParam('tree_roots', '');
+    $criteres = (new Class_CriteresRecherche_Authority)->setParams($this->_request->getParams());
+
+    if ($this->_request->isPost()) {
+      $redirect_params = $criteres->getUrlCriteres();
+      if ($tree_roots)
+        $redirect_params['tree_roots'] = $tree_roots;
+
+      return $this->_redirect($this->view->url($redirect_params, null, true),
+                              ['prependBase' => false]);
+    }
+
+    $prefs = $this->_getActionPreferences();
+
+    $this->view->titre = $prefs['titre'];
+    $this->view->tree_roots = $tree_roots;
+    $action_params = $criteres->getUrlWithoutExpression();
+    if ($tree_roots)
+      $action_params['tree_roots'] = $tree_roots;
+
+    $this->view->form = (new ZendAfi_Form_AuthoritySearch())
+      ->setAction($this->view->url($action_params, null, true));
+
+    $this->view->form->populate($this->_request->getParams());
+
+    if (($record_id = (int)$this->_getParam('record_id'))
+        && ($record = Class_Notice::find($record_id)))
+      return $this->_handleRecord($record);
+
+    if ($criteres->isEmpty())
+      return; // do not search without criteria
+
+    $search_start_time = microtime(true);
+    $this->view->search_result = $search_result = Class_MoteurRecherche::getInstance()->lancerRecherche($criteres);
+
+    $search_result
+      ->setDuration(microtime(true) - $search_start_time)
+      ->setSettings(['liste_format' => Class_Systeme_ModulesAppli::LISTE_FORMAT_LINKS]);
+
+    if ($this->_isInspecting())
+      $this->_inspectorButton(new Class_Entity(['Label' => $this->_('Configuration de la recherche'),
+                                                'Content' => $this->view->searchInspector($search_result)]));
+  }
+
+
+  protected function _handleRecord($record) {
+    if ($this->_isInspecting())
+      $this->_inspectorButton(new Class_Entity(['Label' => $this->_('Notice Bokeh'),
+                                                'Content' => $this->view->notice_Unimarc($record)]));
+
+    return $this->view->record = $record;
+  }
+}
diff --git a/application/modules/opac/controllers/ErrorController.php b/application/modules/opac/controllers/ErrorController.php
index 8f01967fe020bd3fccc3ba1ac8c498c96427816f..714d41d0b3eeb164f173add9a66b413c22458460 100644
--- a/application/modules/opac/controllers/ErrorController.php
+++ b/application/modules/opac/controllers/ErrorController.php
@@ -34,9 +34,7 @@ class ErrorController extends ZendAfi_Controller_Action {
     $this->_response->clearBody();
 
     if (($this->_request->getServer('HTTP_HOST') == 'localhost')
-        || (($ig = Zend_Controller_Front::getInstance()
-             ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget'))
-            && $ig->isEnabled())
+        || $this->_isInspecting()
         || ((null != ($user = Class_Users::getLoader()->getIdentity()))
             && $user->isAdmin())) {
       $this->view->errors = $errors;
diff --git a/application/modules/opac/controllers/RechercheController.php b/application/modules/opac/controllers/RechercheController.php
index f7bd5adbbe08fcfb7b23211dc85d5a546bbf808c..471aecccbaf974c09b7fc530a0cae8bce6126d99 100644
--- a/application/modules/opac/controllers/RechercheController.php
+++ b/application/modules/opac/controllers/RechercheController.php
@@ -166,11 +166,9 @@ class RechercheController extends ZendAfi_Controller_Action {
 
 
   protected function _logSearch($search_result) {
-    if (($ig = Zend_Controller_Front::getInstance()
-         ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget'))
-        && $ig->isEnabled())
-      $ig->addButton(new Class_Entity(['Label' => $this->_('Configuration de la recherche'),
-                                       'Content' => $this->view->searchInspector($search_result)]));
+    if ($this->_isInspecting())
+      $this->_inspectorButton(new Class_Entity(['Label' => $this->_('Configuration de la recherche'),
+                                                'Content' => $this->view->searchInspector($search_result)]));
   }
 
 
@@ -892,19 +890,15 @@ class RechercheController extends ZendAfi_Controller_Action {
 
 
   protected function _addInspectorGadget($record) {
-    if (!$ig = Zend_Controller_Front::getInstance()
-         ->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget'))
+    if (!$this->_isInspecting())
       return;
 
-    if(!$ig->isEnabled())
-      return;
-
-    $ig->addButton(new Class_Entity(['Label' => $this->_('Notice Bokeh'),
-                                     'Content' => $this->view->notice_Unimarc($record)]));
+    $this->_inspectorButton(new Class_Entity(['Label' => $this->_('Notice Bokeh'),
+                                              'Content' => $this->view->notice_Unimarc($record)]));
 
-    if($record->isDilicom())
-      $ig->addButton(new Class_Entity(['Label' => $this->_('Dilicom'),
-                                       'Content' => $this->view->notice_Dilicom($record)]));
+    if ($record->isDilicom())
+      $this->_inspectorButton(new Class_Entity(['Label' => $this->_('Dilicom'),
+                                                'Content' => $this->view->notice_Dilicom($record)]));
   }
 }
 
diff --git a/application/modules/opac/views/scripts/authority-search/index.phtml b/application/modules/opac/views/scripts/authority-search/index.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..5d1459f3ed3ed10bf096883dab58e6467d079e0e
--- /dev/null
+++ b/application/modules/opac/views/scripts/authority-search/index.phtml
@@ -0,0 +1,6 @@
+<?php
+$this->openBoite($this->titre);
+echo $this->renderForm($this->form);
+echo $this->AuthoritySearch_Header($this->search_result);
+echo $this->AuthoritySearch_Result($this->search_result, $this->record, $this->tree_roots);
+$this->closeBoite();
diff --git a/library/Class/CriteresRecherche.php b/library/Class/CriteresRecherche.php
index ae2615a9852d1aea5a408e42227aab4b0a24206e..d00b5cc055ff0c8acb8addbe01ab14ff66acf643 100644
--- a/library/Class/CriteresRecherche.php
+++ b/library/Class/CriteresRecherche.php
@@ -19,29 +19,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
-class Class_CriteresRecherche {
-  use Trait_Translator;
-
-  const
-    SORT_RELEVANCE = '*',
-    SORT_TITLE = 'alpha_titre',
-    SORT_AUTHOR = 'alpha_auteur',
-    SORT_PUBLICATION = 'annee desc',
-    SORT_DOCTYPE = 'type_doc, alpha_titre',
-    SORT_NOVELTY = 'date_creation desc',
-    SORT_VIEWS = 'nb_visu desc',
-    SORT_RANDOM = 'RAND()',
-    MAX_PAGE_SIZE = 50;
-
-  protected static $_MAX_SEARCH_RESULTS = '';
-
-  protected
-    $_params = [],
-    $_validate_facette,
-    $_default_page_size = 20,
-    $_profil,
-    $_time,
-    $_validator;
+class Class_CriteresRecherche extends Class_CriteresRecherche_Abstract {
 
   public static $criteres = ['expressionRecherche' => 'Expression',
                              'rech_titres' => 'Titre',
@@ -81,16 +59,6 @@ class Class_CriteresRecherche {
   ];
 
 
-  public static function setMaxSearchResults($max) {
-    static::$_MAX_SEARCH_RESULTS = $max;
-  }
-
-
-  public function getMaxSearchResults() {
-    return (int) static::$_MAX_SEARCH_RESULTS;
-  }
-
-
   public function __construct() {
     $this->_profil = Class_Profil::getCurrentProfil();
   }
@@ -107,13 +75,6 @@ class Class_CriteresRecherche {
   }
 
 
-  public function getValidateFacette() {
-    if (!isset($this->_validate_facette))
-      $this->_validate_facette = new ZendAfi_Validate_Facette();
-    return $this->_validate_facette;
-  }
-
-
   public function getValidParameters() {
     return array_merge(array_keys(static::$criteres),
                        ['filtres',
@@ -167,48 +128,6 @@ class Class_CriteresRecherche {
   }
 
 
-  /**
-   * @param $rech array paramètres de recherche et leurs valeurs
-   * @return Class_CritereRecherche
-   */
-  public function setParams($rech) {
-    $this->_params = $this->filterParams($rech);
-    return $this;
-  }
-
-
-  public function setDefaultPageSize($page_size) {
-    $page_size = (int)$page_size;
-    if (0 < $page_size && static::MAX_PAGE_SIZE >= $page_size)
-      $this->_default_page_size = $page_size;
-    return $this;
-  }
-
-
-  public function setTime($time) {
-    $this->_time = $time;
-    return $this;
-  }
-
-
-  public function getTime() {
-    return $this->_time;
-  }
-
-
-  public function getParam($name, $default_value = null) {
-    return isset($this->_params[$name]) ? $this->_params[$name] : $default_value;
-  }
-
-
-  public function unsetParam($name) {
-    if (array_key_exists($name, $this->_params))
-      unset($this->_params[$name]);
-
-    return $this;
-  }
-
-
   public function rechercheElargie() {
     $this->_params['pertinence']=1;
     return $this;
@@ -225,18 +144,6 @@ class Class_CriteresRecherche {
   }
 
 
-  public function getFacettes() {
-    $facettes = explode('-', $this->getParam('facettes', ''));
-    $facettes[] = $this->getParam('facette', '');
-
-    return  array_unique(array_filter($facettes,
-                                      [$this->getValidateFacette(),
-                                       'isValid']
-                                      ));
-  }
-
-
-
   public function getMultiFacets() {
     return array_filter(array_merge(explode('-', $this->getParam('multifacets','')),
                                     $this->selectionToArray(Class_CodifGenre::CODE_FACETTE,
@@ -330,18 +237,6 @@ class Class_CriteresRecherche {
   }
 
 
-  public function getFacettesUrlEncoded() {
-    $facettes = $this->getFacettes();
-    return $facettes ? implode('-', $facettes) : null;
-  }
-
-
-  public function getFacettesForMoteurRecherche() {
-    $facettes = $this->getFacettes();
-    return $facettes ? '['.implode('][',$facettes).']' : '';
-  }
-
-
   public function getTypeDoc() {
     $digital_resource = Class_DigitalResource::getInstance();
     $validator = function($type) use($digital_resource){
@@ -385,7 +280,7 @@ class Class_CriteresRecherche {
     $id_panier = $this->getParam('id_panier','');
 
     if ($id_user=$this->getParam('id_user'))
-      $panier = Class_PanierNotice::getLoader()->findFirstBy(['id_user' => $id_user,
+      $panier = Class_PanierNotice::findFirstBy(['id_user' => $id_user,
                                                               'id' => $id_panier]);
     return $panier ? $panier : Class_PanierNotice::find($id_panier);
   }
@@ -648,17 +543,6 @@ class Class_CriteresRecherche {
   }
 
 
-  public function getPage() {
-    return $this->getParam('page', null);
-  }
-
-
-  public function getPageSize() {
-    return $this->getParam('page_size',
-                           $this->_default_page_size);
-  }
-
-
   public function getFrom() {
     return $this->getParam('from', null);
   }
@@ -681,33 +565,8 @@ class Class_CriteresRecherche {
   }
 
 
-  public function filterParams($params) {
-    $valid_parameters = $this->getValidParameters();
-    $filtered_params = [];
-
-    $params = $this->replaceEmptyRechercheByStar($params);
-
-    foreach($valid_parameters as $key)
-      if (array_isset($key, $params)
-          && $this->_getValidator()->isValid($key, $params))
-        $filtered_params[$key] = $params[$key];
-
-    if (isset($params['page_size']) && (static::MAX_PAGE_SIZE < (int)$params['page_size']))
-      $filtered_params['page_size']  = static::MAX_PAGE_SIZE;
-
-    return $filtered_params;
-  }
-
-
-  protected function _getValidator() {
-    return $this->_validator
-      ? $this->_validator
-      : $this->_validator = new Class_CriteresRecherche_Validator();
-  }
-
-
-  public function getCriteres() {
-    return $this->_params;
+  protected function _prepareParamsForValidation($params) {
+    return $this->replaceEmptyRechercheByStar($params);
   }
 
 
@@ -767,6 +626,11 @@ class Class_CriteresRecherche {
   }
 
 
+  public function getUrlCriteres() {
+    return $this->getUrlCriteresWithFacettes();
+  }
+
+
   public function getUrlCriteresWithFacettes() {
     $intersect = $this->_params;
 
@@ -783,9 +647,9 @@ class Class_CriteresRecherche {
 
     return ['controller' => 'recherche',
             'action' => 'simple'];
-
   }
 
+
   public function getCVSUrlCriteresWithFacettes() {
     $intersect=$this->_params;
 
@@ -878,6 +742,13 @@ class Class_CriteresRecherche {
   }
 
 
+  public function getUrlPager() {
+    return array_merge($this->getUrlRetourListe(),
+                       ['controller' => 'recherche',
+                        'action' => 'simple']);
+  }
+
+
   public function getUrlRemoveFacette($facette) {
     $facettes = array_diff($this->getFacettes(), [$facette->getCle()]);
     $url = $this->getUrlRetourListe();
@@ -1026,18 +897,6 @@ class Class_CriteresRecherche {
   }
 
 
-  public function setPageSize($size) {
-    $this->_params['page_size'] = $size;
-    return $this;
-  }
-
-
-  public function setPage($page) {
-    $this->_params['page'] = $page;
-    return $this;
-  }
-
-
   protected function _getBookmark() {
     return Class_User_BookmarkedSearch::find($this->getParam('bookmarked_search'));
   }
@@ -1048,4 +907,16 @@ class Class_CriteresRecherche {
               || $this->getFacettes()
               || $this->getMultiFacets());
   }
+
+
+  public function getStateError() {
+    if ($this->hasEmptyDomain()
+        && !$this->isSearchInBasket())
+      return $this->_('Domaine non paramétré');
+
+    if ($this->isEmptySelection())
+      return $this->_('La sélection courante est vide');
+
+    return parent::getStateError();
+  }
 }
diff --git a/library/Class/CriteresRecherche/Abstract.php b/library/Class/CriteresRecherche/Abstract.php
new file mode 100644
index 0000000000000000000000000000000000000000..382255cc9dd8de0c28bb3f5d9aefbe3a7c93afa5
--- /dev/null
+++ b/library/Class/CriteresRecherche/Abstract.php
@@ -0,0 +1,228 @@
+<?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
+ */
+
+abstract class Class_CriteresRecherche_Abstract {
+  use Trait_Translator;
+
+  const
+    SORT_RELEVANCE = '*',
+    SORT_TITLE = 'alpha_titre',
+    SORT_AUTHOR = 'alpha_auteur',
+    SORT_PUBLICATION = 'annee desc',
+    SORT_DOCTYPE = 'type_doc, alpha_titre',
+    SORT_NOVELTY = 'date_creation desc',
+    SORT_VIEWS = 'nb_visu desc',
+    SORT_RANDOM = 'RAND()',
+    MAX_PAGE_SIZE = 50;
+
+  protected static $_MAX_SEARCH_RESULTS = '';
+
+  protected
+    $_params = [],
+    $_validate_facette,
+    $_default_page_size = 20,
+    $_profil,
+    $_time,
+    $_validator;
+
+
+  public static function setMaxSearchResults($max) {
+    static::$_MAX_SEARCH_RESULTS = $max;
+  }
+
+
+  public static function getMaxSearchResults() {
+    return (int) static::$_MAX_SEARCH_RESULTS;
+  }
+
+
+  /**
+   * @param $rech array paramètres de recherche et leurs valeurs
+   * @return Class_CritereRecherche
+   */
+  public function setParams($rech) {
+    $this->_params = $this->filterParams($rech);
+    return $this;
+  }
+
+
+  public function getParam($name, $default_value = null) {
+    return isset($this->_params[$name]) ? $this->_params[$name] : $default_value;
+  }
+
+
+  public function unsetParam($name) {
+    if (array_key_exists($name, $this->_params))
+      unset($this->_params[$name]);
+
+    return $this;
+  }
+
+
+  public function getAvailablePageSize() {
+    $profil_param = (new Class_Profil_Preferences_SearchResult())->getPageSize($this->_profil);
+    $options = array_unique(['10' => 10,
+                             '20' => 20,
+                             '30' => 30,
+                             '40' => 40,
+                             '50' => 50,
+                             $profil_param => $profil_param]);
+    ksort($options);
+    return $options;
+  }
+
+
+  public function setDefaultPageSize($page_size) {
+    $page_size = (int)$page_size;
+    if (0 < $page_size && static::MAX_PAGE_SIZE >= $page_size)
+      $this->_default_page_size = $page_size;
+    return $this;
+  }
+
+
+  public function setTime($time) {
+    $this->_time = $time;
+    return $this;
+  }
+
+
+  public function getTime() {
+    return $this->_time;
+  }
+
+
+  public function getPage() {
+    return $this->getParam('page', null);
+  }
+
+
+  public function getPageSize() {
+    return $this->getParam('page_size',
+                           $this->_default_page_size);
+  }
+
+
+  public function filterParams($params) {
+    $valid_parameters = $this->getValidParameters();
+    $filtered_params = [];
+
+    $params = $this->_prepareParamsForValidation($params);
+
+    foreach($valid_parameters as $key)
+      if (array_isset($key, $params)
+          && $this->_getValidator()->isValid($key, $params))
+        $filtered_params[$key] = $params[$key];
+
+    if (isset($params['page_size']) && (static::MAX_PAGE_SIZE < (int)$params['page_size']))
+      $filtered_params['page_size']  = static::MAX_PAGE_SIZE;
+
+    return $filtered_params;
+  }
+
+
+  public function getValidParameters() {
+    return ['page', 'page_size', 'tri', 'facette', 'facettes'];
+  }
+
+
+  public function getValidateFacette() {
+    if (!isset($this->_validate_facette))
+      $this->_validate_facette = new ZendAfi_Validate_Facette();
+    return $this->_validate_facette;
+  }
+
+
+  public function getFacettes() {
+    $facettes = explode('-', $this->getParam('facettes', ''));
+    $facettes[] = $this->getParam('facette', '');
+
+    return  array_unique(array_filter($facettes,
+                                      [$this->getValidateFacette(),
+                                       'isValid']
+                                      ));
+  }
+
+
+  public function getFacettesUrlEncoded() {
+    $facettes = $this->getFacettes();
+    return $facettes ? implode('-', $facettes) : null;
+  }
+
+
+  protected function _prepareParamsForValidation($params) {
+    return $params;
+  }
+
+
+  protected function _getValidator() {
+    return $this->_validator
+      ? $this->_validator
+      : $this->_validator = new Class_CriteresRecherche_Validator();
+  }
+
+
+  public function getCriteres() {
+    return $this->_params;
+  }
+
+
+  public function setPageSize($size) {
+    $this->_params['page_size'] = $size;
+    return $this;
+  }
+
+
+  public function setPage($page) {
+    $this->_params['page'] = $page;
+    return $this;
+  }
+
+
+  public function getTri() {
+    return static::SORT_RELEVANCE;
+  }
+
+
+  public function getStateError() {
+    return false;
+  }
+
+
+  /** @return array suitable for url helpers */
+  public function getUrlPager() {
+    return $this->getUrlCriteres();
+  }
+
+
+  /**
+   * @param Trait_SearchCriteriaVisitor $visitor
+   * @return Class_CriteresRecherche_Abstract
+   */
+  abstract public function acceptVisitor($visitor);
+
+
+  /** @return bool */
+  abstract public function isEmpty();
+
+
+  /** @return array suitable for url helpers */
+  abstract public function getUrlCriteres();
+}
diff --git a/library/Class/CriteresRecherche/Authority.php b/library/Class/CriteresRecherche/Authority.php
new file mode 100644
index 0000000000000000000000000000000000000000..80d6be4e30dc1296310097afdd3cf7923056aa9c
--- /dev/null
+++ b/library/Class/CriteresRecherche/Authority.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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_CriteresRecherche_Authority extends Class_CriteresRecherche_Abstract {
+  public function getValidParameters() {
+    $parameters = parent::getValidParameters();
+    $parameters[] = 'expressionRecherche';
+    return $parameters;
+  }
+
+
+  public function acceptVisitor($visitor) {
+    $visitor->visitNoExtension(true);
+    $visitor->visitExpression($this->getParam('expressionRecherche'), false, $this->getTri());
+    $visitor->visitRecordType(Class_Notice::TYPE_AUTHORITY);
+    foreach($this->getFacettes() as $facette)
+      $visitor->visitFacette($facette);
+  }
+
+
+  public function getUrlCriteres() {
+    return array_merge($this->_params,
+                       ['controller' => 'authority-search', 'action' => 'index']);
+  }
+
+
+  public function getUrlWithoutExpression() {
+    $params = $this->getUrlCriteres();
+    unset($params['expressionRecherche']);
+    unset($params['page']);
+    return $params;
+  }
+
+
+  public function isEmpty() {
+    return in_array($this->getParam('expressionRecherche', ''),
+                    ['', '*']);
+  }
+
+
+  public function getExpressionRecherche() {
+    return $this->getParam('expressionRecherche');
+  }
+}
diff --git a/library/Class/MoteurRecherche.php b/library/Class/MoteurRecherche.php
index 7a898e15c51bb9817cae9fd37aeaca88b47c3804..39125c56aae7800ebb5f7174f0476e08628242e5 100644
--- a/library/Class/MoteurRecherche.php
+++ b/library/Class/MoteurRecherche.php
@@ -461,14 +461,8 @@ 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())
-      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')];
+    if ($error = $this->criteres_recherche->getStateError())
+      return ['statut' => 'erreur', 'erreur' => $error];
 
     return $this->getConditionsForRequest($this->getConditions(),
                                           $this->_or_conditions,
@@ -714,4 +708,19 @@ class Class_MoteurRecherche {
 
     $this->setCondition('id_notice in (' . implode(',', $selection->values()). ')');
   }
+
+
+  public function visitRecordType($type) {
+    $this->setTypeCondition($type);
+  }
+
+
+  public function setTypeCondition($type) {
+    if (in_array($type, [Class_Notice::TYPE_BIBLIOGRAPHIC,
+                         Class_Notice::TYPE_AUTHORITY]))
+
+      $this->_type_condition = 'type=' . $type;
+
+    return $this;
+  }
 }
\ No newline at end of file
diff --git a/library/Class/Notice.php b/library/Class/Notice.php
index a4ed9fa41db1d7549509d432444eccc8f7ab7e4e..6ad8cb9cf15eceacdafe2154f3c3697d5c6c8ee3 100644
--- a/library/Class/Notice.php
+++ b/library/Class/Notice.php
@@ -226,6 +226,11 @@ class Class_Notice extends Storm_Model_Abstract {
   }
 
 
+  public function getTypeLabel() {
+    return $this->_getDataMap()->getTypeLabel();
+  }
+
+
   public function initializeAttributes($datas) {
     parent::initializeAttributes($datas);
     if (isset($datas['unimarc']))
diff --git a/library/Class/Notice/AuthorityRelations.php b/library/Class/Notice/AuthorityRelations.php
new file mode 100644
index 0000000000000000000000000000000000000000..4469d034fe7e9c8befb96f1a515672da8950af7a
--- /dev/null
+++ b/library/Class/Notice/AuthorityRelations.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright (c) 2019, 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_Notice_AuthorityRelations extends Storm_Collection {
+  public static function allFor($record) {
+    return new static(Class_Notice_AuthorityRelation::allFor($record));
+  }
+
+
+  public function generics() {
+    return $this->select(function($one) { return $one->isGeneric(); });
+  }
+
+
+  public function specifics() {
+    return $this->select(function($one) { return $one->isSpecific(); });
+  }
+
+
+  public function rejects() {
+    return $this->select(function($one) { return $one->isReject(); });
+  }
+
+
+  public function links() {
+    return $this->select(function($one) { return $one->isLink(); });
+  }
+}
diff --git a/library/Class/Notice/AuthorityType.php b/library/Class/Notice/AuthorityType.php
index dbccbe72dc47e1a554c4f0126f4317364d64f72c..fcf8898fdfb406b5dc6e4b21d47295e3e3901a41 100644
--- a/library/Class/Notice/AuthorityType.php
+++ b/library/Class/Notice/AuthorityType.php
@@ -42,20 +42,32 @@ class Class_Notice_AuthorityType {
     ];
 
 
+  public function typeLabels() {
+    return ['a' => $this->_('nom de personne'),
+            'b' => $this->_('nom de collectivité'),
+            'c' => $this->_('nom de territoire ou nom géographique'),
+            'd' => $this->_('marque'),
+            'e' => $this->_('famille'),
+            'f' => $this->_('titre uniforme'),
+            'g' => $this->_('rubrique de classement'),
+            'h' => $this->_('auteur / titre'),
+            'i' => $this->_('auteur / rubrique de classement'),
+            'j' => $this->_('matière nom commun'),
+            'k' => $this->_('lieu d’édition'),
+            'l' => $this->_('forme, genre ou caractéristiques physiques')];
+  }
+
+
+  public function labelOfType($type) {
+    $labels = $this->typeLabels();
+    return isset($labels[$type])
+      ? $labels[$type]
+      : '';
+  }
+
+
   public function withTypesDo($closure) {
-    foreach(['a' => $this->_('nom de personne'),
-             'b' => $this->_('nom de collectivité'),
-             'c' => $this->_('nom de territoire ou nom géographique'),
-             'd' => $this->_('marque'),
-             'e' => $this->_('famille'),
-             'f' => $this->_('titre uniforme'),
-             'g' => $this->_('rubrique de classement'),
-             'h' => $this->_('auteur / titre'),
-             'i' => $this->_('auteur / rubrique de classement'),
-             'j' => $this->_('matière nom commun'),
-             'k' => $this->_('lieu d’édition'),
-             'l' => $this->_('forme, genre ou caractéristiques physiques'),
-             ] as $code => $label)
+    foreach($this->typeLabels() as $code => $label)
       $closure($code, $label);
   }
 
diff --git a/library/Class/Notice/DataMap/Abstract.php b/library/Class/Notice/DataMap/Abstract.php
index 1ee196b5faa53663821b2ca3e144ec0f841a9114..5aa3ac019ae9758d81f3f6b0cb868fe675474751 100644
--- a/library/Class/Notice/DataMap/Abstract.php
+++ b/library/Class/Notice/DataMap/Abstract.php
@@ -33,6 +33,7 @@ abstract class Class_Notice_DataMap_Abstract {
   /** @return string */
   abstract public function getMainTitle();
 
+
   /**
    * @param $field string field facet code
    * @param $facets string
@@ -40,4 +41,8 @@ abstract class Class_Notice_DataMap_Abstract {
    * @return array
    */
   abstract public function getRecordField($field, $facets='');
+
+
+  /** @return string */
+  abstract public function getTypeLabel();
 }
diff --git a/library/Class/Notice/DataMap/UnimarcAuthority.php b/library/Class/Notice/DataMap/UnimarcAuthority.php
index aabd9c86ea18ee2443b478c8cba6034aa50edee6..962407b54536e57eb996e61b1bf07bde6acdfe0e 100644
--- a/library/Class/Notice/DataMap/UnimarcAuthority.php
+++ b/library/Class/Notice/DataMap/UnimarcAuthority.php
@@ -21,12 +21,25 @@
 
 
 class Class_Notice_DataMap_UnimarcAuthority extends Class_Notice_DataMap_Abstract {
+  protected $_authority_type;
+
+
   public function getMainTitle() {
-    $titres = $this->_record->get_subfield('250', 'a');
+    $zone = $this->_authorityType()->zoneForType('2', $this->_record->getTypeDoc());
+    $titres = $this->_record->get_subfield($zone, 'a');
     return $titres ? trim($titres[0]) : '';
   }
 
 
+  public function getTypeLabel() {
+    $label = [$this->_authorityType()->labelOfType($this->_record->getTypeDoc())];
+    if ($system = $this->_record->get_subfield('152', 'b'))
+      $label[] = $system[0];
+
+    return implode(', ', array_filter($label));
+  }
+
+
   public function getRecordField($field, $facets='') {
     if (Class_Codification::CODE_AUTHORITY_DATAS !== $field)
       return [];
@@ -35,6 +48,13 @@ class Class_Notice_DataMap_UnimarcAuthority extends Class_Notice_DataMap_Abstrac
             new Class_Notice_DataMap_UnimarcAuthorityNotes($this->_record),
             new Class_Notice_DataMap_UnimarcAuthorityUsages($this->_record)];
   }
+
+
+  protected function _authorityType() {
+    return $this->_authority_type
+      ? $this->_authority_type
+      : $this->_authority_type = new Class_Notice_AuthorityType();
+  }
 }
 
 
@@ -57,8 +77,7 @@ abstract class Class_Notice_DataMap_UnimarcAuthorityComponent {
 
 class Class_Notice_DataMap_UnimarcAuthorityNotes extends Class_Notice_DataMap_UnimarcAuthorityComponent {
   public function renderOn($view) {
-    if ($notes = $this->_record->get_subfield('330', 'a'))
-      return $view->tag('h3', 'Note d\'application') . $view->tag('p', reset($notes));
+    return $view->AuthoritySearch_RecordNotes($this->_record);
   }
 }
 
@@ -67,83 +86,28 @@ class Class_Notice_DataMap_UnimarcAuthorityNotes extends Class_Notice_DataMap_Un
 
 class Class_Notice_DataMap_UnimarcAuthorityUsages extends Class_Notice_DataMap_UnimarcAuthorityComponent {
   public function renderOn($view) {
-    $facets = array_filter($this->_record->getFacetCodes(),
-                           function($facet) { return $this->_isDynamicFacetValue($facet); });
-
-    if (!$facets)
-      return $this->_('Utilisé dans aucune notice');
-
-    $criterias = (new Class_CriteresRecherche())->setParams(['multifacets' => implode('-', $facets)]);
-
-    if (!$count = $this->_countByCriterias($criterias))
-      return $this->_('Utilisé dans aucune notice');
-
-    return $view->tagAnchor($view->url($criterias->getUrlCriteresWithFacettes(), null, true),
-                            $this->_plural($count,
-                                           'Utilisé dans aucune notice',
-                                           'Utilisé dans 1 notice',
-                                           'Utilisé dans %d notices',
-                                           $count));
-  }
-
-
-  protected function _isDynamicFacetValue($facet) {
-    return Class_CodifThesaurus::CODE_FACETTE === substr($facet, 0, 1)
-      && strlen($facet) === (Class_CodifThesaurus::ID_KEY_LENGTH * 2) + 1;
-  }
-
-
-  protected function _countByCriterias($criterias) {
-    return (new Class_MoteurRecherche)
-      ->beNotExtensible()
-      ->lancerRecherche($criterias)
-      ->getRecordsCount();
+    return $view->AuthoritySearch_RecordUsages($this->_record);
   }
 }
 
 
 
 
-class Class_Notice_DataMap_UnimarcAuthorityRelations extends Class_Notice_DataMap_UnimarcAuthorityComponent{
+class Class_Notice_DataMap_UnimarcAuthorityRelations
+  extends Class_Notice_DataMap_UnimarcAuthorityComponent{
+
   protected $_relations;
 
   public function renderOn($view) {
-    $this->_relations = new Storm_Collection(Class_Notice_AuthorityRelation::allFor($this->_record));
-
-    $render = [];
-    foreach(['isGeneric' => $this->_('Terme générique'),
-             'isSpecific'=> $this->_('Terme spécifique'),
-             'isReject'  => $this->_('Terme rejeté'),
-             'isLink'    => $this->_('Terme associé')]
-            as $selector => $label)
-      $render[] = $this->_renderLabelledList($view, $label, $selector);
-
-    return implode($render);
-  }
-
-
-  protected function _renderLabelledList($view, $label, $selector) {
-    $closure = function($item) use ($selector) { return $item->$selector(); };
-    $relations = $this->_relations->select($closure);
-    if ($relations->isEmpty())
-      return;
-
-    $terms = [];
-    foreach($relations as $relation)
-      $terms[] = $this->_renderLabelledItem($view, $relation);
-
-    return $view->tag('h3', $label) . $view->tag('ul', implode($terms));
-  }
-
-
-  protected function _renderLabelledItem($view, $relation) {
-    $label = $relation->label();
-    if ($item = Class_Exemplaire::findFirstAuthorityItemByOriginId($relation->id()))
-      $label = $view->tagAnchor($view->url(['controller' => 'recherche',
-                                            'action' => 'viewnotice',
-                                            'id' => $item->getIdNotice()],
-                                           null, true), $label);
-
-    return $view->tag('li', $label);
+    $record_url_closure = function($record_id) use($view) {
+      return $view->url(['controller' => 'recherche',
+                         'action' => 'viewnotice',
+                         'id' => $record_id],
+                        null, true);
+    };
+
+    return $view
+      ->AuthoritySearch_RecordRelations($this->_record,
+                                        $record_url_closure);
   }
 }
diff --git a/library/Class/Notice/DataMap/UnimarcBiblio.php b/library/Class/Notice/DataMap/UnimarcBiblio.php
index ad7df0b6664b1c0a500678944f0baa3997fefff1..bd8dc0498d5858a18b956b323653fa76bb877ce1 100644
--- a/library/Class/Notice/DataMap/UnimarcBiblio.php
+++ b/library/Class/Notice/DataMap/UnimarcBiblio.php
@@ -27,6 +27,11 @@ class Class_Notice_DataMap_UnimarcBiblio extends Class_Notice_DataMap_Abstract {
   }
 
 
+  public function getTypeLabel() {
+    return '';
+  }
+
+
   public function getRecordField($field, $facets='') {
     if ($this->_isReboundField($field))
       return $this->_getReboundField($field, $facets);
diff --git a/library/Class/Systeme/ModulesAppli.php b/library/Class/Systeme/ModulesAppli.php
index 3ba3de66167c1967bf126177b15368167e37cd96..05aff322785eaabf82ae07914b4aee03ae3a3981 100644
--- a/library/Class/Systeme/ModulesAppli.php
+++ b/library/Class/Systeme/ModulesAppli.php
@@ -29,6 +29,7 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
   const LISTE_FORMAT_VIGNETTES = 3;
   const LISTE_FORMAT_MUR = 4;
   const LISTE_FORMAT_CHRONO = 5;
+  const LISTE_FORMAT_LINKS = 6;
 
   const
     CVS_NONE = 0,
@@ -144,7 +145,10 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
 
                       'catalogue' => ['*' => ['libelle' => 'Catalogues',
                                               'popup_width' => 710,
-                                              'popup_height' => 620]]
+                                              'popup_height' => 620]],
+                      'authority-search' => ['*' => ['libelle' => 'Parcours des autorités',
+                                                     'popup_width' => 500,
+                                                     'popup_height' => 260]]
   ];
 
 
@@ -195,26 +199,25 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
    * @return array | false
    */
   public function getModule($type_module=false, $action=false) {
-    if (false !== $type_module) {
-      $type_module = (string)$type_module;
+    if (false === $type_module)
+      return $this->modules;
 
-      if (!array_key_exists($type_module, $this->modules))
-        return false;
+    $type_module = (string)$type_module;
 
-      if (
-          (false === $action)
-          || (!array_key_exists((string)$action, $this->modules[$type_module]))
-      ) {
-        $action = '*';
-      }
+    if (!array_key_exists($type_module, $this->modules))
+      return false;
 
-      if (!isset($this->modules[$type_module][$action]))
-        return [];
-      return $this->modules[$type_module][$action];
+    if (
+        (false === $action)
+        || (!array_key_exists((string)$action, $this->modules[$type_module]))
+    ) {
+      $action = '*';
     }
 
-    return $this->modules;
+    if (!isset($this->modules[$type_module][$action]))
+      return [];
 
+    return $this->modules[$type_module][$action];
   }
 
   /**
diff --git a/library/Class/Systeme/ModulesAppli/Default.php b/library/Class/Systeme/ModulesAppli/Default.php
index 15d39132226611ffb8042fa32d24ed88f50e8c23..ef193f32c4d3ca81d1d3104c69dd6309b7657867 100644
--- a/library/Class/Systeme/ModulesAppli/Default.php
+++ b/library/Class/Systeme/ModulesAppli/Default.php
@@ -21,6 +21,8 @@
 
 
 class Class_Systeme_ModulesAppli_Default {
+  use Trait_Translator;
+
   protected
     $_controller,
     $_action,
@@ -99,6 +101,9 @@ class Class_Systeme_ModulesAppli_Default {
       case 'domains':
         $valeurs = (new Class_Systeme_ModulesAccueil_DomainBrowser())->getDefaultValues();
         break;
+      case 'authority-search':
+        $valeurs = ['titre' => $this->_('Parcours des autorités')];
+        break;
 
       default : $valeurs = [];
     }
diff --git a/library/Trait/SearchCriteriaVisitor.php b/library/Trait/SearchCriteriaVisitor.php
index f52cd242d2a5cc3e7c15c54ff4adbaa0fab29cb9..71478b94c177e9ac0f7b5d6977e9e76467b522e6 100644
--- a/library/Trait/SearchCriteriaVisitor.php
+++ b/library/Trait/SearchCriteriaVisitor.php
@@ -55,4 +55,6 @@ trait Trait_SearchCriteriaVisitor {
   public function visitLimit($limit) {}
 
   public function visitBookmarkedSearch($bookmark, $version) {}
+
+  public function visitRecordType($type) {}
 }
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Action.php b/library/ZendAfi/Controller/Action.php
index f0f9a612ff01c28aded62d2aaffedc759392ac5e..7656aa5dbf25d0be44d7ab8461d493cda96591ec 100644
--- a/library/ZendAfi/Controller/Action.php
+++ b/library/ZendAfi/Controller/Action.php
@@ -24,7 +24,8 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 
   protected
     $_definitions,
-    $_plugins;
+    $_plugins,
+    $_inspector;
 
 
   protected function _getActionPlugins() {
@@ -376,4 +377,48 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
   public function getPluginsCollection() {
     return $this->_plugins;
   }
+
+
+  protected function _getActionPreferences() {
+    return Class_Profil::getCurrentProfil()
+      ->getCfgModulesPreferences($this->_request->getControllerName(),
+                                 $this->_request->getActionName());
+  }
+
+
+  protected function _inspectorButton($definition) {
+    $this->_getInspector()->addButton($definition);
+    return $this;
+  }
+
+
+  protected function _isInspecting() {
+    return $this->_getInspector()->isEnabled();
+  }
+
+
+  protected function _getInspector() {
+    if ($this->_inspector)
+      return $this->_inspector;
+
+    $ig = Zend_Controller_Front::getInstance()->getPlugin('ZendAfi_Controller_Plugin_InspectorGadget');
+
+    return $this->_inspector = $ig
+      ? $ig
+      : new ZendAfi_Controller_Action_NullInspector();
+  }
+}
+
+
+
+
+class ZendAfi_Controller_Action_NullInspector {
+  public function isEnabled() {
+    return false;
+  }
+
+
+  public function addButton($definition) {
+    return $this;
+  }
 }
diff --git a/library/ZendAfi/Form/AuthoritySearch.php b/library/ZendAfi/Form/AuthoritySearch.php
new file mode 100644
index 0000000000000000000000000000000000000000..59366814ef6af7ec8f615613c36ea33be0427c0a
--- /dev/null
+++ b/library/ZendAfi/Form/AuthoritySearch.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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_Form_AuthoritySearch extends ZendAfi_Form {
+  public function init() {
+    parent::init();
+    $this
+      ->addElement('text', 'expressionRecherche', [])
+      ->addElement('submit', 'run', ['label' => $this->_('Rechercher')]);
+  }
+}
diff --git a/library/ZendAfi/View/Helper/AuthoritySearch/Header.php b/library/ZendAfi/View/Helper/AuthoritySearch/Header.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef1f39c78aa683d5e5cd2fb601acf016fbe690d4
--- /dev/null
+++ b/library/ZendAfi/View/Helper/AuthoritySearch/Header.php
@@ -0,0 +1,43 @@
+<?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_AuthoritySearch_Header extends ZendAfi_View_Helper_BaseHelper {
+  public function AuthoritySearch_Header($result) {
+    return $result
+      ? $this->_tag('div',
+                    $this->_tag('div',
+                                $this->_renderCount($result),
+                                ['class' => 'info-recherche']),
+                    ['class' => 'resultats_page'])
+      : '';
+  }
+
+
+  protected function _renderCount($result) {
+    return $this->_tag('div',
+                       $this->view->search_ResultCount($result->getRecordsCount(),
+                                                       Class_CriteresRecherche_Authority::getMaxSearchResults())
+                       . ' '
+                       . $this->_tag('small', $this->_('(%1.2f secondes)', $result->getDuration())),
+                       ['class' => 'search-sentence']);
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/AuthoritySearch/Record.php b/library/ZendAfi/View/Helper/AuthoritySearch/Record.php
new file mode 100644
index 0000000000000000000000000000000000000000..109328a27d5a7285e7292d7675479fb484862031
--- /dev/null
+++ b/library/ZendAfi/View/Helper/AuthoritySearch/Record.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright (c) 2019, 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_AuthoritySearch_Record extends ZendAfi_View_Helper_BaseHelper {
+  public function AuthoritySearch_Record($record) {
+    if (!$record)
+      return '';
+
+    return
+      $this->_tag('h2', $record->getTitrePrincipal())
+      . $this->view->AuthoritySearch_RecordRelations($record)
+      . $this->view->AuthoritySearch_RecordNotes($record)
+      . $this->view->AuthoritySearch_RecordUsages($record)
+      ;
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/AuthoritySearch/RecordNotes.php b/library/ZendAfi/View/Helper/AuthoritySearch/RecordNotes.php
new file mode 100644
index 0000000000000000000000000000000000000000..f9f3dbd5d9190682b0a123230708f0c625a9a5fd
--- /dev/null
+++ b/library/ZendAfi/View/Helper/AuthoritySearch/RecordNotes.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright (c) 2019, 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_AuthoritySearch_RecordNotes extends ZendAfi_View_Helper_BaseHelper {
+  public function AuthoritySearch_RecordNotes($record) {
+    return ($record && ($notes = $record->get_subfield('330', 'a')))
+      ? $this->_renderNotes(reset($notes))
+      : '';
+  }
+
+
+  protected function _renderNotes($notes) {
+    return $notes
+      ? ($this->_tag('h3', $this->_('Note d\'application')) . $this->_tag('p', $notes))
+      : '';
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/AuthoritySearch/RecordRelations.php b/library/ZendAfi/View/Helper/AuthoritySearch/RecordRelations.php
new file mode 100644
index 0000000000000000000000000000000000000000..7b0c8bb9eaedd47df90492b3752c013e5a125c2c
--- /dev/null
+++ b/library/ZendAfi/View/Helper/AuthoritySearch/RecordRelations.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright (c) 2019, 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_AuthoritySearch_RecordRelations extends ZendAfi_View_Helper_BaseHelper {
+  protected $_record_url_closure;
+
+  public function AuthoritySearch_RecordRelations($record, $record_url_closure=null) {
+    if (!$record)
+      return '';
+
+    $this->_record_url_closure = $record_url_closure;
+
+    $relations = Class_Notice_AuthorityRelations::allFor($record);
+    $parts = [];
+    foreach([$this->_('Terme générique') => $relations->generics(),
+             $this->_('Terme spécifique') => $relations->specifics(),
+             $this->_('Terme rejeté') => $relations->rejects(),
+             $this->_('Terme associé') => $relations->links()]
+            as $label => $relations)
+      $parts[] = $this->_renderLabelledRelations($label, $relations);
+
+    return implode(array_filter($parts));
+  }
+
+
+  protected function _renderLabelledRelations($label, $relations) {
+    if ($relations->isEmpty())
+      return '';
+
+    $items = $relations
+      ->collect(function($relation)
+                {
+                  return $this->_renderRelation($relation);
+                });
+
+    return
+      $this->_tag('h3', $label)
+      . $this->_tag('ul', implode($items->getArrayCopy()));
+  }
+
+
+  protected function _renderRelation($relation) {
+    $label = $relation->label();
+    if ($item = Class_Exemplaire::findFirstAuthorityItemByOriginId($relation->id()))
+      $label = $this->_tagAnchor($this->_recordUrl($item->getIdNotice()),
+                                 $label);
+
+    return $this->_tag('li', $label);
+  }
+
+
+  protected function _recordUrl($record_id) {
+    return ($closure = $this->_record_url_closure)
+      ? $closure($record_id)
+      : ['record_id' => $record_id];
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/AuthoritySearch/RecordUsages.php b/library/ZendAfi/View/Helper/AuthoritySearch/RecordUsages.php
new file mode 100644
index 0000000000000000000000000000000000000000..b459f158f0360b8a56580e47d8bff98c327d63c5
--- /dev/null
+++ b/library/ZendAfi/View/Helper/AuthoritySearch/RecordUsages.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Copyright (c) 2019, 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_AuthoritySearch_RecordUsages extends ZendAfi_View_Helper_BaseHelper {
+  public function AuthoritySearch_RecordUsages($record) {
+    if (!$record)
+      return '';
+
+    return $this->_tag('p', $this->_renderUsage($record));
+  }
+
+
+  protected function _renderUsage($record) {
+    $facets = array_filter($record->getFacetCodes(),
+                           function($facet) { return $this->_isDynamicFacetValue($facet); });
+
+    if (!$facets)
+      return $this->_('Utilisé dans aucune notice');
+
+    $criterias = (new Class_CriteresRecherche())
+      ->setParams(['multifacets' => implode('-', $facets)]);
+
+    if (!$count = $this->_countByCriterias($criterias))
+      return $this->_('Utilisé dans aucune notice');
+
+    return $this->_tagAnchor($this->_url($criterias->getUrlCriteresWithFacettes(), null, true),
+                             $this->_plural($count,
+                                           'Utilisé dans aucune notice',
+                                           'Utilisé dans 1 notice',
+                                           'Utilisé dans %d notices',
+                                           $count));
+  }
+
+
+  protected function _isDynamicFacetValue($facet) {
+    return Class_CodifThesaurus::CODE_FACETTE === substr($facet, 0, 1)
+      && strlen($facet) === (Class_CodifThesaurus::ID_KEY_LENGTH * 2) + 1;
+  }
+
+
+  protected function _countByCriterias($criterias) {
+    return (new Class_MoteurRecherche)
+      ->beNotExtensible()
+      ->lancerRecherche($criterias)
+      ->getRecordsCount();
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/AuthoritySearch/Result.php b/library/ZendAfi/View/Helper/AuthoritySearch/Result.php
new file mode 100644
index 0000000000000000000000000000000000000000..cffde8f0256d1245de1bfa50c5f310e5aafeb153
--- /dev/null
+++ b/library/ZendAfi/View/Helper/AuthoritySearch/Result.php
@@ -0,0 +1,140 @@
+<?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_AuthoritySearch_Result extends ZendAfi_View_Helper_BaseHelper {
+  protected
+    $_result,
+    $_record,
+    $_record_path = [];
+
+  public function AuthoritySearch_Result($result, $record, $tree_roots) {
+    $this->_result = $result;
+    $this->_record = $record;
+
+    return $this->_tag('div',
+                       $this->_renderRecordOrResult()
+                       . $this->_renderTree($tree_roots)
+                       . $this->_tag('div', '', ['class' => 'clear']),
+                       ['class' => 'conteneur_simple']);
+  }
+
+
+  protected function _renderRecordOrResult() {
+    $html = ($record = $this->view->AuthoritySearch_Record($this->_record))
+      ? $record
+      : $this->_renderRecords();
+
+    return $this->_tag('div', $html, ['class' => 'resultat_recherche']);
+  }
+
+
+  protected function _renderRecords() {
+    return $this->_result
+      ? $this->view->listeNotices($this->_result)
+      : '';
+  }
+
+
+  protected function _renderTree($roots) {
+    if (!$roots || (!$roots = $this->_treeRootRecords($roots)))
+      return '';
+
+    $this->_prepareRecordPath();
+
+    return $this->_tag('div',
+                       $this->_tag('div',
+                                   $this->_tag('ul',
+                                               implode(array_map([$this, '_treeNodefor'],
+                                                                 $roots))),
+                                   ['class' => 'facette_outer']),
+                       ['class' => 'filtre_recherche']);
+  }
+
+
+  protected function _treeRootRecords($roots) {
+    return array_filter(array_map([$this, '_recordFromIdOrigine'], explode('-', $roots)));
+  }
+
+
+  protected function _treeNodeFor($record) {
+    $attribs = in_array($record->getId(), $this->_record_path)
+      ? ['class' => 'bold']
+      : [];
+
+    return $this->_tag('li',
+                       $this->_tagAnchor($this->_url(['record_id' => $record->getId()]),
+                                         $record->getTitrePrincipal(),
+                                         $attribs)
+                       . $this->_treeNodeSpecificsFor($record));
+  }
+
+
+  protected function _treeNodeSpecificsFor($record) {
+    if (!in_array($record->getId(), $this->_record_path))
+      return '';
+
+    $specifics = Class_Notice_AuthorityRelations::allFor($record)
+      ->specifics()
+      ->injectInto('',
+                   function($html, $one)
+                   {
+                     return $html
+                       . (($record = $this->_recordFromIdOrigine($one->id()))
+                          ? $this->_treeNodeFor($record)
+                          : '');
+                   });
+
+    return $specifics
+      ? $this->_tag('ul', $specifics)
+      : '';
+  }
+
+
+  protected function _recordFromIdOrigine($id) {
+    return $id && ($item = Class_Exemplaire::findFirstAuthorityItemByOriginId($id))
+      ? $item->getNotice()
+      : null;
+  }
+
+
+  protected function _prepareRecordPath() {
+    if (!$this->_record_path && $this->_record)
+      $this->_addRecordPathOf($this->_record);
+  }
+
+
+  protected function _addRecordPathOf($record) {
+    $this->_record_path[] = $record->getId();
+
+    $generic = Class_Notice_AuthorityRelations::allFor($record)
+      ->generics()
+      ->first();
+
+    if (!$generic
+        || (!$id = $generic->id())
+        || (!$generic_record = $this->_recordFromIdOrigine($id))
+        || in_array($generic_record->getId(), $this->_record_path))
+      return;
+
+    $this->_addRecordPathOf($generic_record);
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Avis.php b/library/ZendAfi/View/Helper/Avis.php
index 1253a451cb3af9c0037810672df34a94728ad648..d18e4b4e2926520cc0ddd7db1e53e182f77b5c4c 100644
--- a/library/ZendAfi/View/Helper/Avis.php
+++ b/library/ZendAfi/View/Helper/Avis.php
@@ -127,7 +127,7 @@ class ZendAfi_View_Helper_Avis extends ZendAfi_View_Helper_BaseHelper {
                                        $this->view->tagImg($url_vignette,
                                                            ['alt' => $this->_('vignette de \'%s\'', $title),
                                                             'title' => $type_doc_label . ' : ' . $title]),
-                                     ['href' => $this->_getUrlClickVignette($avis)])
+                                       ['href' => $this->_getUrlClickVignette($avis)])
                          . $this->_tag('a', $this->_('Voir la notice'),
                                        ['href' => $this->_getUrlNotice($avis)]),
                          ['class' => 'vignette_notice'])
@@ -171,7 +171,7 @@ class ZendAfi_View_Helper_Avis extends ZendAfi_View_Helper_BaseHelper {
 
   protected function _renderAuthor($avis) {
     $auteur = $this->view->escape($avis->getUserName());
-    $url_auteur = $this->_url($this->_getUrlAuthor($avis));
+    $url_auteur = $this->_urlWithContext($this->_getUrlAuthor($avis));
 
     $html = '' != $auteur ?
       ' ' . $this->_tag('a', $auteur, ['href' => $url_auteur])
@@ -214,8 +214,8 @@ class ZendAfi_View_Helper_Avis extends ZendAfi_View_Helper_BaseHelper {
 
 
   /** @params parts array*/
-  public function _url($parts) {
-    return $this->view->url(array_merge($parts, $this->_url_context));
+  public function _urlWithContext($parts) {
+    return $this->_url(array_merge($parts, $this->_url_context));
   }
 
 
@@ -231,10 +231,10 @@ class ZendAfi_View_Helper_Avis extends ZendAfi_View_Helper_BaseHelper {
     $html_actions = '';
     $suffix = ($avis->isAvisNotice()) ? 'avisnotice' : '-aviscms';
     foreach($this->_actions as $action) {
-      $link = $this->view->tagAnchor($this->_url(['action' => $action . $suffix,
-                                                  'id' => $avis->getId(),
-                                                  'active_tab' => $this->_active_tab,
-                                                  'page' => $this->_page]),
+      $link = $this->view->tagAnchor($this->_urlWithContext(['action' => $action . $suffix,
+                                                             'id' => $avis->getId(),
+                                                             'active_tab' => $this->_active_tab,
+                                                             'page' => $this->_page]),
                                      $this->view->boutonIco('type=' . $action));
 
       $html_actions .= $this->_tag('span', $link, ['rel' => $action]);
@@ -253,11 +253,11 @@ class ZendAfi_View_Helper_Avis extends ZendAfi_View_Helper_BaseHelper {
   protected function _getAdminActionsTag($avis) {
     $html_actions = '';
     foreach($this->_admin_actions as $action) {
-      $link = $this->view->tagAnchor($this->_url(['controller' => 'abonne',
-                                                  'action' => $action . 'avisnotice',
-                                                  'id' => $avis->getId(),
-                                                  'active_tab' => $this->_active_tab,
-                                                  'page' => $this->_page]),
+      $link = $this->view->tagAnchor($this->_urlWithContext(['controller' => 'abonne',
+                                                             'action' => $action . 'avisnotice',
+                                                             'id' => $avis->getId(),
+                                                             'active_tab' => $this->_active_tab,
+                                                             'page' => $this->_page]),
                                      $this->view->boutonIco('type=' .$action),
                                      ['data-popup' => 'true']);
       $html_actions .= $this->_tag('span', $link, ['rel' => $action]);
@@ -273,20 +273,20 @@ class ZendAfi_View_Helper_Avis extends ZendAfi_View_Helper_BaseHelper {
     if (null == $avis->getId() || !$avis->isAvisNotice())
       return '#';
 
-    return $this->_url(['module' => 'opac',
-                        'controller' => 'blog',
-                        'action' => 'viewavis',
-                        'id' => $avis->getId()]);
+    return $this->_urlWithContext(['module' => 'opac',
+                                   'controller' => 'blog',
+                                   'action' => 'viewavis',
+                                   'id' => $avis->getId()]);
   }
 
 
   protected function _getUrlNotice($avis) {
     if (null !== $notice = $avis->getFirstNotice())
-      return $this->_url(['module' => 'opac',
-                          'controller' => 'recherche',
-                          'action' => 'viewnotice',
-                          'id' => $notice->getId(),
-                          'clef' => $notice->getClefAlpha()]);
+      return $this->_urlWithContext(['module' => 'opac',
+                                     'controller' => 'recherche',
+                                     'action' => 'viewnotice',
+                                     'id' => $notice->getId(),
+                                     'clef' => $notice->getClefAlpha()]);
 
     return '';
   }
diff --git a/library/ZendAfi/View/Helper/BaseHelper.php b/library/ZendAfi/View/Helper/BaseHelper.php
index 1b09abaefe85d606ae8e1501f126f9d0fcdeb8cc..1742041c9f67ea7be2d5bdd222d087ff8fb65310 100644
--- a/library/ZendAfi/View/Helper/BaseHelper.php
+++ b/library/ZendAfi/View/Helper/BaseHelper.php
@@ -76,4 +76,9 @@ class ZendAfi_View_Helper_BaseHelper extends Zend_View_Helper_HtmlElement {
   protected function _div($attributes = [], $content = '') {
     return call_user_func_array([$this->view, 'div'], func_get_args());
   }
+
+
+  protected function _url(array $urlOptions = [], $name = null, $reset = false, $encode = true) {
+    return call_user_func_array([$this->view, 'url'], func_get_args());
+  }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/ListeNotices.php b/library/ZendAfi/View/Helper/ListeNotices.php
index dd630173d730eed2440bd6a149efe763b139465b..2230626f4673cd2abcdb2acde7d4d6a1a5ba36ac 100644
--- a/library/ZendAfi/View/Helper/ListeNotices.php
+++ b/library/ZendAfi/View/Helper/ListeNotices.php
@@ -39,10 +39,7 @@ class ZendAfi_View_Helper_ListeNotices extends ZendAfi_View_Helper_BaseHelper {
     $pager = $this->view->pager($nombre_resultats,
                                 $criteres_recherche->getPageSize(),
                                 $criteres_recherche->getPage(),
-                                array_merge($criteres_recherche->getUrlRetourListe(),
-                                            ['controller' => 'recherche',
-                                             'action' => 'simple']));
-
+                                $criteres_recherche->getUrlPager());
 
     if (Class_AdminVar::displayPagerOnTop())
       $html = $pager . $html;
@@ -81,7 +78,8 @@ class ZendAfi_View_Helper_ListeNotices extends ZendAfi_View_Helper_BaseHelper {
     $helpers = [Class_Systeme_ModulesAppli::LISTE_FORMAT_TABLEAU => 'ListeNotices_Tableau',
                 Class_Systeme_ModulesAppli::LISTE_FORMAT_VIGNETTES => 'ListeNotices_Vignettes',
                 Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR => 'ListeNotices_Mur',
-                Class_Systeme_ModulesAppli::LISTE_FORMAT_CHRONO => 'ListeNotices_Chrono'];
+                Class_Systeme_ModulesAppli::LISTE_FORMAT_CHRONO => 'ListeNotices_Chrono',
+                Class_Systeme_ModulesAppli::LISTE_FORMAT_LINKS => 'ListeNotices_Links'];
 
     $helper = $helpers[$preferences['liste_format']];
     return call_user_func_array([$this->view, $helper], [$notices, $preferences]);
diff --git a/library/ZendAfi/View/Helper/ListeNotices/Links.php b/library/ZendAfi/View/Helper/ListeNotices/Links.php
new file mode 100644
index 0000000000000000000000000000000000000000..8f4c49a97a0c032cc4f0a27733835bd75c853702
--- /dev/null
+++ b/library/ZendAfi/View/Helper/ListeNotices/Links.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright (c) 2019, 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_Links extends ZendAfi_View_Helper_BaseHelper {
+  protected $_prefs;
+
+  public function listeNotices_Links($records, $preferences=[]) {
+    $this->_prefs = $preferences;
+
+    return $this->_tag('ul',
+                       implode(array_map([$this, '_renderOne'], $records)),
+                       ['class' => 'liste_links']);
+  }
+
+
+  protected function _renderOne($record) {
+    return $this
+      ->_tag('li',
+             $this->_tag('a',
+                         $record->getTitrePrincipal() . $this->_renderTypeLabel($record),
+                         ['href' => $this->view->url(['record_id' => $record->getId()]),
+                          'data-record-id' => $record->getId()]));
+  }
+
+
+  protected function _renderTypeLabel($record) {
+    return $this->_tag('span', ' (' . $record->getTypeLabel() . ')',
+                       ['style' => 'font-size:smaller']);
+  }
+}
diff --git a/library/ZendAfi/View/Helper/Search/ResultCount.php b/library/ZendAfi/View/Helper/Search/ResultCount.php
new file mode 100644
index 0000000000000000000000000000000000000000..225b5442c326906f0aa80c38bc7312a187dad991
--- /dev/null
+++ b/library/ZendAfi/View/Helper/Search/ResultCount.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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_Search_ResultCount extends ZendAfi_View_Helper_BaseHelper {
+  public function search_ResultCount($count, $limit) {
+    return ($limit && ($count == $limit))
+      ? $this->_('Il y a plus de %s résultats',
+                 $this->_tag('span',
+                             ' ' . $count . ' ',
+                             ['class' => 'nombre-recherche']))
+      : $this->_plural($count,
+                       'Aucun résultat trouvé',
+                       'Il y a %s résultat',
+                       'Il y a %s résultats',
+                       $this->_tag('span', ' ' . $count . ' ',
+                                   ['class' => 'nombre-recherche']));
+  }
+}
diff --git a/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php b/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php
index 2f1d2e13ffa98add6bf7f7a024b0013559bd6b3a..219646909673b233f3614bb7ecfbb73e3d646c35 100644
--- a/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php
+++ b/library/ZendAfi/View/Helper/TagTitreEtNombreDeResultats.php
@@ -20,27 +20,16 @@
  */
 class ZendAfi_View_Helper_TagTitreEtNombreDeResultats extends ZendAfi_View_Helper_BaseHelper {
 
-  public function tagTitreEtNombreDeResultats($search_result){
+  public function tagTitreEtNombreDeResultats($search_result) {
     $search_duration = $search_result->getDuration();
     $criteres_recherche = $search_result->getCriteresRecherche();
     $expression_recherche = $this->_getSearchTerm($criteres_recherche);
 
     $nombre_resultats = $search_result->getRecordsCount();
 
-    $plural_expression = $this->_islimited($nombre_resultats, $criteres_recherche->getMaxSearchResults())
-      ? $this->view->_("Il y a plus de %s résultats",
-                       $this->_tag('span',
-                                   ' ' . $nombre_resultats . ' ',
-                                   ['class' => 'nombre-recherche']))
-      : $this->view->_plural( $nombre_resultats,
-                             "Aucun résultat trouvé",
-                             "Il y a %s résultat",
-                             "Il y a %s résultats",
-                             $this->_tag('span',
-                                         ' ' . $nombre_resultats . ' ',
-                                         ['class' => 'nombre-recherche']));
-
-    $url_rss = $criteres_recherche->getUrlCriteresWithFacettes();
+    $plural_expression = $this->view->search_ResultCount($nombre_resultats,
+                                                         $criteres_recherche->getMaxSearchResults());
+    $url_rss = $criteres_recherche->getUrlCriteres();
     $url_rss['format'] = 'atom';
     $html = $this->view->tagRss($this->view->url($url_rss, null, true),
                                  $this->view->_('S\'abonner à cette recherche'));
@@ -58,11 +47,6 @@ 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())
diff --git a/tests/application/modules/AbstractControllerTestCase.php b/tests/application/modules/AbstractControllerTestCase.php
index 612ecce99607d199fd04bae4238e867598f3c985..2e9a9a47feffa686971862aeef2c1c5025f3bc59 100644
--- a/tests/application/modules/AbstractControllerTestCase.php
+++ b/tests/application/modules/AbstractControllerTestCase.php
@@ -467,6 +467,13 @@ abstract class AbstractControllerTestCase extends Zend_Test_PHPUnit_ControllerTe
   }
 
 
+  public function assertRedirectRegex($pattern, $message = '') {
+    $this->assertRedirect($message);
+    $location = $this->response->getHeaders()[0]['value'];
+    parent::assertRedirectRegex($pattern, 'Headers location : ' . $location);
+  }
+
+
   public function xhprofile($closure) {
     xhprof_enable();
 
diff --git a/tests/scenarios/Authorities/AuthoritiesTest.php b/tests/scenarios/Authorities/AuthoritiesTest.php
index c8b6ce93a9eaef90b2d1aa01e4ca2e258e0558c5..12e313c9e1c436eff1af851c1ab9216f13d80ebc 100644
--- a/tests/scenarios/Authorities/AuthoritiesTest.php
+++ b/tests/scenarios/Authorities/AuthoritiesTest.php
@@ -41,6 +41,25 @@ abstract class AuthoritiesTestCase extends AbstractControllerTestCase {
                     'type' => Class_Notice::TYPE_AUTHORITY,
                     'id_origine' => '185611',
                     'id_notice' => 1]);
+
+
+    $unimarc = (new Class_Notice_AuthorityPartial)
+      ->newWith('j', '190254', 'Schéma de services', ['b' => 'TESS'])
+      ->render();
+
+    $this->fixture('Class_Notice',
+                   ['id' => 2,
+                    'type_doc' => 'j',
+                    'annee' => '2017',
+                    'type' => Class_Notice::TYPE_AUTHORITY,
+                    'facettes' => 'HMOTS HMOTS0002',
+                    'unimarc' => $unimarc]);
+
+    $this->fixture('Class_Exemplaire',
+                   ['id' => 1022,
+                    'type' => Class_Notice::TYPE_AUTHORITY,
+                    'id_origine' => '190254',
+                    'id_notice' => 2]);
   }
 }
 
@@ -73,6 +92,297 @@ class AuthoritiesRechercheControllerViewNoticeWithAuthorityIdAndThesaurusIdTest
 
 
 
+
+class AuthoritiesAuthoritySearchControllerWithoutCritereTest extends AuthoritiesTestCase {
+  public function setUp() {
+    parent::setUp();
+    Class_MoteurRecherche::setInstance($this->mock()
+                                       ->whenCalled('lancerRecherche')
+                                       ->answers(null));
+    $this->dispatch('/opac/authority-search');
+  }
+
+
+  public function tearDown() {
+    Class_MoteurRecherche::setInstance(null);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function titleShouldBeParcoursDesAutorites() {
+    $this->assertXPathContentContains('//h1', 'Parcours des autorités');
+  }
+
+
+  /** @test */
+  public function shouldDisplaySearchInput() {
+    $this->assertXPath('//form[contains(@action, "/authority-search")]//input[@name="expressionRecherche"]');
+  }
+
+
+  /** @test */
+  public function shouldNotLaunchSearch() {
+    $this->assertFalse(Class_MoteurRecherche::getInstance()->methodHasBeenCalled('lancerRecherche'));
+  }
+}
+
+
+
+
+class AuthoritiesAuthoritySearchControllerWithTreeRootsTest extends AuthoritiesTestCase {
+  public function setUp() {
+    parent::setUp();
+    Class_MoteurRecherche::setInstance($this->mock()
+                                       ->whenCalled('lancerRecherche')
+                                       ->answers(null));
+    $this->dispatch('/opac/authority-search/index/tree_roots/185611');
+  }
+
+
+  public function tearDown() {
+    Class_MoteurRecherche::setInstance(null);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function shouldDisplayDeveloppementlocalInTree() {
+    $this->assertXPathContentContains('//div[@class="filtre_recherche"]//a[contains(@href, "record_id/1")]',
+                                      'Développement local');
+  }
+}
+
+
+
+
+class AuthoritiesAuthoritySearchControllerWithTreeRootsSelectedTest extends AuthoritiesTestCase {
+  public function setUp() {
+    parent::setUp();
+    Class_MoteurRecherche::setInstance($this->mock()
+                                       ->whenCalled('lancerRecherche')
+                                       ->answers(null));
+    $this->dispatch('/opac/authority-search/index/tree_roots/185611/record_id/1');
+  }
+
+
+  public function tearDown() {
+    Class_MoteurRecherche::setInstance(null);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function shouldDisplayDeveloppementlocalSelectedInTree() {
+    $this->assertXPathContentContains('//div[@class="filtre_recherche"]//a[contains(@href, "record_id/1")][@class="bold"]',
+                                      'Développement local');
+  }
+
+
+  /** @test */
+  public function shouldDisplayDeveloppementlocalSpecificsInTree() {
+    $this->assertXPathContentContains('//div[@class="filtre_recherche"]//a[contains(@href, "record_id/2")]',
+                                      'Schéma de services');
+  }
+}
+
+
+
+
+class AuthoritiesAuthoritySearchControllerPostTest extends AuthoritiesTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->postDispatch('/opac/authority-search', ['expressionRecherche' => 'local']);
+  }
+
+
+  /** @test */
+  public function shouldRedirectToUrlWithExpressionRecherche() {
+    $this->assertRedirectRegex('#/authority-search/index/expressionRecherche/local$#');
+  }
+}
+
+
+
+
+class AuthoritiesAuthoritySearchControllerWithExpressionLocalAndAResultTest
+  extends AuthoritiesTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    Zend_Registry::set('sql',
+                       $this->mock()
+                       ->whenCalled('fetchAll')
+                       ->with("select id_notice, facettes from notices Where (MATCH(titres, auteurs, editeur, collection, matieres, dewey) AGAINST('+(LOCAL LOCAUX LOKAL)' IN BOOLEAN MODE)) and type=2 order by (MATCH(titres) AGAINST(' LOCAL') * 1.5) + (MATCH(auteurs) AGAINST(' LOCAL')) desc", true, false)
+                       ->answers([[1, '']]));
+
+    $this->dispatch('/opac/authority-search/index/expressionRecherche/local');
+  }
+
+
+  /** @test */
+  public function titleShouldBeParcoursDesAutorites() {
+    $this->assertXPathContentContains('//h1', 'Parcours des autorités');
+  }
+
+
+  /** @test */
+  public function shouldDisplaySearchInputWithValue() {
+    $this->assertXPath('//form[contains(@action, "/authority-search")]//input[@name="expressionRecherche"][@value="local"]');
+  }
+
+
+  /** @test */
+  public function shouldContainsIlYAUnResultat() {
+    $this->assertContains('Il y a <span class="nombre-recherche"> 1 </span> résultat',
+                          $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function shouldContainsDeveloppementLocalRecordLink() {
+    $this->assertXPathContentContains('//a[contains(@href, "/authority-search/index/expressionRecherche/local/record_id/1")]',
+                                      'Développement local');
+  }
+
+
+  /** @test */
+  public function shouldContainsTypeMatiereNomCommun() {
+    $this->assertXPathContentContains('//span', '(matière nom commun, TESS)');
+  }
+}
+
+
+
+
+class AuthoritiesAuthoritySearchControllerWithExpressionLocalLimitedToFacetHMOTSAndAResultTest
+  extends AuthoritiesTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    Zend_Registry::set('sql',
+                       $this->mock()
+                       ->whenCalled('fetchAll')
+                       ->with("select id_notice, facettes from notices Where (MATCH(titres, auteurs, editeur, collection, matieres, dewey) AGAINST('+(LOCAL LOCAUX LOKAL)' IN BOOLEAN MODE) and MATCH(facettes) AGAINST('+HMOTS' IN BOOLEAN MODE)) and type=2 order by (MATCH(titres) AGAINST(' LOCAL') * 1.5) + (MATCH(auteurs) AGAINST(' LOCAL')) desc", true, false)
+                       ->answers([[1, '']]));
+
+    $this->dispatch('/authority-search/index/facettes/HMOTS/expressionRecherche/local');
+  }
+
+
+  /** @test */
+  public function titleShouldBeParcoursDesAutorites() {
+    $this->assertXPathContentContains('//h1', 'Parcours des autorités');
+  }
+
+
+  /** @test */
+  public function shouldDisplaySearchInputWithValue() {
+    $this->assertXPath('//form[contains(@action, "/authority-search/index/facettes/HMOTS")][not(contains(@action, "/expressionRecherche"))]//input[@name="expressionRecherche"][@value="local"]');
+  }
+
+
+  /** @test */
+  public function shouldContainsIlYAUnResultat() {
+    $this->assertContains('Il y a <span class="nombre-recherche"> 1 </span> résultat',
+                          $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function shouldContainsDeveloppementLocalRecordLink() {
+    $this->assertXPathContentContains('//a[contains(@href, "/authority-search/index/facettes/HMOTS/expressionRecherche/local/record_id/1")]',
+                                      'Développement local');
+  }
+
+
+  /** @test */
+  public function shouldContainsTypeMatiereNomCommun() {
+    $this->assertXPathContentContains('//span', '(matière nom commun, TESS)');
+  }
+}
+
+
+
+
+class AuthoritiesAuthoritySearchControllerWithRecordIdTest
+  extends AuthoritiesTestCase {
+
+  protected function _urlToRecord($id) {
+    return '/authority-search/index/expressionRecherche/local/record_id/' . $id;
+  }
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_Exemplaire',
+                   ['id' => 234,
+                    'type' => Class_Notice::TYPE_AUTHORITY,
+                    'id_notice' => 4,
+                    'id_origine' => '185349']);
+
+    $this->fixture('Class_Exemplaire',
+                   ['id' => 238,
+                    'type' => Class_Notice::TYPE_AUTHORITY,
+                    'id_notice' => 5,
+                    'id_origine' => '189260']);
+
+    $this->dispatch($this->_urlToRecord(1));
+  }
+
+
+  public function sectionsWithLink() {
+    return [
+            ['Terme générique', 'Aménagement du territoire', 4],
+            ['Terme spécifique', 'Contrat de pays', 5],
+    ];
+  }
+
+
+  /**
+   * @test
+   * @dataProvider sectionsWithLink
+   */
+  public function shouldContainsSectionWithLinkTo($section_label, $relation_label, $record_id) {
+    $this->assertXPathContentContains('//h3', $section_label);
+    $this->assertXPathContentContains('//a[contains(@href, "' . $this->_urlToRecord($record_id) . '")]',
+                                      $relation_label);
+  }
+
+
+  /** @test */
+  public function shouldContainsRejectedTermDL() {
+    $this->assertXPathContentContains('//h3', 'Terme rejeté');
+    $this->assertXPathContentContains('//li', 'DL');
+  }
+
+
+  /** @test */
+  public function shouldContainsLinkedTermActeurLocalEncore() {
+    $this->assertXPathContentContains('//h3', 'Terme associé');
+    $this->assertXPathContentContains('//li', 'Acteur local encore');
+  }
+
+
+  /** @test */
+  public function shouldContainsNotes() {
+    $this->assertXPathContentContains('//h3', 'Note d\'application');
+    $this->assertXPathContentContains('//p', 'lorsque le besoin');
+  }
+
+
+  /** @test */
+  public function shouldContainsUsages() {
+    $this->assertXPathContentContains('//p', 'Utilisé dans aucune notice');
+  }
+}
+
+
+
+
 class AuthoritiesNoticeAjaxControllerTest extends AuthoritiesTestCase {
   public function setUp() {
     parent::setUp();