diff --git a/cosmogramme/php/classes/classe_notice_integration.php b/cosmogramme/php/classes/classe_notice_integration.php
index 6dc6ea8e9ae544be399cfd74229ac3d2daa0e565..6c87647d25a3722ff74201db398191508597d92d 100644
--- a/cosmogramme/php/classes/classe_notice_integration.php
+++ b/cosmogramme/php/classes/classe_notice_integration.php
@@ -177,7 +177,7 @@ class notice_integration
 			if($this->id_article_periodique == 1)
 			{
 				$clef_chapeau=$this->notice["clef_chapeau"];
-				$clef_numero=$this->notice["tome_alpha"];
+				$clef_numero=addslashes($this->notice["tome_alpha"]);
 				$date=dateDuJour(0);
 				$sql->execute("delete from notices_articles where clef_chapeau='$clef_chapeau' and clef_numero='$clef_numero' and date_maj!='$date'");
 			}
diff --git a/cosmogramme/php/web_services/temps_reel_pergame.php b/cosmogramme/php/web_services/temps_reel_pergame.php
index 139d9d186d0e62727da3690246a344c044b5b7f4..3ff399a50ca27336d4ecedb9d080ac449622a4da 100644
--- a/cosmogramme/php/web_services/temps_reel_pergame.php
+++ b/cosmogramme/php/web_services/temps_reel_pergame.php
@@ -84,7 +84,11 @@ if($statut == "busy") retour($statut,"Trop de connexions");
 $nomBase=$_REQUEST["base"];
 $user=$_REQUEST["user"];
 $pwd=$_REQUEST["pass"];
-$sql = mysql_connect("172.16.77.60", $user, $pwd);
+
+if($_SERVER['HTTP_HOST']=="localhost") $host="localhost"; else $host="172.16.77.60";
+
+//$sql = mysql_connect("172.16.77.60", $user, $pwd);
+$sql = mysql_connect($host, $user, $pwd);
 if(!$sql) retour("sqlerror" ,"Impossible de se connecter a mysql");
 if(! mysql_select_db($nomBase)) retour("sqlerror","Impossible de selectionner la base de donnees");
 
@@ -131,8 +135,47 @@ switch($action)
 	case "7": // Suppression de réservation
 		$req="Delete from reservations Where ID_PERGAME=".$_REQUEST["ligne"];
 		break;
+	case "8": // Abonnés
+		$id_pergame=$values_array[0];
+		$ordre_abon=$values_array[1];
+		$result=mysql_query("select ID_USER from bib_admin_users where IDABON=$id_pergame and ORDREABON=$ordre_abon");
+		$row = mysql_fetch_array($result, MYSQL_NUM);
+		$id_user=$row[0];
+		if($id_user>0)
+		{
+			$req="update bib_admin_users set ";
+			$req.="NOM='".addslashes($values_array[2])."',";
+			$req.="PRENOM='".addslashes($values_array[3])."',";
+			$req.="NAISSANCE='".$values_array[4]."',";
+			$req.="LOGIN='".$values_array[0]."',";	
+			$req.="PASSWORD='".substr($values_array[4],8,2).substr($values_array[4],4,4).substr($values_array[4],0,4)."',";
+			$req.="MAIL='".addslashes($values_array[7])."',";
+			$req.="DATE_DEBUT='".$values_array[5]."',";
+			$req.="DATE_FIN='".$values_array[6]."'";	
+			$req.=" where ID_USER=".$id_user;
+		}
+		else
+		{
+			$req="insert into bib_admin_users (NOM, PRENOM, NAISSANCE, ID_SITE, LOGIN, PASSWORD, 
+				ROLE, ROLE_LEVEL, IDABON, ORDREABON, MAIL, DATE_DEBUT, DATE_FIN) Values(";
+			$req.="'".$values_array[2]."',";
+			$req.="'".$values_array[3]."',";
+			$req.="'".$values_array[4]."',";
+			$req.='1,';
+			$req.="'".$values_array[0]."',";
+			$req.="'".substr($values_array[4],8,2).substr($values_array[4],4,4).substr($values_array[4],0,4)."',";
+			$req.="'abonne_sigb',";
+			$req.="2,";
+			$req.=$values_array[0].",";
+			$req.=$values_array[1].",";
+			$req.="'".addslashes($values_array[7])."',";
+			$req.="'".$values_array[5]."',";
+			$req.="'".$values_array[6]."'";
+			$req.=')';
+		}
+		break;
 	default: 
-		retour("erreur","fonction incorrecte : doit etre comprise entre 2 et 7");
+		retour("erreur","fonction incorrecte : doit etre comprise entre 2 et 8");
 		break;
 }
 
diff --git a/library/Class/Exemplaire.php b/library/Class/Exemplaire.php
index 0386aa74c943fb742b479773879d13fab6cf046a..fb96f1585dfe0111fa7561220f048995a35d3a3f 100644
--- a/library/Class/Exemplaire.php
+++ b/library/Class/Exemplaire.php
@@ -60,6 +60,10 @@ class Class_Exemplaire extends Storm_Model_Abstract {
 		return $site->getLibelle();
 	}
 
+	public function getBibLibelle() {
+		return $this->hasBib() ? $this->getBib()->getLibelle() : '';
+
+	}
 
 	public function getDateRetour() {
 		if ($this->hasPret())
diff --git a/library/Class/Notice.php b/library/Class/Notice.php
index fa16cff1aee06b1acd256f5e2068e371bd05a497..28ead8a5f0c92c6dac820b1f0344df886c995a14 100644
--- a/library/Class/Notice.php
+++ b/library/Class/Notice.php
@@ -1470,8 +1470,11 @@ class Class_Notice extends Storm_Model_Abstract {
 			foreach ($data as $items)	{
 					$sous_champs = $this->decoupe_bloc_champ($items);
 					foreach ($sous_champs as $item)	{
-							if ($collation) $collation .= " ; ";
-							$collation.=$item["valeur"];
+							if(strpos('; '.$collation.' ;','; '. $item["valeur"].' ;')=== false)
+							{
+								if ($collation) $collation .= " ; ";
+								$collation.=$item["valeur"];
+							}
 						}
 			}
 			$collation=str_replace("+ ;","+",$collation);
diff --git a/library/Class/Systeme/PergameService.php b/library/Class/Systeme/PergameService.php
index 4ca210112e785e766a994d16b5c2a73b8b4f9a0c..2e7f6cb5284a4182f5bb0b6b60aa2d9d307832f8 100644
--- a/library/Class/Systeme/PergameService.php
+++ b/library/Class/Systeme/PergameService.php
@@ -212,8 +212,8 @@ class Class_Systeme_PergameService
 		// Controle connexion
 		if(!$this->user->ID_USER) $ret["erreur"]="Vous devez être connecté pour réserver un document";
 		else if(!$this->user->IDABON) $ret["erreur"]="Vous devez être connecté en tant qu'abonné pour réserver un document";
+		
 		// Lire exemplaire et notice
-
 		if(!$exemplaire) return array("erreur"=>"Une erreur s'est produite lors de la lecture de la notice.");
 
 		$notice= $exemplaire->getNotice();
@@ -251,11 +251,13 @@ class Class_Systeme_PergameService
 		}
 		
 		// Ecrire enreg reservation
+		if(!$id_bib) $id_bib=1;
 		$req="insert into reservations(ID_SITE,ID_PERGAME,IDABON,ORDREABON,DATE_RESA,SUPPORT,ID_NOTICE_ORIGINE)";
 		$req.="Values($id_bib,0,$id_abon,$ordre_abon,'".date("Y-m-d")."',$support,'$id_origine')";
 		sqlExecute($req);
 
 		// Ecrire enreg transaction
+		if(!$code_annexe) $code_annexe=1;
 		$date=date("Y-m-d H:i:s");
 		$heure=date("H");
 		$this->ecrireTransaction(6,array($id_abon,$ordre_abon,$support,$id_origine,$date,$code_annexe,$heure));
@@ -309,7 +311,7 @@ class Class_Systeme_PergameService
 		// Controle si le doc est réservé
 		if($regles["Interdire_si_reservation"]==1)
 		{
-			$controle=fetchOne("Select Count(*) From reservations Where ID_NOTICE_ORIGINE=".$pret["ID_NOTICE_ORIGINE"]." and IDABON='".$pret["ID_ABON"]."'");
+			$controle=fetchOne("Select Count(*) From reservations Where ID_NOTICE_ORIGINE=".$pret["ID_NOTICE_ORIGINE"]);
 			if($controle>0) return array('statut'=>0,"erreur"=>"Le prêt n'a pas pu être prolongé car il est réservé.".$complement_msg);
 		}
 		
diff --git a/library/Class/WebService/SIGB/Exemplaire.php b/library/Class/WebService/SIGB/Exemplaire.php
index cd786e893f68350b60d53f6c3328d2ed352d2aff..7f0962377844b06643f99bd15d343924b15d83aa 100644
--- a/library/Class/WebService/SIGB/Exemplaire.php
+++ b/library/Class/WebService/SIGB/Exemplaire.php
@@ -177,7 +177,7 @@ class Class_WebService_SIGB_Exemplaire {
 
 	public function getBibliotheque(){
 		if (!$this->bibliotheque  and ($exemplaire = $this->getExemplaireOPAC()))
-			$this->bibliotheque = $exemplaire->getBib()->getLibelle();
+			$this->bibliotheque = $exemplaire->getBibLibelle();
 
 		return $this->bibliotheque;
 	}
diff --git a/library/Class/WebService/SIGB/ExemplaireOperation.php b/library/Class/WebService/SIGB/ExemplaireOperation.php
index 537555d369172a770817664b38ecfb2b7288c5f4..ebf868deaba9168e5ad8b30c08a228dd18499d33 100644
--- a/library/Class/WebService/SIGB/ExemplaireOperation.php
+++ b/library/Class/WebService/SIGB/ExemplaireOperation.php
@@ -229,6 +229,7 @@ abstract class Class_WebService_SIGB_ExemplaireOperation {
 		$this->_exemplaire->setNoNotice($this->getAttribute('N° de notice'));
 
 		$this->onParseAttributes();
+		return $this;
 	}
 
 
diff --git a/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php b/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php
index c530877e013ffedcc948fd2683bbcc36656687b1..e2c48f7968cb895ea7b981b330b91a95345bd27c 100644
--- a/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php
+++ b/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php
@@ -21,23 +21,23 @@
 
 class Class_WebService_SIGB_VSmart_SearchResponseReader extends Class_WebService_SIGB_AbstractMarcXMLNoticeReader {
 	protected $_current_exemplaire;
-	protected $_STATUT_SYSTEME = array('0' => 'Disponible',
-																		 '4' => 'En prêt',
-																		 '8' => 'En attende de retrait',
-																		 '10' => 'En déplacement',
-																		 '23' => 'Non empruntable',
-																		 '11' => 'Prétendu rendu',
-																		 '12' => 'Perdu',
-																		 '13' => 'Manquant',
-																		 '21' => 'Autre',
-																		 '22' => 'Nouveauté',
-																		 '25' => 'En rachat',
-																		 '26' => 'En réparation',
-																		 '27' => 'En magasin',
-																		 '28' => 'Pilon',
-																		 '29' => 'Exclu du prêt',
-																		 '30' => 'En commande',
-																		 '31' => 'A l\'équipement');
+	protected $_STATUT_SYSTEME = ['0' => 'Disponible',
+																'4' => 'En prêt',
+																'8' => 'En attende de retrait',
+																'10' => 'En déplacement',
+																'23' => 'Non empruntable',
+																'11' => 'Prétendu rendu',
+																'12' => 'Perdu',
+																'13' => 'Manquant',
+																'21' => 'Autre',
+																'22' => 'Nouveauté',
+																'25' => 'En rachat',
+																'26' => 'En réparation',
+																'27' => 'En magasin',
+																'28' => 'Pilon',
+																'29' => 'Exclu du prêt',
+																'30' => 'En commande',
+																'31' => 'A l\'équipement'];
 
 	public static function newInstance() {
 		return new self();
@@ -70,16 +70,21 @@ class Class_WebService_SIGB_VSmart_SearchResponseReader extends Class_WebService
 
 
 	public function endSubfield_852_y($data) {
-		$this->_current_exemplaire->setReservable($data == '4');
+		$this->_current_exemplaire
+			->setReservable($this->isReservable($data));
+
+		$dispo = (array_key_exists($data, $this->_STATUT_SYSTEME)) 
+			? $this->_STATUT_SYSTEME[$data] : 'Inconnu';
 
-		if (array_key_exists($data, $this->_STATUT_SYSTEME))
-			$dispo = $this->_STATUT_SYSTEME[$data];
-		else
-			$dispo = 'Inconnu';
 		$this->_current_exemplaire->setDisponibilite($dispo);
 	}
 
 
+	protected function isReservable($data) {
+		return in_array((int)$data, [4, 8]);
+	}
+
+
 	public function endSubfield_852_u($data) {
 		$this->_current_exemplaire->setVisibleOpac($data != '0');
 	}
@@ -89,18 +94,14 @@ class Class_WebService_SIGB_VSmart_SearchResponseReader extends Class_WebService
 		$date = $data;
 		// date reçue au format AAAAMMJJ, transformée en jj/mm/aaaa
 		if (8 == strlen($date)) {
-			$parts = array(
-				substr($data, 6, 2),
-				substr($date, 4, 2),
-				substr($date, 0, 4),
-			);
+			$parts = [substr($data, 6, 2),
+								substr($date, 4, 2),
+								substr($date, 0, 4)];
 
 			$date = implode('/', $parts);
-
 		}
 
 		$this->_current_exemplaire->setDateRetour($date);
-
 	}
 }
 
diff --git a/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php b/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php
index a5b48fcc50314f78d92cf1a7b46228e3a3c9610a..655b08c6bf318989cfc265e4929b52cc2e2be823 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerPretsTest.php
@@ -197,33 +197,44 @@ class AbonneControllerPretsListReservationTest extends AbstractAbonneControllerP
 	public function setUp() {
 		parent::setUp();
 
-		$potter = new Class_WebService_SIGB_Reservation('12', new Class_WebService_SIGB_Exemplaire(123));
-		$potter->getExemplaire()->setTitre('Potter');
-		$potter->parseExtraAttributes(array('Etat' => 'Réservation émise',
-																				'Rang' => '2',
-																				'Bibliotheque' => 'Tombouctou',
-																				'N° de notice' => 564));
-
-		$exemplaire_potter = Class_Exemplaire::newInstanceWithId(918, ['id_origine' => 564,
-																																	 'notice' => Class_Notice::newInstanceWithId(823,
-																																																							['titre_principal' => 'Potter'])]);
-		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Exemplaire')
-			->whenCalled('findFirstBy')
-			->with(['id_origine' => 564])
-			->answers($exemplaire_potter);
-
-
-		$emprunteur = new Class_WebService_SIGB_Emprunteur('1234', 'Florence');
-		$emprunteur->reservationsAddAll(array($potter));
-
-		$fiche_sigb = array('type_comm' => 2, //OPSYS
-												'fiche' => $emprunteur,
-												'message' => '',
-												'erreur' => '',
-												'nom_aff' => 'FloFlo');
-
-		$this->florence->setFicheSigb($fiche_sigb)
-									->setPseudo('FloFlo');
+		Class_Exemplaire::beVolatile();
+
+		$potter = 
+			(new Class_WebService_SIGB_Reservation('12', 
+																						 (new Class_WebService_SIGB_Exemplaire(123))->setTitre('Potter')))
+			->parseExtraAttributes(array('Etat' => 'Réservation émise',
+																	 'Rang' => '2',
+																	 'Bibliotheque' => 'Tombouctou',
+																	 'N° de notice' => 564));
+
+		Class_Exemplaire::newInstance(['id_origine' => 564,
+																	 'notice' => $this->fixture('Class_Notice',
+																															 ['id' => 823,
+																																'titre_principal' => 'Potter'])
+																		])->assertSave();
+
+		// This item has no library: non-regression test.
+		$dobby = 
+			(new Class_WebService_SIGB_Reservation('13', 
+																						 (new Class_WebService_SIGB_Exemplaire(124))->setTitre('Dobby')))
+			->parseExtraAttributes(array('Etat' => 'Réservation émise',
+																	 'Rang' => '2',
+																	 'N° de notice' => 565));
+
+		Class_Exemplaire::newInstance(['id_origine' => 565,
+																	 'notice' => $this->fixture('Class_Notice',
+																															['id' => 824,
+																															 'titre_principal' => 'Dobby'])
+																		])->assertSave();
+
+
+		$this->florence
+			->setFicheSigb(['type_comm' => Class_IntBib::COM_OPSYS,
+											'fiche' => (new Class_WebService_SIGB_Emprunteur('1234', 'Florence'))
+																	->reservationsAddAll([$potter, $dobby]),
+											'message' => '',
+											'erreur' => '',
+											'nom_aff' => 'FloFlo']);
 
 		$this->dispatch('/opac/abonne/reservations');
 	}
@@ -296,6 +307,15 @@ class AbonneControllerPretsListReservationTest extends AbstractAbonneControllerP
 		$this->assertXPathContentContains('//tbody/tr[1]//td', 'Tombouctou', $this->_response->getBody());
 	}
 
+
+
+	/** @test */
+	public function secondReservationTitleShouldBeDobby() {
+		$this->assertXPathContentContains('//tbody/tr[2]//td//a', 'Dobby',
+																			$this->_response->getBody());
+	}
+
+
 }
 
 
diff --git a/tests/library/Class/WebService/SIGB/VSmartFixtures.php b/tests/library/Class/WebService/SIGB/VSmartFixtures.php
index 77398e9e3fe0e853ab7d2af5ca2f73c72233151b..7afd273e10b4de498798729e12b5472f210f0135 100644
--- a/tests/library/Class/WebService/SIGB/VSmartFixtures.php
+++ b/tests/library/Class/WebService/SIGB/VSmartFixtures.php
@@ -220,7 +220,7 @@ class VSmartFixtures {
 												 <subfield code="t">NEM</subfield>
 												 <subfield code="y">4</subfield>
 												 <subfield code="x">20110205</subfield>
-												 <subfield code="y">8</subfield>
+												 <subfield code="y">10</subfield>
 										 </datafield>
 								 </zs:recordData>
 								 <zs:recordPosition>1</zs:recordPosition>
@@ -309,6 +309,17 @@ class VSmartFixtures {
 														 <subfield code="t">LFA</subfield>
 														 <subfield code="y">0</subfield>
 												 </datafield>
+												 <datafield tag="852">
+														 <subfield code="a">RES</subfield>
+														 <subfield code="b">MCFC</subfield>
+														 <subfield code="c">MCRPT</subfield>
+														 <subfield code="e">20110301</subfield>
+														 <subfield code="h">R</subfield>
+														 <subfield code="p">9988O4DV</subfield>
+														 <subfield code="q">9988O4DV</subfield>
+														 <subfield code="t">LFA</subfield>
+														 <subfield code="y">8</subfield>
+												 </datafield>
 										 </zs:recordData>
 										 <zs:recordPosition>-1</zs:recordPosition>
 								 </zs:record>
diff --git a/tests/library/Class/WebService/SIGB/VSmartTest.php b/tests/library/Class/WebService/SIGB/VSmartTest.php
index 7a7393fd518973066ce645cfd3564bdf80f78d42..d58efb954d242e9e4ad504fd706877098372dc77 100644
--- a/tests/library/Class/WebService/SIGB/VSmartTest.php
+++ b/tests/library/Class/WebService/SIGB/VSmartTest.php
@@ -22,20 +22,15 @@ include_once('VSmartFixtures.php');
 
 abstract class  VSmartServiceTestCase extends Storm_Test_ModelTestCase {
 	public function setUp() {
-		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_CodifAnnexe')
-			->whenCalled('findFirstBy')
-			->with(array('code' => 'MCFC'))
-			->answers(Class_CodifAnnexe::getLoader()->newInstanceWithId(2)
-								->setCode('MCFC')
-								->setLibelle('Médiathèque communautaire'))
-			->getWrapper()
-
-			->whenCalled('findFirstBy')
-			->with(array('code' => 'AVER'))
-			->answers(Class_CodifAnnexe::getLoader()->newInstanceWithId(4)
-								->setCode('AVER')
-								->setLibelle('Avermes'))
-			->getWrapper();
+		$this->fixture('Class_CodifAnnexe', 
+									 ['id'=> 1,
+										'code' => 'MCFC',
+										'libelle' => 'Médiathèque communautaire']);
+
+		$this->fixture('Class_CodifAnnexe', 
+									 ['id' => 2,
+										'code' => 'AVER',
+										'libelle' => 'Avermes']);
 	}
 }
 
@@ -66,7 +61,7 @@ class VSmartServiceDummyFunctionsTest extends Storm_Test_ModelTestCase {
 class VSmartGetServiceTest extends Storm_Test_ModelTestCase {
 	public function setUp() {
 		Class_WebService_SIGB_VSmart::reset();
-		$this->service = Class_WebService_SIGB_VSmart::getService(array('url_serveur' => 'vpn.moulins.fr'));
+		$this->service = Class_WebService_SIGB_VSmart::getService(['url_serveur' => 'vpn.moulins.fr']);
 	}
 
 
@@ -90,12 +85,10 @@ class VSmartGetServiceTest extends Storm_Test_ModelTestCase {
 class VSmartServiceWithEmprunteurEvelyneTest extends VSmartServiceTestCase {
 	public function setUp() {
 		parent::setUp();
-		$mock_web_client = $this->getMock('Class_WebService_SimpleWebClient');
-		$mock_web_client
-			->expects($this->once())
-			->method('open_url')
+		$mock_web_client = $this->mock()
+			->whenCalled('open_url')
 			->with('http://86.64.58.38/formation/VubisSmartHttpApi.csp?fu=GetBorrower&MetaInstitution=RES&BorrowerId=04051972')
-			->will($this->returnValue(VSmartFixtures::xmlBorrowerEvelyne()));
+			->answers(VSmartFixtures::xmlBorrowerEvelyne());
 
 		$this->evelyne = Class_WebService_SIGB_VSmart_Service::newInstance()
 			->setServerRoot('86.64.58.38/formation/')
@@ -270,12 +263,10 @@ class VSmartServiceWithEmprunteurEvelyneTest extends VSmartServiceTestCase {
 class VSmartServiceWithEmprunteurEvelyneResponseErrorTest extends VSmartServiceTestCase {
 	public function setUp() {
 		parent::setUp();
-		$mock_web_client = $this->getMock('Class_WebService_SimpleWebClient');
-		$mock_web_client
-			->expects($this->once())
-			->method('open_url')
+		$mock_web_client = $this->mock()
+			->whenCalled('open_url')
 			->with('http://86.64.58.38/formation/VubisSmartHttpApi.csp?fu=GetBorrower&MetaInstitution=RES&BorrowerId=04051972')
-			->will($this->returnValue(''));
+			->answers('');
 
 		$this->evelyne = Class_WebService_SIGB_VSmart_Service::newInstance()
 			->setServerRoot('86.64.58.38/formation/')
@@ -298,12 +289,10 @@ class VSmartServiceWithEmprunteurEvelyneResponseErrorTest extends VSmartServiceT
 class VSmartServiceWithEmprunteurFranckTest extends  VSmartServiceTestCase {
 	public function setUp() {
 		parent::setUp();
-		$mock_web_client = $this->getMock('Class_WebService_SimpleWebClient');
-		$mock_web_client
-			->expects($this->once())
-			->method('open_url')
+		$mock_web_client = $this->mock()
+			->whenCalled('open_url')
 			->with('http://46.20.169.8/production/VubisSmartHttpApi.csp?fu=GetBorrower&MetaInstitution=RES&BorrowerId=30101964')
-			->will($this->returnValue(VSmartFixtures::xmlBorrowerFranck()));
+			->answers(VSmartFixtures::xmlBorrowerFranck());
 
 		$this->franck = Class_WebService_SIGB_VSmart_Service::newInstance()
 			->setServerRoot('http://46.20.169.8/production')
@@ -430,12 +419,10 @@ class VSmartServiceWithEmprunteurFranckTest extends  VSmartServiceTestCase {
 
 class VSmartServiceBibGetAnthologieLitteratureTest extends Storm_Test_ModelTestCase {
 	public function setUp() {
-		$mock_web_client = $this->getMock('Class_WebService_SimpleWebClient');
-		$mock_web_client
-			->expects($this->once())
-			->method('open_url')
+		$mock_web_client = $this->mock()
+			->whenCalled('open_url')
 			->with('http://86.64.58.38/formation/VubisSmartHttpApi.csp?fu=BibSearch&Application=Bib&Database=1&RequestType=RecordNumber&Request=47918')
-			->will($this->returnValue(VSmartFixtures::xmlNoticeAnthologie()));
+			->answers(VSmartFixtures::xmlNoticeAnthologie());
 
 		$this->anthologie = Class_WebService_SIGB_VSmart_Service::newInstance()
 			->setServerRoot('http://86.64.58.38/formation')
@@ -473,12 +460,10 @@ class VSmartServiceBibGetAnthologieLitteratureTest extends Storm_Test_ModelTestC
 
 class VSmartServiceBibGetHarryPotterTest extends Storm_Test_ModelTestCase {
 	public function setUp() {
-		$mock_web_client = $this->getMock('Class_WebService_SimpleWebClient');
-		$mock_web_client
-			->expects($this->once())
-			->method('open_url')
+		$mock_web_client = $this->mock()
+			->whenCalled('open_url')
 			->with('http://vpn.agglo-moulins.fr/formation/VubisSmartHttpApi.csp?fu=BibSearch&Application=Bib&Database=2&RequestType=RecordNumber&Request=3066')
-			->will($this->returnValue(VSmartFixtures::xmlNoticeHarryPotter()));
+			->answers(VSmartFixtures::xmlNoticeHarryPotter());
 
 		$this->service = Class_WebService_SIGB_VSmart_Service::newInstance()
 			                                ->setServerRoot('vpn.agglo-moulins.fr/formation/')
@@ -508,8 +493,8 @@ class VSmartServiceBibGetHarryPotterTest extends Storm_Test_ModelTestCase {
 
 
 	/** @test */
-	public function nbExemplairesShouldReturnFour() {
-		$this->assertEquals(4, $this->potter->nbExemplaires());
+	public function nbExemplairesShouldReturnFive() {
+		$this->assertEquals(5, $this->potter->nbExemplaires());
 	}
 
 
@@ -615,14 +600,18 @@ class VSmartServiceBibGetHarryPotterTest extends Storm_Test_ModelTestCase {
 		$this->assertEquals('Inconnu', $this->potter->exemplaireAt(2)->getDisponibilite());
 	}
 
+
+	/** @test */
+	public function fiftItemShouldBeHoldable() {
+		$this->assertTrue($this->potter->exemplaireAt(4)->isReservable());
+	}
 }
 
 
 
 class VSmartServiceFunctionsTest extends Storm_Test_ModelTestCase {
 	public function setUp() {
-		$this->mock_web_client = $this->getMock('Class_WebService_SimpleWebClient');
-
+		$this->mock_web_client = $this->mock();
 		$this->service = Class_WebService_SIGB_VSmart_Service::getService('86.64.58.38/formation/');
 		$this->service->setWebClient($this->mock_web_client);
 	}
@@ -636,92 +625,23 @@ class VSmartServiceFunctionsTest extends Storm_Test_ModelTestCase {
 													<ErrorCode>0</ErrorCode>
 												</Header>
 											</VubisSmart>';
+
 		$this->mock_web_client
-			->expects($this->once())
-			->method('open_url')
+			->whenCalled('open_url')
 			->with('http://86.64.58.38/formation/VubisSmartHttpApi.csp?'.http_build_query($expected_params))
-			->will($this->returnValue($returnValue));
-	}
-
-
-	/** testDisabled */
-	public function evelyneReserveHarryPotterShouldAnswerOK() {
-		$this->_setupExpectationsFor(array('fu' => 'ReservationTitle',
-																			 'BorrowerId' => '04051972',
-																			 'Database' => 2,
-																			 'ReserveArea' => 'RES',
-																			 'BibRecord' => '3066',
-																			 'PickupLocation' => 'INST/LOC',
-																			 'MetaInstitution' => 'RES',
-																			 'Language' => 'fre'));
-
-		$this->assertEquals(array('statut' => true,
-															'erreur' => ''),
-												$this->service->reserverExemplaire('04051972', 
-																													 
-																													 '', 
-																													 
-																													 Class_Exemplaire::getLoader()
-																													 ->newInstanceWithId(234)
-																													 ->setIdOrigine('2/3066'), 
-																													  
-																													 'RES'));
-	}
-
-
-
-	/** testDisabled */
-	public function franckReserveAnthologieShouldAnswerOK() {
-		$this->_setupExpectationsFor(array('fu' => 'ReservationTitle',
-																			 'BorrowerId' => '30101964',
-																			 'Database' => 1,
-																			 'ReserveArea' => 'MCFC',
-																			 'BibRecord' => '47918',
-																			 'PickupLocation' => 'INST/LOC',
-																			 'MetaInstitution' => 'RES',
-																			 'Language' => 'fre'));
-
-		$this->assertEquals(array('statut' => true,
-															'erreur' => ''),
-												$this->service->reserverExemplaire('30101964', '', '1/47918', 'MCFC'));
-	}
-
-
-	/** testDisabled */
-	public function franckReserveHarryPotterShouldAnswerError() {
-		$this->_setupExpectationsFor(array('fu' => 'ReservationTitle',
-																			 'BorrowerId' => '30101964',
-																			 'Database' => 2,
-																			 'ReserveArea' => 'RES',
-																			 'BibRecord' => '3066',
-																			 'PickupLocation' => 'INST/LOC',
-																			 'MetaInstitution' => 'RES',
-																			 'Language' => 'fre'),
-
-																 '<VubisSmart>
-																		<Header>
-  																			<Function>ReservationTitle</Function>
-																				<ErrorCode>2</ErrorCode>
-																				<ErrorText>Document non-réservable</ErrorText>
-																		</Header>
-																	</VubisSmart>');
-
-		$this->assertEquals(array('statut' => false,
-															'erreur' => 'Document non-réservable'),
-												$this->service->reserverExemplaire('30101964', '', '2/3066', 'RES'));
+			->answers($returnValue);
 	}
 
 
 	/** @test */
 	public function evelyneSupprimerReservationHarryPotterShouldAnswerOK() {
-		$this->_setupExpectationsFor(array('fu' => 'ReservationCancel',
-																			 'BorrowerId' => '04051972',
-																			 'ItemId' => '1032650148',
-																			 'MetaInstitution' => 'RES',
-																			 'Language' => 'fre'));
-
-		$this->assertEquals(array('statut' => true,
-															'erreur' => ''),
+		$this->_setupExpectationsFor(['fu' => 'ReservationCancel',
+																	'BorrowerId' => '04051972',
+																	'ItemId' => '1032650148',
+																	'MetaInstitution' => 'RES',
+																	'Language' => 'fre']);
+
+		$this->assertEquals(['statut' => true, 'erreur' => ''],
 												$this->service->supprimerReservation(
 																Class_Users::getLoader()->newInstance()
 																	->setLogin('04051972')
@@ -732,14 +652,13 @@ class VSmartServiceFunctionsTest extends Storm_Test_ModelTestCase {
 
 	/** @test */
 	public function evelyneProlongerPretHarryPotterShouldAnswerOK() {
-		$this->_setupExpectationsFor(array('fu' => 'Renewal',
-																			 'BorrowerId' => '04051972',
-																			 'ItemId' => '1032650148',
-																			 'MetaInstitution' => 'RES',
-																			 'Language' => 'fre'));
-
-		$this->assertEquals(array('statut' => true,
-															'erreur' => ''),
+		$this->_setupExpectationsFor(['fu' => 'Renewal',
+																	'BorrowerId' => '04051972',
+																	'ItemId' => '1032650148',
+																	'MetaInstitution' => 'RES',
+																	'Language' => 'fre']);
+
+		$this->assertEquals(['statut' => true, 'erreur' => ''],
 												$this->service->prolongerPret(
 																Class_Users::getLoader()->newInstance()
 																	->setLogin('04051972')
@@ -750,11 +669,11 @@ class VSmartServiceFunctionsTest extends Storm_Test_ModelTestCase {
 
 	/** @test */
 	public function getExemplaireFromNoticeShouldReturnInvalidExemplaire() {
-		$this->_setupExpectationsFor(array('fu' => 'BibSearch',
-																			 'Application' => 'Bib',
-																			 'Database' => '2',
-																			 'RequestType' => 'RecordNumber',
-																			 'Request' => '234'));
+		$this->_setupExpectationsFor(['fu' => 'BibSearch',
+																	'Application' => 'Bib',
+																	'Database' => '2',
+																	'RequestType' => 'RecordNumber',
+																	'Request' => '234']);
 
 		$this->assertFalse($this->service->getExemplaire('2/234', '987')->isValid());
 	}