diff --git a/VERSIONS_WIP/dev_13769_cache_doc_availability b/VERSIONS_WIP/dev_13769_cache_doc_availability
index 899ca4b7e50018ff328a7dacde94b9cc50cf0308..767209e27c72b51261ec2e432ca61771abf8df0f 100644
--- a/VERSIONS_WIP/dev_13769_cache_doc_availability
+++ b/VERSIONS_WIP/dev_13769_cache_doc_availability
@@ -1 +1 @@
-ticket 13769 : Import de la disponibilité des exemplaires unimarc (Nanook) et affichage de la facette en résultat de recherche
+- ticket #13769 : Import de la disponibilité des exemplaires unimarc (Nanook) et affichage de la facette en résultat de recherche.
diff --git a/VERSIONS_WIP/dev_17649_webservice_update_availability b/VERSIONS_WIP/dev_17649_webservice_update_availability
new file mode 100644
index 0000000000000000000000000000000000000000..407a7d8eb162f3e17ae8515e5f07336dd991a4b1
--- /dev/null
+++ b/VERSIONS_WIP/dev_17649_webservice_update_availability
@@ -0,0 +1 @@
+- ticket #17649: mise à jour de la facette "En rayon" depuis les informations de disponibilité renvoyées par le web service SIGB.  Si le webservice ne répond pas, affichage de la dernière disponibilité connue.
\ No newline at end of file
diff --git a/application/modules/opac/controllers/NoticeajaxController.php b/application/modules/opac/controllers/NoticeajaxController.php
index 7cccb976bcca098ad073f7acaa2baadfe536a210..4a0f120f8b33cd64cf53af72411443900b0e0f6b 100644
--- a/application/modules/opac/controllers/NoticeajaxController.php
+++ b/application/modules/opac/controllers/NoticeajaxController.php
@@ -87,67 +87,70 @@ class NoticeAjaxController extends Zend_Controller_Action {
 	}
 
 
-	public function exemplairesAction()	{
+	public function exemplairesSameWorkAction() {
+		$notices = Class_Notice::findAllBy(['clef_oeuvre' => $this->notice->getClefOeuvre(),
+																				'id_notice not' =>  $this->notice->getId()]);
+
+		$ids=[];
+		foreach ($notices as $notice) {
+			$ids[]= $notice->getId();
+		 }
+
+		$this->renderExemplaires($ids, 0,'oeuvre');
+
+	}
+
+	public function renderExemplaires($notice_ids, $nb_notices_oeuvre,$display) {
 		session_write_close();
 
 		$this->getResponse()->setHeader('Content-Type', 'text/html;charset=utf-8');
 
-		if (!$this->id_notice) {
+		if (!$this->notice->hasExemplaires()) {
 			$this->getResponse()->setBody('');
 			return;
 		}
 
-		// Condition oeuvre ou id_notice
-		$clef_oeuvre=fetchOne("select CLEF_OEUVRE from notices where id_notice=" . $this->id_notice);
-		if (array_key_exists('data', $_REQUEST)
-				&& $_REQUEST["data"]=="OEUVRE") {
-			$aff = "oeuvre";
-			$nb_notices_oeuvre = 0;
-			$notices = fetchAll("select id_notice from notices where clef_oeuvre='$clef_oeuvre' and id_notice!=" . $this->id_notice);
-			if ($notices) {
-				foreach ($notices as $notice) {
-					if ($insql)
-						$insql .= ',';
-					$insql .= $notice["id_notice"];
-				}
-			}
-			$cond[] = "id_notice in(" . $insql . ")";
-		} else {
-			$aff = "normal";
-			$nb_notices_oeuvre = fetchOne("select count(*) from notices where clef_oeuvre='$clef_oeuvre' and id_notice!=" . $this->id_notice);
-			$cond[] = "id_notice=" . $this->id_notice;
-		}
 
-		// Conditions liees au profil
-		$sel_section = Class_Profil::getCurrentProfil()->getSelSection();
+		$exemplaires = $this->_loadExemplaire(["id_notice" => $notice_ids]);
 
-		if ($sel_section)
-			$cond[] = "section in(" . implode(',', explode(';', $sel_section)) . ")";
+		foreach($exemplaires as $exemplaire)
+			$exemplaire->updateAvailabilityFromSIGB()
+								 ->save();
 
-		if (array_key_exists('selection_bib', $_SESSION)
-				&& array_key_exists('id_bibs', $_SESSION['selection_bib'])) {
-			$sel_bib = $_SESSION["selection_bib"]["id_bibs"];
-			if ($sel_bib)
-				$cond[] = "id_bib in(" . $sel_bib . ")";
-		}
-		$where = getWhereSql($cond);
+		$notices = Class_Notice::findAllBy(['id_notice' => $notice_ids]);
+		foreach($notices as $notice)
+			$notice->updateFacetsFromExemplaires()
+						 ->save();
 
-		$data = $this->_loadExemplaireWhere($where);
-		if (!$data) {
-			$where = " where " . $cond[0];
-			$data = $this->_loadExemplaireWhere($where);
-		}
+		$this->getResponse()->setBody($this->view->Notice_Exemplaires($exemplaires, $nb_notices_oeuvre, $display));
 
-		$this->getResponse()->setBody($this->view->Notice_Exemplaires($data, $nb_notices_oeuvre, $aff));
 	}
 
+	public function exemplairesAction()	{
+		$nb_notices_oeuvre = Class_Notice::countBy(['clef_oeuvre' => $this->notice->getClefOeuvre(),
+																								'id_notice not' =>  $this->id_notice]);
 
-	protected function _loadExemplaireWhere($where) {
-		// Lire les notices groupees ou pas
-		if (0 == $this->notice_html->preferences["exemplaires"]["grouper"])
-			return fetchAll("Select id_notice,id_bib,cote,count(*),id_int_bib,id_origine from exemplaires " . $where . " group by 1,2,3" );
 
-		return fetchAll("Select * from exemplaires " . $where);
+		$this->renderExemplaires($this->id_notice, $nb_notices_oeuvre,'normal');
+
+	}
+
+
+	protected function _loadExemplaire($params) {
+		$cond = $params;
+
+		// Conditions liees au profil
+		$sel_section = Class_Profil::getCurrentProfil()->getSelSection();
+
+		if ($sel_section)
+			$cond['section'] =  explode(';', $sel_section);
+
+		$session = Zend_Registry::get('session');
+		$cond['id_bib'] = $session->id_bibs;
+		if ($exemplaires = Class_Exemplaire::findAllBy(array_filter($cond)))
+			return $exemplaires;
+		else return Class_Exemplaire::findAllBy($params);
+
 	}
 
 
@@ -538,6 +541,5 @@ class NoticeAjaxController extends Zend_Controller_Action {
 	protected function _sendResponse($html) {
 		$this->getResponse()->setHeader('Content-Type', 'text/html;charset=utf-8');
 		$this->getResponse()->setBody($html);
-
 	}
 }
diff --git a/library/Class/Bib.php b/library/Class/Bib.php
index 36d4ea618ffe8f1eecf81a52c01df539b0e5a265..11357f4840092928b25df64979567f35977385c2 100644
--- a/library/Class/Bib.php
+++ b/library/Class/Bib.php
@@ -209,7 +209,9 @@ class Class_Bib extends Storm_Model_Abstract {
 																					'libelle' => '',
 																					'id_zone' => 0,
 																					'ville' => '',
-																					'aff_zone' => ''];
+																					'aff_zone' => '',
+																					'interdire_resa' => 0,
+																					'google_map' => ''];
 
 	protected $_translate;
 
diff --git a/library/Class/CommSigb.php b/library/Class/CommSigb.php
index 1f157c2e23f0ec30280a9b6f9f625bf5773bdcf8..ba4ce745ccb7ac1038099fd5df0155c847240631 100644
--- a/library/Class/CommSigb.php
+++ b/library/Class/CommSigb.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 class Class_CommSigb {
 	use Trait_Translator;
@@ -37,29 +37,25 @@ class Class_CommSigb {
 	 * @return array
 	 */
 	public function getDispoExemplaires($exemplaires_to_check) {
-		$exemplaires = array();
+		$exemplaires = [];
 		foreach ($exemplaires_to_check as $exemplaire)	{
-			if ($dispo = $this->getDispoExemplaire($exemplaire["id_int_bib"], 
-																						 $exemplaire["id_origine"], 
-																						 $exemplaire["code_barres"]))
-				$exemplaires []= array_merge($exemplaire, $dispo);
+			if ($dispo = $this->getDispoExemplaire($exemplaire))
+				$exemplaires []= array_merge($exemplaire->toRaw(), $dispo);
 		}
 		return $exemplaires;
 	}
 
 
-	public function getDispoExemplaire($id_bib, $id_origine, $code_barre) {
-	 
-		$exemplaire = ["dispo" => "non connue",
+	public function getDispoExemplaire($bibitem) {
+		$exemplaire = ["dispo" => ($bibitem->getIsAvailable()
+															 ? $this->_('Disponible')
+															 : $this->_('Non disponible')),
 									 "reservable" => false];
 
-		$int_bib = Class_IntBib::find($id_bib);
-		if (! ($int_bib && ($sigb = $int_bib->getSIGBComm())))
+		if (!$sigb_exemplaire = $bibitem->getSigbExemplaire())
 			return $exemplaire;
 
-		$sigb_exemplaire = $sigb->getExemplaire($id_origine, $code_barre);
-
-		if ($sigb_exemplaire->isPilonne() || !$sigb_exemplaire->isVisibleOPAC()) 
+		if ($sigb_exemplaire->isPilonne() || !$sigb_exemplaire->isVisibleOPAC())
 			return null;
 
 		if (!$sigb_exemplaire->isValid())
@@ -71,7 +67,8 @@ class Class_CommSigb {
 		$exemplaire["id_exemplaire"]=$sigb_exemplaire->getId();
 		$exemplaire["nb_resas"]=$sigb_exemplaire->getNbReservations();
 		$exemplaire["edition"]=$sigb_exemplaire->getEdition();
-		
+		$exemplaire["is_available"]=$sigb_exemplaire->isDisponible();
+
 		if ($cote = $sigb_exemplaire->getCote())
 			$exemplaire["cote"] = $cote;
 
@@ -81,8 +78,6 @@ class Class_CommSigb {
 		if (!$code_annexe = $sigb_exemplaire->getCodeAnnexe())
 			return $exemplaire;
 
-		//pour la localisation de l'exemplaire en temps reel
-		$exemplaire["annexe"] = $code_annexe;
 		if ($annexe = Class_CodifAnnexe::findFirstBy(['code' => $code_annexe]))
 			$exemplaire["id_bib"] = $annexe->getIdBib();
 
@@ -123,7 +118,7 @@ class Class_CommSigb {
 		if (!$user = Class_Users::getIdentity())
 			return ['statut' => 2,
 							'erreur' => $this->_('Vous devez vous connecter pour réserver un document.')];
-		
+
 		if (!$user->getIdabon())
 			return ['statut' => 2,
 							"erreur" => $this->_('Vous devez vous connecter sous votre numéro de carte pour effectuer une réservation.')];
@@ -145,7 +140,7 @@ class Class_CommSigb {
 	 */
 	public function supprimerReservation($std_user, $id_reservation) {
 		$supprimer = function ($user, $sigb) use ($id_reservation) {
-					return $sigb->supprimerReservation($user, $id_reservation);			
+					return $sigb->supprimerReservation($user, $id_reservation);
 		};
 
 		return $this->withUserAndSIGBDo($std_user, $supprimer);
@@ -172,7 +167,7 @@ class Class_CommSigb {
 
 		if (null == $sigb = $user->getSIGBComm())
 			return ['erreur' => $this->_('Communication SIGB indisponible')];
-		
+
 		if (!$sigb->isConnected())
 			return ['erreur' => $this->_("Une erreur de communication avec le serveur a fait échouer la requête. Merci de signaler ce problème à la bibliothèque.")];
 
diff --git a/library/Class/Exemplaire.php b/library/Class/Exemplaire.php
index 0efb21012fd00e53ad85f5d6773e5e3b7731d315..cdafaf371c295f16560cdba1926e43fa9bcda1dd 100644
--- a/library/Class/Exemplaire.php
+++ b/library/Class/Exemplaire.php
@@ -102,6 +102,14 @@ class Class_Exemplaire extends Storm_Model_Abstract {
 	}
 
 
+	public function updateAvailabilityFromSIGB() {
+		if (!$sigb_exemplaire = $this->getSigbExemplaire())
+			return $this;
+
+		return $this->setIsAvailable($sigb_exemplaire->isDisponible());
+	}
+
+
 	public function setSigbExemplaire($sigb_exemplaire) {
 		$this->_sigb_exemplaire = $sigb_exemplaire;
 		return $this;
@@ -209,6 +217,14 @@ class Class_Exemplaire extends Storm_Model_Abstract {
 	protected function get995Key($data) {
 		return (isset($data['clef'])) ? $data['clef'] : $data['code'];
 	}
+
+	public function toRaw() {
+		$raw = $this->getRawAttributes() ;
+		// LL: pour Opsys nous avons besoin de l'identifiant de l'annexe, d'où sauvegarde pour réutilisation dans ReservationLink
+		$raw['code_annexe']=$raw['annexe'];
+		return $raw;
+	}
+
 }
 
 ?>
\ No newline at end of file
diff --git a/library/Class/Notice.php b/library/Class/Notice.php
index 00930793a94ba9d4014061deac9adc04d4429846..8712a2f9649b2f6568522492944786e7fa7eb877 100644
--- a/library/Class/Notice.php
+++ b/library/Class/Notice.php
@@ -163,6 +163,7 @@ class Class_Notice extends Storm_Model_Abstract {
 																					'tome_alpha' => '',
 																					'clef_alpha' => '',
 																					'clef_chapeau' => '',
+																					'clef_oeuvre' => '',
 																					'facettes' => '',
 																					'url_vignette' => '',
 																					'url_image' => '',
@@ -1610,7 +1611,7 @@ class Class_Notice extends Storm_Model_Abstract {
 
 	public function updateFacetsFromExemplaires() {
 			$facettes = [];
-			$filtered = ['B', 'E', 'S', 'Y', 'T', '2'];
+			$filtered = ['B', 'E', 'S', 'Y', 'T', '2', 'V'];
 			foreach (array_filter(explode(' ',  $this->getFacettes())) as $f) {
 				$type = substr($f, 0, 1);
 				if (in_array($type, $filtered))
diff --git a/library/ZendAfi/View/Helper/Notice/Exemplaires.php b/library/ZendAfi/View/Helper/Notice/Exemplaires.php
index 127465d662472a69150d671bbb3e3353db45df16..e384cb464219debb27cb771e144837185fe10118 100644
--- a/library/ZendAfi/View/Helper/Notice/Exemplaires.php
+++ b/library/ZendAfi/View/Helper/Notice/Exemplaires.php
@@ -20,164 +20,110 @@
  */
 class ZendAfi_View_Helper_Notice_Exemplaires extends Zend_View_Helper_HtmlElement {
 	use Trait_Translator;
+	protected $renderers = [];
 
-	public function Notice_Exemplaires($exemplaires,$nb_notices_oeuvre=0,$aff="normal") {
-		$this->preferences = Class_Profil::getCurrentProfil()->getCfgNoticeAsArray();
+	public function Notice_Exemplaires($exemplaires, $nb_notices_oeuvre=0, $aff="normal") {
+		$preferences = Class_Profil::getCurrentProfil()->getCfgNoticeAsArray()['exemplaires'];
     if (!$exemplaires)
 			return false;
 
-		$html = $this->_fonctionsAdmin();
-		$preferences = $this->preferences["exemplaires"];
+		return ($preferences['grouper'] == 0)
+			? $this->view->Notice_Exemplaires_RenderByGroup($exemplaires, $preferences, $nb_notices_oeuvre, $aff)
+			: $this->view->Notice_Exemplaires_RenderByItem($exemplaires, $preferences, $nb_notices_oeuvre, $aff);
+	}
 
-		// Recup des donnees de dispo et reservable
-		$cls_comm = null;
-		if ($preferences["grouper"] == 1) {
-			$cls_comm = new Class_CommSigb();
-			$exemplaires = $cls_comm->getDispoExemplaires($exemplaires);
+	public function exemplairesToRows($exemplaires) {
+		$rows=[];
+		foreach ($exemplaires as $exemplaire) {
+			$rows[] = $exemplaire->toRaw() ;
 		}
+		return $rows;
+	}
+
+	public function renderExemplairesTable($exemplaires, $preferences, $aff) {
+		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Num');
+    if($preferences["bib"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Bib');
+    if($preferences["annexe"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Annexe');
+    if($preferences["section"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Section');
+    if($preferences["emplacement"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Emplacement');
+    if($preferences["grouper"]==0) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Grouper');
+		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Cote');
+    if($preferences["dispo"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Dispo');
+    if($preferences["date_retour"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_DateRetour');
+    if($preferences["localisation"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Localisation');
+    if($preferences["plan"]==1) 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Plan');
+    if($preferences["resa"]==1 && $aff=="normal") 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Resa');
+    if($aff=="oeuvre") 		$renderers[]=$this->view->getHelper('Notice_Exemplaires_Oeuvre');
 
-		$cote_libelle = $this->_('Cote').$this->editionLabelle($exemplaires);
 
-		$html .='<table class="exemplaires" cellpadding="5" cellspacing="1">';
+		$html ='<table class="exemplaires" cellpadding="5" cellspacing="1">';
 		$html.='<tr>';
-    $html.='<th class="num" >'.$this->_('n°').'</th>';
-    if($preferences["bib"]==1) $html.='<th class="bib" >'.$this->_('Bibliothèque').'</th>';
-		if($preferences["annexe"]==1) $html.='<th class="annexe" >'.$this->_('Bibliothèque').'</th>';
-		if($preferences["section"]==1) $html.='<th class="section" >'.$this->_('Section').'</th>';
-		if($preferences["emplacement"]==1) $html.='<th class="emplacement" >'.$this->_('Emplacement').'</th>';
-    if($preferences["grouper"]==0) $html.='<th class="grouper" >'.$this->_('Exemplaires').'</th>';
-    $html.='<th class="cote" >'.$cote_libelle.'</th>';
-    if($preferences["dispo"]==1) $html.='<th class="dispo" >'.$this->_('Disponibilité').'</th>';
-    if($preferences["date_retour"]==1) $html.='<th class="date_retour" >'.$this->_('Retour').'</th>';
-		if($preferences["localisation"]==1) $html.='<th class="localisation" >'.$this->_('Situer.').'</th>';
-    if($preferences["plan"]==1) $html.='<th class="plan" >'.$this->_('Plan').'</th>';
-    if($preferences["resa"]==1 and $aff=="normal") $html.='<th class="resa" >'.$this->_('Réserver').'</th>';
-		if($aff=="oeuvre") $html.='<th class="oeuvre" >'.$this->_('Voir').'</th>';
+
+		foreach ($renderers as $renderer) {
+			$renderer->setExemplaires($exemplaires);
+			$html.=$renderer->renderHead();
+		}
+
     $html.='</tr>';
-    $num=0;
 
-    foreach($exemplaires as $ex)
-		{
-			// Infos bib
-			$bib=fetchEnreg("select LIBELLE,GOOGLE_MAP,INTERDIRE_RESA from bib_c_site where ID_SITE=".$ex["id_bib"]);
+    foreach($exemplaires as $ex)	{
+			if (!$bib=Class_Bib::find($ex["id_bib"]))
+				$bib=new Class_Bib();
 
 			// html
 			$html.='<tr>';
-			$html.='<td class="num">'.++$num.'</td>';
-			if($preferences["bib"]==1) $html.='<td class="bib">'.$bib["LIBELLE"].'</td>';
-
-			//Annexe
-			$ex["code_annexe"] = $ex["annexe"]; // LL: pour Opsys nous avons besoin de l'identifiant de l'annexe, d'où sauvegarde pour réutilisation plus bas
-			if($preferences["annexe"]==1)
-			{
-				if($ex["annexe"] > '') $ex["annexe"]=fetchOne("select libelle from codif_annexe where id_bib=".$ex["id_bib"]." and code='".$ex["annexe"]."'");
-				if(!$ex["annexe"]) $ex["annexe"]="&nbsp;";
-				$html.='<td class="annexe" style="text-align:left">'.$ex["annexe"].'</td>';
-			}
-			if($preferences["section"]==1) $html.='<td class="section">'.Class_Codification::getInstance()->getLibelleFacette("S".$ex["section"]).'</td>';
-			if($preferences["emplacement"]==1) $html.='<td class="emplacement">'.Class_Codification::getInstance()->getLibelleFacette("E".$ex["emplacement"]).'</td>';
-			if($preferences["grouper"]==0) $html.='<td class="grouper">'.$ex["count(*)"].' ex.</td>';
-			$html.='<td class="cote">'.$ex["cote"].(isset($ex["edition"]) && ($ex["edition"]!='') ? '<span>'.$ex["edition"].'</span>' : '').'</td>';
-			if($preferences["dispo"]==1) {
-				$class_dispo='';
-				if($ex["dispo"] == Class_WebService_SIGB_Exemplaire::DISPO_LIBRE){
-					$class_dispo = 'disponible';
-				}
-				if ( isset($ex['nb_resas']) &&  $ex['nb_resas']>0)
-					$ex['dispo'].='<span>'.$this->view->_plural($ex['nb_resas'],'','Nb résa: %s ','Nb résas: %s ',$ex['nb_resas']).'</span>';
-				$html.='<td class="dispo '.$class_dispo.'">'.$ex["dispo"].'</td>';
-			}
-			if($preferences["date_retour"]==1) $html.='<td class="date_retour">'.$ex["date_retour"].'</td>';
-
-			//Localisation sur le pan
-			if($preferences["localisation"]==1)
-			{
-				$html.='<td class="localisation" style="text-align:center">';
-
-				if(!isset($controle[$ex["id_bib"]]))
-					$controle[$ex["id_bib"]]=fetchOne("select count(*) from bib_localisations where ID_BIB=".$ex["id_bib"]);
-
-				$onclick="localisationExemplaire(this,".$ex["id_bib"].",'".$ex["cote"]."','".$ex["code_barres"]."')";
-
-				if($controle[$ex["id_bib"]]>0)
-					$html.= sprintf('<img src="%s" border="0"  title="%s" style="cursor:pointer" onclick="%s" alt="%s" />',
-													URL_ADMIN_IMG.'picto/localisation.png',
-													$this->_('Situer cet exemplaire dans la bibliothèque'),
-													$onclick,
-													$this->_('Situer en exemplaire'));
-				else
-					$html.='&nbsp;';
-				$html.='</td>';
-			}
-			// Google maps
-			if($preferences["plan"]==1)
-			{
-				$html.='<td class="gmap" style="text-align:center;">';
-				if($bib["GOOGLE_MAP"] > "")
-					$html .= sprintf('<a href="%s"><img src="%s" border="0" alt="%s" title="%s" /></a>',
-													 BASE_URL.'/bib/mapview?id_bib='.$ex["id_bib"].'&amp;retour=notice',
-													 URL_ADMIN_IMG.'picto/map.gif',
-													 $this->_('Afficher la carte'),
-													 $this->_('Afficher la carte'));
-				else $html.='&nbsp;';
-				$html.='</td>';
-			}
 
-			// Réservation
-			if ($preferences["resa"]==1 and $aff=="normal") {
-				$html = $this->view->Notice_ReservationLink($bib, $ex, $html);
+			foreach ($renderers as $renderer) {
+				$html.=$renderer->renderContent($ex);
 			}
 
-			// Lien vers notice en affichage oeuvre
-			if($aff=="oeuvre")
-			{
-//				$onclick="document.location=baseUrl+'/recherche/viewnotice/id/".$ex["id_notice"]."'";
-				$onclick="document.location='".$this->view->url(['controller' => 'recherche',
-																												'action' => 'viewnotice',
-																												'id' => $ex["id_notice"]])."'";
-				$html.='<td class="oeuvre" style="text-align:center;">';
-				$html.= sprintf('<img src="%s" border="0" alt="%s" title="%s" onclick="%s" style="cursor:pointer" />',
-												URL_IMG.'bouton/loupe.gif',
-												$this->_('Afficher la notice'),
-												$this->_('Afficher la notice'),
-												$onclick);
-				$html.='</td>';
-			}
-
-			// fin ligne
 			$html.='</tr>';
 		}
 		$html.='</table>';
+		return $html;
+	}
 
-		// lien pour exemplaires de la meme oeuvre
-		if($nb_notices_oeuvre)
-		{
-			$onclick="$('.exemplaires_oeuvre').slideToggle().load(baseUrl+'/opac/noticeajax/exemplaires?id_notice=".$ex["id_notice"]."&data=OEUVRE');$('.notice_bloc_titre b').toggleClass(function(){ if($('.exemplaires_oeuvre').is(':visible')) return 'opened_exemplaires_oeuvre';});";
-			$html.='<div class="notice_bloc_titre" onclick="'.$onclick.'">';
-			$html.=sprintf('<b>%s</b>', $this->_('Afficher toutes les éditions de ce document'));
-			$html.='</div>';
-			$html.='<div class="exemplaires_oeuvre" style="display:none"><img src="'.URL_IMG.'patience.gif"></div>';
-		}
 
-		// Pour afficher la localisation sur le plan
-		$html.='<div id="plan_localisation" style="display:none"></div>';
+	public function renderSameWorkLink($nb_notices_oeuvre, $id_notice) {
+		if (!$nb_notices_oeuvre)
+			return '';
 
-		$html.=sprintf('<div id="point_localisation" style="%s"><img src="" border="0" alt="%s" /></div>',
-									 'position:absolute;z-index:10000;display:none;cursor:pointer',
-									 $this->_('Localisation'));
+		$onclick=
+			"$('.exemplaires_oeuvre').slideToggle().load(baseUrl+'/opac/noticeajax/exemplaires-same-work/id/".$id_notice."');"
+			."$('.notice_bloc_titre b').toggleClass("
+			."   function(){ if($('.exemplaires_oeuvre').is(':visible')) "
+			."                   return 'opened_exemplaires_oeuvre';"
+			."});";
 
-		$html.='<div id="bulle_localisation" style="display:none"></div>';
-		return $html;
+		return
+			'<div class="notice_bloc_titre" onclick="'.$onclick.'">'
+			. sprintf('<b>%s</b>', $this->_('Afficher toutes les éditions de ce document'))
+			.'</div>'
+			. '<div class="exemplaires_oeuvre" style="display:none"><img src="'.URL_IMG.'patience.gif"></div>';
 	}
 
 
-	public function editionLabelle($exemplaires) {
-		foreach($exemplaires as $ex){
-			return (isset($ex["edition"]) && ($ex["edition"]!='') ? '<span>('.$this->_("Edition").')</span>' : '');
-		}
+	public function renderLocalizationMap() {
+		return
+			'<div id="plan_localisation" style="display:none"></div>'
+			. sprintf('<div id="point_localisation" style="%s"><img src="" border="0" alt="%s" /></div>',
+								'position:absolute;z-index:10000;display:none;cursor:pointer',
+								$this->_('Localisation'))
+			. '<div id="bulle_localisation" style="display:none"></div>';
 	}
 
 
+	public function render($exemplaires, $preferences, $nb_notices_oeuvre, $aff) {
+		return
+			$this->_fonctionsAdmin()
+			. $this->renderExemplairesTable($exemplaires, $preferences, $aff)
+			. $this->renderSameWorkLink($nb_notices_oeuvre,
+																	array_values($exemplaires)[0]['id_notice'])
+			. $this->renderLocalizationMap();
+	}
+
+
+
 	public function _fonctionsAdmin() {
 		if (!Class_Users::isCurrentUserCanConfigFront())
 			return '';
@@ -193,9 +139,282 @@ class ZendAfi_View_Helper_Notice_Exemplaires extends Zend_View_Helper_HtmlElemen
 																	['data-popup' => 'true',
 																	 'style' => 'position: absolute']);
 	}
+}
+
+
+class ZendAfi_View_Helper_Notice_Exemplaires_RenderByGroup extends ZendAfi_View_Helper_Notice_Exemplaires {
+	public function Notice_Exemplaires_RenderByGroup($exemplaires, $preferences, $nb_notices_oeuvre=0, $aff="normal") {
+
+		$group_exemplaires = [];
+		foreach($this->exemplairesToRows($exemplaires) as $ex) {
+			$group_key = $ex['id_notice'].'_'.$ex['id_bib'].'_'.$ex['cote'];
+			if (!isset($group_exemplaires[$group_key]))
+					$group_exemplaires[$group_key]['count(*)'] = 0;
+			$group_exemplaires[$group_key]['count(*)']++;
+			$group_exemplaires[$group_key] = array_merge($group_exemplaires[$group_key], $ex);
+		}
+
+
+		return $this->render($group_exemplaires, $preferences, $nb_notices_oeuvre, $aff);
+	}
+}
+
+
+class ZendAfi_View_Helper_Notice_Exemplaires_RenderByItem extends ZendAfi_View_Helper_Notice_Exemplaires {
+	public function Notice_Exemplaires_RenderByItem($exemplaires, $preferences, $nb_notices_oeuvre=0, $aff="normal") {
+		return $this->render((new Class_CommSigb())->getDispoExemplaires($exemplaires),
+												 $preferences,
+												 $nb_notices_oeuvre,
+												 $aff);
+	}
+}
+
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Abstract extends Zend_View_Helper_HtmlElement {
+	use Trait_Translator;
+	protected $_exemplaires;
+
+	public function setExemplaires($exemplaires) {
+		$this->_exemplaires=$exemplaires;
+	}
+	public function renderHead() {
+		return '<th class="'.$this->getHeadClass().'" >'.$this->getLibelle().'</th>';
+	}
+
+	public function getHeadClass() {
+		$parts=explode('_',get_class($this));
+		return Storm_Inflector::underscorize(end($parts));
+	}
+
+	public function renderContent($exemplaire) {
+		return '<td class="'.$this->getHeadClass().'" >'.$this->getContent($exemplaire).'</td>';
+	}
+
+	public function getContent($exemplaire) {
+		return '';
+	}
+
+	public function getBib($exemplaire){
+		return ($bib = Class_Bib::find($exemplaire['id_bib']))
+			? $bib
+			: new Class_Bib();
+	}
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Bib extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Bibliothèque');
+	}
+
+	public function getContent($exemplaire) {
+		return $this->getBib($exemplaire)->getLibelle();
+	}
+
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Annexe extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Bibliothèque');
+	}
+
+	public function getContent($exemplaire) {
+		if(!$exemplaire["annexe"])
+			return "&nbsp;";
+		if (!$annexe=Class_CodifAnnexe::findFirstBy(['id_bib'=> $exemplaire["id_bib"],
+																								 'code' => $exemplaire["annexe"]]))
+			return "&nbsp;";
+		return $annexe->getLibelle();
+	}
+
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Section extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Section');
+	}
+
+	public function getContent($exemplaire) {
+		return Class_Codification::getLibelleFacette("S".$exemplaire["section"]);
+	}
+
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Grouper extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Exemplaires');
+	}
+
+	public function getContent($exemplaire) {
+		return $exemplaire["count(*)"].' ex.';
+	}
+
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Dispo extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Disponibilité');
+	}
+
+	public function renderContent($exemplaire) {
+		$class_dispo='';
+		$libelle = $exemplaire["dispo"];
+		$class_dispo = ($libelle == Class_WebService_SIGB_Exemplaire::DISPO_LIBRE)
+			? 'disponible'
+			: '';
+
+		if ( isset($exemplaire['nb_resas']) &&  $exemplaire['nb_resas']>0)
+			$libelle.=
+				'<span>'
+				.$this->view->_plural($exemplaire['nb_resas'],
+																							'','Nb résa: %s ',
+																							'Nb résas: %s ',
+																							$exemplaire['nb_resas'])
+				.'</span>';
+
+		return '<td class="dispo '.$class_dispo.'">'.$libelle.'</td>';
+	}
+}
+
+
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Cote extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Cote').$this->editionLabel($this->_exemplaires);
+
+	}
+
+	public function editionLabel($exemplaires) {
+		foreach($exemplaires as $ex){
+			return (isset($ex["edition"]) && ($ex["edition"]!='') ? '<span>('.$this->_("Edition").')</span>' : '');
+		}
+	}
+
+	public function getContent($exemplaire) {
+		return $exemplaire["cote"].(isset($exemplaire["edition"]) && ($exemplaire["edition"]!='')
+																?	'<span>'.$exemplaire["edition"].'</span>'
+																: '');
+
+	}
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_DateRetour extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Retour');
+	}
+	public function getContent($exemplaire) {
+		return $exemplaire['date_retour'];
+	}
+
 
 }
 
 
+class ZendAfi_View_Helper_Notice_Exemplaires_Localisation extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Situer');
+	}
+
+	public function renderContent($exemplaire) {
+		$html='<td class="localisation" style="text-align:center">';
+
+
+		$onclick="localisationExemplaire(this,".$exemplaire["id_bib"].",'".$exemplaire["cote"]."','".$exemplaire["code_barres"]."')";
+		if ($this->getBib($exemplaire)->numberOfLocalisations()>0)
+			$html.= sprintf('<img src="%s" border="0"  title="%s" style="cursor:pointer" onclick="%s" alt="%s" />',
+											URL_ADMIN_IMG.'picto/localisation.png',
+											$this->_('Situer cet exemplaire dans la bibliothèque'),
+											$onclick,
+											$this->_('Situer en exemplaire'));
+		else
+			$html.='&nbsp;';
+		$html.='</td>';
+		return $html;
+	}
+
+}
+
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Plan extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Plan');
+	}
+
+	public function renderContent($exemplaire) {
+		$html='<td class="gmap" style="text-align:center;">';
+
+		if($this->getBib($exemplaire)->getGoogleMap() > "")
+			$html .= sprintf('<a href="%s"><img src="%s" border="0" alt="%s" title="%s" /></a>',
+											 BASE_URL.'/bib/mapview?id_bib='.$exemplaire["id_bib"].'&amp;retour=notice',
+											 URL_ADMIN_IMG.'picto/map.gif',
+											 $this->_('Afficher la carte'),
+											 $this->_('Afficher la carte'));
+		else $html.='&nbsp;';
+		$html.='</td>';
+		return $html;
+	}
+
+}
+
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Resa extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Réserver');
+	}
+
+	public function renderContent($exemplaire) {
+		return $this->view->Notice_ReservationLink($this->getBib($exemplaire), $exemplaire, '');
+	}
+
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Oeuvre extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Voir');
+	}
+
+	public function  renderContent($exemplaire) {
+
+		$html='<td class="oeuvre" style="text-align:center;">';
+		$html.= sprintf('<a href="%s"> <img src="%s" border="0" alt="%s" title="%s" /></a>',
+										$this->view->url(['controller' => 'recherche',
+																			'action' => 'viewnotice',
+																			'id' => $exemplaire["id_notice"]]),
+										URL_IMG.'bouton/loupe.gif',
+										$this->_('Afficher la notice'),
+										$this->_('Afficher la notice')
+		);
+		$html.='</td>';
+		return $html;
+
+	}
+
+}
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Num extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	protected $num=0;
+	public function getLibelle() {
+		return $this->_('n°');
+	}
+
+	public function getContent($exemplaire) {
+		return ++$this->num;
+	}
+}
+
+
+class ZendAfi_View_Helper_Notice_Exemplaires_Emplacement extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+	public function getLibelle() {
+		return $this->_('Emplacement');
+	}
+
+	public function getContent($exemplaire) {
+		return Class_Codification::getLibelleFacette("E".$exemplaire["emplacement"]);
+	}
+
+
+}
+
+
+
 
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Notice/ReservationLink.php b/library/ZendAfi/View/Helper/Notice/ReservationLink.php
index 124b318225259d07ff7901e713fd1a3f3c375630..5d9adec5650f1abf3246480c5eaec2424eb7e576 100644
--- a/library/ZendAfi/View/Helper/Notice/ReservationLink.php
+++ b/library/ZendAfi/View/Helper/Notice/ReservationLink.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301	 USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301	 USA
  */
 class ZendAfi_View_Helper_Notice_ReservationLink extends Zend_View_Helper_HtmlElement {
 	use Trait_Translator;
@@ -25,7 +25,7 @@ class ZendAfi_View_Helper_Notice_ReservationLink extends Zend_View_Helper_HtmlEl
 
 	protected $_bib;
 	protected $_holdLabel;
-	
+
 	public function Notice_ReservationLink($bib, $ex, $html) {
 		$this->_bib = $bib;
 		$this->_holdLabel = $this->_('Réserver');
@@ -41,7 +41,7 @@ class ZendAfi_View_Helper_Notice_ReservationLink extends Zend_View_Helper_HtmlEl
 	public function renderItemOn($ex, $html) {
 		$html .= '<td class="resa" style="text-align:center;">';
 
-		if (1 == $this->_bib['INTERDIRE_RESA'])
+		if (1 == $this->_bib->getInterdireResa())
 			return $html .= '&nbsp;</td>';
 
 		$type_comm = ($int_bib = Class_IntBib::find($ex['id_int_bib'])) ? $int_bib->getCommSigb() : 0;
diff --git a/library/storm b/library/storm
index bb7de527436a525b8253c97f7b225f1e054d41f6..b292eac5efe58a03b180d12586537b4d7acae0a8 160000
--- a/library/storm
+++ b/library/storm
@@ -1 +1 @@
-Subproject commit bb7de527436a525b8253c97f7b225f1e054d41f6
+Subproject commit b292eac5efe58a03b180d12586537b4d7acae0a8
diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
index bf3da407b41e01d9d1f0d58468581ef4d5c30ecd..e600010a60b9ca52f16f1e9cbc251745fb8c8c73 100644
--- a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
+++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
@@ -23,14 +23,15 @@ require_once 'AbstractControllerTestCase.php';
 class NoticeAjaxControllerNonRegressionTest extends AbstractControllerTestCase {
 	public function setUp() {
 		parent::setUp();
-		Class_Notice::getLoader()->newInstanceWithId('197143');
+		$this->fixture('Class_Notice',
+									 ['id' => '197143']);
 	}
 
 
 	/** @test */
 	function exemplairesWithoutIdNoticeShouldRenderEmptyHtml() {
 		$this->dispatch('noticeAjax/exemplaires');
-		$this->assertEmpty($this->_response->getBody());
+		$this->assertEmpty($this->_response->getBody(),$this->response->getBody());
 	}
 
 
@@ -455,7 +456,7 @@ class NoticeAjaxControllerResumeAlbumTest extends AbstractControllerTestCase {
 
 
 
-class NoticeAjaxControllerExemplairesTest extends AbstractControllerTestCase {
+abstract class NoticeAjaxControllerExemplairesTestCase extends AbstractControllerTestCase {
 	protected $_notice;
 
 	public function setUp() {
@@ -463,9 +464,31 @@ class NoticeAjaxControllerExemplairesTest extends AbstractControllerTestCase {
 
 		ZendAfi_Auth::getInstance()->clearIdentity();
 
-		$this->_notice = Class_Notice::newInstanceWithId(123)
-			->beLivreNumerique()
-			->setExemplaires([]);
+		$this->_notice = $this->fixture('Class_Notice', ['id' => 123,
+																										 'clef_oeuvre' => 'AAA'])
+													->beLivreNumerique()
+													->setExemplaires([$this->fixture('Class_Exemplaire', ['id' =>999,
+																																								'id_bib' => 99,
+																																								'id_int_bib' => 4,
+																																								'id_notice' => 123,
+
+																																								'annexe' => 'MOUL',
+																																								'section' => 'A9',
+																																								'emplacement' => 'emplacement de test',
+																																								'cote' => 'VOD-T-DLJ',
+																																								'dispo' => 'Disponible',
+																																								'date_retour' => 'En mai',
+																																								'reservable' => true,
+																																								'code_barres' => '7777734343488'])
+																						]);
+
+		$this->fixture('Class_Notice', ['id' => 125,
+																		'clef_oeuvre' => 'AAA',
+																		'exemplaires' => [$this->fixture('Class_Exemplaire', ['id' =>799,
+																																													'id_bib' => 99,
+																																													'cote' => 'VOD',
+																																													'dispo' => 'Disponible'])]
+																		]);
 
 
 		Class_Profil::getCurrentProfil()->setCfgNotice([]);
@@ -473,28 +496,82 @@ class NoticeAjaxControllerExemplairesTest extends AbstractControllerTestCase {
 		$mock_sql = Storm_Test_ObjectWrapper::on(Zend_Registry::get('sql'));
 		Zend_Registry::set('sql', $mock_sql);
 
-		$this->fixture('Class_IntBib', ['id' => 4,'comm_sigb' => Class_IntBib::COM_NANOOK]);
-
-		$exemplaires = [ [
-											'id_bib' => 99,
-			'id_int_bib' => 4,
-											'id_notice' => 123,
-											'id' => '6778778778',
-											'annexe' => 'MOUL',
-											'section' => 'A9',
-											'emplacement' => 'emplacement de test',
-											'count(*)' => 3,
-											'cote' => 'VOD-T-DLJ',
-											'dispo' => 'Disponible',
-											'date_retour' => 'En mai',
-											'reservable' => true,
-											'code_barres' => '7777734343488']];
+		$this->fixture('Class_IntBib', ['id' => 4,
+																		'comm_sigb' => Class_IntBib::COM_NANOOK,
+																		'comm_params' => serialize(['url_serveur' => ''])]);
+		$this->fixture('Class_bib',
+									 ['id' => 99,
+									 ]);
 
-		$mock_sql
-			->whenCalled('fetchAll')
-			->with('Select id_notice,id_bib,cote,count(*),id_int_bib,id_origine from exemplaires  where id_notice=123 group by 1,2,3',
-						 false)
-			->answers($exemplaires);
+
+
+	}
+}
+
+
+
+class NoticeAjaxControllerExemplairesSameWorkTest extends NoticeAjaxControllerExemplairesTestCase {
+	public function setUp() {
+		parent::setUp();
+
+		$this->dispatch('noticeajax/exemplaires-same-work/id/123', true);
+	}
+
+
+	/** @test */
+	public function shouldRenderNumber() {
+		$this->assertXPathContentContains('//td', '1');
+	}
+
+/** @test */
+	public function iconShouldBeLinkToAnotherNotice() {
+		$this->assertXPath('//a[@href="/recherche/viewnotice/id/125"]//img[contains(@src,"loupe.gif")]'
+											 ,$this->_response->getBody());
+
+	}
+}
+
+
+class NoticeAjaxControllerExemplairesWithIdBibs extends NoticeAjaxControllerExemplairesTestCase {
+
+	public function setUp() {
+		parent::setUp();
+
+		$this->_notice->addExemplaire(
+																$this->fixture('Class_Exemplaire',
+																							 ['id' =>777,
+																								'id_bib' => 77,
+																								'id_int_bib' => 0,
+																								'id_notice' => 123,
+																								'annexe' => 'MOUL',
+																								'section' => 'A9',
+																								'emplacement' => 'emplacement de test',
+																								'cote' => 'VOD-T-II',
+																								'dispo' => 'Disponible',
+																								'date_retour' => 'En mai',
+																								'reservable' => true,
+																								'code_barres' => '7777734343488']));
+		$this->_notice->save();
+		Zend_Registry::get('session')->id_bibs=[77];
+		$this->dispatch('noticeajax/exemplaires/id/123/id_notice/8', true);
+	}
+
+  /** @test */
+	public function coteVODTIIShouldBeInExemplaire() {
+		$this->assertXPathContentContains('//td[@class="cote"]','VOD-T-II');
+	}
+
+  /** @test */
+	public function coteVODTShouldBeNotBeInExemplaire() {
+		$this->assertNotXPathContentContains('//td[@class="cote"]','VOD-T-DLJ');
+	}
+
+}
+
+
+class NoticeAjaxControllerExemplairesTest extends NoticeAjaxControllerExemplairesTestCase {
+	public function setUp() {
+		parent::setUp();
 
 		$this->dispatch('noticeajax/exemplaires/id/123/id_notice/8', true);
 	}
@@ -969,8 +1046,8 @@ abstract class NoticeAjaxMemeAuteurTest extends AbstractControllerTestCase {
 
 	/** @test */
 	public function withoutSeriesNoticeShouldRenderAucuneSerie() {
-		Class_Notice::newInstanceWithId(123,
-																		['titre_principal' => 'Tarzan']);
+		$this->fixture('Class_Notice', ['id'=>123,
+																		'titre_principal' => 'Tarzan']);
 
 		$this->dispatch('/noticeajax/series?id_notice=123', true);
 		$this->assertXPathContentContains('//body', utf8_encode('Aucune information'),$this->_response->getBody());
@@ -979,48 +1056,108 @@ abstract class NoticeAjaxMemeAuteurTest extends AbstractControllerTestCase {
 
 
 class NoticeAjaxControllerDisponibiliteNoticeTest extends AbstractControllerTestCase {
-	protected $_notice;
+	protected
+		$_notice,
+		$_exemplaire,
+		$_sigb_exemplaire;
 
 	public function setUp() {
 		parent::setUp();
+		$this->_sigb_exemplaire = Storm_Test_ObjectWrapper::mock();
 
-		$this->_notice = Class_Notice::getLoader()
-			->newInstanceWithId(123)
-			->setTitrePrincipal('Tarzan')
-			->setExemplaires([]);
+
+		$this->_exemplaire = $this->fixture('Class_Exemplaire',
+																				['id' => 34,
+																				 'id_bib' => 456,
+																				 'id_int_bib' => 456,
+																				 'id_origine' => 12,
+																				 'id_notice' => 123,
+																				 'code_barres' => '12256663233656',
+																				 'is_available' => false,
+																				 'cote' => 'DDD',
+																				 'dispo' => 'Disponible',
+																				 'sigb_exemplaire' => $this->_sigb_exemplaire
+																				]);
+
+		$this->_notice = $this->fixture('Class_Notice', ['id'=>123,
+																										 'titre_principal' => 'Tarzan',
+																										 'exemplaires' => [$this->_exemplaire]]);
+	}
+
+
+	private function assertDispoNoticeHtmlContains($available) {
+		$this->dispatch('/noticeajax/dispo-notice?id_notice=123',true);
+		$this->assertXPathContentContains('//body', $available, $this->_response->getBody());
 	}
 
+
 	/** @test */
 	public function withoutExemplaireShouldNotBeAvailable () {
-		$this->assertAvailability('false');
+		$this->_notice->setExemplaires([])
+									->save();
+		$this->assertDispoNoticeHtmlContains('false');
 	}
 
 	/** @test */
 	public function withNonAvailableExemplaireShouldNotBeAvailable() {
-		$this->prepareExemplaireWithAvailability(false);
-		$this->assertAvailability('false');
+		$this->_sigb_exemplaire->whenCalled('isDisponible')
+													 ->answers(false);
+		$this->assertDispoNoticeHtmlContains('false');
 	}
 
   /** @test */
 	public function withAvailableExemplaireShouldBeAvailable() {
-		$this->prepareExemplaireWithAvailability(true);
-		$this->assertAvailability('true');
+		$this->_sigb_exemplaire->whenCalled('isDisponible')
+													 ->answers(true);
+		$this->assertDispoNoticeHtmlContains('true');
 	}
 
-	private function assertAvailability($available) {
-		$this->dispatch('/noticeajax/dispo-notice?id_notice=123',true);
-		$this->assertXPathContentContains('//body', $available, $this->_response->getBody());
+
+  /** @test */
+	public function assertNoticeShouldBeUpdatedWithAvailabilityTrue() {
+		$this->_sigb_exemplaire->whenCalled('isDisponible')
+													 ->answers(true);
+
+		$this->dispatch('/noticeajax/exemplaires/id/123',true);
+		Class_Exemplaire::clearCache();
+		Class_Notice::clearCache();
+
+		$this->assertTrue(Class_Exemplaire::find(34)->getIsAvailable());
+		return $this->_notice;
+	}
+
+	/**
+	 * @test
+	 * @depends assertNoticeShouldBeUpdatedWithAvailabilityTrue
+	 */
+	public function noticeShouldContainsFacetV456($notice) {
+		$this->assertContains('V456', $notice->getFacettes());
+	}
+
+
+  /** @test */
+	public function assertNoticeShouldBeUpdatedWithAvailabilityFalse() {
+		$this->_notice->setFacettes('V456')->save();
+		$this->_exemplaire->setIsAvailable(true)->save();
+
+		$this->_sigb_exemplaire->whenCalled('isDisponible')
+													 ->answers(false);
+
+		$this->dispatch('/noticeajax/exemplaires/id/123',true);
+		Class_Exemplaire::clearCache();
+		Class_Notice::clearCache();
+
+		$this->assertFalse(Class_Exemplaire::find(34)->getIsAvailable());
+		return $this->_notice;
 	}
 
-	private function prepareExemplaireWithAvailability($availability) {
-		$this->_notice->setExemplaires([Class_Exemplaire::getLoader()
-																	 ->newInstanceWithId(34)
-																	 ->setIdBib('456')
-																	 ->setIdOrigine('12')
-																	 ->setCodeBarres('12256663233656')
-																	 ->setSigbExemplaire(Storm_Test_ObjectWrapper::mock()
-																											 ->whenCalled('isDisponible')
-																											 ->answers($availability))]);
+
+	/**
+	 * @test
+	 * @depends assertNoticeShouldBeUpdatedWithAvailabilityFalse
+	 */
+	public function noticeShouldNotContainsFacetV456($notice) {
+		$this->assertNotContains('V456', $notice->getFacettes());
 	}
 }
 
diff --git a/tests/library/Class/CommSigbTest.php b/tests/library/Class/CommSigbTest.php
index 3406abadfc2536eb4a8848ddd34c5a4463a10532..a21bf636de5b763494331f0802acc15e13a5398b 100644
--- a/tests/library/Class/CommSigbTest.php
+++ b/tests/library/Class/CommSigbTest.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
@@ -38,11 +38,11 @@ abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
 		ZendAfi_Auth::getInstance()->getStorage()->write($florence);
 		$this->florence = $florence;
 
-		$this->userModel = Class_Users::getLoader()->newInstanceWithId(1)
-			->setLogin('florence')
-			->setPassword('secret')
-			->setIdSite(5)
-			->setIdabon('0123456789');
+		$this->userModel = $this->fixture('Class_Users', ['id' => 1,
+																										'login' => 'florence',
+																										'password' => 'secret',
+																										'id_site' => 5,
+																										'idabon' => '0123456789']);
 
 		$this->zend_cache = Storm_Test_ObjectWrapper::mock();
 		$this->zend_cache
@@ -107,72 +107,133 @@ abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
 			->will($this->returnValueMap($map));
 
 
-		$this->assertEquals(array(array('id_origine' => '123',
-																		'code_barres' => 'ABC',
-																		'id_int_bib' => 5,
-																		'dispo' => 'En pret',
-																		'reservable' => true,
-																		'date_retour' => '17/02/1978',
-																		'id_exemplaire' => '123',
-																		'cote' => 'POT',
-																		'emplacement' => '1',
-																		'nb_resas' => 0,
-																		'edition' => ''),
-															
-															array('id_origine' => '789',
-																		'code_barres' => 'ALM',
-																		'id_int_bib' => 5,
-																		'annexe' => 8,
-																		'dispo' => 'Sur demande calligraphiee',
-																		'reservable' => false,
-																		'date_retour' => '',
-																		'id_exemplaire' => '789',
-																		'cote' => 'ALI MER',
-																		'emplacement' => '2',
-																		'nb_resas' => 0,
-																		'edition' => ''),
-
-															array('id_origine' => '666',
-																		'code_barres' => 'PTI',
-																		'id_int_bib' => 5,
-																		'dispo' => 'non connue',
-																		'reservable' => false)),
-
-												$this->comm_sigb->getDispoExemplaires(array(array('id_origine' => '123',
-																																					'code_barres' => 'ABC',
-																																					'id_int_bib' => 5,
-																																					'cote' => 'POT',
-																																					'emplacement' => '1'),
-
-																																		array('id_origine' => '456',
-																																					'code_barres' => 'LOR',
-																																					'id_int_bib' => 5),
-
-																																		array('id_origine' => '789',
-																																					'code_barres' => 'ALM',
-																																					'id_int_bib' => 5,
-																																					'annexe' => 5,
-																																					'cote' => 'A',
-																																					'emplacement' => '9'),
-
-																																		array('id_origine' => '666',
-																																					'code_barres' => 'PTI',
-																																					'id_int_bib' => 5),
-
-																																		array('id_origine' => '999',
-																																					'code_barres' => 'PTP',
-																																					'id_int_bib' => 5),
-
-																																		array('id_origine' => '0001',
-																																					'code_barres' => 'PTIO',
-																																					'id_int_bib' => 5))));
+		$this->assertEquals([['id_origine' => '123',
+													'code_barres' => 'ABC',
+													'id_int_bib' => 5,
+													'dispo' => 'En pret',
+													'reservable' => true,
+													'date_retour' => '17/02/1978',
+													'id_exemplaire' => '123',
+													'cote' => 'POT',
+													'emplacement' => '1',
+													'nb_resas' => 0,
+													'edition' => '',
+													'annexe' => null,
+													'code_annexe' => null,
+													'is_available' => false,
+													'section' => '',
+													'genre' => null,
+													'date_nouveaute' => '',
+													'id' => 10
+														],
+
+												 ['id_origine' => '789',
+													'code_barres' => 'ALM',
+													'id_int_bib' => 5,
+													'annexe' => 5,
+													'code_annexe' => 5,
+													'dispo' => 'Sur demande calligraphiee',
+													'reservable' => false,
+													'date_retour' => '',
+													'id_exemplaire' => '789',
+													'cote' => 'ALI MER',
+													'emplacement' => '2',
+													'nb_resas' => 0,
+													'edition' => '',
+													'is_available' => true,
+													'section' => '',
+													'genre' => null,
+													'date_nouveaute' => '',
+													'id' => 12
+												 ],
+
+												 ['id_origine' => '666',
+													'code_barres' => 'PTI',
+													'id_int_bib' => 5,
+													'dispo' => 'Disponible',
+													'reservable' => false,
+													'annexe' => null,
+													'code_annexe' => null,
+													'is_available' => true,
+													'section' => '',
+													'genre' => null,
+													'emplacement' => '',
+													'date_nouveaute' => '',
+													'id' => 13],
+
+												 ['id'=> 16,
+													'id_origine' => '999',
+													'code_barres' => 'UNKNOWN',
+													'id_int_bib' => 5,
+													'annexe' => null,
+													'code_annexe' => null,
+													'is_available' => false,
+													'section' => '',
+													'genre' => null,
+													'emplacement' => '',
+													'date_nouveaute' => '',
+													'dispo' => 'Non disponible',
+													'reservable' => false]
+												 ],
+
+												$this->comm_sigb->getDispoExemplaires(
+																															[
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 10,
+																																							 'id_origine' => '123',
+																																							 'code_barres' => 'ABC',
+																																							 'id_int_bib' => 5,
+																																							 'cote' => 'POT',
+																																							 'emplacement' => '1']),
+
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 11,
+																																							 'id_origine' => '456',
+																																							 'code_barres' => 'LOR',
+																																							 'id_int_bib' => 5]),
+
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 12,
+																																							 'id_origine' => '789',
+																																							 'code_barres' => 'ALM',
+																																							 'id_int_bib' => 5,
+																																							 'annexe' => 5,
+																																							 'cote' => 'A',
+																																							 'emplacement' => '9',
+																																							 'is_available' => false]),
+
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 13,
+																																							 'id_origine' => '666',
+																																							 'code_barres' => 'PTI',
+																																							 'id_int_bib' => 5,
+																																							 'is_available'=> true]),
+
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 14,
+																																							 'id_origine' => '999',
+																																							 'code_barres' => 'PTP',
+																																							 'id_int_bib' => 5]),
+
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 15,
+																																							 'id_origine' => '0001',
+																																							 'code_barres' => 'PTIO',
+																																							 'id_int_bib' => 5]),
+
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 16,
+																																							 'id_origine' => '999',
+																																							 'code_barres' => 'UNKNOWN',
+																																							 'id_int_bib' => 5])
+																															]));
 	}
 
 
 	public function createMockForService($name) {
 		$this->mock_service = $this->getMockBuilder("Class_WebService_SIGB_".$name."_Service")
-												->disableOriginalConstructor()
-												->getMock();
+															 ->disableOriginalConstructor()
+															 ->getMock();
 		$this->mock_service
 			->expects($this->any())
 			->method('isConnected')
@@ -187,12 +248,12 @@ abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
 		$this->mock_service
 			->expects($this->once())
 			->method('reserverExemplaire')
-			->with($this->userModel, 
-						 Class_Exemplaire::getLoader()->newInstanceWithId(123), 
+			->with($this->userModel,
+						 Class_Exemplaire::getLoader()->newInstanceWithId(123),
 						 'ABC')
 			->will($this->returnValue(array('statut' => 1,
 																			'erreur' => '')));
-		
+
 		$this->assertEquals(array('statut' => 1,
 															'erreur' => ''),
 												$this->comm_sigb->reserverExemplaire(5, '123', 'ABC'));
@@ -201,8 +262,8 @@ abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
 	}
 
 
-	/** 
-	 * @test 
+	/**
+	 * @test
 	 * @depends reserverExemplaireShouldReturnAnArrayWithPotterInfos
 	 */
 	public function reserverExemplaireShouldClearCacheForUser($zend_cache) {
@@ -227,9 +288,9 @@ abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
 	}
 
 
-	/** 
+	/**
 	 * @depends ficheAbonneShouldReturnAnArrayWithEmprunteurFlorence
-	 * @test 
+	 * @test
 	 */
 	public function ficheAbonneShouldReturnAnArrayWithEmprunteurFlorenceWhenInCache($emprunteur_florence) {
 		$this->zend_cache
@@ -256,8 +317,8 @@ abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
 	}
 
 
-	/** 
-	 * @test 
+	/**
+	 * @test
 	 * @depends supprimerReservationShouldReturnStatutOK
 	 */
 	public function supprimerReservationShouldClearCacheForUser($zend_cache) {
@@ -281,8 +342,8 @@ abstract class CommSigbTestCase extends Storm_Test_ModelTestCase {
 	}
 
 
-	/** 
-	 * @test 
+	/**
+	 * @test
 	 * @depends prolongerPretShouldReturnStatutOK
 	 */
 	public function prolongerPretShouldClearCacheForUser($zend_cache) {
@@ -345,7 +406,7 @@ class CommSigbMoulinsVSmartTest extends CommSigbTestCase {
 class CommSigbMeuseKohaTest extends CommSigbTestCase {
 	public function setUp() {
 		parent::setUp();
-		
+
 		$params = ['url_serveur' => 'http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl',
 							 'Codification_disponibilites' => "1:En prêt\r\n2:Réservable"];
 
@@ -547,27 +608,27 @@ class CommSigbWithNotAbonneTest extends Storm_Test_ModelTestCase {
 
 	/** @test */
 	public function prolongerPretShouldReturnError() {
-		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'], 
+		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'],
 												$this->comm_sigb->prolongerPret($this->user, 0));
 	}
 
 
 	/** @test */
 	public function supprimerReservationShouldReturnError() {
-		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'], 
+		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'],
 												$this->comm_sigb->supprimerReservation($this->user, 0));
 	}
 
 	/** @test */
 	public function ficheAbonneShouldReturnError() {
-		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'], 
+		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'],
 												$this->comm_sigb->ficheAbonne($this->user));
 	}
 
 
 	/** @test */
 	public function reserverExemplaireShouldReturnError() {
-		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'], 
+		$this->assertEquals(['erreur' => 'Communication SIGB indisponible'],
 												$this->comm_sigb->reserverExemplaire(0, 0, 0));
 	}
 
@@ -575,20 +636,29 @@ class CommSigbWithNotAbonneTest extends Storm_Test_ModelTestCase {
 	/** @test */
 	public function getDispoExemplairesShouldReturnNonReservable() {
 		$this->assertEquals([
-			[
-				'id' => 2,
-				'id_int_bib' => 0,
-				'id_origine' => 0,
-				'code_barres' => 0,
-				'dispo' => 'non connue',
-				'reservable' => false]
-		],
-		$this->comm_sigb->getDispoExemplaires([
-			[
-				'id' => 2,
-				'id_origine' => 0,
-				'code_barres' => 0,
-				'id_int_bib' => 0]]));
+												 [
+													'id' => 2,
+													'id_int_bib' => 0,
+													'id_origine' => 0,
+													'code_barres' => 0,
+													'dispo' => 'Non disponible',
+													'reservable' => false,
+													'annexe' => null,
+													'code_annexe' => null,
+													'is_available' => false,
+													'section' => '',
+													'genre' => null,
+													'emplacement' => '',
+													'date_nouveaute' => ''
+												 ]
+												 ],
+												$this->comm_sigb->getDispoExemplaires([
+																															 $this->fixture('Class_Exemplaire',
+																																							['id'=> 19,
+																																							 'id' => 2,
+																																							 'id_origine' => 0,
+																																							 'code_barres' => 0,
+																																							 'id_int_bib' => 0])]));
 	}
 }
 
diff --git a/tests/library/Class/UserGroupTest.php b/tests/library/Class/UserGroupTest.php
index d368b8ac2171109f0cba7e18c492030813581c97..3b9bf57543c5438131303089b4472164be44b720 100644
--- a/tests/library/Class/UserGroupTest.php
+++ b/tests/library/Class/UserGroupTest.php
@@ -23,6 +23,8 @@ abstract class UserGroupsTestCase extends Storm_Test_ModelTestCase {
 	public function setUp() {
 		parent::setUp();
 
+		Class_SessionFormation::beVolatile();
+
 		$this->_florence = $this->fixture('Class_Users',
 																			['id' => 1,
 																			 'login' => 'flo',
diff --git a/tests/library/ZendAfi/View/Helper/Notice/ExemplairesTest.php b/tests/library/ZendAfi/View/Helper/Notice/ExemplairesTest.php
index 58a12929d0d1e807b2a91bc5c9cba746ec738ccd..8259b96c9fda4659b696886c0d2cf7b82264d813 100644
--- a/tests/library/ZendAfi/View/Helper/Notice/ExemplairesTest.php
+++ b/tests/library/ZendAfi/View/Helper/Notice/ExemplairesTest.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 require_once 'library/ZendAfi/View/Helper/ViewHelperTestCase.php';
@@ -49,16 +49,27 @@ class NoticeHtmlGetExemplairesWithOneExemplaireNoWebServiceTest extends ZendAfi_
 	public function setUp() {
 		parent::setUp();
 		Class_Profil::setCurrentProfil(new Class_Profil());
-		$exemplaire = [
-			'id_bib' => -1,
-			'id_int_bib' => 0,
-			'id_notice' => '24765',
-			'annexe' => 'MOUL',
-			'count(*)' => 2, //???
-			'cote' => 'DSEM',
-			'dispo' => "Disponible",
-			'code_barres' => "12345"]; 
-		$this->html = $this->_helper->Notice_Exemplaires([$exemplaire]);
+
+		$exemplaires = [$this->fixture('Class_Exemplaire',
+																	 [ 'id' => 10,
+																		'id_bib' => -1,
+																		'id_int_bib' => 0,
+																		'id_notice' => '24765',
+																		'annexe' => 'MOUL',
+																		'cote' => 'DSEM',
+																		'dispo' => "Disponible",
+																		'code_barres' => "12345"]),
+										$this->fixture('Class_Exemplaire',
+																	 ['id' => 11,
+																		'id_bib' => -1,
+																		'id_int_bib' => 0,
+																		'id_notice' => '24765',
+																		'annexe' => 'MOUL',
+																		'cote' => 'DSEM',
+																		'dispo' => "Disponible",
+																		'code_barres' => "12346"])
+		];
+		$this->html = $this->_helper->Notice_Exemplaires($exemplaires, 2);
 	}
 
 
@@ -75,6 +86,12 @@ class NoticeHtmlGetExemplairesWithOneExemplaireNoWebServiceTest extends ZendAfi_
 	}
 
 
+	/** @test */
+	public function columnAvailabilityShouldDisplayDisponible() {
+		$this->assertXPathContentContains($this->html, '//td[@class="dispo disponible"]', 'Disponible');
+	}
+
+
 	/** @test */
 	public function reservationLinkShouldBeRechercheReservation() {
 		$this->assertXPath(
@@ -82,10 +99,26 @@ class NoticeHtmlGetExemplairesWithOneExemplaireNoWebServiceTest extends ZendAfi_
 			'//a[contains(@href, "recherche/reservation/id_int_bib/0/id_bib/-1/id_notice/24765/cote/DSEM")]');
 	}
 
+
+	/** @test */
+	public function pageShouldContainsLinkToDisplaySameWork() {
+		$this->assertXPath($this->html,
+											 '//div[@class="notice_bloc_titre"][contains(@onclick, "/exemplaires-same-work/id/24765")]',
+		$this->html);
+	}
+
 	/** @test **/
 	public function coteShouldNotContainsSpan() {
 		$this->assertNotXPathContentContains($this->html, '//td', utf8_encode('DSEM<span></span>'),$this->html);
 	}
+
+
+	/** @test */
+	public function columnGrouperShouldContainsTwoExemplaires() {
+		$this->assertXPathContentContains($this->html,
+																			'//td[@class="grouper"]',
+																			'2 ex.');
+	}
 }
 
 
@@ -98,7 +131,7 @@ abstract class NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTestCase ex
 	public function setUp() {
 		parent::setUp();
 		$_SESSION['id_profil'] = 4;
-		
+
 		$this->sigb_exemplaire =	Class_WebService_SIGB_Exemplaire::newInstance()
 			->setId(5)
 			->setDisponibiliteEnPret()
@@ -135,33 +168,34 @@ abstract class NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTestCase ex
 																							 ->answers(true)
 																							 ->getWrapper());
 
-		$this->exemplaire = ['id' => 12,
-												 'id_bib' => 4,
-												 'id_int_bib' => 1,
-												 'id_notice' => '24765',
-												 'id_origine' => '666',
-												 'annexe' => 'MOUL',
-												 'count(*)' => 2, //???
-												 'cote' => 'DSEM',
-												 'dispo' => "Disponible",
-												 'code_barres' => "12345",
-												 'section' => 3,
-												 'emplacement' => 2,
-												 'nb_resas'=>0];
+		$this->exemplaire = $this->fixture('Class_Exemplaire',
+																			 ['id' => 12,
+																				'id_bib' => 4,
+																				'id_int_bib' => 1,
+																				'id_notice' => '24765',
+																				'id_origine' => '666',
+																				'annexe' => 'MOUL',
+																				'count(*)' => 2, //???
+																				'cote' => 'DSEM',
+																				'dispo' => "Disponible",
+																				'code_barres' => "12345",
+																				'section' => 3,
+																				'emplacement' => 2,
+																				'nb_resas'=>0]);
 	}
 }
 
 
 
 
-class NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTest 
+class NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTest
 extends NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTestCase {
 
 	public function setUp() {
 		parent::setUp();
 		Class_CosmoVar::newInstanceWithId('site_retrait_resa', ['valeur' => 0]);
 		Class_CodifEmplacement::newInstanceWithId('2', ['libelle' => 'Etage 2']);
-		$this->html = $this->_helper->Notice_Exemplaires(array($this->exemplaire));
+		$this->html = $this->_helper->Notice_Exemplaires([$this->exemplaire]);
 	}
 
 
@@ -177,7 +211,7 @@ extends NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTestCase {
 		'//a[@data-popup="true"][contains(@href, "recherche/reservation-pickup-ajax/id_int_bib/1/id_bib/4/id_origine/12/code_annexe/MOUL")]');
 	}
 
-	
+
 	/** @test **/
 	public function disponibiliteShoudBeDisponibleAnd4Reservations() {
 		$this->assertXPathContentContains($this->html,'//td',utf8_encode('Nb résas: 4'),$this->html);
@@ -189,7 +223,7 @@ extends NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTestCase {
 	public function withOutEditionCoteColonneTitleShoudBeCote() {
 		$this->assertNotXPathContentContains($this->html, '//th', utf8_encode('<span>(Edition)</span>'),$this->html);
 	}
-	
+
 }
 
 class NoticeHtmlGetExemplairesWithOneExemplairesAndWebServiceAndEditionTest extends NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTestCase {
@@ -200,9 +234,9 @@ class NoticeHtmlGetExemplairesWithOneExemplairesAndWebServiceAndEditionTest exte
 		Class_CosmoVar::newInstanceWithId('site_retrait_resa', ['valeur' => 0]);
 		$this->html = $this->_helper->Notice_Exemplaires(array($this->exemplaire));
 	}
-	
 
-	/** @test **/ 
+
+	/** @test **/
 	public function coteShouldBeDSEMAnd2011() {
 		$this->assertXPathContentContains($this->html, '//td', utf8_encode('DSEM<span>2011</span>'), $this->html);
 	}
@@ -219,7 +253,7 @@ class NoticeHtmlGetExemplairesWithOneExemplairesAndWebServiceAndEditionTest exte
 
 class NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceAndPickupActiveTest
 extends NoticeHtmlGetExemplairesWithOneExemplaireAndWebServiceTestCase {
-	
+
 
 	public function setUp() {
 		parent::setUp();