diff --git a/VERSIONS_HOTLINE/94530 b/VERSIONS_HOTLINE/94530
new file mode 100644
index 0000000000000000000000000000000000000000..2994b28746e5e36efe17314099b382654b02a39a
--- /dev/null
+++ b/VERSIONS_HOTLINE/94530
@@ -0,0 +1 @@
+ - ticket #94530 : connecteur Philharmonie Paris : nouvelle url de moissonnage prise en compte
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/94750 b/VERSIONS_HOTLINE/94750
new file mode 100644
index 0000000000000000000000000000000000000000..529a4eab3c75731ccc548bf66440b37b02ef1a23
--- /dev/null
+++ b/VERSIONS_HOTLINE/94750
@@ -0,0 +1 @@
+ - ticket #94750 : Facettes dynamiques : correction de la mise à jour des libellés
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/96483 b/VERSIONS_HOTLINE/96483
new file mode 100644
index 0000000000000000000000000000000000000000..348f008e466f259816517e79216918fdcd04a485
--- /dev/null
+++ b/VERSIONS_HOTLINE/96483
@@ -0,0 +1 @@
+ - ticket #96483 : Compte utilisateur : Les liens de réinitialisation de mot de passe envoyés par courriel expirent désormais en 24h
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/96508 b/VERSIONS_HOTLINE/96508
new file mode 100644
index 0000000000000000000000000000000000000000..fd5ab085a0e787ac35162b549ac576ca6f1cc7ce
--- /dev/null
+++ b/VERSIONS_HOTLINE/96508
@@ -0,0 +1 @@
+ - ticket #96508 : Facettes dynamiques : Seul le premier des sous champs unimarc répétés dans les notices était pris en compte dans la recherche
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/97222 b/VERSIONS_HOTLINE/97222
new file mode 100644
index 0000000000000000000000000000000000000000..176ba82e1bb7b58957708dacaebfd56c62fd43a5
--- /dev/null
+++ b/VERSIONS_HOTLINE/97222
@@ -0,0 +1 @@
+ - ticket #97222: OPAC Compte utilisateur : La page d'impression de la liste de prêt dans le compte utilisateur à l'OPAC n'affichait pas les données
\ No newline at end of file
diff --git a/application/modules/opac/views/scripts/print.phtml b/application/modules/opac/views/scripts/print.phtml
index 272b2434bcc5366b648a4236b7efb9a4884c55ac..fc0e8c9ff08fe956eb09a711e1f79940701f0d30 100644
--- a/application/modules/opac/views/scripts/print.phtml
+++ b/application/modules/opac/views/scripts/print.phtml
@@ -1,3 +1,11 @@
-<?php
-echo $this->tagModelFusion($this->params);
-?>
+<!DOCTYPE html>
+<html lang="<?php echo $this->_translate()->getLocale() ?>">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+  </head>
+  <body>
+    <?php
+    echo $this->tagModelFusion($this->params);
+    ?>
+  </body>
+</html>
diff --git a/cosmogramme/VERSIONS_HOTLINE/96549 b/cosmogramme/VERSIONS_HOTLINE/96549
new file mode 100644
index 0000000000000000000000000000000000000000..eaf69e81d9dbba63dc6945659ae294d9477f479c
--- /dev/null
+++ b/cosmogramme/VERSIONS_HOTLINE/96549
@@ -0,0 +1 @@
+ - ticket #96549 : SIGB Orphée : les exemplaires avec la situation "en réserve" sont réservables
\ No newline at end of file
diff --git a/cosmogramme/php/classes/classe_unimarc.php b/cosmogramme/php/classes/classe_unimarc.php
index 9d1ccacbc8d32a64645140bdf7180f35fc36e413..7ba8693ba23f6dd50a7a1379de50ea8e0e776922 100644
--- a/cosmogramme/php/classes/classe_unimarc.php
+++ b/cosmogramme/php/classes/classe_unimarc.php
@@ -50,6 +50,7 @@ class notice_unimarc extends iso2709_record {
   private $id_genre_documentaire;  // Identifiant pour le genre "documentaire"
   private $controle_codes_barres;  // Exception de filtrage des codes-barres
   protected $_id_bib;              // Bibliotheque d'intégration
+  protected $_fluent; // Class_NoticeUnimarc_Fluent
 
 
   public function __construct($id_bib=null) {
@@ -94,10 +95,18 @@ class notice_unimarc extends iso2709_record {
     }
 
     $this->setNotice($data, $this->profil['accents']);
+    $this->_fluent = null;
     return true;
   }
 
 
+  protected function _getFluent() {
+    return $this->_fluent
+      ? $this->_fluent
+      : $this->_fluent = Class_NoticeUnimarc_Fluent::fromLegacy($this);
+  }
+
+
   public function updateItemsWithUrl(&$exemplaires) {
     if (!$champ_url = $this->profil['attributs'][Class_IntProfilDonnees::FT_RECORDS][Class_IntProfilDonnees::FIELD_ITEM_URL])
       return $this;
@@ -187,7 +196,7 @@ class notice_unimarc extends iso2709_record {
 
     $notice["dewey"] = $this->getDewey();
 
-    $notice["thesauri"] = $this->getThesauri($notice);
+    $notice["thesauri"] = $this->getThesauri();
 
     $notice["pcdm4"] = $this->getPcdm4();
 
@@ -1258,7 +1267,7 @@ class notice_unimarc extends iso2709_record {
   }
 
 
-  public function getThesauri($notice) {
+  public function getThesauri() {
     return array_merge($this->_findThesauriIn686(),
                        $this->_findOtherThesauri());
 
@@ -1271,27 +1280,34 @@ class notice_unimarc extends iso2709_record {
   }
 
 
+  /** @return array thesaurus list */
   protected function _findThesauriIn686() {
-    $thesaurus = [];
-    $data = $this->get_subfield('686');
+    $thesauri = $this
+      ->_getFluent()
+      ->zonesCollect(function($zone)
+                     {
+                       return $this->_findThesauriIn686Zone($zone);
+                     });
 
-    foreach($data as $items) {
-      $sous_champs = $this->decoupe_bloc_champ($items);
-      $code_thesaurus = null;
-      $id_origine = null;
-      foreach($sous_champs as $item) {
-        if ($item["code"] == "a")
-          $id_origine = $item['valeur'];
-        if ($item["code"] == "2")
-          $code_thesaurus = trim($item['valeur']);
-
-        if ($code_thesaurus && $id_origine ) {
-          $thesaurus[] = Class_CodifThesaurus::findByIdOrigineAndCode($id_origine,
-                                                                      $code_thesaurus);
-        }
-      }
-    }
-    return $thesaurus;
+    return array_filter($thesauri->getArrayCopy());
+  }
+
+
+  /**
+   * @param $zone Class_NoticeUnimarc_Zone
+   * @return Class_CodifThesaurus
+   */
+  protected function _findThesauriIn686Zone($zone) {
+    if (!$zone->isLabel('686'))
+      return;
+
+    $id_field = $zone->detectFieldByCode('a');
+    $code_field = $zone->detectFieldByCode('2');
+
+    return $id_field && $code_field
+      ? Class_CodifThesaurus::findByIdOrigineAndCode($id_field->getValue(),
+                                                     trim($code_field->getValue()))
+      : null;
   }
 
 
diff --git a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
index 34f0c629639d6688d7495dbcbd63175b947c44f4..1c2f9090e044c611244dbc2b12cb6f04dca31f88 100644
--- a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
@@ -585,18 +585,18 @@ class KohaRecordIntegrationDeduplicateTest extends KohaRecordIntegrationTestCase
     $this->loadRecordsFromFile('unimarc_mementos');
 
     $this->fixture('Class_IntBib',
-									 ['id' => 2,
-										'nom' => 'My other library',
-										'nom_court' => 'MOL',
-										'mail' => '',
-										'qualite' => 10,
-										'dernier_ajout' => '2015-01-01',
-										'ecart_ajouts' => '0',
-										'date_mail' => '',
-										'sigb' => $this->_sigb,
-										'planif_mode' => 'r',
-										'comm_sigb' => 0,
-										'comm_params' => 'N']);
+                   ['id' => 2,
+                    'nom' => 'My other library',
+                    'nom_court' => 'MOL',
+                    'mail' => '',
+                    'qualite' => 10,
+                    'dernier_ajout' => '2015-01-01',
+                    'ecart_ajouts' => '0',
+                    'date_mail' => '',
+                    'sigb' => $this->_sigb,
+                    'planif_mode' => 'r',
+                    'comm_sigb' => 0,
+                    'comm_params' => 'N']);
 
     $this->loadRecordsFromFile('unimarc_mementos', 2);
     $this->loadRecordsFromFile('unimarc_mementos');
@@ -734,6 +734,7 @@ class KohaRecordIntegrationPommeWithAttachedPdfAndHtmlFileTest
 
 
 
+
 class KohaRecordIntegrationFileInfoFactory {
   public function __invoke($path) {
     $wrapper = Storm_Test_ObjectWrapper::on(new SplFileInfo($path))
@@ -746,3 +747,72 @@ class KohaRecordIntegrationFileInfoFactory {
     return $wrapper;
   }
 }
+
+
+
+
+/** @see http://forge.afi-sa.fr/issues/96508 */
+class KohaRecordIntegrationMultipleSECTIntegrationTest extends KohaRecordIntegrationTestCase {
+  protected $_storm_default_to_volatile = true;
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 74,
+                    'libelle' => 'Secteur',
+                    'libelle_facette' => '',
+                    'id_thesaurus' => 'SECT',
+                    'id_origine' => null,
+                    'code' => 'SECT',
+                    'rule_zone' => '099',
+                    'rule_label_field' => 'y',
+                    'rule_id_field' => '',
+                    'rule_filter_field' => '',
+                    'rule_filter_value' => ''
+                   ]);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 76,
+                    'libelle' => 'SANTESOCIAL',
+                    'libelle_facette' => 'SANTESOCIAL',
+                    'id_thesaurus' => 'SECT0001',
+                    'id_origine' => 'SANTESOCIAL',
+                    'code' => 'SECT',
+                   ]);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 77,
+                    'libelle' => 'ADMINISTRATION',
+                    'libelle_facette' => '',
+                    'id_thesaurus' => 'SECT0002',
+                    'id_origine' => 'ADMINISTRATION',
+                    'code' => 'SECT']
+                   );
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 78,
+                    'libelle' => 'TRAVAILEMPLOI',
+                    'libelle_facette' => 'TRAVAILEMPLOI',
+                    'id_thesaurus' => 'SECT0003',
+                    'id_origine' => 'TRAVAILEMPLOI',
+                    'code' => 'SECT',
+                   ]);
+
+    $writer = new Class_NoticeUnimarc_Writer();
+    $writer->setNotice(file_get_contents(dirname(__FILE__)."/unimarc_minsoc_ia.txt"));
+
+    $writer->add_field('995', '  ', [['f', '12345'],
+                                     ['v', '1']]);
+    $writer->update();
+
+    $this->loadNoticeFromString($writer->getFullRecord());
+  }
+
+
+  /** @test */
+  public function RecordFacetsShouldContainsHSECT0001AndHSECT0002AndHSECT0003() {
+    $this->assertContains('HSECT0002 HSECT0001 HSECT0003', Class_Notice::find(1)->getFacettes());
+  }
+}
diff --git a/cosmogramme/tests/php/classes/NanookRecordsIntegrationTest.php b/cosmogramme/tests/php/classes/NanookRecordsIntegrationTest.php
index 44c24977976bfec71c78bca49999fd7d3db83f71..018efa8ca9031abc42aad52d4f773e4ed3262d2a 100644
--- a/cosmogramme/tests/php/classes/NanookRecordsIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/NanookRecordsIntegrationTest.php
@@ -23,147 +23,147 @@
 require_once('NoticeIntegrationTest.php');
 
 abstract class NanookRecordsIntegrationTestCase extends NoticeIntegrationTestCase {
-	public function getProfilDonnees() {
-		$profil = Class_IntProfilDonnees::forNanook()->setIdProfil(110);
-		return $profil->getRawAttributes();
+  public function getProfilDonnees() {
+    $profil = Class_IntProfilDonnees::forNanook()->setIdProfil(110);
+    return $profil->getRawAttributes();
   }
 }
 
 
 /** @see http://forge.afi-sa.fr/issues/13769 */
 class NanookRecordsIntegrationAvailabilityFacetTest extends NanookRecordsIntegrationTestCase {
-	public function getProfilDonnees() {
-		return Class_IntProfilDonnees::forNanook()
-			->setIdProfil(110)
-			->setAvailabilityField('v')
-			->getRawAttributes();
-	}
-
-
-	public function setUp() {
-		parent::setUp();
+  public function getProfilDonnees() {
+    return Class_IntProfilDonnees::forNanook()
+      ->setIdProfil(110)
+      ->setAvailabilityField('v')
+      ->getRawAttributes();
+  }
 
-		/*
-		 * cf class_unimarc: [[file:../../../php/classes/classe_unimarc.php::$notice%5B"sections"%5D%5B%5D%20%3D%20$exemplaire%5B"section"%5D%3B][item data to record]] ,
-		 * [[file:../../../php/classes/classe_unimarc.php::if%20($champ_availability%20and%20$champ%5B'code'%5D%20%3D%3D%20$champ_availability)%20{][item parse unimarc]]
-		 */
-		$writer = new Class_NoticeUnimarc_Writer();
-		$writer->setNotice(file_get_contents(dirname(__FILE__)."/unimarc_symphonie.txt"));
-		$writer->add_field('995',
-											 '  ',
-											 [
-												['f', '12345'],
-												['v', '1']
-											 ]);
-		$writer->add_field('995',
-											 '  ',
-											 [
-												['f', '12346'],
-												['v', 'ordered']
-											 ]);
 
-		$writer->update();
+  public function setUp() {
+    parent::setUp();
 
-		$this->loadNoticeFromString($writer->getFullRecord());
-		Class_Notice::find(1)->updateFacetsFromExemplaires();
+    /*
+     * cf class_unimarc: [[file:../../../php/classes/classe_unimarc.php::$notice%5B"sections"%5D%5B%5D%20%3D%20$exemplaire%5B"section"%5D%3B][item data to record]] ,
+     * [[file:../../../php/classes/classe_unimarc.php::if%20($champ_availability%20and%20$champ%5B'code'%5D%20%3D%3D%20$champ_availability)%20{][item parse unimarc]]
+     */
+    $writer = new Class_NoticeUnimarc_Writer();
+    $writer->setNotice(file_get_contents(dirname(__FILE__)."/unimarc_symphonie.txt"));
+    $writer->add_field('995',
+                       '  ',
+                       [
+                        ['f', '12345'],
+                        ['v', '1']
+                       ]);
+    $writer->add_field('995',
+                       '  ',
+                       [
+                        ['f', '12346'],
+                        ['v', 'ordered']
+                       ]);
+
+    $writer->update();
+
+    $this->loadNoticeFromString($writer->getFullRecord());
+    Class_Notice::find(1)->updateFacetsFromExemplaires();
 
-	}
+  }
 
 
-	/** @test */
-	public function firstItemShouldNotBeAvailable() {
-		$this->assertFalse(Class_Exemplaire::find(1)->isDisponible(true));
-	}
+  /** @test */
+  public function firstItemShouldNotBeAvailable() {
+    $this->assertFalse(Class_Exemplaire::find(1)->isDisponible(true));
+  }
 
 
-	/** @test */
-	public function secondItemShouldBeAvailable() {
-		$this->assertTrue(Class_Exemplaire::find(2)->isDisponible(true));
-	}
+  /** @test */
+  public function secondItemShouldBeAvailable() {
+    $this->assertTrue(Class_Exemplaire::find(2)->isDisponible(true));
+  }
 
 
-	/** @test */
-	public function thirdItemShouldNotBeAvailable() {
-		$this->assertFalse(Class_Exemplaire::find(3)->isDisponible(true));
-	}
+  /** @test */
+  public function thirdItemShouldNotBeAvailable() {
+    $this->assertFalse(Class_Exemplaire::find(3)->isDisponible(true));
+  }
 
 
   /** @test */
-	public function noticeShouldContainsFacetV1() {
-		$this->assertContains('V1', Class_Notice::find(1)->getFacettes());
-	}
+  public function noticeShouldContainsFacetV1() {
+    $this->assertContains('V1', Class_Notice::find(1)->getFacettes());
+  }
 }
 
 
 
 /** @see http://forge.afi-sa.fr/issues/16358 */
 class NanookRecordsIntegrationSymphonieTest extends NanookRecordsIntegrationTestCase {
-	public function getProfilDonnees() {
-		return Class_IntProfilDonnees::forNanook()
+  public function getProfilDonnees() {
+    return Class_IntProfilDonnees::forNanook()
       ->setItemField(Class_IntProfilDonnees::FIELD_ITEM_ID_ORIGINE,
                      ['zone' => '001', 'champ' => 'zz'])
       ->setIdProfil(110)
       ->getRawAttributes();
-	}
-
-
-	public function setUp() {
-		parent::setUp();
-
-		$symphonie = $this->fixture('Class_Notice',
-																['id' => 1,
-																 'type_doc' => 3,
-																 'alpha_titre' => 'SYMPHONIES 38  PRAGUE    41  JUPITER',
-																 'alpha_auteur' => 'MOZART WOLFGANG AMADEUS',
-																 'titres' => 'SYMPHONIES SINFONI 38  PRAGUE PRAG 41 JUPITER JUPIT',
-																 'auteurs' => 'MOZART MOZAR WOLFGANG OLFGANG AMADEUS AMAD JACOBS JAKOB RENE RAN FREIBURGER FREIBURJ BAROCKORCHESTER BAROKORKEST',
-																 'editeur' => 'Harmonia Mundi',
-																 'collection' => '',
-																 'matieres' => 'MUSIQUE MUSIK 18E  SIECLE SIEKL AUTRICHE OTRICH',
-																 'dewey' => '',
-																 'facettes' => '  A1 A2 A3 M1 T3 B1',
-																 'cote' => '3 MOZ 24',
-																 'isbn' => '',
-																 'ean' => '3149020195840',
-																 'id_commerciale' => 'HARMONIAMUNDI2901958SYMPHONIES38PRAGUE41',
-																 'id_bnf' => '',
-																 'clef_alpha' => 'SYMPHONIES38PRAGUE41JUPITER--MOZARTW--HARMONIAMUNDI-2012-3',
-																 'clef_oeuvre' => 'SYMPHONIES38PRAGUE41JUPITER--MOZARTW-',
-																 'clef_chapeau' => '',
-																 'tome_alpha' => '',
-																 'annee' => 2010,
-																 'qualite' => 5,
-																 'exportable' => 1,
-																 'date_creation' => '2000-01-01 00:00:00',
-																 'date_maj' => '2014-09-16 12:25:58',
-																 'unimarc' => "02135njm0 2200409   450 001000700000010001100007071002800018073001800046100004500064126004500109200013500154210002500289215002800314300002800342345002200370464006700392464005900459464006600518464006600584464006900650464007800719464006500797610003600862686004700898700005800945702005201003702005701055801002201112856006701134856005901201856006601260856006601326856006901392856007801461856006501539992012101604196508  d8,05 E01a2901958bHarmonia Mundi  a3149020195840  a20140613d2007    m  y0frea0103    ba      aax  hx       cd                         1 aSymphonies 38 \"Prague\" & 41 \"Jupiter\"bCDfWolfgang Amadeus Mozart, compos.gRené Jacobs, dir.gFreiburger Barockorchester, orch. 1cHarmonia Mundid2012 1a1 CD (68 min)e1 livret  aEnregistrement de 2007.  b3149020195840cCD  tSymphonii nع38 en ré majeur, k504 'prague' : adagio, allegro  tSymphonie nع38 en ré majeur, k504 'prague' : andante  tSymphonie n°38 en ré majeur, k504 'prague' : finale, presto  tSymphonie n°41 en ut majeur, k551 'jupiter' : allegro vivace  tSymphonie n°41 en ut majeur, k551 'jupiter' : andante cantabile  tSymphonie n°41 en ut majeur, k551 'jupiter' : menuetto, allegretto, trio  tSymphonie n°41 en ut majeur, k551 'jupiter' : molto allegro  aMusique - 18e siècleyAutriche  a3.24tSymphonie, poème symphonique2PCDM4 1aMozartbWolfgang Amadeusf1756-179142306Compositeur 1aJacobsbRenéf1946-....4qco6chef d'orchestre 1aFreiburger Barockorchester4ost6orchestre à cordes 1aFRbCVSc201406134 zSymphonie nع38 en ré majeur, k504 'prague' : adagio, allegro4 zSymphonie nع38 en ré majeur, k504 'prague' : andante4 zSymphonie nع38 en ré majeur, k504 'prague' : finale, presto4 zSymphonie nع41 en ut majeur, k551 'jupiter' : allegro vivace4 zSymphonie nع41 en ut majeur, k551 'jupiter' : andante cantabile4 zSymphonie nع41 en ut majeur, k551 'jupiter' : menuetto, allegretto, trio4 zSymphonie nع41 en ut majeur, k551 'jupiter' : molto allegro  uhttp://ecx.images-amazon.com/images/I/51nXuj1YJPL._SL160_.jpgvhttp://ecx.images-amazon.com/images/I/51nXuj1YJPL.jpg",
-																 'z3950_retry' => 0,
-																 'nb_visu' => 0,
-																 'nb_resa' => 0,
-																 'url_vignette' => '',
-																 'url_image' => '']);
-
-		$this->_mock_sql
-			->whenCalled('fetchEnreg')
-			->with('select * from int_bib where id_bib=1')
-			->answers(['id' => 1,
-								 'qualite' => 5]);
-
-
-		$this->_mock_sql
-			->whenCalled('fetchEnreg')
-			->with('select qualite,unimarc,facettes from notices where id_notice=1')
-			->answers($symphonie->toArray());
+  }
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $symphonie = $this->fixture('Class_Notice',
+                                ['id' => 1,
+                                 'type_doc' => 3,
+                                 'alpha_titre' => 'SYMPHONIES 38  PRAGUE    41  JUPITER',
+                                 'alpha_auteur' => 'MOZART WOLFGANG AMADEUS',
+                                 'titres' => 'SYMPHONIES SINFONI 38  PRAGUE PRAG 41 JUPITER JUPIT',
+                                 'auteurs' => 'MOZART MOZAR WOLFGANG OLFGANG AMADEUS AMAD JACOBS JAKOB RENE RAN FREIBURGER FREIBURJ BAROCKORCHESTER BAROKORKEST',
+                                 'editeur' => 'Harmonia Mundi',
+                                 'collection' => '',
+                                 'matieres' => 'MUSIQUE MUSIK 18E  SIECLE SIEKL AUTRICHE OTRICH',
+                                 'dewey' => '',
+                                 'facettes' => '  A1 A2 A3 M1 T3 B1',
+                                 'cote' => '3 MOZ 24',
+                                 'isbn' => '',
+                                 'ean' => '3149020195840',
+                                 'id_commerciale' => 'HARMONIAMUNDI2901958SYMPHONIES38PRAGUE41',
+                                 'id_bnf' => '',
+                                 'clef_alpha' => 'SYMPHONIES38PRAGUE41JUPITER--MOZARTW--HARMONIAMUNDI-2012-3',
+                                 'clef_oeuvre' => 'SYMPHONIES38PRAGUE41JUPITER--MOZARTW-',
+                                 'clef_chapeau' => '',
+                                 'tome_alpha' => '',
+                                 'annee' => 2010,
+                                 'qualite' => 5,
+                                 'exportable' => 1,
+                                 'date_creation' => '2000-01-01 00:00:00',
+                                 'date_maj' => '2014-09-16 12:25:58',
+                                 'unimarc' => "02135njm0 2200409   450 001000700000010001100007071002800018073001800046100004500064126004500109200013500154210002500289215002800314300002800342345002200370464006700392464005900459464006600518464006600584464006900650464007800719464006500797610003600862686004700898700005800945702005201003702005701055801002201112856006701134856005901201856006601260856006601326856006901392856007801461856006501539992012101604196508  d8,05 E01a2901958bHarmonia Mundi  a3149020195840  a20140613d2007    m  y0frea0103    ba      aax  hx       cd                         1 aSymphonies 38 \"Prague\" & 41 \"Jupiter\"bCDfWolfgang Amadeus Mozart, compos.gRené Jacobs, dir.gFreiburger Barockorchester, orch. 1cHarmonia Mundid2012 1a1 CD (68 min)e1 livret  aEnregistrement de 2007.  b3149020195840cCD  tSymphonii nع38 en ré majeur, k504 'prague' : adagio, allegro  tSymphonie nع38 en ré majeur, k504 'prague' : andante  tSymphonie n°38 en ré majeur, k504 'prague' : finale, presto  tSymphonie n°41 en ut majeur, k551 'jupiter' : allegro vivace  tSymphonie n°41 en ut majeur, k551 'jupiter' : andante cantabile  tSymphonie n°41 en ut majeur, k551 'jupiter' : menuetto, allegretto, trio  tSymphonie n°41 en ut majeur, k551 'jupiter' : molto allegro  aMusique - 18e siècleyAutriche  a3.24tSymphonie, poème symphonique2PCDM4 1aMozartbWolfgang Amadeusf1756-179142306Compositeur 1aJacobsbRenéf1946-....4qco6chef d'orchestre 1aFreiburger Barockorchester4ost6orchestre à cordes 1aFRbCVSc201406134 zSymphonie nع38 en ré majeur, k504 'prague' : adagio, allegro4 zSymphonie nع38 en ré majeur, k504 'prague' : andante4 zSymphonie nع38 en ré majeur, k504 'prague' : finale, presto4 zSymphonie nع41 en ut majeur, k551 'jupiter' : allegro vivace4 zSymphonie nع41 en ut majeur, k551 'jupiter' : andante cantabile4 zSymphonie nع41 en ut majeur, k551 'jupiter' : menuetto, allegretto, trio4 zSymphonie nع41 en ut majeur, k551 'jupiter' : molto allegro  uhttp://ecx.images-amazon.com/images/I/51nXuj1YJPL._SL160_.jpgvhttp://ecx.images-amazon.com/images/I/51nXuj1YJPL.jpg",
+                                 'z3950_retry' => 0,
+                                 'nb_visu' => 0,
+                                 'nb_resa' => 0,
+                                 'url_vignette' => '',
+                                 'url_image' => '']);
+
+    $this->_mock_sql
+      ->whenCalled('fetchEnreg')
+      ->with('select * from int_bib where id_bib=1')
+      ->answers(['id' => 1,
+                 'qualite' => 5]);
+
+
+    $this->_mock_sql
+      ->whenCalled('fetchEnreg')
+      ->with('select qualite,unimarc,facettes from notices where id_notice=1')
+      ->answers($symphonie->toArray());
 
 
     $this->loadNotice('unimarc_symphonie');
-	}
+  }
 
 
-	/** @test */
-	public function degreeShouldStayUTF8Degree() {
-		$this->assertContains('n°', Class_Notice::find(1)->get_subfield(464, 't')[0]);
-	}
+  /** @test */
+  public function degreeShouldStayUTF8Degree() {
+    $this->assertContains('n°', Class_Notice::find(1)->get_subfield(464, 't')[0]);
+  }
 
 
   /** @test */
@@ -179,62 +179,62 @@ class NanookRecordsIntegrationSymphonieTest extends NanookRecordsIntegrationTest
 class NanookRecordsIntegrationInterestEsperluetteTest extends NanookRecordsIntegrationTestCase {
   protected $_storm_default_to_volatile = true;
 
-	public function setUp() {
-		parent::setUp();
-
-		$this->_mock_sql
-			->whenCalled('fetchEnreg')
-			->with('select * from int_bib where id_bib=1')
-			->answers(['id' => 1,
-								 'qualite' => 5,
-								 'sigb' => 13]);
-		$this->loadNotice('unimarc_esperluette_2014');
-		$this->loadNotice('unimarc_esperluette_2014');
-		$this->notice = Class_Notice::find(1);
-	}
-
-
-	/** @test */
-	public function deweyShouldContainsEsperluette() {
-		$this->assertEquals('80993352  ESPERLUETTE ESPERLUET 2014', $this->notice->getDewey());
-	}
+  public function setUp() {
+    parent::setUp();
+
+    $this->_mock_sql
+      ->whenCalled('fetchEnreg')
+      ->with('select * from int_bib where id_bib=1')
+      ->answers(['id' => 1,
+                 'qualite' => 5,
+                 'sigb' => 13]);
+    $this->loadNotice('unimarc_esperluette_2014');
+    $this->loadNotice('unimarc_esperluette_2014');
+    $this->notice = Class_Notice::find(1);
+  }
+
+
+  /** @test */
+  public function deweyShouldContainsEsperluette() {
+    $this->assertEquals('80993352  ESPERLUETTE ESPERLUET 2014', $this->notice->getDewey());
+  }
 }
 
 
 
 class NanookRecordsIntegrationAuxAnimauxLaGuerreTest extends NanookRecordsIntegrationTestCase {
-	public function setUp() {
-		parent::setUp();
-		$this->loadNotice('unimarc_aux_animaux_la_guerre');
-		$this->loadNotice('unimarc_aux_animaux_la_guerre');
-	}
-
-
-	/** @test */
-	public function noticeAuxAnimauxLaGuerreCallNumberShouldNotBeEmpty() {
-		$notice = Class_Notice::find(1);
-		$this->assertEquals('RP MATH', $notice->getCote());
-	}
+  public function setUp() {
+    parent::setUp();
+    $this->loadNotice('unimarc_aux_animaux_la_guerre');
+    $this->loadNotice('unimarc_aux_animaux_la_guerre');
+  }
+
+
+  /** @test */
+  public function noticeAuxAnimauxLaGuerreCallNumberShouldNotBeEmpty() {
+    $notice = Class_Notice::find(1);
+    $this->assertEquals('RP MATH', $notice->getCote());
+  }
 }
 
 
 
 class NanookRecordsIntegrationUpdateNoticeTest extends NoticeIntegrationTestCase {
-	protected $_profil_donnees = ['id_profil' => 150,
-																'id' => 150,
-																'libelle' => 'Unimarc Nanook plop',
-																'accents' => '0',
-																'rejet_periodiques' =>  '1',
-																'id_article_periodique' => '1',
-																'type_fichier' => '0',
-																'format' => '0',
-																'attributs' => 'a:7:{i:0;a:8:{s:8:"type_doc";a:26:{i:0;a:3:{s:4:"code";s:1:"0";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:1;a:3:{s:4:"code";s:1:"1";s:5:"label";s:2:"am";s:8:"zone_995";s:0:"";}i:2;a:3:{s:4:"code";s:1:"2";s:5:"label";s:2:"as";s:8:"zone_995";s:0:"";}i:3;a:3:{s:4:"code";s:1:"3";s:5:"label";s:0:"";s:8:"zone_995";s:2:"jz";}i:4;a:3:{s:4:"code";s:1:"4";s:5:"label";s:4:"g;gm";s:8:"zone_995";s:0:"";}i:5;a:3:{s:4:"code";s:1:"5";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:6;a:3:{s:4:"code";s:1:"8";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:7;a:3:{s:4:"code";s:1:"9";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:8;a:3:{s:4:"code";s:2:"10";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:9;a:3:{s:4:"code";s:2:"11";s:5:"label";s:0:"";s:8:"zone_995";s:2:"xz";}i:10;a:3:{s:4:"code";s:2:"12";s:5:"label";s:0:"";s:8:"zone_995";s:2:"kk";}i:11;a:3:{s:4:"code";s:2:"13";s:5:"label";s:0:"";s:8:"zone_995";s:2:"me";}i:12;a:3:{s:4:"code";s:2:"14";s:5:"label";s:0:"";s:8:"zone_995";s:2:"iz";}i:13;a:3:{s:4:"code";s:2:"15";s:5:"label";s:0:"";s:8:"zone_995";s:2:"mz";}i:14;a:3:{s:4:"code";s:3:"100";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:15;a:3:{s:4:"code";s:3:"101";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:16;a:3:{s:4:"code";s:3:"102";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:17;a:3:{s:4:"code";s:3:"103";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:18;a:3:{s:4:"code";s:3:"104";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:19;a:3:{s:4:"code";s:3:"105";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:20;a:3:{s:4:"code";s:3:"106";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:21;a:3:{s:4:"code";s:3:"107";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:22;a:3:{s:4:"code";s:3:"108";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:23;a:3:{s:4:"code";s:3:"109";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:24;a:3:{s:4:"code";s:3:"111";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:25;a:3:{s:4:"code";s:3:"110";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}}s:17:"champ_code_barres";s:1:"f";s:10:"champ_cote";s:1:"k";s:14:"champ_type_doc";s:0:"";s:11:"champ_genre";s:1:"7";s:13:"champ_section";s:1:"9";s:17:"champ_emplacement";s:1:"6";s:12:"champ_annexe";s:1:"8";}i:1;a:1:{s:6:"champs";s:0:"";}i:2;a:1:{s:6:"champs";s:0:"";}i:3;a:1:{s:6:"champs";s:0:"";}i:5;a:3:{s:6:"champs";s:0:"";s:17:"xml_balise_abonne";s:0:"";s:17:"xml_champs_abonne";a:22:{s:6:"IDABON";s:0:"";s:9:"ORDREABON";s:0:"";s:3:"NOM";s:0:"";s:6:"PRENOM";s:0:"";s:9:"NAISSANCE";s:0:"";s:8:"PASSWORD";s:0:"";s:4:"MAIL";s:0:"";s:10:"DATE_DEBUT";s:0:"";s:8:"DATE_FIN";s:0:"";s:7:"ID_SIGB";s:0:"";s:7:"_IDABON";s:0:"";s:10:"_ORDREABON";s:0:"";s:4:"_NOM";s:0:"";s:7:"_PRENOM";s:0:"";s:10:"_NAISSANCE";s:0:"";s:9:"_PASSWORD";s:0:"";s:5:"_MAIL";s:0:"";s:11:"_DATE_DEBUT";s:0:"";s:9:"_DATE_FIN";s:0:"";s:8:"_ID_SIGB";s:0:"";s:10:"_NUM_CARTE";s:0:"";s:5:"_NULL";s:0:"";}}i:4;a:5:{s:4:"zone";s:3:"995";s:5:"champ";s:1:"4";s:6:"format";s:1:"1";s:5:"jours";s:0:"";s:7:"valeurs";s:0:"";}i:6;a:2:{s:4:"zone";s:0:"";s:5:"champ";s:0:"";}}'
-	];
-
-	public function setUp() {
-		parent::setUp();
-
-		$profil_donnees_1 = $this->fixture('Class_IntProfilDonnees', [
+  protected $_profil_donnees = ['id_profil' => 150,
+                                'id' => 150,
+                                'libelle' => 'Unimarc Nanook plop',
+                                'accents' => '0',
+                                'rejet_periodiques' =>  '1',
+                                'id_article_periodique' => '1',
+                                'type_fichier' => '0',
+                                'format' => '0',
+                                'attributs' => 'a:7:{i:0;a:8:{s:8:"type_doc";a:26:{i:0;a:3:{s:4:"code";s:1:"0";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:1;a:3:{s:4:"code";s:1:"1";s:5:"label";s:2:"am";s:8:"zone_995";s:0:"";}i:2;a:3:{s:4:"code";s:1:"2";s:5:"label";s:2:"as";s:8:"zone_995";s:0:"";}i:3;a:3:{s:4:"code";s:1:"3";s:5:"label";s:0:"";s:8:"zone_995";s:2:"jz";}i:4;a:3:{s:4:"code";s:1:"4";s:5:"label";s:4:"g;gm";s:8:"zone_995";s:0:"";}i:5;a:3:{s:4:"code";s:1:"5";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:6;a:3:{s:4:"code";s:1:"8";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:7;a:3:{s:4:"code";s:1:"9";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:8;a:3:{s:4:"code";s:2:"10";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:9;a:3:{s:4:"code";s:2:"11";s:5:"label";s:0:"";s:8:"zone_995";s:2:"xz";}i:10;a:3:{s:4:"code";s:2:"12";s:5:"label";s:0:"";s:8:"zone_995";s:2:"kk";}i:11;a:3:{s:4:"code";s:2:"13";s:5:"label";s:0:"";s:8:"zone_995";s:2:"me";}i:12;a:3:{s:4:"code";s:2:"14";s:5:"label";s:0:"";s:8:"zone_995";s:2:"iz";}i:13;a:3:{s:4:"code";s:2:"15";s:5:"label";s:0:"";s:8:"zone_995";s:2:"mz";}i:14;a:3:{s:4:"code";s:3:"100";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:15;a:3:{s:4:"code";s:3:"101";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:16;a:3:{s:4:"code";s:3:"102";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:17;a:3:{s:4:"code";s:3:"103";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:18;a:3:{s:4:"code";s:3:"104";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:19;a:3:{s:4:"code";s:3:"105";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:20;a:3:{s:4:"code";s:3:"106";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:21;a:3:{s:4:"code";s:3:"107";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:22;a:3:{s:4:"code";s:3:"108";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:23;a:3:{s:4:"code";s:3:"109";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:24;a:3:{s:4:"code";s:3:"111";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:25;a:3:{s:4:"code";s:3:"110";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}}s:17:"champ_code_barres";s:1:"f";s:10:"champ_cote";s:1:"k";s:14:"champ_type_doc";s:0:"";s:11:"champ_genre";s:1:"7";s:13:"champ_section";s:1:"9";s:17:"champ_emplacement";s:1:"6";s:12:"champ_annexe";s:1:"8";}i:1;a:1:{s:6:"champs";s:0:"";}i:2;a:1:{s:6:"champs";s:0:"";}i:3;a:1:{s:6:"champs";s:0:"";}i:5;a:3:{s:6:"champs";s:0:"";s:17:"xml_balise_abonne";s:0:"";s:17:"xml_champs_abonne";a:22:{s:6:"IDABON";s:0:"";s:9:"ORDREABON";s:0:"";s:3:"NOM";s:0:"";s:6:"PRENOM";s:0:"";s:9:"NAISSANCE";s:0:"";s:8:"PASSWORD";s:0:"";s:4:"MAIL";s:0:"";s:10:"DATE_DEBUT";s:0:"";s:8:"DATE_FIN";s:0:"";s:7:"ID_SIGB";s:0:"";s:7:"_IDABON";s:0:"";s:10:"_ORDREABON";s:0:"";s:4:"_NOM";s:0:"";s:7:"_PRENOM";s:0:"";s:10:"_NAISSANCE";s:0:"";s:9:"_PASSWORD";s:0:"";s:5:"_MAIL";s:0:"";s:11:"_DATE_DEBUT";s:0:"";s:9:"_DATE_FIN";s:0:"";s:8:"_ID_SIGB";s:0:"";s:10:"_NUM_CARTE";s:0:"";s:5:"_NULL";s:0:"";}}i:4;a:5:{s:4:"zone";s:3:"995";s:5:"champ";s:1:"4";s:6:"format";s:1:"1";s:5:"jours";s:0:"";s:7:"valeurs";s:0:"";}i:6;a:2:{s:4:"zone";s:0:"";s:5:"champ";s:0:"";}}'
+  ];
+
+  public function setUp() {
+    parent::setUp();
+
+    $profil_donnees_1 = $this->fixture('Class_IntProfilDonnees', [
                                                                   'id_profil' => 1,
                                                                   'id' => 1,
                                                                   'libelle' => 'Unimarc Standard',
@@ -246,184 +246,184 @@ class NanookRecordsIntegrationUpdateNoticeTest extends NoticeIntegrationTestCase
                                                                   'attributs' => 'a:7:{i:0;a:8:{s:8:"type_doc";a:26:{i:0;a:3:{s:4:"code";s:1:"0";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:1;a:3:{s:4:"code";s:1:"1";s:5:"label";s:5:"am;na";s:8:"zone_995";s:0:"";}i:2;a:3:{s:4:"code";s:1:"2";s:5:"label";s:2:"as";s:8:"zone_995";s:0:"";}i:3;a:3:{s:4:"code";s:1:"3";s:5:"label";s:3:"i;j";s:8:"zone_995";s:0:"";}i:4;a:3:{s:4:"code";s:1:"4";s:5:"label";s:1:"g";s:8:"zone_995";s:0:"";}i:5;a:3:{s:4:"code";s:1:"5";s:5:"label";s:3:"l;m";s:8:"zone_995";s:0:"";}i:6;a:3:{s:4:"code";s:1:"8";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:7;a:3:{s:4:"code";s:1:"9";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:8;a:3:{s:4:"code";s:2:"10";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:9;a:3:{s:4:"code";s:2:"11";s:5:"label";s:0:"";s:8:"zone_995";s:2:"xz";}i:10;a:3:{s:4:"code";s:2:"12";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:11;a:3:{s:4:"code";s:2:"13";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:12;a:3:{s:4:"code";s:2:"14";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:13;a:3:{s:4:"code";s:2:"15";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:14;a:3:{s:4:"code";s:3:"100";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:15;a:3:{s:4:"code";s:3:"101";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:16;a:3:{s:4:"code";s:3:"102";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:17;a:3:{s:4:"code";s:3:"103";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:18;a:3:{s:4:"code";s:3:"104";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:19;a:3:{s:4:"code";s:3:"105";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:20;a:3:{s:4:"code";s:3:"106";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:21;a:3:{s:4:"code";s:3:"107";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:22;a:3:{s:4:"code";s:3:"108";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:23;a:3:{s:4:"code";s:3:"109";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:24;a:3:{s:4:"code";s:3:"111";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}i:25;a:3:{s:4:"code";s:3:"110";s:5:"label";s:0:"";s:8:"zone_995";s:0:"";}}s:17:"champ_code_barres";s:1:"f";s:10:"champ_cote";s:1:"k";s:14:"champ_type_doc";s:0:"";s:11:"champ_genre";s:0:"";s:13:"champ_section";s:1:"q";s:17:"champ_emplacement";s:1:"u";s:12:"champ_annexe";s:1:"a";}i:1;a:1:{s:6:"champs";s:0:"";}i:2;a:1:{s:6:"champs";s:0:"";}i:3;a:1:{s:6:"champs";s:0:"";}i:5;a:3:{s:6:"champs";s:0:"";s:17:"xml_balise_abonne";s:0:"";s:17:"xml_champs_abonne";a:22:{s:6:"IDABON";s:0:"";s:9:"ORDREABON";s:0:"";s:3:"NOM";s:0:"";s:6:"PRENOM";s:0:"";s:9:"NAISSANCE";s:0:"";s:8:"PASSWORD";s:0:"";s:4:"MAIL";s:0:"";s:10:"DATE_DEBUT";s:0:"";s:8:"DATE_FIN";s:0:"";s:7:"ID_SIGB";s:0:"";s:7:"_IDABON";s:0:"";s:10:"_ORDREABON";s:0:"";s:4:"_NOM";s:0:"";s:7:"_PRENOM";s:0:"";s:10:"_NAISSANCE";s:0:"";s:9:"_PASSWORD";s:0:"";s:5:"_MAIL";s:0:"";s:11:"_DATE_DEBUT";s:0:"";s:9:"_DATE_FIN";s:0:"";s:8:"_ID_SIGB";s:0:"";s:10:"_NUM_CARTE";s:0:"";s:5:"_NULL";s:0:"";}}i:4;a:5:{s:4:"zone";s:0:"";s:5:"champ";s:0:"";s:6:"format";s:0:"";s:5:"jours";s:0:"";s:7:"valeurs";s:0:"";}i:6;a:2:{s:4:"zone";s:0:"";s:5:"champ";s:0:"";}}'
                                                                   ]);
 
-		$req_profils = 'select * from profil_donnees where id_profil=1';
-		$this->_mock_sql
-			->whenCalled('fetchEnreg')
-			->with($req_profils)
-			->answers($profil_donnees_1->getRawAttributes())
-
-			->whenCalled('fetchEnreg')
-			->with($req_profils, false)
-			->answers($profil_donnees_1->getRawAttributes());
-
-		Class_CosmoVar::newInstanceWithId('types_docs',
-																			['liste' => "0:non identifié\r\n1:livres\r\n2:périodiques\r\n3:disques\r\n4:DVD\r\n5:cédéroms\r\n8:articles cms\r\n9:fils rss\r\n10:sites internet\r\n15:Liseuse\r\n100:Livre Numérique\r\n101:Diaporamas\r\n102:Type doc\r\n103:OAI\r\n104:Type doc\r\n105:Formation Vodéclic\r\n106:Livres Numériques\r\n107:Vidéos à la demande\r\n108:Tout apprendre\r\n109:Enregistrement audio\r\n110:Numérique Premium"]);
-
-		Class_CosmoVar::newInstanceWithId('nature_docs',
-																			['liste' => '1:Collection\r\n2:Dataset\r\n3:Event\r\n4:Image']);
-	}
-
-	/** @test */
-	public function noticeLiseuseCybookOdyssey4shouldhaveTypeDocQuoi() {
-		$this->loadNotice('unimarc_liseuse_cybook_odyssey_4');
-		$notice = Class_Notice::find(1);
-		$this->assertEquals(15, $notice->getTypeDoc());
-
-		$this->loadNotice('unimarc_liseuse_cybook_odyssey_4');
-		$notice = Class_Notice::find(1);
-		$this->assertEquals(15, $notice->getTypeDoc());
-	}
+    $req_profils = 'select * from profil_donnees where id_profil=1';
+    $this->_mock_sql
+      ->whenCalled('fetchEnreg')
+      ->with($req_profils)
+      ->answers($profil_donnees_1->getRawAttributes())
+
+      ->whenCalled('fetchEnreg')
+      ->with($req_profils, false)
+      ->answers($profil_donnees_1->getRawAttributes());
+
+    Class_CosmoVar::newInstanceWithId('types_docs',
+                                      ['liste' => "0:non identifié\r\n1:livres\r\n2:périodiques\r\n3:disques\r\n4:DVD\r\n5:cédéroms\r\n8:articles cms\r\n9:fils rss\r\n10:sites internet\r\n15:Liseuse\r\n100:Livre Numérique\r\n101:Diaporamas\r\n102:Type doc\r\n103:OAI\r\n104:Type doc\r\n105:Formation Vodéclic\r\n106:Livres Numériques\r\n107:Vidéos à la demande\r\n108:Tout apprendre\r\n109:Enregistrement audio\r\n110:Numérique Premium"]);
+
+    Class_CosmoVar::newInstanceWithId('nature_docs',
+                                      ['liste' => '1:Collection\r\n2:Dataset\r\n3:Event\r\n4:Image']);
+  }
+
+  /** @test */
+  public function noticeLiseuseCybookOdyssey4shouldhaveTypeDocQuoi() {
+    $this->loadNotice('unimarc_liseuse_cybook_odyssey_4');
+    $notice = Class_Notice::find(1);
+    $this->assertEquals(15, $notice->getTypeDoc());
+
+    $this->loadNotice('unimarc_liseuse_cybook_odyssey_4');
+    $notice = Class_Notice::find(1);
+    $this->assertEquals(15, $notice->getTypeDoc());
+  }
 }
 
 
 
 class NanookRecordsIntegrationPoorNoticeUpdateTest extends NanookRecordsIntegrationTestCase {
-	public function setUp() {
-		parent::setUp();
+  public function setUp() {
+    parent::setUp();
 
-		$this->loadNotice('unimarc_la_route_sombre_poor');
+    $this->loadNotice('unimarc_la_route_sombre_poor');
 
-		$this->_mock_sql
-			->whenCalled('fetchOne')
-			->with("select id_notice from exemplaires where id_int_bib=1 and  code_barres='L-038374'")
-			->answers(1);
+    $this->_mock_sql
+      ->whenCalled('fetchOne')
+      ->with("select id_notice from exemplaires where id_int_bib=1 and  code_barres='L-038374'")
+      ->answers(1);
 
-		$this->loadNotice('unimarc_la_route_sombre');
-	}
+    $this->loadNotice('unimarc_la_route_sombre');
+  }
 
-	/** @test */
-	public function recordShouldBeUpdatedAndHaveAnISBN() {
-		$record = Class_Notice::find(1);
-		$this->assertEquals('978-2-08-130888-6', $record->getIsbn());
-	}
+  /** @test */
+  public function recordShouldBeUpdatedAndHaveAnISBN() {
+    $record = Class_Notice::find(1);
+    $this->assertEquals('978-2-08-130888-6', $record->getIsbn());
+  }
 }
 
 
 
 
 class NanookRecordsIntegrationLeChatonDansLaSouriciereTest extends NanookRecordsIntegrationTestCase {
-	public function setUp() {
-		parent::setUp();
-		$this->loadNotice('unimarc_un_chaton_dans_la_souriciere');
-		$this->_notice = Class_Notice::find(1);
-	}
+  public function setUp() {
+    parent::setUp();
+    $this->loadNotice('unimarc_un_chaton_dans_la_souriciere');
+    $this->_notice = Class_Notice::find(1);
+  }
 
 
-	/** @test */
-	public function titleShouldBeChatonDansLaSouriciere() {
-		$this->assertEquals('Un Chaton dans la souricière - (pastille verte) policier',
-												$this->_notice->getTitrePrincipal());
-	}
+  /** @test */
+  public function titleShouldBeChatonDansLaSouriciere() {
+    $this->assertEquals('Un Chaton dans la souricière - (pastille verte) policier',
+                        $this->_notice->getTitrePrincipal());
+  }
 
 
-	/** @test */
-	public function tomeAlphaShouldBeSix() {
-		$this->assertEquals('6', $this->_notice->getTomeAlpha());
-	}
+  /** @test */
+  public function tomeAlphaShouldBeSix() {
+    $this->assertEquals('6', $this->_notice->getTomeAlpha());
+  }
 
 
-	/** @test */
-	public function collectionShouldBeMiniSourisNoire() {
-		$this->assertEquals('Mini souris noire', $this->_notice->getCollections()[0]);
-	}
+  /** @test */
+  public function collectionShouldBeMiniSourisNoire() {
+    $this->assertEquals('Mini souris noire', $this->_notice->getCollections()[0]);
+  }
 
 
-	/** @test */
-	public function noticeShouldNotHaveTomes() {
-		$this->assertEquals([],$this->_notice->getNoticesMemeSeries());
-	}
+  /** @test */
+  public function noticeShouldNotHaveTomes() {
+    $this->assertEquals([],$this->_notice->getNoticesMemeSeries());
+  }
 
   /** @test */
-	public function clefChapeauShouldBeMiniSourisNoire() {
-		$this->assertEquals('MINI SOURIS NOIRE', $this->_notice->getClefChapeau());
-	}
+  public function clefChapeauShouldBeMiniSourisNoire() {
+    $this->assertEquals('MINI SOURIS NOIRE', $this->_notice->getClefChapeau());
+  }
 }
 
 
 
 
 class NanookRecordsIntegrationOblivionTest extends NanookRecordsIntegrationTestCase {
-	public function setUp() {
-		parent::setUp();
+  public function setUp() {
+    parent::setUp();
 
-		$this->fixture('Class_CodifCentreInteret',
-									 ['id' => 24,
-										'code_alpha' => 'SF   FANTASTIQUE   FANTASY',
-										'libelle' => 'SF']);
+    $this->fixture('Class_CodifCentreInteret',
+                   ['id' => 24,
+                    'code_alpha' => 'SF   FANTASTIQUE   FANTASY',
+                    'libelle' => 'SF']);
 
-		$this->fixture('Class_CodifGenre',
-									 ['id' => 96,
-										'libelle' => 'Film',
-										'regles' => '995$7=15']);
+    $this->fixture('Class_CodifGenre',
+                   ['id' => 96,
+                    'libelle' => 'Film',
+                    'regles' => '995$7=15']);
 
-		$this->loadNotice('unimarc_oblivion');
+    $this->loadNotice('unimarc_oblivion');
 
-		Class_Notice::find(1)
-			->setFacettes('T1 Z3 G23 Z5')
-			->save();
+    Class_Notice::find(1)
+      ->setFacettes('T1 Z3 G23 Z5')
+      ->save();
 
-		$this->loadNotice('unimarc_oblivion');
+    $this->loadNotice('unimarc_oblivion');
 
-		$this->_notice = Class_Notice::find(1);
-	}
+    $this->_notice = Class_Notice::find(1);
+  }
 
 
-	/** @test */
-	public function titleShouldBeOblivion() {
-		$this->assertEquals('Oblivion', $this->_notice->getTitrePrincipal());
-	}
+  /** @test */
+  public function titleShouldBeOblivion() {
+    $this->assertEquals('Oblivion', $this->_notice->getTitrePrincipal());
+  }
 
 
-	/** @test */
-	public function firstInterestShouldBeSF() {
-		$this->assertEquals('SF / Fantastique / Fantasy', $this->_notice->getCentreInteret()[0]);
-	}
+  /** @test */
+  public function firstInterestShouldBeSF() {
+    $this->assertEquals('SF / Fantastique / Fantasy', $this->_notice->getCentreInteret()[0]);
+  }
 
 
-	/** @test */
-	public function secondInterestShouldBeAction() {
-		$this->assertEquals('Action', $this->_notice->getCentreInteret()[1]);
-	}
+  /** @test */
+  public function secondInterestShouldBeAction() {
+    $this->assertEquals('Action', $this->_notice->getCentreInteret()[1]);
+  }
 
 
-	/** @test */
-	public function codifCentreInteretId25LibelleShouldBeAction() {
-		$this->assertEquals('Action', Class_CodifCentreInteret::find(25)->getLibelle());
-	}
+  /** @test */
+  public function codifCentreInteretId25LibelleShouldBeAction() {
+    $this->assertEquals('Action', Class_CodifCentreInteret::find(25)->getLibelle());
+  }
 
-	/** @test */
-	public function genreShouldBeFilm() {
-		$genre = $this->_notice->getGenres()[0];
-		$this->assertEquals('Film', $genre->getLibelle());
-	}
+  /** @test */
+  public function genreShouldBeFilm() {
+    $genre = $this->_notice->getGenres()[0];
+    $this->assertEquals('Film', $genre->getLibelle());
+  }
 
 
-	/** @test */
-	public function facettesShouldContainsF2andF24() {
-		$this->assertEquals('T4 A1 F24 F25 Lfre G96', $this->_notice->getFacettes());
-	}
+  /** @test */
+  public function facettesShouldContainsF2andF24() {
+    $this->assertEquals('T4 A1 F24 F25 Lfre G96', $this->_notice->getFacettes());
+  }
 }
 
 
 
 class NanookRecordsIntegrationSerialTopSanteTest extends NanookRecordsIntegrationTestCase {
-	public function setUp() {
-		parent::setUp();
+  public function setUp() {
+    parent::setUp();
     $this->loadRecordsFromFile("unimarc_top_sante");
-		$this->notice = Class_Notice::find(1);
-	}
+    $this->notice = Class_Notice::find(1);
+  }
 
 
-	/** @test */
-	public function mainTitleShouldBeTopSante() {
-		$this->assertContains('Top Santé n° 295 - Avril 2015', $this->notice->getTitrePrincipal());
-	}
+  /** @test */
+  public function mainTitleShouldBeTopSante() {
+    $this->assertContains('Top Santé n° 295 - Avril 2015', $this->notice->getTitrePrincipal());
+  }
 
 
-	/** @test */
-	public function noticeShouldHaveFiveArticles() {
-		$this->assertCount(5, $this->notice->getArticlesPeriodique());
-	}
+  /** @test */
+  public function noticeShouldHaveFiveArticles() {
+    $this->assertCount(5, $this->notice->getArticlesPeriodique());
+  }
 }
 
 
@@ -587,4 +587,189 @@ class NanookRecordsIntegrationMultiClassificationTest extends NanookRecordsInteg
                                                             'id_origine' => 'A302',
                                                             'libelle' => 'JEU D\'AGENCEMENT']));
   }
+}
+
+
+
+
+/** @see http://forge.afi-sa.fr/issues/94786 */
+class NanookRecordsIntegrationExistingRecordWithRemovedClasstificationTest
+  extends NanookRecordsIntegrationTestCase {
+  protected $_facets;
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_Notice',
+                   [
+                    'id' => 10843,
+                    'type_doc' => '3',
+                    'alpha_titre' => 'SUITES DE BALLETS',
+                    'alpha_auteur' => 'TCHAIKOVSKI PIOTR ILYICH',
+                    'titres' => 'SUITES SUIT BALLETS BAL LAC  CYGNES SIN SUITE EXTRAITE EXTRAIT BALLET 20 BELLE BEL BOIS BOI DORMANT DORMAN 66 CASSE KAS NOISETTE NOISET 71 PIOTR ILYICH ILICH TCHAIKOVSKI WITOLD OUITOL ROWICKI ROUIKI DIR FERDINAND FERDINAN LEITNER LEITN ORCHESTRE ORKESTR SYMPHONIQUE SINFONIK PHILHARMONIE FILARMONI NATIONALE NASIONAL VARSOVIE VARSOVI BERL PANORAMA CLASSIQUE KLASIK',
+                    'auteurs' => 'TCHAIKOVSKI PIOTR ILYICH ILICH ROWICKI ROUIKI WITOLD OUITOL LEITNER LEITN FERDINAND FERDINAN ORCHESTRE ORKESTR SYMPHONIQUE SINFONIK PHILHARMONIE FILARMONI NATIONALE NASIONAL VARSOVIE VARSOVI BERLINER BERLIN PHILHARMONIKER FILARMONIK',
+                    'editeur' => 'Polydor',
+                    'collection' => 'PANORAMA CLASSIQUE KLASIK',
+                    'matieres' => 'BALLET BAL MUSIQUE MUSIK CLASSIQUE KLASIK',
+                    'dewey' => 'MUSIQUE MUSIK CLASSIQUE KLASIK SAVANTE SAVANT OCCIDENTALE OKSIDANTAL 4  10 ANS TEST TES 1 COMPACT KONPAKT DISQUES DISK ADULTECOMPACT ADULTEKONPAKT ADULTE ADULT',
+                    'facettes' => 'P3 HNIVE0003 HNIVE0001 A19940 A25031 A25032 A25033 A13670 M6999 M4926 G5 T3 B1 S1 E37 Y1 V1',
+                    'cote' => '3 TCH 28',
+                    'isbn' => '',
+                    'ean' => '',
+                    'id_commerciale' => '',
+                    'id_bnf' => '',
+                    'clef_alpha' => 'SUITESDEBALLETS--TCHAIKOVSKIP--POLYDOR-1993-3',
+                    'clef_oeuvre' => 'SUITESDEBALLETS--TCHAIKOVSKIP-',
+                    'clef_chapeau' => 'PANORAMA CLASSIQUE',
+                    'tome_alpha' => '',
+                    'annee' => '1993',
+                    'qualite' => '5',
+                    'exportable' => '1',
+                    'date_creation' => '0000-00-00 00:00:00',
+                    'date_maj' => '2019-07-26 23:13:37',
+                    'unimarc' => '01613njm0 2200301   450 00100060000001000110000610000450001720000220006221000260008422500320011041000230014246400540016546400610021946401950028060600110047560600220048668600760050868600390058470000310062370200200065470200230067471200670069771200280076480100170079290003240080999300150113399601630114811785  d41,5 F  a20110812u        u  u0frey50            1 aSuites de ballets  cPolydordRééd. 19932 aPanorama classique9id:2999 0tPanorama classique  tLe Lac des cygnes:suite extraite du ballet op. 20  tLa belle au bois dormant:suite extraite du ballet op. 66  tCasse-noisette:suite extraite du ballet op. 71/ Piotr Ilyich Tchaïkovski, Witold Rowicki, dir., Ferdinand Leitner, dir., Orchestre Symphonique de la Philharmonie Nationale de Varsovie, Berl 1aballet  amusique classique  a3tMusique classique (Musique savante de tradition occidentale)2Cestas  aAdultestAdultes2Code stat Cestas 1aTchaïkovskibPiotr Ilyich 1aRowickibWitold 1aLeitnerbFerdinand02aOrchestre Symphonique de la Philharmonie Nationale de Varsovie 1aBerliner Philharmoniker 2aFrc20190726  aLe Lac des cygnes:suite extraite du ballet op. 20 ; La belle au bois dormant:suite extraite du ballet op. 66 ; Casse-noisette:suite extraite du ballet op. 71/ Piotr Ilyich Tchaïkovski, Witold Rowicki, dir., Ferdinand Leitner, dir., Orchestre Symphonique de la Philharmonie Nationale de Varsovie, BerllContientntracks  41a0-4 ans  f35025224k3 TCH 28m00000000n00000000aFonds propreb2vMédiathèque MunicipalexCompact disques adulteeCompact disque adulterCD1Document en bon état31',
+                    'z3950_retry' => '0',
+                    'nb_visu' => '0',
+                    'nb_resa' => '0',
+                    'url_vignette' => 'NO',
+                    'url_image' => 'NO',
+                    'created_at' => null,
+                    'other_terms' => '',
+                    'type' => '1',
+                    'file_content' => '',
+                   ]);
+
+    $this->fixture('Class_Exemplaire',
+                   [
+                    'id' => '58723',
+                    'id_notice' => '10843',
+                    'id_bib' => '1',
+                    'code_barres' => '35025224',
+                    'cote' => '3 TCH 28',
+                    'genre' => '5',
+                    'documentaire' => '0',
+                    'section' => '1',
+                    'activite' => 'En rayon',
+                    'emplacement' => '37',
+                    'annexe' => '1',
+                    'date_nouveaute' => '0000-00-00',
+                    'zone995' => 'a:14:{i:0;a:2:{s:4:"code";s:1:"a";s:6:"valeur";s:23:"Médiathèque de Cestas";}i:1;a:2:{s:4:"code";s:1:"f";s:6:"valeur";s:8:"35025224";}i:2;a:2:{s:4:"code";s:1:"k";s:6:"valeur";s:8:"3 TCH 28";}i:3;a:2:{s:4:"code";s:1:"m";s:6:"valeur";s:8:"20190726";}i:4;a:2:{s:4:"code";s:1:"q";s:6:"valeur";s:1:"d";}i:5;a:2:{s:4:"code";s:1:"r";s:6:"valeur";s:2:"je";}i:6;a:2:{s:4:"code";s:1:"o";s:6:"valeur";s:1:"p";}i:7;a:2:{s:4:"code";s:1:"v";s:6:"valeur";s:1:"1";}i:8;a:2:{s:4:"code";s:1:"2";s:6:"valeur";s:47:"[DISPO][Disponible][0][1][En rayon][0][0][0][0]";}i:9;a:2:{s:4:"code";s:1:"5";s:6:"valeur";s:1:"0";}i:10;a:2:{s:4:"code";s:1:"6";s:6:"valeur";s:2:"41";}i:11;a:2:{s:4:"code";s:1:"7";s:6:"valeur";s:1:"5";}i:12;a:2:{s:4:"code";s:1:"8";s:6:"valeur";s:1:"1";}i:13;a:2:{s:4:"code";s:1:"9";s:6:"valeur";s:1:"1";}}',
+                    'id_origine' => '11785',
+                    'id_int_bib' => '1',
+                    'is_available' => '1',
+                    'url' => null,
+                    'to_delete' => '0',
+                    'type' => '1',
+                   ]);
+
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 73,
+                    'libelle' => 'Niveau de lecture',
+                    'libelle_facette' => 'Niveau de lecture',
+                    'Id_thesaurus' => 'NIVE',
+                    'id_origine' => null,
+                    'code' => 'NIVE',
+                    'rule_zone' => '993',
+                    'rule_label_field' => 'a',
+                    'rule_id_field' => '4',
+                    'rule_filter_field' => '',
+                    'rule_filter_value' => '',
+                    'rules' => '{"LabelStartPos":"1","LabelLength":"0","Zone":"993","LabelField":"a","IdField":"4","FilterField":"","FilterValue":""}',
+                   ]);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 75,
+                    'libelle' => '0-4 ans',
+                    'libelle_facette' => '0-4 ans',
+                    'id_thesaurus' => 'NIVE0001',
+                    'id_origine' => 1,
+                    'code' => 'NIVE',
+                   ]);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 89,
+                    'libelle' => '4-10 Ans',
+                    'libelle_facette' => '4-10 Ans',
+                    'id_thesaurus' => 'NIVE0003',
+                    'id_origine' => 3,
+                    'code' => 'NIVE',
+                   ]);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 5,
+                    'libelle' => 'Adultes',
+                    'id_thesaurus' => 'CFCF00010003',
+                    'id_origine' => 'CFCF00010003',
+                    'code' => 'Custom Fields',
+                    'rule' => null
+                   ]);
+
+    // storm volatile cannot find all by not null
+    $this->onLoaderOfModel('Class_CodifThesaurus')
+         ->whenCalled('findAllBy')
+         ->with(['rules not' => null])
+         ->answers([Class_CodifThesaurus::find(73)]);
+
+    $this->loadNotice('unimarc_cestas_tchaikovsky');
+    $this->_facets = Class_Notice::find(10843)->getFacetCodes();
+  }
+
+
+  /** @test */
+  public function recordFacetsShouldStillContainsNIVE0001() {
+    $this->assertContains('HNIVE0001', $this->_facets,
+                          json_encode($this->_facets, JSON_PRETTY_PRINT));
+  }
+
+
+  /** @test */
+  public function recordFacetsShouldNoLongerContainsNIVE0003() {
+    $this->assertNotContains('HNIVE0003', $this->_facets,
+                             json_encode($this->_facets, JSON_PRETTY_PRINT));
+  }
+}
+
+
+
+
+class NanookRecordsIntegrationModifLabelOnDynamicFacetTest extends NanookRecordsIntegrationTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 1,
+                    'libelle' => 'Niveau de lecture',
+                    'libelle_facette' => 'Niveau de lecture',
+                    'id_thesaurus' => 'NIVE',
+                    'id_origine' => '',
+                    'code' => 'NIVE',
+                    'rule_zone' => '993',
+                    'rule_label_field' => 'a',
+                    'rule_id_field' => '4'
+                   ]);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 2,
+                    'libelle' => 'wrong',
+                    'libelle_facette' => 'wrong',
+                    'id_thesaurus' => 'NIVE0001',
+                    'id_origine' => 1,
+                    'code' => 'NIVE',
+                   ]);
+
+    $this->loadRecordsFromFile("unimarc_coq");
+  }
+
+
+  /** @test */
+  public function firstRecordFacetsShouldContainsHNIVE0001() {
+    $this->assertEquals('T3 HNIVE0001 A1', Class_Notice::find(1)->getFacettes());
+  }
+
+
+  /** @test */
+  public function codifThesaurusShouldHaveLibelle0_4ans() {
+    $this->assertEquals('0-4 ans' , Class_CodifThesaurus::find(2)->getLibelle());
+  }
 }
\ No newline at end of file
diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
index b6068ed7c5e3f6c5ec291085ea109a596349748d..93b12efde0a9e3801b3b6c796a5d2b653fc07582 100644
--- a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
@@ -401,7 +401,9 @@ class NoticeIntegrationMarc21WithItemsIn952Test extends NoticeIntegrationMarc21D
 
 
 
-class NoticeIntegrationBourdieuWithElectreGeneratedNoticeRecordTest extends NoticeIntegrationTestCase {
+class NoticeIntegrationBourdieuWithElectreGeneratedNoticeRecordTest
+  extends NoticeIntegrationTestCase {
+
   public function setUp() {
     parent::setUp();
 
@@ -409,14 +411,6 @@ class NoticeIntegrationBourdieuWithElectreGeneratedNoticeRecordTest extends Noti
       ->setCodif(['fre' => ['id_langue' => 'fre',
                             'libelle' => 'français']]);
 
-    $this->fixture('Class_CodifThesaurus',
-                   ['id' => 2222,
-                    'id_origine' => 'T380500',
-                    'id_thesaurus' => 'AAAA0001222',
-                    'code' => 'thèmeelectre',
-                    'libelle' => 'Modes de vie et comportements selon les pays',
-                    'rules' => null]);
-
     $this->fixture('Class_CodifThesaurus',
                    ['id' => 88,
                     'id_origine' => 'PS0100',
@@ -430,7 +424,6 @@ class NoticeIntegrationBourdieuWithElectreGeneratedNoticeRecordTest extends Noti
     $this->notice_integration->traiteNotice(file_get_contents(dirname(__FILE__)."/unimarc_bourdieu.txt"));
     $this->notice_integration->traiteFacettes();
     $this->notice_data = $this->notice_integration->getNotice();
-
   }
 
 
@@ -440,33 +433,27 @@ class NoticeIntegrationBourdieuWithElectreGeneratedNoticeRecordTest extends Noti
   }
 
 
-  /** @test */
-  public function themeElectreShouldBeTAAAA0001222() {
-    $this->assertEquals('AAAA0001222', $this->notice_data['thesauri'][0]->getIdThesaurus());
-  }
-
-
   /** @test */
   public function codeShouldBePublicElectre() {
-    $this->assertEquals('publicelectre', $this->notice_data['thesauri'][2]->getCode());
+    $this->assertEquals('publicelectre', $this->notice_data['thesauri'][0]->getCode());
   }
 
 
   /** @test */
   public function libelleShouldBePublicMotive() {
-    $this->assertEquals('Public motivé', $this->notice_data['thesauri'][2]->getLibelle());
+    $this->assertEquals('Public motivé', $this->notice_data['thesauri'][0]->getLibelle());
   }
 
 
   /** @test */
   public function facetteShouldContainsThesaurusIds() {
-    $this->assertContains('HAAAA0001222 HAAAA88 ', $this->notice_data['facettes']);
+    $this->assertContains('HAAAA88 ', $this->notice_data['facettes']);
   }
 
 
   /** @test */
   public function fullTextShouldContainsThesaurusLibelles() {
-    $this->assertContains('Modes de vie et comportements selon les pays Public motivé', $this->notice_data['full_dewey']);
+    $this->assertContains('Public motivé', $this->notice_data['full_dewey']);
   }
 }
 
diff --git a/cosmogramme/tests/php/classes/unimarc_cestas_tchaikovsky.txt b/cosmogramme/tests/php/classes/unimarc_cestas_tchaikovsky.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d5b8235cb8bcf73147545220f645eb28bb504877
--- /dev/null
+++ b/cosmogramme/tests/php/classes/unimarc_cestas_tchaikovsky.txt
@@ -0,0 +1 @@
+01762njm0 2200313   450 00100060000001000110000610000450001720000220006221000260008422500320011041000230014246400540016546400610021946401950028060600110047560600220048668600760050868600390058470000310062370200200065470200230067471200670069771200280076480100170079290003240080999300150113399501370114899601630128511785  d41,5 F  a20110812u        u  u0frey50            1 aSuites de ballets  cPolydordRééd. 19932 aPanorama classique9id:2999 0tPanorama classique  tLe Lac des cygnes:suite extraite du ballet op. 20  tLa belle au bois dormant:suite extraite du ballet op. 66  tCasse-noisette:suite extraite du ballet op. 71/ Piotr Ilyich Tchaïkovski, Witold Rowicki, dir., Ferdinand Leitner, dir., Orchestre Symphonique de la Philharmonie Nationale de Varsovie, Berl 1aballet  amusique classique  a3tMusique classique (Musique savante de tradition occidentale)2Cestas  aAdultestAdultes2Code stat Cestas 1aTchaïkovskibPiotr Ilyich 1aRowickibWitold 1aLeitnerbFerdinand02aOrchestre Symphonique de la Philharmonie Nationale de Varsovie 1aBerliner Philharmoniker 2aFrc20190726  aLe Lac des cygnes:suite extraite du ballet op. 20 ; La belle au bois dormant:suite extraite du ballet op. 66 ; Casse-noisette:suite extraite du ballet op. 71/ Piotr Ilyich Tchaïkovski, Witold Rowicki, dir., Ferdinand Leitner, dir., Orchestre Symphonique de la Philharmonie Nationale de Varsovie, BerllContientntracks  41a0-4 ans  aMédiathèque de Cestasf35025224k3 TCH 28m20190726qdrjeopv12[DISPO][Disponible][0][1][En rayon][0][0][0][0]50641758191   f35025224k3 TCH 28m00000000n00000000aFonds propreb2vMédiathèque MunicipalexCompact disques adulteeCompact disque adulterCD1Document en bon état31
\ No newline at end of file
diff --git a/cosmogramme/tests/php/classes/unimarc_coq.txt b/cosmogramme/tests/php/classes/unimarc_coq.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fb4d7f0e39ea614fb5400bc6752c915d5e80d959
--- /dev/null
+++ b/cosmogramme/tests/php/classes/unimarc_coq.txt
@@ -0,0 +1 @@
+03285njm0 2200541   450 001000700000010001200007071002200019073001800041100001300059200004200072210002000114215003100134300001600165330137700181345001801558349002901576464003501605464003301640464003701673464003601710464003701746464003701783464004601820464004001866464002701906464003401933464004001967464002802007464003002035464005002065464003302115464003402148464003302182606002102215606001902236606001302255606002102268606001002289610001302299686003602312700002002348700002402368801001202392902000902404992016402413993001502577995015102592274318  d20,36 E01bArb Musica486130  a3760124861303  a201906201 aMaroceComptines, danses et berceuses 1cARB Musicd2018 1a1 disque compacte1 livret  aDès 3 mois  aL'album "Maroc, comptines, danses et berceuses", allie l'agilité du phrasé chanté de Halima et l'intensité chaleureuse de Zakariae, véritable homme-orchestre Halima et Zachariae ont spontanément puisé, dans leurs souvenirs d'enfance, les comptines populaires qui racontent en arabe et en français, des histoires qui se transmettent, de génération en génération, Le cheval d'Ali, Le porteur d'eau, La maison du sultan.  Ils ont aussi choisi des mélodies à la douceur enchantée du luth et des chansons dont les rythmes pétillants font entrer spontanément les tout-petits dans la danse orientale Halima Hamdane, conteuse d'origine marocaine, anime l'Arbre à palabres au Musée du Quai Branly et travaille dans le cadre d'un programme d'alphabétisation pour l'apprentissage de la langue française à partir du conte et des comptines Zakariae Heddouchi chanteur et musicien multi-instrumentiste, guitare, guenbri, percussions, accompagne Halima Hamdane sur scène. Il est aussi compositeur de musiques et de chansons pour des spectacles jeune public"Les aventures de Charlie et Zoé : mission planète"  Sofiane Negra, luthiste, accompagne Halima Hamdane. Diplômé d'un DEA de musicologie de la Sorbonne, il est membre de l'orchestre de la Rachidiyya de Tunis en tant que soliste et participe, avec cet ensemble, à plusieurs festivals à travers le monde.  b3760124861303  bArb Musicc3760124861303  tFarasso Ali  - Le cheval d'Ali  tAmchichti - Ma petite chatte  tWahed zouj tlata - Un deux trois  tJrada malha - Sauterelle salée  tAchmicha lalla - Mon beau soleil  tDar Sultan - La maison du Sultan  tWahed el roseya - La biche : instrumental  tArsoumou mama - Je dessine ma maman  tMawlana : instrumental  tDiki ya diki - Coq ô mon coq  tAna zahro - La primevère : poésie  tQum tara : instrumental  tGaraab - Le porteur d'eau  tGhzeyel meyel - Petite gazelle : instrumental  tMini ya moumou - Dodo bébé  tYa tayre - L'oiseau : poésie  tMoumou - Dodo : instrumental  achanson : enfant  adanse : enfant  aberceuse  aMaroc : comptine  aMaroc  aComptine  a710tChansons et rondes2Cestas 1aHamdanebHalima 1aHeddouchibZakariae 1aFRbCVS  a7101  uhttps://websvc.afi-sa.net/afi_opac_services/images/jaquettes/thumbs/8782508.jpegvhttps://websvc.afi-sa.net/afi_opac_services/images/jaquettes/big/8782508.jpeg  41a0-4 ans  aMédiathèque de Cestasf351365212k710 HAM VIOLETm20190911qdrjev02[EQU][À équiper][0][0][bientôt disponible][0][0][0][0]506467328191
\ No newline at end of file
diff --git a/cosmogramme/tests/php/classes/unimarc_minsoc_ia.txt b/cosmogramme/tests/php/classes/unimarc_minsoc_ia.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ad68dbe65ebc5d246ceaf1795676174237c45381
--- /dev/null
+++ b/cosmogramme/tests/php/classes/unimarc_minsoc_ia.txt
@@ -0,0 +1 @@
+03378cam a2200397   4500001000700000010002300007090001100030099011600041100004100157101000800198102000700206200040200213210002800615215004200643225005600685300003800741330083500779410005901614609003801673609003201711609002301743712003701766801004801803856020601851856022902057003004702286020001702333105001802350106000602368606012502374606013602499676001902635686006602654930011702720930014302837440414  a9782111526341bbr.  a440414  tOUVRAGEyADMINISTRATIONySANTESOCIALyTRAVAILEMPLOIaBéatrice LEROYbBéatrice LEROYc2019-08-13d2019-08-13  a20190228d2019    m  h0frey50      ba0 afre  aFR1 aIntelligence artificiellebOUVRAGEbDocument électroniquebRapporteétat de l'art et perspectives pour la Franceerapport finalfPIPAME, Pôle interministériel de prospective et d'anticipation des mutations économiques ; DGE, Direction générale des entreprises ; CGET, Commissariat général à l'égalité des territoires... [et al.]g[rapport réalisé par ATAWAO Consulting]  e53-MayennegImpr. Jouve  a1 vol. (311 p.)cill. en coul.d30 cm  aProspectiveeétudes économiquesfDGEx2491-0058  aBibliogr. et webliogr. p. 306-309  aAprès un état de l’art des différentes technologies du domaine, l’étude propose une méthode de classification des secteurs potentiellement les plus transformés par l’essor de l’intelligence artificielle et établit une analyse macroscopique de son adoption par ceux-ci.  Elle approfondit ensuite cette analyse pour quatre secteurs : Énergie et environnement, Transport et logistique, Santé et Industrie. Pour chacun de ces quatre secteurs, un bilan des opportunités générées par l’IA est établi et une stratégie cible à adopter est proposée. Dans sa dernière partie, l’étude dessine une feuille de route ainsi que des recommandations sectorielles et transverses qui permettront à la France et à ses entreprises de relever les défis en matière d’intelligence artificielle.  044481451tEtudes économiquesx2491-0058d2019947552  9209229aIntelligence artificielle  939035aSecteur économique  937657aProspective  317815993aAtawao consulting4710 0aFRbFR-751131015c20190228gAFNOR2intermrc  2Rapportuhttps://www.entreprises.gouv.fr/files/files/directions_services/etudes-et-statistiques/prospective/Intelligence_artificielle/2019-02-intelligence-artificielle-etat-de-l-art-et-perspectives.pdf  2Synthèse du rapportuhttps://www.entreprises.gouv.fr/files/files/directions_services/etudes-et-statistiques/prospective/Intelligence_artificielle/2019-02-intelligence-artificielle-etat-de-l-art-et-perspectives-synthese.pdfhttp://catalogue.bnf.fr/ark:/12148/cb45679700r  aFRb01927606  a||||z   00|y|  ar  311932084aIntelligence artificielle311975935xApplications industrielles311931476yFrance312432924z1990-....2rameau  311932084aIntelligence artificielle311939593xInnovations technologiques311931476yFrance311950184xÉtudes de marché2rameau  a006.309 44v23  2Cadre de classement de la Bibliographie nationale française  5FR-751131009:45679700001001a2019-44342b759999999cTolbiac - Rez de Jardin - Sciences et technique - MagasindO  5FR-751131008:45679700002001a084.05 DGE ib759999999cTolbiac - Haut de Jardin - Droit, économie, politique - Salle D - Libre accèsdN
\ No newline at end of file
diff --git a/library/Class/CodifThesaurus.php b/library/Class/CodifThesaurus.php
index 6d148193a5463d56644699c96a5a12fba334c089..9488d3245abeb91ce85582b3db5fa9430c8234f5 100644
--- a/library/Class/CodifThesaurus.php
+++ b/library/Class/CodifThesaurus.php
@@ -278,11 +278,9 @@ class CodifThesaurusLoader extends Storm_Model_Loader {
    * @param int
    * $return Class_CodifThesaurus
    */
-  public function findByIdOrigineAndCode($id_origine,$code_thesaurus) {
-    if ($thesaurus = Class_CodifThesaurus::findFirstBy(['id_origine' => $id_origine,
-                                                        'code' => $code_thesaurus ]))
-      return $thesaurus;
-    return Class_CodifThesaurus::findFirstBy(['id_origine' => $id_origine]);
+  public function findByIdOrigineAndCode($id_origine, $code_thesaurus) {
+    return Class_CodifThesaurus::findFirstBy(['id_origine' => $id_origine,
+                                              'code' => $code_thesaurus ]);
   }
 
 
@@ -671,13 +669,14 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
 
 
   public function getOrCreateChild($id_origine, $label) {
-    if ($entry = $this->getChild($id_origine))
+    if (!$entry = $this->getChild($id_origine))
+      $entry = $this->newChildEntry();
+
+    if ($label == $entry->getLibelle())
       return $entry;
 
-    $entry = $this
-      ->newChildEntry()
-      ->updateAttributes(['id_origine' => $id_origine,
-                          'libelle' => $label]);
+    $entry ->updateAttributes(['id_origine' => $id_origine,
+                               'libelle' => $label]);
 
     return $entry->save() ? $entry : null;
   }
diff --git a/library/Class/CodifThesaurus/Rules.php b/library/Class/CodifThesaurus/Rules.php
index f9b054539d6759c8e292636dda420a663ce13d21..98ae173f5694a3b40e36cfacc80c5541229d05b9 100644
--- a/library/Class/CodifThesaurus/Rules.php
+++ b/library/Class/CodifThesaurus/Rules.php
@@ -87,7 +87,6 @@ class Class_CodifThesaurus_Rules extends Class_Entity {
   }
 
 
-
   /**
    * @param $reader cosmogramme notice_unimarc
    */
@@ -118,27 +117,46 @@ class Class_CodifThesaurus_Rules extends Class_Entity {
    * @param $reader cosmogramme notice_unimarc
    */
   public function extractIdAndFields($reader) {
+
     $label_field = trim($this->getLabelField());
     $id_field = trim($this->getIdField());
 
-    $id_labels =  array_map(function($fields) use ($label_field, $id_field)
-                            {
-                              if (!isset($fields[$label_field]))
-                                return null;
-
-                              $label = $this->truncateLabel($fields[$label_field]);
-                              if (!$this->isValidLabel($label))
-                                return null;
-
-                              $id = (isset($fields[$id_field]) ? $fields[$id_field] : null);
-                              return ['id' => strtoupper($this->isValidLabel($id) ? $id : $label),
-                                      'label' => $label];
-                            },
-                            $this->_getZonesToParse($reader));
-    return array_filter($id_labels);
-  }
 
+    if (!$label_field)
+      return [];
+
+    $filter_field = $this->getFilterField();
+
+    $filter_subfield_in = function($block) {
+
+      $label = $this->truncateLabel($block->get('label'));
+      if (!$this->isValidLabel($label))
+        return false;
+      $filter_zone = $this->getZone();
+      $filter_field = $this->getFilterField();
+      $filter_value = $this->getFilterValue();
 
+      if (!$filter_zone || (null === $filter_field) | !$filter_value)
+        return  true;
+      return  ($block->get('filter') == $filter_value);
+
+    };
+
+    $fields = $reader->cutBlockBySubfields($this->getZonePadded(),
+                                           [$label_field =>'label',
+                                            $id_field =>'id',
+                                            $filter_field => 'filter'], $filter_subfield_in);
+
+      return array_filter(array_map([$this,'buildAuthorityStructure'],$fields));
+  }
+
+  public function buildAuthorityStructure($block){
+    $label = $this->truncateLabel($block->get('label'));
+    return ['id' => $block->get('id')
+            ? strtoupper($block->get('id'))
+            : strtoupper($label),
+            'label' => $label];
+  }
 
   public function truncateLabels($labels) {
     return array_filter(
diff --git a/library/Class/Mail.php b/library/Class/Mail.php
index fb3b43e08f606adae3fba5bf505623c51b59e9b3..3fdf7a80af82f1ebf206d2c0febb21fc5ac8e024 100644
--- a/library/Class/Mail.php
+++ b/library/Class/Mail.php
@@ -76,17 +76,7 @@ class Class_Mail {
     if (!$this->isMailValid($destinataire))
       return $this->_("L'adresse e-mail du destinataire est incorrecte.");
 
-
-    // Fusion
-    if($data)
-    {
-      foreach($data as $var => $valeur)
-      {
-        $var="{".$var."}";
-        $body=str_replace($var,$valeur,$body);
-      }
-    }
-    $body = wordwrap($body, 60);
+    $body = $this->_injectDatasInto($data, $body);
 
     $statut = $this->mail($destinataire, $sujet, $body);
 
@@ -96,6 +86,17 @@ class Class_Mail {
   }
 
 
+  protected function _injectDatasInto($data, $body) {
+    if (!$data)
+      return $body;
+
+    foreach ($data as $name => $value)
+      $body = str_replace('{' . $name . '}', $value, $body);
+
+    return $body;
+  }
+
+
   public function isMailValid($mail) {
     $validator = new Zend_Validate_EmailAddress();
     return $validator->isValid($mail);
@@ -105,4 +106,4 @@ class Class_Mail {
   public function getMailFrom() {
     return $this->mail_from;
   }
-}
\ No newline at end of file
+}
diff --git a/library/Class/NoticeUnimarc.php b/library/Class/NoticeUnimarc.php
index a1e25d6a7da4a5bd2e2df48f7335c1f1f047ec12..6fdbb3b724ebb39f1b271bec1c702b4ccdb5c2af 100644
--- a/library/Class/NoticeUnimarc.php
+++ b/library/Class/NoticeUnimarc.php
@@ -40,6 +40,7 @@ class Class_NoticeUnimarc {
   protected $rgx_field_end;
   protected $subfield_begin;
   protected $rgx_subfield_begin;
+  protected $blocks = [];
 
   public function __construct() {
     $this->tracer_accents = isset(self::$_tracer_accents_iso)
@@ -177,6 +178,70 @@ class Class_NoticeUnimarc {
   }
 
 
+  /**
+     @data $subfields_mapping = [ 'y' => 'label', '4'=> 'id' ]
+
+     @return  [ Class_Entity ('id' => 'valeur',
+                        'label' => 'label'
+                        ),...
+              ]
+  */
+  public function cutBlockBySubfields($zone, $subfields_mapping, $closure_valid) {
+
+    $this->blocks=[];
+
+    foreach ($this->get_subfield($zone) as $line) {
+      $this->_cutLineBySubfields($line, $subfields_mapping,$closure_valid);
+    }
+    return $this->blocks;
+  }
+
+
+  protected function _cutLineBySubfields($line, $subfields_mapping, $closure_valid) {
+    $block = $this->_newBlock();
+
+    $fields = $this->_bloc_to_array($line);
+
+    $bloc_values = array_values($subfields_mapping);
+
+    foreach($fields as $field) {
+      $code = substr($field, 0, 1);
+      $value = trim(substr($field, 1));
+      if (!in_array($code,array_keys($subfields_mapping)))
+        continue;
+
+      if ($block->get($subfields_mapping[$code])) {
+        $block = $this->_addBlock($block,$closure_valid);
+      }
+
+      $block->set($subfields_mapping[$code], $value);
+
+    }
+
+    $this->_addBlock($block,$closure_valid);
+
+    return $this;
+  }
+
+
+  protected function _newBlock() {
+    return new Class_Entity();
+  }
+
+
+  protected function _addBlock($block, $closure_valid) {
+    if (call_user_func($closure_valid,$block))
+      $this->blocks[] = $block;
+    return $this->_newBlock();
+  }
+
+
+  protected function _bloc_to_array($bloc) {
+    $bloc = substr($bloc, 3);
+    return explode($this->subfield_begin, $bloc);
+  }
+
+
   public function decoupe_bloc_champ($bloc,$num=false) {
     $sc = [];
     $bloc = substr($bloc, 3);
@@ -185,44 +250,10 @@ class Class_NoticeUnimarc {
       $sc[] = $num == true
       ? [substr($field, 0, 1), trim(substr($field, 1))]
       : ['code' => substr($field, 0, 1), 'valeur' => trim(substr($field, 1))];
-
     return (0 == count($sc)) ? null : $sc;
   }
 
 
-
-  /**
-   * ex: $unimarc->parseZone(686)
-   *
-   * answers:
-   *   [
-   *       [ 'a' => 'A12+'
-   *         't' => 'A12+'
-   *         '2' => 'Ludo - Age'],
-   *
-   *       [ 'a' => '3-5J'
-   *         't' => '3-5 JOUEURS'
-   *         '2' => 'Ludo - Nb joueurs']
-   *   ]
-   */
-  public function parseZone($zone) {
-    return array_map(function($bloc)
-                     {
-                       return $this->parseZoneFields($bloc);
-                     },
-                     $this->get_subfield($this->getZonePadded()));
-  }
-
-
-  /** @see parseZone */
-  public function parseZoneFields($marc) {
-    $fields = [];
-    foreach(explode($this->subfield_begin, substr($marc,3)) as $field)
-      $fields[substr($field, 0, 1)] = trim(substr($field, 1));
-    return $fields;
-  }
-
-
   public function reset_notice() {
     $this->full_record = '';
     $this->guide = '';
diff --git a/library/Class/NoticeUnimarc/Fluent.php b/library/Class/NoticeUnimarc/Fluent.php
index a60d7bac7bbd4cc1f81e2c8bb79dea74592c8347..4fbfdd00bc0375a864d807fdf2b44a6e06a41566 100644
--- a/library/Class/NoticeUnimarc/Fluent.php
+++ b/library/Class/NoticeUnimarc/Fluent.php
@@ -25,6 +25,13 @@ class Class_NoticeUnimarc_Fluent {
     $_label,
     $_zones;
 
+  /** @param $reader Class_NoticeUnimarc */
+  public static function fromLegacy($reader) {
+    return (new Class_NoticeUnimarc_LegacyVisitor())
+      ->legacyToFluent($reader);
+  }
+
+
   public function __construct() {
     $this->_label = new Class_NoticeUnimarc_BibliographicLabel();
     $this->_zones = new Storm_Collection();
@@ -65,20 +72,26 @@ class Class_NoticeUnimarc_Fluent {
   }
 
 
+  public function zonesCollect($callback) {
+    return $this->_zones->collect($callback);
+  }
+
+
   public function render() {
     $address   = 0;
     $directory = '';
 
-    $zones = implode($this->_zones
-                     ->collect(
-                               function($zone) use(&$address, &$directory) {
-                                 $marc = $zone->render();
-                                 $length = strlen($marc);
-                                 $directory .= $zone->directoryWith($length, $address);
-                                 $address += $length;
-                                 return $marc;
-                               })
-                     ->getArrayCopy());
+    $zones = $this
+      ->zonesCollect(function($zone) use(&$address, &$directory)
+                     {
+                       $marc = $zone->render();
+                       $length = strlen($marc);
+                       $directory .= $zone->directoryWith($length, $address);
+                       $address += $length;
+                       return $marc;
+                     });
+
+    $zones = implode($zones->getArrayCopy());
 
     $zones     .= chr(0x1d);
     $directory .= chr(0x1e);
@@ -183,6 +196,11 @@ class Class_NoticeUnimarc_Zone {
   }
 
 
+  public function isLabel($label) {
+    return $label == $this->_label;
+  }
+
+
   public function content($content) {
     $this->_content = $content;
     $this->_sub_zones = new Storm_Collection();
@@ -192,9 +210,17 @@ class Class_NoticeUnimarc_Zone {
 
   public function children($children) {
     foreach($children as $code => $value)
-      $this->_sub_zones->append((new Class_NoticeUnimarc_SubZone)->code($code)->value($value));
-    $this->_content = null;
+      $this->addChild($code, $value);
+
+    return $this;
+  }
+
 
+  public function addChild($code, $value) {
+    $this->_sub_zones
+      ->append((new Class_NoticeUnimarc_SubZone)->code($code)->value($value));
+
+    $this->_content = null;
     return $this;
   }
 
@@ -205,6 +231,19 @@ class Class_NoticeUnimarc_Zone {
   }
 
 
+  public function detectFieldByCode($code) {
+    return $this->detectField(function($field) use($code)
+                              {
+                                return $field->isCode($code);
+                              });
+  }
+
+
+  public function detectField($callback) {
+    return $this->_sub_zones->detect($callback);
+  }
+
+
   public function render() {
     $content = $this->_content
       ? $this->_content
@@ -234,13 +273,60 @@ class Class_NoticeUnimarc_SubZone {
   }
 
 
+  public function isCode($code) {
+    return $code == $this->_code;
+  }
+
+
   public function value($value) {
     $this->_value = $value;
     return $this;
   }
 
 
+  public function getValue() {
+    return $this->_value;
+  }
+
+
   public function render() {
     return chr(0x1f) . $this->_code . $this->_value;
   }
+}
+
+
+
+
+class Class_NoticeUnimarc_LegacyVisitor {
+  protected $_fluent;
+
+  public function __call($name, $args) {
+    if ('visit' === substr($name, 0, 5))
+      return $this;
+
+    throw new RuntimeException('Call to undefine method Class_NoticeUnimarc_LegacyVisitor::' . $name);
+  }
+
+
+  public function legacyToFluent($reader) {
+    $this->_fluent = new Class_NoticeUnimarc_Fluent;
+    $reader->acceptVisitor($this);
+
+    return $this->_fluent;
+  }
+
+
+  public function visitZone($label, $definition) {
+    $zone = $this->_fluent->newZone()->label($label);
+    $fields = $definition['champs'];
+    if (1 == count($fields) && '' === $fields[0]['code']) {
+      $zone->content($fields[0]['valeur']);
+      return $this;
+    }
+
+    foreach($fields as $field)
+      $zone->addChild(substr($field['code'], 1, 1), $field['valeur']);
+
+    return $this;
+  }
 }
\ No newline at end of file
diff --git a/library/Class/User/LostPass.php b/library/Class/User/LostPass.php
index 8ea5047aec07c92031f1fe14c787cdd549330194..1225309f77a03acc4354b479e61e174de4610399 100644
--- a/library/Class/User/LostPass.php
+++ b/library/Class/User/LostPass.php
@@ -24,7 +24,7 @@ class Class_User_LostPass {
 
   use Trait_TimeSource, Trait_Translator;
 
-  const MAX_MINUTES = 30;
+  const MAX_HOURS = 24;
   const TOKEN_SEPARATOR = '@';
   const TOKEN_DATE_FORMAT = 'YmdHis';
 
@@ -56,7 +56,7 @@ class Class_User_LostPass {
   public function tokenHasExpiredFrom($date) {
     $from = DateTime::createFromFormat(static::TOKEN_DATE_FORMAT, $date);
     $now = new DateTime($this->getCurrentDateTime());
-    $from->add(new DateInterval('PT' . static::MAX_MINUTES . 'M'));
+    $from->add(new DateInterval('PT' . static::MAX_HOURS . 'H'));
 
     return $from < $now;
   }
@@ -141,9 +141,9 @@ class Class_User_LostPassResetLink extends Class_User_LostPassSender{
                                       'id' => $user->getId(),
                                       'token' => $token,
                                       'created' => $created_at_part], null, true))
-      . $this->_("ATTENTION : ce lien créé à %s est valide pendant %s minutes\n",
+      . $this->_("ATTENTION : ce lien créé à %s est valide pendant %s heures\n",
                  date('H:i', $created_at),
-                 Class_User_LostPass::MAX_MINUTES)
+                 Class_User_LostPass::MAX_HOURS)
       . sprintf("%s\n\n", $this->_('Bonne navigation sur le portail'));
   }
 
diff --git a/library/Class/WebService/BibNumerique/CiteDeLaMusique.php b/library/Class/WebService/BibNumerique/CiteDeLaMusique.php
index 42c80339fb9d3895c925bdc09674d95f47a44df4..400228a2d3a5bbea76aad2b1cf727580417f371e 100644
--- a/library/Class/WebService/BibNumerique/CiteDeLaMusique.php
+++ b/library/Class/WebService/BibNumerique/CiteDeLaMusique.php
@@ -30,7 +30,7 @@ class Class_WebService_BibNumerique_CiteDeLaMusique
   public function __construct() {
     $this->_ermes_parser = new Class_WebService_OAI_ErmesParser();
     $this->_oaiws = (new Class_WebService_OAI())
-      ->setMetadataPrefix('Ermes')
+      ->setMetadataPrefix('ermes')
       ->setParser($this->_ermes_parser)
       ->setOAIHandler($this->getUrlOrigine())
       ->setNumericResourceClass('Class_WebService_BibNumerique_CiteDeLaMusique_Album');
diff --git a/library/Class/WebService/SIGB/Orphee/GetLstDmtResponseReader.php b/library/Class/WebService/SIGB/Orphee/GetLstDmtResponseReader.php
index 92313530da48edab5c85065e462b181578378985..078bfdbdf0c42d0fff6f87ff9ded79c038fb4882 100644
--- a/library/Class/WebService/SIGB/Orphee/GetLstDmtResponseReader.php
+++ b/library/Class/WebService/SIGB/Orphee/GetLstDmtResponseReader.php
@@ -22,6 +22,8 @@
 class Class_WebService_SIGB_Orphee_GetLstDmtResponseReader extends Class_WebService_SIGB_AbstractXMLNoticeReader {
   const CODE_SITUTATION_SORTI = 2;
   const CODE_SITUTATION_RESERVE = 3;
+  const CODE_SITUTATION_PERDU = 5;
+  const CODE_SITUTATION_EN_RESERVE = 10;
   const CODE_SITUTATION_ARCHIVAGE = 14;
   const CODE_SITUTATION_CATALOGAGE = 17;
 
@@ -71,8 +73,12 @@ class Class_WebService_SIGB_Orphee_GetLstDmtResponseReader extends Class_WebServ
 
 
   public function endSit($data) {
-    $reservable = ($data==self::CODE_SITUTATION_SORTI || $data==self::CODE_SITUTATION_RESERVE);
+    $reservable = in_array($data, [self::CODE_SITUTATION_SORTI,
+                                   self::CODE_SITUTATION_RESERVE,
+                                   self::CODE_SITUTATION_EN_RESERVE]);
+
     $this->_current_exemplaire->setReservable($reservable);
+
     $visible = ($data!=self::CODE_SITUTATION_ARCHIVAGE && $data!=self::CODE_SITUTATION_CATALOGAGE);
     $this->_current_exemplaire->setVisibleOPAC($visible);
   }
diff --git a/library/ZendAfi/View/Helper/ModeleFusion/Template/Loans.php b/library/ZendAfi/View/Helper/ModeleFusion/Template/Loans.php
index e801960ccc64d43a0097a06ec254d7143dd25221..655beeb126a783fd14cc4decefc230907f109272 100644
--- a/library/ZendAfi/View/Helper/ModeleFusion/Template/Loans.php
+++ b/library/ZendAfi/View/Helper/ModeleFusion/Template/Loans.php
@@ -28,19 +28,19 @@ class ZendAfi_View_Helper_ModeleFusion_Template_Loans extends ZendAfi_View_Helpe
 
   protected function _getRow() {
     $html = [$this->_tag('h1',
-                         $this->_('Titre : {getTitle}')),
+                         $this->_('Titre : {title}')),
 
-             $this->_tag('span', '{getThumbnail}'),
+             $this->_tag('span', '{thumbnail}'),
 
-             $this->_tag('span', $this->_('emprunté par : {getLoanedBy}')),
+             $this->_tag('span', $this->_('Emprunté par : {loaned_by}')),
 
-             $this->_tag('span', $this->_('code barre : {getBarCode}')),
+             $this->_tag('span', $this->_('Code-barre : {bar_code}')),
 
-             $this->_tag('span', $this->_('Auteur : {getAuthor}')),
+             $this->_tag('span', $this->_('Auteur : {author}')),
 
-             $this->_tag('span', $this->_('date de prêt : {getIssueDate}')),
+             $this->_tag('span', $this->_('Date de prêt : {issue_date}')),
 
-             $this->_tag('span', $this->_('dates de retour prévu : {getReturnDate}')),
+             $this->_tag('span', $this->_('Date de retour prévue : {return_date}')),
     ];
 
     return $this->_getRowWrapper(implode(BR, $html));
diff --git a/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php b/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php
index 29afa75929066d772190d96017fd4312cc39cb22..63be51b750b03d0d4fbd2d3abc34ba67bc52f1c8 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php
@@ -162,13 +162,16 @@ abstract class AbonneControllerPretsListThreePretsTestCase extends AbstractAbonn
                                           'notice' => $this->fixture('Class_Notice',
                                                                      ['id' => 827,
                                                                       'titre_principal' => 'Alice',
-                                                                      'unimarc' => '01175cam0 22002771  450 001001500000010003700015100004100052101000800093102000700101105001800108106000600126200009300132210002400225211001300249215006400262300002400326307002900350330027300379345001800652461005600670700001800726701003000744801003300774856008300807940000700890frOr0354235228  a978-2-35592-635-8bbr.d7,65 EUR  a20140225d2014    |  |0fre|0103||||ba  afre  aFR  a        0||y|  ar1 aAlice au royaume de TrèfleeCheshire cat Waltzh5fQuinRosegdessin Mamenosuke Fujimaru  aPariscKi-oond2014 1a20140227  a1 vol. (164 p.)cillustrations en noir et blancd18 x 13 cm  aTraduit du japonais  aSens de lecture japonais  aPerdue dans la forêt aux portes, Alice tombe nez à nez avec Ace. Devenue malgré elle la confidente du chevalier, elle ne sait comment repousser ses avances. Lorsque le chat du Cheshire, qui a assisté à la scène, intervient, la rencontre tourne à l\'affrontement.  b9782355926358 1tAlice au royaume de Trèfle : Cheshire cat Waltzv5 1aQuinRose4070 1aFujimarubMamenosuke4440  aFRbElectrec20140225gAFNOR  uhttp://www.electre.com//GetBlob.ashx?Ean=9782355926358,0-1913692&Size=Original  aLR'])]));
+                                                                      'unimarc' => '01175cam0 22002771  450 001001500000010003700015100004100052101000800093102000700101105001800108106000600126200009300132210002400225211001300249215006400262300002400326307002900350330027300379345001800652461005600670700001800726701003000744801003300774856008300807940000700890frOr0354235228  a978-2-35592-635-8bbr.d7,65 EUR  a20140225d2014    |  |0fre|0103||||ba  afre  aFR  a        0||y|  ar1 aAlice au royaume de TrèfleeCheshire cat Waltzh5fQuinRosegdessin Mamenosuke Fujimaru  aPariscKi-oond2014 1a20140227  a1 vol. (164 p.)cillustrations en noir et blancd18 x 13 cm  aTraduit du japonais  aSens de lecture japonais  aPerdue dans la forêt aux portes, Alice tombe nez à nez avec Ace. Devenue malgré elle la confidente du chevalier, elle ne sait comment repousser ses avances. Lorsque le chat du Cheshire, qui a assisté à la scène, intervient, la rencontre tourne à l\'affrontement.  b9782355926358 1tAlice au royaume de Trèfle : Cheshire cat Waltzv5 1aQuinRose4070 1aFujimarubMamenosuke4440  aFRbElectrec20140225gAFNOR  uhttp://www.electre.com//GetBlob.ashx?Ean=9782355926358,0-1913692&Size=Original  aLR',
+                                                                      'url_image' => 'Alice.jpg',
+                                                                     ])]));
 
     $alice->parseExtraAttributes(['Dateretourprevue' => '21/10/2010',
                                   'Section' => 'Espace jeunesse',
                                   'Auteur' => 'Lewis Caroll',
                                   'Bibliotheque' => 'Almont',
                                   'N° de notice' => '5678']);
+    $alice->setIssueDate('10/10/2010');
 
     $this->fixture('Class_Exemplaire',
                    ['id' => 918,
@@ -1155,28 +1158,44 @@ class AbonneControllerBarcodesExportThreePretsTest extends AbonneControllerPrets
 class AbonneControllerPrintActionPretsTest extends AbonneControllerPretsListThreePretsTestCase {
   public function setUp() {
     parent::setUp();
+    $helper = new ZendAfi_View_Helper_ModeleFusion_Template_Loans();
+    $helper->setView(new ZendAfi_Controller_Action_Helper_View());
+
     $this->fixture('Class_ModeleFusion',
                    ['id' => 9,
                     'type' => 'Loans_List',
                     'nom' => 'loans',
-                    'contenu' => '<div style="page-break-inside:auto">{loans.each[
-<div style="page-break-inside:avoid; page-break-after:auto;overflow:hidden;float:left;clear:both;padding: 0.5em;margin: 0.5em 0;border: 1px solid black;width:190mm;box-shadow: 0px 0px 5px;">
-<h1>Titre : {title}</h1>
-<br />
-<span>{thumbnail}</span><br />
-<span>emprunt&eacute; par : {loaned_by}</span><br />
-<span>code barre : {bar_code}</span><br />
-<span>Auteur : {author}</span><br />
-<span>date de pr&ecirc;t : {issue_date}</span><br />
-<span>dates de retour pr&eacute;vu : {return_date}</span></div>
-]}</div>']);
+                    'contenu' => $helper->ModeleFusion_Template_Loans()]);
     $this->dispatch('abonne/print/ids/reload/strategy/Loans_List/modele_fusion/9', true);
   }
 
 
   /** @test */
-  public function responseShouldContainsSomethings() {
-    $this->assertXPathContentContains('//div', 'Titre : Alice au royaume de ');
+  public function h1ShouldContainsAliceAuRoyaume() {
+    $this->assertXPathContentContains('//h1', 'Titre : Alice au royaume de ');
+  }
+
+  /** @test */
+  public function spanShouldContainsThumbnailAliceDotJpg() {
+    $this->assertXPath('//span//img[contains(@src, "Alice.jpg")]');
+  }
+
+  /** @test */
+  public function spanShouldContainsCodeBarre124() {
+    $this->assertXPathContentContains('//span', 'Code-barre : 124');
+  }
+
+
+  /** @test */
+  public function spanShouldContainsDateRetour21102010() {
+    $this->assertXPathContentContains('//span', utf8_encode('Date de retour prévue : 21/10/2010'),
+                                      $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function spanShouldContainsDateDePret10102010() {
+    $this->assertXPathContentContains('//span', utf8_encode('Date de prêt : 10/10/2010'));
   }
 }
 
diff --git a/tests/application/modules/opac/controllers/AuthControllerLostPasswordTest.php b/tests/application/modules/opac/controllers/AuthControllerLostPasswordTest.php
index 481509f9164e32c1d101525e4a747694fbd4a4f8..e9fa77ea2aa2523979b63ff3de3ad4581285da89 100644
--- a/tests/application/modules/opac/controllers/AuthControllerLostPasswordTest.php
+++ b/tests/application/modules/opac/controllers/AuthControllerLostPasswordTest.php
@@ -96,7 +96,7 @@ class AuthControllerLostPasswordActionTest extends AuthControllerLostPasswordTes
 
 
 class AuthControllerLostPasswordValidPostTest extends AuthControllerLostPasswordTestCase {
-  protected $_mail_transport;
+  protected $_mail_transport, $_mail;
 
   public function setUp() {
     parent::setUp();
@@ -124,19 +124,27 @@ class AuthControllerLostPasswordValidPostTest extends AuthControllerLostPassword
     $user->beAbonneSIGB()->assertSave();
 
     $this->postDispatch('/opac/auth/lostpass', ['lost_username' => 'Chambelle']);
+    $this->_mail = $this->_mail_transport->sent_mail;
   }
 
 
   /** @test */
   public function mailShouldBeSent() {
-    $this->assertNotNull($this->_mail_transport->sent_mail);
+    $this->assertNotNull($this->_mail);
   }
 
 
   /** @test */
   public function mailShouldContainsVousAvezFaitUneDemande() {
     $this->assertContains('Vous avez fait une demande',
-                          $this->_mail_transport->sent_mail->getBodyText(true));
+                          $this->_mail->getBodyText(true));
+  }
+
+
+  /** @test */
+  public function mailShouldContainsExpirationIn24H() {
+    $this->assertContains('est valide pendant 24 heures',
+                          $this->_mail->getBodyText(true));
   }
 }
 
diff --git a/tests/library/Class/WebService/LastfmTest.php b/tests/library/Class/WebService/LastfmTest.php
index 8ea9c61f26947360e792fef0c38007042a19c1c0..55563792128a83b977557a3a37abdad56b39ad59 100644
--- a/tests/library/Class/WebService/LastfmTest.php
+++ b/tests/library/Class/WebService/LastfmTest.php
@@ -153,7 +153,7 @@ class LastfmGetMorceauxNoTracksIntegrationTest extends ModelTestCase {
   public function setUp() {
     parent::setUp();
     $this->_last_fm = new Class_WebService_Lastfm();
-    $this->_album = $this->_last_fm->getMorceaux('No track', 'Not found');
+    $this->_album = $this->_last_fm->getMorceaux('uiaunesrttt', 'auierst');
   }
 
 
diff --git a/tests/library/Class/WebService/SIGB/OrpheeFixtures.php b/tests/library/Class/WebService/SIGB/OrpheeFixtures.php
index 3cadcc7ff088fd0434dd2bdfd995f34a652a15d8..a70b3eca6ef44478dc920cb0b26191205adacdc5 100644
--- a/tests/library/Class/WebService/SIGB/OrpheeFixtures.php
+++ b/tests/library/Class/WebService/SIGB/OrpheeFixtures.php
@@ -366,6 +366,48 @@ class OrpheeFixtures {
         <titre><![CDATA[[Millenium (Larsson, Stieg (1954-2004))]]></titre>
         <date_edi><![CDATA[2010]]></date_edi>
         <can_rsv>0</can_rsv>
+      </document>
+
+      <document>
+        <no><![CDATA[9876123]]></no>
+        <ntc><![CDATA[1301700727]]></ntc>
+        <carte><![CDATA[9876123]]></carte>
+        <sit><![CDATA[10]]></sit>
+        <lib_sit><![CDATA[  en reserve]]></lib_sit>
+        <loc><![CDATA[2]]></loc>
+        <lib_loc><![CDATA[  Salle bleue]]></lib_loc>
+        <loc_ori><![CDATA[2]]></loc_ori>
+        <lib_loc_ori><![CDATA[  Salle bleue]]></lib_loc_ori>
+        <cote><![CDATA[952.05 SCO]]></cote>
+        <anx_ori><![CDATA[1]]></anx_ori>
+        <lib_anx_ori><![CDATA[  Bibliothèque]]></lib_anx_ori>
+        <anx_cur><![CDATA[1]]></anx_cur>
+        <lib_anx_cur><![CDATA[  Bibliothèque]]></lib_anx_cur>
+        <anx_nxt><![CDATA[1]]></anx_nxt>
+        <lib_anx_nxt><![CDATA[  Bibliothèque]]></lib_anx_nxt>
+        <no_coll><![CDATA[0]]></no_coll>
+        <site><![CDATA[20]]></site>
+        <lib_site><![CDATA[  Saint Cloud]]></lib_site>
+        <sup><![CDATA[108]]></sup>
+        <lib_sup><![CDATA[  Livre]]></lib_sup>
+        <sec><![CDATA[2]]></sec>
+        <lib_sec><![CDATA[  Adultes]]></lib_sec>
+        <uti><![CDATA[2]]></uti>
+        <lib_uti><![CDATA[  Prêt normal]]></lib_uti>
+        <sta1><![CDATA[98]]></sta1>
+        <lib_sta1><![CDATA[  Docum Adulte]]></lib_sta1>
+        <sta2><![CDATA[57]]></sta2>
+        <lib_sta2><![CDATA[  Histoire]]></lib_sta2>
+        <sta3><![CDATA[0]]></sta3>
+        <lib_sta3 />
+        <date_last_pret><![CDATA[03/05/2018]]></date_last_pret>
+        <date_last_retour><![CDATA[31/08/2018]]></date_last_retour>
+        <droit_resa><![CDATA[0]]></droit_resa>
+        <lib_droit_resa />
+        <titre><![CDATA[[Millenium (Larsson, Stieg (1954-2004))]]></titre>
+        <date_edi><![CDATA[2010]]></date_edi>
+      </document>
+
     </documents>
   </datas>';
   }
diff --git a/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php b/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php
index abe98d5289229a07ccfbd152b838cc5fe9478cff..b81fe8c145c3c5b7c5a5278517071e3e587e25dd 100644
--- a/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php
+++ b/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php
@@ -377,7 +377,12 @@ class OrpheeServiceTestGetLstDmntWithMillenium extends OrpheeServiceTestCase {
                                       $this->fixture('Class_Exemplaire',
                                                      ['id' => 6,
                                                       'code_barres' => '200014900',
-                                                      'id_origine' => 'frOr1301200059'])
+                                                      'id_origine' => 'frOr1301200059']),
+
+                                      $this->fixture('Class_Exemplaire',
+                                                     ['id' => 7,
+                                                      'code_barres' => '9876123',
+                                                      'id_origine' => 'frOr1301700727'])
                     ]
                    ]);
 
@@ -532,6 +537,14 @@ class OrpheeServiceTestGetLstDmntWithMillenium extends OrpheeServiceTestCase {
     $this->assertNotEmpty($exemplaire);
     $this->assertFalse($exemplaire->isReservable());
   }
+
+
+  /** @test */
+  public function exemplaireByCodeBarre9876123ShouldBeReservable() {
+    $exemplaire = $this->_orphee->getExemplaire('frOr1301700727', '9876123');
+    $this->assertTrue($exemplaire->isReservable());
+  }
+
 }
 
 
diff --git a/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php b/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php
index 8b1ef762286f30c42cba55acd61376d772dbcbc0..bf1b5fa72ff9fce28d8931d0a047b256518ffa66 100644
--- a/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php
+++ b/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php
@@ -242,7 +242,7 @@ class CiteDeLaMusiqueParserTest extends ModelTestCase {
     $this->_http_client = $this->mock();
     $this->_http_client
       ->whenCalled('open_url')
-      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&metadataPrefix=Ermes&set=videos-concerts-docu-entiers')
+      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&metadataPrefix=ermes&set=videos-concerts-docu-entiers')
       ->answers(CiteDeLaMusiqueFixtures::getFixtureContent('cite_de_la_musique_oai.xml'))
 
       ->whenCalled('open_url')
@@ -250,7 +250,7 @@ class CiteDeLaMusiqueParserTest extends ModelTestCase {
       ->answers(CiteDeLaMusiqueFixtures::getFixtureContent('cite_de_la_musique_oai_end.xml'))
 
       ->whenCalled('open_url')
-      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&metadataPrefix=Ermes&set=audios-concerts-entiers')
+      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&metadataPrefix=ermes&set=audios-concerts-entiers')
       ->answers(CiteDeLaMusiqueFixtures::getFixtureContent('cite_de_la_musique_oai_audios.xml'))
 
       ->whenCalled('open_url')
@@ -466,7 +466,7 @@ class CiteDeLaMusiqueOAIHarvestTest extends ModelTestCase {
     $http_client = $this->mock();
     $http_client
       ->whenCalled('open_url')
-      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&metadataPrefix=Ermes&set=videos-concerts-docu-entiers&from=2017-10-11')
+      ->with('https://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx?verb=ListRecords&metadataPrefix=ermes&set=videos-concerts-docu-entiers&from=2017-10-11')
       ->answers(CiteDeLaMusiqueFixtures::getFixtureContent('cite_de_la_musique_oai.xml'))
 
       ->whenCalled('open_url')