diff --git a/VERSIONS b/VERSIONS
index 0b380c4a4dc4453bc8bb9b194b725c721dcc8994..f96cadc70d11783f2764f709af537446bada439e 100644
--- a/VERSIONS
+++ b/VERSIONS
@@ -1,9 +1,8 @@
+
 16/02/2016 - v7.5.10
 
  - ticket #37996 : Correction des liens Premier Chapitre
 
-
-
 15/02/2016 - v7.5.9
 
  - ticket #37288 : Correction de la localisation des exemplaires
diff --git a/VERSIONS_WIP/32668 b/VERSIONS_WIP/32668
new file mode 100644
index 0000000000000000000000000000000000000000..ce0e59b44903949b495e6ef4d03c7305914abf59
--- /dev/null
+++ b/VERSIONS_WIP/32668
@@ -0,0 +1 @@
+ - ticket #32668 : bibliothèque - sandbox gladys (hackfest)
\ No newline at end of file
diff --git a/application/modules/opac/controllers/BibController.php b/application/modules/opac/controllers/BibController.php
index b444b8d60f11ec268a1b0dc34b57489aa55d5229..4496366df18c89f940e340bb98c07a673b785a4e 100644
--- a/application/modules/opac/controllers/BibController.php
+++ b/application/modules/opac/controllers/BibController.php
@@ -194,26 +194,45 @@ class BibController extends ZendAfi_Controller_Action {
 
   function bibviewAction() {
     $id_bib = (int)$this->_request->getParam('id');
-    if(!$id_bib || $id_bib==0) {
+
+    if (!$id_bib || $id_bib == 0) {
+      $this->_redirect('opac/bib/index');
+      return;
+    }
+
+    if (!($bib = Class_Bib::getLoader()->find($id_bib))) {
       $this->_redirect('opac/bib/index');
       return;
     }
 
-    $bib = Class_Bib::getLoader()->find($id_bib);
     $zone = $bib->getZone();
+    $this->view->url_retour = ($zone)
+      ? $this->view->url(['action' => 'zoneview', 'id' => $zone->getId()])
+      : $this->_request->getServer('HTTP_REFERER');
 
-    $this->view->url_retour = $this->view->url(array('action' => 'zoneview',
-                                                     'id' => $zone->getId()));
     if (3 == count($specs = explode(' ', $this->_getParam('retour')))) {
-      $this->view->url_retour = $this->view->url(array('controller' => $specs[0],
-                                                       'action' => $specs[1],
-                                                       'id' => $specs[2]));
+      $this->view->url_retour = $this->view->url(['controller' => $specs[0],
+                                                  'action' => $specs[1],
+                                                  'id' => $specs[2]]);
     }
 
     $this->view->bib = $bib;
-    $this->view->zone_name = $zone->getLibelle();
     $this->view->id_bib = $bib->getId();
-    $this->view->id_zone = $zone->getId();
+
+    $this->view->zone_name = ($zone) ? $zone->getLibelle() : '';
+    $this->view->id_zone = ($zone) ? $zone->getId() : 0;
+
+    $this->view->form =
+      ZendAfi_Form::newWithOptions([])
+      ->setAttribs(['action' => $this->view->url(['controller' => 'recherche',
+                                                  'action' => 'simple',
+                                                  'geo_bib' => $bib->getId()]),
+                    'id' => 'recherche',
+                    'class' => 'bibview_find'])
+
+      ->addElement('text', 'expressionRecherche', ['id' => 'expressionRecherche'])
+
+      ->addElement('submit', 'Rechercher', ['class' => 'submit']);
   }
 
 
diff --git a/application/modules/opac/views/scripts/bib/bibview.phtml b/application/modules/opac/views/scripts/bib/bibview.phtml
index 8f8fb48ee40e1077efbc2584caf2f182ebd8db07..90abed64513060934d62f6e38a3a37467441b8f9 100644
--- a/application/modules/opac/views/scripts/bib/bibview.phtml
+++ b/application/modules/opac/views/scripts/bib/bibview.phtml
@@ -1,137 +1,21 @@
 <?php
 $this->openBoite($this->_("Rechercher un livre, un disque, une vidéo"));
 
-if(!$_SESSION["selection_bib"]["nb_notices"]) print($this->_("Le catalogue de cette bibliothèque n'est pas encore intégré au portail"));
-else
-{
-?>
-
-
-<form id="recherche" style="text-align: left;" name="recherche" method="post" action="<?php echo $this->url(['controller'=>'recherche',
-                                                                                                             'action'=>'simple',
-                                                                                                             'geo_bib'=>$this->id_bib]); ?>">
-  <input type="field" style="width: 250px;" value="" name="expressionRecherche" id="expressionRecherche" />
-  <input class="submit" type="submit" value="" name="button"/>
-  <?php echo $this->_('La bibliothèque contient %s notices.', $_SESSION["selection_bib"]["nb_notices"]) ?>
-  <br/>
-  <?php echo $this->_('Dans cette bibliothèque.') ?>
-</form>
-
-<?php
+if (!$_SESSION["selection_bib"]["nb_notices"])
+  print($this->_("Le catalogue de cette bibliothèque n'est pas encore intégré au portail"));
+else {
+  echo $this->renderForm($this->form);
+
+  echo $this->tag('p',
+                  $this->_('La bibliothèque contient %s notices.',
+                           $_SESSION["selection_bib"]["nb_notices"]) .
+                           '<br/>' .
+                           $this->_('Dans cette bibliothèque.'));
 }
-$this->closeBoite();
-?>
-
-<table class="bibview" width="635px" border="0" cellpadding="0" cellspacing="0">
-  <tr>
-    <td valign="top">
-      <table width="460" border="0" cellpadding="3" cellspacing="1">
-        <tr>
-          <td colspan="2"><h1><?php echo $this->_('Fiche de la bibliothèque :') ?><br /></h1></td>
-        </tr>
-        <tr>
-          <td width="120" style="text-align:right;padding-right:5px;" valign="top"><?php echo $this->_('Nom :') ?></td>
-          <td width="346"><h2><?php echo $this->bib->LIBELLE ;?></h2></td>
-       </tr>
-
-<?php
-if ( strlen($this->bib->ADRESSE) > 0 || strlen($this->bib->CP) > 0 || strlen($this->bib->VILLE) > 0) echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Adresse : ') ?></td>
-      <td valign="top"><h2>
-<?php if (strlen($this->bib->ADRESSE) > 0) echo $this->bib->ADRESSE .'<br />' . $this->bib->CP .'&nbsp;'. $this->bib->VILLE ;
-else echo $this->bib->CP .'&nbsp;'. $this->bib->VILLE ;?>
-      </h2></td>
-      </tr>
-<?php if (strlen($this->bib->TELEPHONE) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Tel. :') ?> </td>
-      <td><h2><?php echo $this->bib->TELEPHONE ;?></h2></td>
-      </tr>
-<?php if (strlen($this->bib->MAIL) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Mail : ') ?></td>
-      <td><a href="mailto:<?php echo $this->bib->MAIL ;?>"><?php echo $this->_('Mail') ?></a></td>
-      </tr>
-<?php if (strlen($this->bib->URL_WEB) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Site internet :') ?> </td>
-      <td><a href="<?php echo $this->bib->URL_WEB ;?>" target="_blank"><?php echo $this->_('Site') ?></a></td>
-      </tr>
-<?php if (strlen($this->bib->LIEN_CARTO) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Lien cartographique :') ?> </td>
-      <td><a href="<?php echo $this->bib->LIEN_CARTO ;?>" target="_blank"><?php echo $this->_('Carte') ?></a></td>
-      </tr>
-<?php if (strlen($this->bib->HORAIRE) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Horaires :') ?> </td>
-      <td><h2><?php $horaire = str_replace('%0D%0A','BR',$this->bib->HORAIRE);
-      echo  str_replace ('BR','<br />',urldecode($horaire));?></h2></td>
-      </tr>
-<?php if (strlen($this->bib->INSCRIPTION) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Conditions inscription :') ?></td>
-      <td><h2><?php $inscr = str_replace('%0D%0A','BR',$this->bib->INSCRIPTION);
-      echo str_replace ('BR','<br />',urldecode($inscr)) ;?></h2></td>
-      </tr>
-<?php if (strlen($this->bib->PRET) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Prêts et réservations :') ?> </td>
-      <td><h2><?php $pret = str_replace('%0D%0A','BR',$this->bib->PRET);
-      echo str_replace ('BR','<br />',urldecode($pret));?></h2></td>
-      </tr>
-<?php if (strlen($this->bib->ANNEXE) > 0)echo ('<tr>');
-else echo ('<tr style="display:none;">'); ?>
-      <td style="text-align:right;padding-right:5px;width:117px;" valign="top"><?php echo $this->_('Annexe :') ?> </td>
-      <td><h2><?php $annexe = str_replace('%0D%0A','BR',$this->bib->ANNEXE) ;
-      echo str_replace ('BR','<br />',urldecode($annexe));?></h2></td>
-      </tr>
-    </td>
-    </tr>
-  </table>
-</td>
-    <td valign="top">
-      <table border="0" cellspacing="0" cellpadding="0" >
-          <tr>
-            <td align="right"></td>
-          </tr>
-          <tr>
-            <td>
-              <br /><center><div align="center">
-              <?php
-                if (trim($this->bib->PHOTO) !="") $img_bib = '<img src="'.BASE_URL.'/bib/photobib?id_bib='.$this->bib->ID_SITE.'" border="0" width="180" height="140"/>';
-                else $img_bib = '';
-                 print($img_bib);
-if(trim($this->bib->GOOGLE_MAP) !="") print('<br /> <a href="'.$this->url(['module'=>'opac',
-                                                                           'controller'=>'bib',
-                                                                           'action'=>'mapview',
-                                                                           'id_bib'=>$this->bib->ID_SITE]).'">'.$this->_('Voir le plan').'</a>');
-                 ?>
-              </div> </center>
-            </td>
-          </tr>
-        </table>
-    </td>
-  </tr>
-  <tr>
-    <td colspan="20" style="background:transparent url(<?php echo URL_IMG; ?>box/menu/separ.gif) repeat-x scroll center bottom">&nbsp;</td>
-  </tr>
-  <tr>
-    <td style="text-align:left"><a href="<?php echo $this->url_retour ?>"><?php echo $this->_('Retour') ?></a></td>
-    <td style="text-align:right"><a href="#Top">Haut</a></td>
-  </tr>
- </table>
-
-<?php
 
+$this->closeBoite();
 
-foreach(Class_CustomField_Model::getModel('Bib')->find($this->bib->getId())->getFieldValues() as $value) {
-  echo $value->getLabel() . ': ' . $value->getValue() . '<br>';
-}
+echo $this->bibView($this->bib, $this->url_retour);
 
+echo $this->newsBibHelper($this->bib->ID_SITE);
 ?>
-
-
-
-<?php echo $this->newsBibHelper($this->bib->ID_SITE);?>
diff --git a/cosmogramme/sql/patch/patch_287.sql b/cosmogramme/sql/patch/patch_287.sql
new file mode 100644
index 0000000000000000000000000000000000000000..d9a88ffb45e33f2add219e3ee5cc4fa63d90da6a
--- /dev/null
+++ b/cosmogramme/sql/patch/patch_287.sql
@@ -0,0 +1,7 @@
+<?php
+$adapter = Zend_Db_Table::getDefaultAdapter();
+
+try {
+  $adapter->query('alter table custom_field_values add index (value(50));');
+} catch(Exception $e) {}
+?>
diff --git a/library/Class/Article.php b/library/Class/Article.php
index d887a4a1a722b38c2f2236282bc3c6abbc2bfdcd..0c84579bd51f52d5c1980e07cbe9fb7523cfda0e 100644
--- a/library/Class/Article.php
+++ b/library/Class/Article.php
@@ -270,6 +270,7 @@ class ArticleLoader extends Storm_Model_Loader {
     return $this;
   }
 
+
   protected function _byCustomFields($custom_fields) {
     foreach ($custom_fields as $id => $value) {
       $this->_select
@@ -277,8 +278,9 @@ class ArticleLoader extends Storm_Model_Loader {
           [ "cfv$id" => 'custom_field_values' ],
           "cms_article.ID_ARTICLE = cfv$id.model_id AND cfv$id.custom_field_id = $id",
           []
-        )
-        ->where("cfv$id.value = ?", $value);
+        );
+//      $this->_select
+//        ->where(" cfv$id.value = ? ", $value);
     }
 
     return $this;
@@ -348,7 +350,7 @@ class ArticleLoader extends Storm_Model_Loader {
       ->_publishedNow()
       ->_byIdBib($this->_id_bib)
       ->_byIdLieu($this->_id_lieu)
-      ->_byCustomFields($this->_custom_fields)
+//      ->_byCustomFields($this->_custom_fields)
       ->_whereSelectionIn($this->_id_articles, $this->_id_categories)
       ->_whereEventDateIn($this->_event_date)
       ->_whereEventStartAfter($this->_event_start_after)
@@ -359,7 +361,11 @@ class ArticleLoader extends Storm_Model_Loader {
       ->_getSelect();
 
 
-    $articles = $this->_sortArticles($this->findAll($select));
+    $articles = $this->_sortArticles(
+                  $this->_filterByCustomFields(
+                    Class_Article::getLoader()->findAll($select),
+                    $this->_custom_fields));
+
     if (
       ($this->_sort_order == 'Selection')
       or !$this->_nb_aff
@@ -370,6 +376,32 @@ class ArticleLoader extends Storm_Model_Loader {
   }
 
 
+  protected function _filterByCustomFields($articles, $custom_fields) {
+
+    if (!$custom_fields)
+      return $articles;
+
+    $cfs = [];
+    foreach($custom_fields as $id => $value) {
+      if (!$cf=Class_CustomField::find($id))
+        continue;
+      $cfs[$cf->getLabel()] = $value;
+    }
+
+    return array_filter($articles,
+                        function ($article) use ($cfs)
+                        {
+
+                          foreach($cfs as $name => $value) {
+                            if (!$article->findCustomFieldValueMatching($name,$value))
+                              return false;
+                          }
+                          return true;
+                        }
+                        );
+  }
+
+
   /**
    * @param array $articles
    * @return array
@@ -554,6 +586,14 @@ class Class_Article extends Storm_Model_Abstract {
 																													'referenced_in' => 'id_notice']));
 	}
 
+  public function findCustomFieldValueMatching($name,$match) {
+    $value = $this->getCustomField($name);
+    if (is_array($value))
+      return in_array($match,$value);
+    return in_array($match, explode(';',$value));
+
+  }
+
 
   /**
    * Ne retourne que les traductions des articles donnés
diff --git a/library/Class/Bib.php b/library/Class/Bib.php
index e65bc1dda40b7d5ad4a19e7b2af5686e7fc38c97..1bb3a36861d028900c51d6f7d230d3491ca512a5 100644
--- a/library/Class/Bib.php
+++ b/library/Class/Bib.php
@@ -158,6 +158,7 @@ class BibLoader extends Storm_Model_Loader {
 class Class_Bib extends Storm_Model_Abstract {
   use Trait_PermissionTargetable;
   use Trait_UploadFile;
+  use Trait_CustomFields;
   const V_INVISIBLE = 0;
   const V_NODATA = 1;
   const V_DATA = 2;
@@ -242,8 +243,15 @@ class Class_Bib extends Storm_Model_Abstract {
                                           'redmine_login' => '',
                                           'redmine_password' => '',
                                           'redmine_api_key' => '',
+                                          'cp' => '',
+                                          'lien_carto' => '',
+                                          'horaire' => '',
+                                          'inscription' => '',
+                                          'pret' => '',
+                                          'annexe' => '',
                                           'closed_on_holidays' => true];
 
+
   protected $_translate;
   protected $_fixed_id = true;
 
diff --git a/library/Class/Catalogue.php b/library/Class/Catalogue.php
index 954c5307ef3a6d621a32cede1a84c451d8faa06b..dd244d1e225165cf9b82c767b6b7e1cfe0f38db6 100644
--- a/library/Class/Catalogue.php
+++ b/library/Class/Catalogue.php
@@ -474,7 +474,8 @@ class CatalogueLoader extends Storm_Model_Loader {
   public function getNoticesFromCacheByPreferences($preferences) {
     return (new Storm_Cache())
       ->memoize([$preferences, __CLASS__, __FUNCTION__],
-                function() use ($preferences) { return Class_Catalogue::getLoader()->fetchAllNoticesByPreferences($preferences);});
+                function() use ($preferences) {
+                                                 return Class_Catalogue::getLoader()->fetchAllNoticesByPreferences($preferences);});
   }
 
 
diff --git a/library/Class/CustomField.php b/library/Class/CustomField.php
index b78f29c634ab4f5250f49db2e0579bc936c4b687..212f10d246b47ec2c23ef595cb59594ec4651e81 100644
--- a/library/Class/CustomField.php
+++ b/library/Class/CustomField.php
@@ -39,6 +39,15 @@ class CustomFieldsLoader extends Storm_Model_Loader {
     foreach($fields as $priority => $field)
       $field->setPriority($priority + 1)->save();
   }
+
+
+  public function findTypeForCustomFieldId($id) {
+    if ($cf = Class_CustomField::find($id))
+      return $cf->getMeta()->getFieldType();
+    return '';
+  }
+
+
 }
 
 
diff --git a/library/Class/CustomField/Meta.php b/library/Class/CustomField/Meta.php
index bd9c3817b138270383b7a3a97ffbffb811378db4..21e23f79a57b279822f51810f403b576cb9612bc 100644
--- a/library/Class/CustomField/Meta.php
+++ b/library/Class/CustomField/Meta.php
@@ -92,7 +92,7 @@ class Class_CustomField_Meta extends Storm_Model_Abstract {
   public function serialize($value) {
     if ($this->getFieldType() == self::MULTI_CHECKBOX)
       return implode(';', $value);
-    return $value;
+    return $value;;
   }
 
 
diff --git a/library/Class/CustomField/Model.php b/library/Class/CustomField/Model.php
index 08696278d28538d4af45e264f3df9ec3c7819a18..390c16666baabcd7c0c9c3478f9c03d6272621d8 100644
--- a/library/Class/CustomField/Model.php
+++ b/library/Class/CustomField/Model.php
@@ -21,8 +21,7 @@
 
 
 class Class_CustomField_Model {
-  use Trait_TreeViewableCategorie;
-
+  use Trait_TreeViewableCategorie, Trait_Translator;
   const CLASS_PREFIX = 'Class_';
 
   protected static $_models = [];
@@ -41,6 +40,32 @@ class Class_CustomField_Model {
   }
 
 
+  public static function registerDefault() {
+    $translator = new self(0);
+
+    $array_of_models_configuration =
+      [
+       new Class_CustomField_ModelConfiguration_Article(),
+       new Class_CustomField_ModelConfiguration_Formation(),
+       new Class_CustomField_ModelConfiguration_UserGroup(),
+       new Class_CustomField_ModelConfiguration_Sitotheque(),
+       new Class_CustomField_ModelConfiguration('SessionFormation',
+                                                $translator->_('Session'),
+                                                ['module' => 'admin',
+                                                 'controller' => 'formation',
+                                                 'action' => 'session_edit']),
+       new Class_CustomField_ModelConfiguration('Bib',
+                                                $translator->_('Bibliothèque'),
+                                                ['module' => 'admin',
+                                                 'controller' => 'bib',
+                                                 'action' => 'edit'])
+      ];
+
+    static::$_models = [];
+    foreach ($array_of_models_configuration as $configuration)
+      static::register($configuration);
+  }
+
   public static function isRegistered($name) {
     return array_key_exists(static::sanitizeName($name), static::$_models);
   }
diff --git a/library/Class/CustomField/ModelValues.php b/library/Class/CustomField/ModelValues.php
index 11f7dbd55dc6282b028b89454d62f78c32bc8dc3..d748dff209c58625a47cdb419bf46984dcc4066c 100644
--- a/library/Class/CustomField/ModelValues.php
+++ b/library/Class/CustomField/ModelValues.php
@@ -26,7 +26,10 @@ class Class_CustomField_ModelValues {
     $_model,
     $_values;
 
-
+ /**
+  * @param $customized_model Storm_Model_Abstract
+  * @param $model Class_CustomField_Model
+  */
   public function __construct($customized_model, $model) {
     $this->_customized_model = $customized_model;
     $this->_model = $model;
@@ -75,6 +78,8 @@ class Class_CustomField_ModelValues {
 
 
   public function getFieldValueByName($name) {
+    if (!$this->_model)
+      return null;
     return ($id = $this->_model->getFieldIdByName($name))
       ? $this->getFieldValue($id)
       : null;
diff --git a/library/Class/CustomField/Value.php b/library/Class/CustomField/Value.php
index 8bd29280d432ca959fc4c9193097561dfda8ea03..60c5107632a81abe845e4756613e44b97bdff25a 100644
--- a/library/Class/CustomField/Value.php
+++ b/library/Class/CustomField/Value.php
@@ -66,5 +66,13 @@ class Class_CustomField_Value extends Storm_Model_Abstract {
   public function getOptionsListAsArray() {
     return $this->getField()->getOptionsListAsArray();
   }
+
+
+  public function getSelectedOptionsList() {
+    if (empty($this->getOptionsListAsArray()))
+      return [];
+
+    return explode(';', $this->getValue());
+  }
 }
 ?>
diff --git a/library/Trait/CustomFields.php b/library/Trait/CustomFields.php
index 87f8bea41c06b9890d0bc8f765d8eb9fd5ccea2b..3281bb99e92184115fc000e61940b8ee1ac0d546 100644
--- a/library/Trait/CustomFields.php
+++ b/library/Trait/CustomFields.php
@@ -45,15 +45,13 @@ trait Trait_CustomFields {
       return $this->custom_fields[$name];
     if ($this->isNew())
       return '';
-    $model_values = Class_CustomField_Model::getModel($this->getModelName())->find($this->getId());
 
-    if ($value = $model_values->getFieldValueByName($name))
+    if ($value = $this->getAllCustomFields()->getFieldValueByName($name))
       return $value->getValue();
     return '';
   }
 
 
-
   public function getAllCustomFields() {
     return Class_CustomField_Model::getModel($this->getModelName())->find($this->getId());
   }
@@ -72,7 +70,7 @@ trait Trait_CustomFields {
     if (!Class_CustomField_Model::isRegistered($this->getModelName()))
       return true;
 
-    $model_values = Class_CustomField_Model::getModel($this->getModelName())->find($this->getId());
+    $model_values = $this->getAllCustomFields();
 
     foreach ($this->custom_fields as $key => $value)
       $model_values->setFieldValueByName($key, $value);
diff --git a/library/ZendAfi/Controller/Plugin/CustomFields.php b/library/ZendAfi/Controller/Plugin/CustomFields.php
index 9ff5d94260c6e256ed84b02c0149a858303977af..649b8d4e022cda46e0cac7117f59eb68a41b20db 100644
--- a/library/ZendAfi/Controller/Plugin/CustomFields.php
+++ b/library/ZendAfi/Controller/Plugin/CustomFields.php
@@ -25,22 +25,7 @@ class ZendAfi_Controller_Plugin_CustomFields extends Zend_Controller_Plugin_Abst
 
 
   public function preDispatch(Zend_Controller_Request_Abstract $request) {
-    Class_CustomField_Model::registerAll([
-            new Class_CustomField_ModelConfiguration_Article(),
-            new Class_CustomField_ModelConfiguration_Formation(),
-            new Class_CustomField_ModelConfiguration_UserGroup(),
-            new Class_CustomField_ModelConfiguration_Sitotheque(),
-            new Class_CustomField_ModelConfiguration('SessionFormation',
-                                                     $this->_('Session'),
-                                                     ['module' => 'admin',
-                                                      'controller' => 'formation',
-                                                      'action' => 'session_edit']),
-            new Class_CustomField_ModelConfiguration('Bib',
-                                                     $this->_('Bibliothèque'),
-                                                     ['module' => 'admin',
-                                                      'controller' => 'bib',
-                                                      'action' => 'edit'])
-                                           ]);
+    Class_CustomField_Model::registerDefault();
   }
 }
 ?>
diff --git a/library/ZendAfi/Form/Admin/CustomFields/ModelValues.php b/library/ZendAfi/Form/Admin/CustomFields/ModelValues.php
index 5f8d0620a7c20b33a8ae0e2b8c3b68dbac48b554..6f20afecce63d79d5c2a86e142bfb542afc88dc5 100644
--- a/library/ZendAfi/Form/Admin/CustomFields/ModelValues.php
+++ b/library/ZendAfi/Form/Admin/CustomFields/ModelValues.php
@@ -40,6 +40,7 @@ class ZendAfi_Form_Admin_CustomFields_ModelValues extends ZendAfi_Form {
     $field_names = [];
     foreach($values as $value) {
       $field_names []= $field_name = self::FIELD_PREFIX.$value->getCustomFieldId();
+
       ZendAfi_Form_Admin_CustomFields_ModelValues_Field_Strategy::strategyForValue($this, $value)
                 ->addElement($value, $field_name, $value->getValue());
     }
@@ -127,6 +128,7 @@ class ZendAfi_Form_Admin_CustomFields_ModelValues_Field_Strategy_select extends
       $multioptions[$option]=$option;
     }
     $multioptions['']= _('*Vide*');
+
     return ['multioptions' => $multioptions];
   }
 }
@@ -140,9 +142,14 @@ class ZendAfi_Form_Admin_CustomFields_ModelValues_Field_Strategy_multiCheckbox e
     foreach($options as $option) {
       $multioptions[$option]=$option;
     }
-
     return ['multioptions' => $multioptions];
   }
+
+
+  public function unserialize($value) {
+    return explode(';', $value);
+  }
+
 }
 
 ?>
diff --git a/library/ZendAfi/Form/ContactForm.php b/library/ZendAfi/Form/ContactForm.php
index bc11a3c0d06573a7e9b8a0e0cd246c426534b6c8..0d14149bf32e4f4d7cdb912450b76906696f45d7 100644
--- a/library/ZendAfi/Form/ContactForm.php
+++ b/library/ZendAfi/Form/ContactForm.php
@@ -24,7 +24,7 @@ class ZendAfi_Form_ContactForm extends ZendAfi_Form {
 
   public function init() {
     parent::init();
-    $this->setAttrib('class', 'zend_form')
+    $this->setAttrib('class', 'zend_form form')
          ->addAllElements()
          ->addAllGroups();
   }
diff --git a/library/ZendAfi/Form/Login.php b/library/ZendAfi/Form/Login.php
index 00a80e7bb2d5f006fb3efc9e90b87f05af3e5873..94dce2dd7a5bdd3596a0d456213c5e87eea930d0 100644
--- a/library/ZendAfi/Form/Login.php
+++ b/library/ZendAfi/Form/Login.php
@@ -38,7 +38,7 @@ class ZendAfi_Form_Login extends ZendAfi_Form {
 
     $this->setMethod(Zend_Form::METHOD_POST)
          ->setAttrib('autocomplete', $this->_data['autocomplete_off'] ? 'off' : 'on')
-         ->setAttrib('class', 'login')
+         ->setAttrib('class', 'login form')
          ->addElement('text',
                       'username',
                       ['label' => $this->_data['identifiant'],
diff --git a/library/ZendAfi/View/Helper/BibView.php b/library/ZendAfi/View/Helper/BibView.php
new file mode 100644
index 0000000000000000000000000000000000000000..c04645639061339f8b51e539accc4dd19c7e593a
--- /dev/null
+++ b/library/ZendAfi/View/Helper/BibView.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_View_Helper_BibView extends ZendAfi_View_Helper_BaseHelper {
+  protected $bib;
+
+  public function bibView($bib, $back_url) {
+    $this->bib = $bib;
+
+    return
+      $this->_tag('h1', $this->_('Fiche de la bibliothèque :')) .
+      $this->_renderTable() .
+      $this->_renderPicture() .
+      $this->_renderBackLink($back_url);
+  }
+
+
+  protected function _renderTable() {
+    return '<table class="bibview">' .
+      $this->_renderName() .
+      $this->_renderAdress() .
+      $this->_renderPhone() .
+      $this->_renderMail() .
+      $this->_renderUrlWeb() .
+      $this->_renderLienCarto() .
+      $this->_renderHoraire() .
+      $this->_renderInscription() .
+      $this->_renderPret() .
+      $this->_renderAnnexe() .
+      $this->_renderCustomFields() .
+      '</table>';
+  }
+
+
+  protected function _renderBackLink($back_url) {
+    return $this->_tag('div', $this->view->tagAnchor($back_url, $this->_('Retour')),
+                       ['class' => 'back_link']);
+  }
+
+
+  protected function _renderPicture() {
+    $img = (trim($this->bib->getPhoto()) !== '') ? $this->_getImage() : '';
+    $map = (trim($this->bib->getGoogleMap()) !== '') ? $this->_getMap() : '';
+
+    return $img . $map;
+  }
+
+
+  protected function _getImage() {
+    $url = $this->view->url(['controller' => 'bib',
+                             'action' => 'photobib',
+                             'id_bib' => $this->bib->getIdSite()], null, true);
+
+    return $this->view->tagImg($url, ['class' => 'bibview_image']);
+  }
+
+
+  protected function _getMap() {
+    $url = $this->view->url(['module' => 'opac',
+                             'controller' => 'bib',
+                             'action' => 'mapview',
+                             'id_bib' => $this->bib->getIdSite()], null, true);
+
+    return $this->view->tagAnchor($url, $this->_('Voir le plan'));
+  }
+
+
+  protected function _renderName() {
+    $content = $this->_tag('td', $this->_('Nom :')) .
+      $this->_tag('td', $this->_tag('h2', $this->bib->getLibelle()), ['width' => '346']);
+
+    return $this->_tag('tr', $content);
+  }
+
+
+  protected function _renderAdress() {
+    $display = (strlen($this->bib->getAdresse()) > 0
+                || strlen($this->bib->getCp()) > 0
+                || strlen($this->bib->getVille()) > 0) ? true : false;
+
+    $content = (strlen($this->bib->getAdresse()) > 0)
+      ? $this->bib->getAdresse() . '<br />' . $this->bib->getCp() . ' ' . $this->bib->getVille()
+      : $this->bib->getCp()  . ' ' . $this->bib->getVille();
+
+    return $this->_renderInfo($content, $this->_('Adresse : '), $display);
+  }
+
+
+  protected function _renderPhone() {
+    $display = (strlen($this->bib->getTelephone()) > 0) ? true : false;
+
+    return $this->_renderInfo($this->bib->getTelephone(), $this->_('Tel : '), $display);
+  }
+
+
+  protected function _renderMail() {
+    $display = (strlen($this->bib->getMail()) > 0) ? true : false;
+    $content = $this->view->tagAnchor('mailto:' . $this->bib->getMail(), $this->bib->getMail());
+
+    return $this->_renderInfo($content, $this->_('Mail : '), $display);
+  }
+
+
+  protected function _renderUrlWeb() {
+    $display = (strlen($this->bib->getUrlWeb()) > 0) ? true : false;
+    $content = $this->view->tagAnchor($this->bib->getUrlWeb(),
+                                      $this->_('Site'),
+                                      ['target' => '_blank']);
+
+    return $this->_renderInfo($content, $this->_('Site internet : '), $display);
+  }
+
+
+  protected function _renderLienCarto() {
+    $display = (strlen($this->bib->getLienCarto()) > 0) ? true : false;
+    $content = $this->view->tagAnchor($this->bib->getLienCarto(),
+                                      $this->_('Carte'),
+                                      ['target' => '_blank']);
+
+    return $this->_renderInfo($content, $this->_('Lien cartographique : '), $display);
+  }
+
+
+  protected function _renderHoraire() {
+    $display = (strlen($this->bib->getHoraire()) > 0) ? true : false;
+
+    return $this->_renderInfo($this->_escapeInfo($this->bib->getHoraire()),
+                              $this->_('Horaires : '), $display);
+  }
+
+
+  protected function _renderInscription() {
+    $display = (strlen($this->bib->getInscription()) > 0) ? true : false;
+
+    return $this->_renderInfo($this->_escapeInfo($this->bib->getInscription()),
+                              $this->_('Conditions inscription : '), $display);
+  }
+
+
+  protected function _renderPret() {
+    $display = (strlen($this->bib->getPret()) > 0) ? true : false;
+
+    return $this->_renderInfo($this->_escapeInfo($this->bib->getPret()),
+                              $this->_('Prêts et réservations :'), $display);
+  }
+
+
+  protected function _renderAnnexe() {
+    $display = (strlen($this->bib->getAnnexe()) > 0) ? true : false;
+
+    return $this->_renderInfo($this->_escapeInfo($this->bib->getAnnexe()),
+                              $this->_('Annexe : '), $display);
+  }
+
+
+  protected function _renderCustomFields() {
+    foreach($this->bib->getAllCustomFields()->getFieldValues() as $field) {
+      if ($field->getValue() === '')
+        continue;
+
+      $options = $field->getSelectedOptionsList();
+      if (empty($options))
+        return $this->_renderInfo($field->getValue(),
+                                  $field->getLabel() . ' : ');
+
+      return $this->_renderInfo(implode('<br>', $options),
+                                $field->getLabel() . ' : ');
+    }
+  }
+
+
+  protected function _escapeInfo($info) {
+    return str_replace('BR', '<br />', urldecode(str_replace('%0D%0A','BR', $info)));
+  }
+
+
+  protected function _renderInfo($value, $label, $display = true) {
+    $content = $this->_tag('td', $label) .
+      $this->_tag('td', $this->_tag('h2', $value));
+
+    return $this->_tag('tr',
+                       $content,
+                       ($display) ? [] : ['style' => 'display:none;']);
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Calendar/RenderFilters.php b/library/ZendAfi/View/Helper/Calendar/RenderFilters.php
index f62ef8f630d1104f341439918c05350a86b17baf..b3b67727ca5b7bee7632b8d05d2ad8c4fc1c49b2 100644
--- a/library/ZendAfi/View/Helper/Calendar/RenderFilters.php
+++ b/library/ZendAfi/View/Helper/Calendar/RenderFilters.php
@@ -200,7 +200,14 @@ class ZendAfi_View_Helper_Calendar_FilterElementsCustomField extends ZendAfi_Vie
 
     $elements = [];
     foreach ($values as $value) {
-      $elements[ $value->getValue() ] = $value->getValue();
+      if ($value->getFieldType()!=Class_CustomField_Meta::MULTI_CHECKBOX) {
+        $elements[ $value->getValue() ] = $value->getValue();
+        continue;
+      }
+      foreach (explode(';',$value->getValue()) as $arrvalue) {
+        $elements[$arrvalue] = $arrvalue;
+      }
+
     }
 
     return $elements;
diff --git a/library/ZendAfi/View/Helper/RenderForm.php b/library/ZendAfi/View/Helper/RenderForm.php
index 999e83afa077bb557c741f6c163fe74624c3f638..2bb72af6417e5685acfa131aaa3e2b5ff272ce1c 100644
--- a/library/ZendAfi/View/Helper/RenderForm.php
+++ b/library/ZendAfi/View/Helper/RenderForm.php
@@ -27,7 +27,10 @@ class ZendAfi_View_Helper_RenderForm extends ZendAfi_View_Helper_BaseHelper {
     if (!$form)
       return;
 
-    $form->setAttrib('class', trim($form->getAttrib('class').' form'));
+    if (($class = $form->getAttrib('class')) === null)
+        $class = 'form';
+
+    $form->setAttrib('class', trim($class));
 
     // compatibilité avec les tables admin standard
     $this->setupTableDecoratorsForForm($form);
diff --git a/library/startup.php b/library/startup.php
index bddb56e35f7e54f93838e835ce859960491819f7..091a7ac0adac3e98eb95ce009e4d6ff5efb016be 100644
--- a/library/startup.php
+++ b/library/startup.php
@@ -112,8 +112,8 @@ function setupConstants() {
   defineConstant('PATH_ADMIN_SUPPORTS', ROOT_PATH . 'public/admin/images/supports/');
 
   defineConstant('PATH_FONTS', ROOT_PATH . 'public/opac/fonts/');
-  defineConstant('URL_CAPTCHA', BASE_URL . '/public/captcha/');
-  defineConstant('PATH_CAPTCHA', ROOT_PATH . 'public/captcha/');
+  defineConstant('URL_CAPTCHA', BASE_URL . '/temp/');
+  defineConstant('PATH_CAPTCHA', PATH_TEMP);
   defineConstant('CACHE_LIFETIME', 3600);
   defineConstant('MEMCACHED_ENABLE', false);
   defineConstant('MEMCACHED_HOST', 'localhost');
diff --git a/public/opac/css/global.css b/public/opac/css/global.css
index 35e4ae22dd71ae8ac657e011258180005a405f18..b08a71ed0e285d9e9ad262a317786bc33da50542 100644
--- a/public/opac/css/global.css
+++ b/public/opac/css/global.css
@@ -837,7 +837,40 @@ li.notice_liste {
     white-space:nowrap;
 }
 
+table.bibview {
+    width: 460px;
+    border: 0;
+    cellpadding: 0;
+    cellspacing: 0;
+    float: left;
+    margin: 20px;
+}
+
+
+table.bibview td:first-child {
+    text-align: right;
+    padding-right: 5px;
+    width: 125px;
+    vertical-align: text-top;
+}
 
+.back_link {
+    clear: both;
+}
+
+.bibview_image {
+    border: 0;
+    width: 180px;
+    height: 140px;
+}
+
+.bibview_find {
+    text-align: left;
+}
+
+.bibview_find input[type="text"] {
+    width: 250px;
+}
 
 /** selecteur de langue */
 .country_flag {
diff --git a/public/opac/skins/modele/css/global.css b/public/opac/skins/modele/css/global.css
index de3818f476dc307d9e4c05a167811874da6b2082..6f7329bbbe25a0af1d990484efcb70683c7b173f 100644
--- a/public/opac/skins/modele/css/global.css
+++ b/public/opac/skins/modele/css/global.css
@@ -169,6 +169,7 @@ a:hover {color:#D44100;}
 .form td.saisie{text-align:left;}
 .submit {background:transparent url(../images/bouton/btn_ok.gif) no-repeat scroll 0 0;border:0 none;cursor:pointer;height:18px;width:18px;}
 .panier_index .submit {font-size: 0px;}
+.bibview_find .submit {font-size: 0px;}
 /* Tableau de liste */
 .listeTitre{border-bottom:1px solid #CACFD5;border-top:1px solid #CACFD5;color:#666666;font-weight:bold;}
 .listePaire{background-color:#F4F4EF;}
diff --git a/public/opac/skins/original/css/global.css b/public/opac/skins/original/css/global.css
index 62984b81b48242e5f53457c62c2075184e4e63fe..cd24db1dcfcb0e86c418f3658d00fc1b40693068 100644
--- a/public/opac/skins/original/css/global.css
+++ b/public/opac/skins/original/css/global.css
@@ -191,6 +191,7 @@ a:visited{color:#0058A5; text-decoration:none;}
 .form td.saisie{text-align:left;font-size:8pt}
 .submit {background:transparent url(../images/bouton/btn_ok.gif) no-repeat scroll 0 0;border:0 none;cursor:pointer;height:18px;width:18px;}
 .panier_index .submit {font-size: 0px;}
+.bibview_find .submit {font-size: 0px;}
 /* Tableau de liste */
 .listeTitre{border-bottom:1px solid #CACFD5;border-top:1px solid #CACFD5;color:#666666;font-weight:bold;}
 .listePaire{background-color:#F4F4EF;}
diff --git a/tests/application/modules/admin/controllers/BibControllerTest.php b/tests/application/modules/admin/controllers/BibControllerTest.php
index 0f408e73b4f373df465c5009a47770a78bd980bc..9a895241ed444774ae4eef22f2a785ae8368efe9 100644
--- a/tests/application/modules/admin/controllers/BibControllerTest.php
+++ b/tests/application/modules/admin/controllers/BibControllerTest.php
@@ -25,6 +25,7 @@ abstract class BibControllerTestCase extends AbstractControllerTestCase {
 
   public function setUp() {
     parent::setUp();
+    Class_CustomField_Model::registerDefault();
 
     $this->fixture('Class_CosmoVar', ['id' => 'types_docs', 'liste' => '']);
 
@@ -233,10 +234,21 @@ class BibControllerWithAdminBibEditAnnecyTest extends BibControllerWithAdminBibT
   public function setUp() {
     parent::setUp();
     RessourcesNumeriquesFixtures::activateDilicom();
-
     $this->fixture('Class_Zone',
                    ['id' => 1,
-                    'libelle' => 'Territoire']);
+                    'libelle' => 'Zone 1']);
+
+    $this->custom_field = $this->fixture('Class_CustomField',
+                                          ['id' => 7,
+                                           'label' => 'Options',
+                                           'options_list' => 'Wifi;Projection;Restauration',
+                                           'priority' => 3,
+                                           'field_type' => Class_CustomField_Meta::MULTI_CHECKBOX,
+                                           'model' => 'Bib']);
+
+    $this->bib_annecy->setCustomField('Options', ['Wifi','Restauration']);
+    $this->bib_annecy->saveWithCustomFields();
+
 
     $this->dispatch('admin/bib/edit/id/2');
   }
@@ -293,8 +305,26 @@ class BibControllerWithAdminBibEditAnnecyTest extends BibControllerWithAdminBibT
 
 
   /** @test */
-  public function zoneTerritoireShouldBeDisplayed() {
-    $this->assertXPathContentContains('//select[@name="id_zone"][@id="id_zone"]//option[@value="1"]','Territoire',$this->_response->getBody());
+  public function customFieldWifiShouldBeChecked() {
+    $this->assertXPath("//input[@value='Wifi'][@checked]", $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function customFieldRestaurationShouldBeChecked() {
+    $this->assertXPath("//input[@value='Restauration'][@checked]", $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function customFieldProjectionShouldNotBeChecked() {
+    $this->assertNotXPath("//input[@value='Projection'][@checked]", $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function zoneZone1ShouldBeDisplayed() {
+    $this->assertXPathContentContains('//select[@name="id_zone"][@id="id_zone"]//option[@value="1"]','Zone 1',$this->_response->getBody());
   }
 
 
@@ -486,10 +516,14 @@ class BibControllerWithAdminBibEditAnnecyPostWithVisibiliteZeroAndSomeItemsTest
                          'tel' => '04 56 56 56 56',
                          'gln' => '9876',
                          'visibilite' => '0',
+                         'Options' => 'Wifi;Restauration',
                          'id_bib' => 2]);
   }
 
 
+
+
+
   /** @test */
   public function intBibShouldNotHaveBeenDeleted() {
     $this->assertNotNull(Class_IntBib::find(2));
diff --git a/tests/application/modules/opac/controllers/BibControllerTest.php b/tests/application/modules/opac/controllers/BibControllerTest.php
index 8d62fa98f2e0d2572123842d6258381eeb94e68e..6ed86b314ddfd8c769f13dbab086e9c030ab9d66 100644
--- a/tests/application/modules/opac/controllers/BibControllerTest.php
+++ b/tests/application/modules/opac/controllers/BibControllerTest.php
@@ -21,54 +21,67 @@
 require_once 'AbstractControllerTestCase.php';
 
 abstract class BibControllerWithZoneTestCase extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
   public function setUp() {
     parent::setUp();
+
+    Class_CustomField_Model::registerDefault();
+
     unset($_REQUEST['geo_zone']);
-    $_SESSION['selection_bib'] = ['nb_notices' => 12345,
-                                  'id_bibs' => null];
-
-    $this->bib_annecy = Class_Bib::getLoader()
-      ->newInstanceWithId(4)
-      ->setIdZone(1)
-      ->setLibelle('Annecy')
-      ->setAffZone('')
-      ->setVille('Annecy')
-      ->setUrlWeb('http://www.annecy.fr')
-      ->setMail('jp@annecy.com')
-      ->setTelephone('04 50 51 32 12')
-      ->setAdresse('1 rue Jean Jaures')
-      ->setVisibilite(Class_Bib::V_DATA);
-
-    $this->haute_savoie = Class_Zone::getLoader()
-      ->newInstanceWithId(1)
-      ->setCouleurTexte('#059')
-      ->setCouleurOmbre('#234')
-      ->setTailleFonte('14')
-      ->setImage('carte_moulins.jpg')
-      ->setBibs(array($this->bib_annecy));
-
-    $ecrivez_des_tests = Class_Article::getLoader()
-      ->newInstanceWithId(2)
-      ->setIdSite(0)
-      ->setTitre('Ecrivez des tests !')
-      ->setContenu('Ça fera le plus grand bien')
-      ->setCategorie(Class_ArticleCategorie::getLoader()
-                     ->newInstanceWithId(5)
-                     ->setLibelle('Bonnes pratiques'));
+    $_SESSION['selection_bib'] = ['nb_notices' => 12345, 'id_bibs' => null];
+
+
+    $this->bib_annecy = $this->fixture('Class_Bib', ['id' => 4,
+                                                     'id_zone' => 1,
+                                                     'libelle' => 'Annecy',
+                                                     'aff_zone' => '',
+                                                     'ville' => 'Annecy',
+                                                     'url_web' => 'http://www.annecy.fr',
+                                                     'mail' => 'jp@annecy.com',
+                                                     'telephone' => '04 50 51 32 12',
+                                                     'adresse' => '1 rue Jean Jaures',
+                                                     'visibilite' => Class_Bib::V_DATA]);
+
+    $this->bib_nozone = $this->fixture('Class_Bib', ['id' => 22,
+                                                     'id_zone' => 100,
+                                                     'libelle' => 'NoZone',
+                                                     'aff_zone' => '',
+                                                     'ville' => 'No Zone',
+                                                     'url_web' => 'http://www.nozone.fr',
+                                                     'mail' => 'mail@nozone.com',
+                                                     'telephone' => '04 50 51 32 12',
+                                                     'adresse' => '1 rue Jean Jaures',
+                                                     'visibilite' => Class_Bib::V_DATA]);
+
+
+    $this->haute_savoie = $this->fixture('Class_Zone', ['id' => 1,
+                                                        'libelle' => 'moulins',
+                                                        'couleur_texte' => '#059',
+                                                        'couleur_ombre' => '#234',
+                                                        'taille_fonte' => '14',
+                                                        'image' => 'carte_moulins.png',
+                                                        'bibs' => [$this->bib_annecy]]);
+
+    $ecrivez_des_tests = $this->fixture('Class_Article', ['id' => 2,
+                                                          'id_site' => 0,
+                                                          'titre' => 'Ecrivez des tests !',
+                                                          'contenu' => 'Ça fera le plus grand bien',
+                                                          'categorie' => $this->fixture('Class_ArticleCategorie', ['id' => 5,
+                                                                                                                   'libelle' => 'Bonnes pratiques'])]);
 
     Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Article')
       ->whenCalled('getArticlesByPreferences')
-      ->with(array('id_bib' => '4'))
-      ->answers(array($ecrivez_des_tests))
-
-      ->whenCalled('filterByLocaleAndWorkflow')
-      ->with(array($ecrivez_des_tests))
-      ->answers(array($ecrivez_des_tests));
+      ->with(['id_bib' => '4'])
+      ->answers([$ecrivez_des_tests])
 
+      ->whenCalled('getArticlesByPreferences')
+      ->with(['id_bib' => '22'])
+      ->answers([$ecrivez_des_tests])
 
-    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Zone')
-      ->whenCalled('findAll')
-      ->answers(array($this->haute_savoie));
+      ->whenCalled('filterByLocaleAndWorkflow')
+      ->with([$ecrivez_des_tests])
+      ->answers([$ecrivez_des_tests]);
   }
 }
 
@@ -126,6 +139,8 @@ class BibControllerZoneViewOneTest extends BibControllerWithZoneTestCase {
 }
 
 
+
+
 class BibControllerZoneViewOneWithHideNewsTest extends BibControllerWithZoneTestCase {
   public function setUp() {
     parent::setUp();
@@ -278,7 +293,7 @@ class BibControllerMapViewWithoutProfilTest extends BibControllerMapViewTest {
 
 
 
-class BibControllerBibViewAnnecyTest extends BibControllerWithZoneTestCase {
+abstract class BibControllerBibViewTestCase extends BibControllerWithZoneTestCase {
   protected $_mock_sql;
 
   public function setUp() {
@@ -291,11 +306,24 @@ class BibControllerBibViewAnnecyTest extends BibControllerWithZoneTestCase {
       ->whenCalled('countBy')
       ->with(['model' => $this->bib_annecy, 'role' => 'bib'])
       ->answers(20)
+
+      ->whenCalled('countBy')
+      ->with(['model' => $this->bib_nozone, 'role' => 'bib'])
+      ->answers(20)
       ->beStrict();
 
     $this->_mock_sql
       ->whenCalled('fetchOne')
       ->answers('');
+  }
+}
+
+
+
+class BibControllerBibViewAnnecyTest extends BibControllerBibViewTestCase {
+
+  public function setUp() {
+    parent::setUp();
 
     $this->dispatch('bib/bibview/id/4', true);
   }
@@ -318,11 +346,13 @@ class BibControllerBibViewAnnecyTest extends BibControllerWithZoneTestCase {
     $this->assertXPathContentContains('//h2', 'Ecrivez des tests !');
   }
 
+
   /** @test */
   function libelleCatBonnesPratiquesShouldBeVisible() {
     $this->assertXPathContentContains('//h1', 'Bonnes pratiques');
   }
 
+
   /** @test */
   public function urlRetourShouldBeZoneViewIdOne() {
     $this->assertXPathContentContains('//a[contains(@href, "/bib/zoneview/id/1")]',
@@ -331,6 +361,128 @@ class BibControllerBibViewAnnecyTest extends BibControllerWithZoneTestCase {
 }
 
 
+
+class BibControllerBackUrlTest extends BibControllerBibViewTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $_SERVER['HTTP_REFERER'] = '/link/to/referer';
+  }
+
+
+  /** @test */
+  public function backUrlShouldBeZoneView() {
+    $this->dispatch('bib/bibview/id/4', true);
+    $this->assertXPathContentContains('//div[@class="back_link"]/a[contains(@href, "zoneview/id/1")]', 'Retour');
+  }
+
+
+  /** @test */
+  public function backUrlShouldBeReferer() {
+    $this->dispatch('bib/bibview/id/22', true);
+    $this->assertXPathContentContains('//div[@class="back_link"]/a[contains(@href, "/link/to/referer")]', 'Retour');
+  }
+
+}
+
+
+
+class BibControllerTextCustomFieldsTest extends BibControllerBibViewTestCase {
+  public function setUp() {
+    parent::setUp();
+
+
+    $this->custom_field = $this->fixture('Class_CustomField',
+                                          ['id' => 5,
+                                           'priority' => 3,
+                                           'field_type' => Class_CustomField_Meta::TEXT_INPUT,
+                                           'label' => 'Lieu',
+                                           'model' => 'Bib']);
+  }
+
+
+  /** @test */
+  public function customFieldLieuShouldBeDisplayed() {
+    $this->bib_annecy->setCustomField('Lieu', 'Far Far Away');
+    $this->bib_annecy->saveWithCustomFields();
+    $this->dispatch('bib/bibview/id/4', true);
+    $this->assertXPathContentContains("//table//td", "Lieu :", $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function customFieldValueShouldBeFarFarAway() {
+    $this->bib_annecy->setCustomField('Lieu', 'Far Far Away');
+    $this->bib_annecy->saveWithCustomFields();
+    $this->dispatch('bib/bibview/id/4', true);
+    $this->assertXPathContentContains("//table//td", "Far Far Away", $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function customFieldLieuShouldNotBeDisplayed() {
+    $this->bib_annecy->setCustomField('Lieu', '');
+    $this->bib_annecy->saveWithCustomFields();
+    $this->dispatch('bib/bibview/id/4', true);
+    $this->assertNotXPathContentContains("//table//td", "Lieu :", $this->_response->getBody());
+  }
+}
+
+
+
+
+class BibControllerMultiCheckBoxCustomFieldsTest extends BibControllerBibViewTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->custom_field = $this->fixture('Class_CustomField',
+                                          ['id' => 12,
+                                           'priority' => 3,
+                                           'label' => 'Services',
+                                           'options_list' => 'Wifi;Projection;Restauration',
+                                           'field_type' => Class_CustomField_Meta::MULTI_CHECKBOX,
+                                           'model' => 'Bib']);
+
+    $this->bib_annecy->setCustomField('Services', ['Wifi', 'Restauration']);
+    $this->bib_annecy->saveWithCustomFields();
+    $this->dispatch('bib/bibview/id/4', true);
+
+  }
+
+
+  /** @test */
+  public function customFieldLieuShouldBeDisplayed() {
+    $this->assertXPathContentContains("//table//td", "Services :");
+  }
+
+
+  /** @test */
+  public function servicesShouldContainsWifi() {
+    $this->assertXPathContentContains('//table//td', 'Wifi');
+  }
+
+
+  /** @test */
+  public function servicesShouldContainsRestauration() {
+    $this->assertXPathContentContains('//table//td', 'Restauration');
+  }
+
+
+  /** @test */
+  public function servicesShouldNotContainsProjection() {
+    $this->assertNotXPathContentContains('//table//td', 'Projection');
+  }
+
+
+  /** @test */
+  public function servicesShouldNotContainsSeparator() {
+    $this->assertNotXPathContentContains('//table//td', 'Wifi;Restauration');
+  }
+}
+
+
+
 class BibControllerBibViewAnnecyWithParamRetourHistoriqueTest extends BibControllerWithZoneTestCase {
   /** @test */
   public function withUrlRetourCmsArticleViewFiveShouldBeAccepted() {
diff --git a/tests/application/modules/opac/controllers/CmsControllerCalendarActionTest.php b/tests/application/modules/opac/controllers/CmsControllerCalendarActionTest.php
index 5278437d740f4057c3d84249381277c494d63981..66ee40cda9a2499809b652c345235201a74323e0 100644
--- a/tests/application/modules/opac/controllers/CmsControllerCalendarActionTest.php
+++ b/tests/application/modules/opac/controllers/CmsControllerCalendarActionTest.php
@@ -37,7 +37,7 @@ abstract class CmsControllerCalendarActionTestCase extends AbstractControllerTes
                                    'rss_avis' => false,
                                    'id_categorie' => '12-2',
                                    'display_cat_select' => true,
-                                   'enabled_filters' => 'date;place;custom_field_2;zork',
+                                   'enabled_filters' => 'date;place;custom_field_2;custom_field_20;zork',
                                    'display_event_info' => 'none']]],
        'options' =>   []];
 
@@ -123,6 +123,125 @@ class CmsControllerCalendarActionLanguageEnTest extends CmsControllerCalendarAct
 
 
 
+class CmsControllerCalendarActionWithMultipleFiltersTest extends CmsControllerCalendarActionTestCase {
+  protected $_permaculture;
+  public function setupCustomFields() {
+    Class_CustomField_Meta::beVolatile();
+    $theme = $this->fixture('Class_CustomField',
+                            ['id' => 2,
+                             'priority' => 3,
+                             'label' => 'Theme',
+                             'field_type' => Class_CustomField_Meta::MULTI_CHECKBOX,
+                             'options_list' => 'culture;bd;logiciels libres',
+                             'model' => 'Article']);
+
+    $multi_options = $this->fixture('Class_CustomField',
+                                    ['id' => 20,
+                                     'priority' => 3,
+                                     'label' => 'Options',
+                                     'field_type' => Class_CustomField_Meta::MULTI_CHECKBOX,
+                                     'options_list' => 'wifi;jardinage;projection',
+                                     'model' => 'Article']);
+
+    $this->fixture('Class_CustomField_Value',
+                   ['id' => 59,
+                    'custom_field_id' => $theme->getId(),
+                    'model_id' => $this->_nanook2->getId(),
+                    'value' => ';logiciels libres;']);
+
+
+
+    $this->fixture('Class_CustomField_Value',
+                   ['id' => 5,
+                    'custom_field_id' => $multi_options->getId(),
+                    'model_id' => $this->_permaculture->getId(),
+                    'value' => ';jardinage;']);
+
+    $this->fixture('Class_CustomField_Value',
+                   ['id' => 2,
+                    'custom_field_id' => $theme->getId(),
+                    'model_id' => $this->_permaculture->getId(),
+                    'value' => ';culture;bd;']);
+  }
+
+
+  public function setUp() {
+    parent::setUp();
+    $this->_permaculture = $this->fixture('Class_Article',
+                   ['id' => 5,
+                    'titre' => 'Liberons la permaculture !',
+                    'contenu' => 'Venez avec vos poireaux !',
+                    'events_debut' => '2011-02-17',
+                    'events_fin' => '2011-02-22']);
+    $this->setupCustomFields();
+
+    $common_preferences = ['display_order' => 'EventDebut',
+                           'id_categorie' => '',
+                           'events_only' => true,
+                           'id_bib' => 0,
+                           'id_lieu' => '',
+                           'published' =>true,
+    ];
+
+    $time_source = new TimeSourceForTest('2014-06-06 14:14:14');
+    ZendAfi_View_Helper_CalendarContent::setTimeSource($time_source);
+    ZendAfi_View_Helper_Calendar_Months::setTimeSource($time_source);
+
+    Class_Article::getLoader()
+      ->whenCalled('getArticlesByPreferences')
+      ->with(array_merge($common_preferences, [ 'custom_fields' => [2 => 'culture', 20 => 'jardinage'], 'published' =>true,'event_date' => '2014-07']))
+      ->answers([$this->_permaculture])
+
+      ->whenCalled('getArticlesByPreferences')
+      ->with(array_merge($common_preferences, ['event_date' => '2014-07', 'custom_fields' => [2 =>'logiciels libres']]))
+      ->answers([$this->_permaculture])
+      ->whenCalled('getArticlesByPreferences')
+      ->with(array_merge($common_preferences, ['event_date' => '',
+                                               'custom_fields' => [2 => 'culture', 20 => 'jardinage'],
+                                               'event_start_after' => '2014-07',
+                                               'event_end_after' => '',
+                                               'limit' => 3]))
+
+      ->answers([])
+      ->whenCalled('getArticlesByPreferences')
+      ->with(array_merge($common_preferences, ['event_date' => '',
+                                               'custom_fields' => [2 => 'logiciels libres'],
+                                               'event_start_after' => '2014-07',
+                                               'event_end_after' => '',
+                                               'limit' => 3]))
+      ->answers([])
+      ->beStrict();
+
+
+  }
+
+
+  /** @test */
+  public function articlePermacultureShouldBeDisplayWithOptionSelected() {
+    $this->dispatch('/cms/calendar/id_profil/3/id_module/1/date/2014-07/custom_field_2/culture/custom_field_20/jardinage/render/ajax', true);
+    $this->assertXPathContentContains('//a[@class="calendar_event_title"]', 'Liberons la permaculture !', $this->_response->getBody());
+
+  }
+
+
+  /** @test */
+  public function articleNanookShouldNotBeDisplayWithOptionSelected() {
+    $this->dispatch('/cms/calendar/id_profil/3/id_module/1/date/2014-07/custom_field_2/culture/custom_field_20/jardinage/render/ajax', true);
+    $this->assertNotXPathContentContains('//a[@class="calendar_event_title"]', 'Nanook 2 en prod !', $this->_response->getBody());
+
+  }
+
+
+
+  /** @test */
+  public function articleNanookShouldBeDisplayWithLLSelected() {
+    $this->dispatch('/cms/calendar/id_profil/3/id_module/1/date/2014-07/custom_field_2/logiciels libres/render/ajax', true);
+    $this->assertNotXPathContentContains('//a[@class="calendar_event_title"]', 'Nanook 2 en prod !', $this->_response->getBody());
+
+  }
+
+}
+
 
 class CmsControllerCalendarActionWithFiltersTest extends CmsControllerCalendarActionTestCase {
   protected $_opac4;
@@ -138,12 +257,28 @@ class CmsControllerCalendarActionWithFiltersTest extends CmsControllerCalendarAc
                              'options_list' => 'sigb;opac',
                              'model' => 'Article']);
 
+    $multi_options = $this->fixture('Class_CustomField',
+                            ['id' => 20,
+                             'priority' => 3,
+                             'label' => 'Options',
+                             'field_type' => Class_CustomField_Meta::MULTI_CHECKBOX,
+                             'options_list' => 'wifi;restauration;projection',
+                             'model' => 'Article']);
+
     $this->fixture('Class_CustomField_Value',
-                   ['id' => 5,
+                   ['id' => 59,
                     'custom_field_id' => $theme->getId(),
                     'model_id' => $this->_nanook2->getId(),
                     'value' => 'sigb']);
 
+
+
+    $this->fixture('Class_CustomField_Value',
+                   ['id' => 5,
+                    'custom_field_id' => $multi_options->getId(),
+                    'model_id' => $this->_nanook2->getId(),
+                    'value' => 'wifi;restauration']);
+
     $this->fixture('Class_CustomField_Value',
                    ['id' => 2,
                     'custom_field_id' => $theme->getId(),
@@ -191,6 +326,11 @@ class CmsControllerCalendarActionWithFiltersTest extends CmsControllerCalendarAc
   }
 
 
+  /** @test */
+  public function articleOpacShouldBeDisplay() {
+    $this->assertXPathContentContains('//a[@class="calendar_event_title"]', 'OPAC 4 en prod !', $this->_response->getBody());
+  }
+
   /** @test **/
   public function calendarWithCustomFieldFiltersShouldBuildPreferencesForGetArticlesByPreferences() {
     $this->assertXPathContentContains('//a[@class="calendar_event_title"]',
@@ -224,6 +364,35 @@ class CmsControllerCalendarActionWithFiltersTest extends CmsControllerCalendarAc
   }
 
 
+  /** @test */
+  public function optionFilterHeaderShouldBeDisplayed() {
+    $this->assertXPathContentContains('//li[@class="custom_field_20"]/h2', 'Options',$this->_response->getBody());
+  }
+
+
+
+  /** @test */
+  public function optionFilterShouldContainsWifi() {
+    $this->assertXPathContentContains('//li[@class="custom_field_20"]//li//a[contains(@href, "/cms/calendar/id_module/1/custom_field_2/opac/date/2014-07/custom_field_20/wifi")]',
+                                      'wifi',$this->_response->getBody());
+  }
+
+
+
+  /** @test */
+  public function optionFilterShouldContainsRestauration() {
+    $this->assertXPathContentContains('//li[@class="custom_field_20"]//li//a[contains(@href, "/cms/calendar/id_module/1/custom_field_2/opac/date/2014-07/custom_field_20/restauration")]',
+                                      'restauration',$this->_response->getBody());
+  }
+
+
+
+  /** @test */
+  public function optionFilterShouldNotContainsProjection() {
+    $this->assertNotXPathContentContains('//li[@class="custom_field_20"]//li//a[contains(@href, "/cms/calendar/id_module/1/custom_field_2/opac/date/2014-07/custom_field_20/projection")]',
+                                      'projection',$this->_response->getBody());
+  }
+
   /** @test */
   public function monthFilterShouldHaveTitleMoisJuillet() {
     $this->assertXPathContentContains('//ul[@class="filters"]/li[@class="date"]/h2',
diff --git a/tests/library/Class/ArticleLoaderTest.php b/tests/library/Class/ArticleLoaderTest.php
index 07c4f5822830b5bb01a829ac9b1846bfa840ad22..1fdc0d5563eb94417b7ae71cbeee56f89de8b0c2 100644
--- a/tests/library/Class/ArticleLoaderTest.php
+++ b/tests/library/Class/ArticleLoaderTest.php
@@ -248,13 +248,21 @@ class ArticleLoaderGetArticlesByPreferencesTest extends ModelTestCase {
 
   /** @test */
   function withArticleAndCustomFieldValueSelectionSqlShouldFilterByCustomField() {
-    $articles = $this->getArticles(array('display_order' => 'EventDebut',
-                                         'custom_fields' => [5 => 'value1',
-                                                             12 => 'value2'],
-                                         'id_categorie' => '4',
-                                         'nb_aff' => 3));
-    $expected = sprintf("INNER JOIN `custom_field_values` AS `cfv5` ON cms_article.ID_ARTICLE = cfv5.model_id AND cfv5.custom_field_id = 5 INNER JOIN `custom_field_values` AS `cfv12` ON cms_article.ID_ARTICLE = cfv12.model_id AND cfv12.custom_field_id = 12 WHERE %s AND (cfv5.value = 'value1') AND (cfv12.value = 'value2') AND (`cms_article`.ID_CAT in (4)) ORDER BY FIELD(`cms_article`.ID_CAT, 4) ASC", self::WHERE_VISIBLE_CLAUSE);
-    $this->assertSelect($expected);
+    $this->fixture('Class_CustomField',
+                   ['id' => 5,
+                    'priority' => 3,
+                    'label' => 'Options',
+                    'field_type' => Class_CustomField_Meta::MULTI_CHECKBOX,
+                    'options_list' => 'wifi;jardinage;projection',
+                    'model' => 'Article']);
+
+    $articles = $this->getArticles(['display_order' => 'EventDebut',
+                                    'custom_fields' => [5 => 'value1',
+                                                        12 => 'value2'],
+                                    'id_categorie' => '4',
+                                    'nb_aff' => 3]);
+    $expected = sprintf("INNER JOIN `custom_field_values` AS `cfv5` ON cms_article.ID_ARTICLE = cfv5.model_id AND cfv5.custom_field_id = 5 INNER JOIN `custom_field_values` AS `cfv12` ON cms_article.ID_ARTICLE = cfv12.model_id AND cfv12.custom_field_id = 12 WHERE %s AND (`cms_article`.ID_CAT in (4)) ORDER BY FIELD(`cms_article`.ID_CAT, 4) ASC", self::WHERE_VISIBLE_CLAUSE);
+    $this->assertSelect('SELECT `cms_article`.* FROM `cms_article` WHERE ((DEBUT IS NULL) OR (DEBUT <= CURDATE())) AND ((FIN IS NULL) OR (FIN >= CURDATE())) AND (`cms_article`.ID_CAT in (4)) ORDER BY FIELD(`cms_article`.ID_CAT, 4) ASC');
   }
 
 
@@ -373,6 +381,68 @@ abstract class ArticleLoaderGroupByBibTestCase extends ModelTestCase {
 
 
 
+class ArticleLoaderWithCustomFieldsTest extends ModelTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CustomField',
+                   ['id' => 5,
+                    'priority' => 3,
+                    'label' => 'Options',
+                    'field_type' => Class_CustomField_Meta::MULTI_CHECKBOX,
+                    'options_list' => 'wifi;jardinage;projection',
+                    'model' => 'Article']);
+
+    $soiree_net = $this->fixture('Class_Article',
+                                 ['id' => 1,
+                                  'titre' => 'Soirée internet',
+                                  'contenu' => 'Ondes power',
+                                 ]);
+    $soiree_net
+      ->setCustomField('Options', ['wifi', 'projection'])
+      ->saveWithCustomFields();
+
+    $journee_potager = $this->fixture('Class_Article',
+                                      ['id' => 2,
+                                       'titre' => 'Massacre de limaces',
+                                       'contenu' => '50 façons de tuer les limaces']);
+    $journee_potager
+      ->setCustomField('Options', ['jardinage','projection'])
+      ->saveWithCustomFields();
+
+
+    $table = $this->mock();
+    $table
+      ->whenCalled('select')->with('cms_article.*')->answers($table)
+      ->whenCalled('setIntegrityCheck')->with(false)->answers($table)
+      ->whenCalled('from')->with('cms_article')->answers($table)
+      ->whenCalled('where')->answers($table)
+      ->whenCalled('join')->answers($table)
+      ->whenCalled('order')->answers($table)
+      ->whenCalled('limit')->answers($table);
+
+    Class_Article::setTable($table);
+
+    $this->onLoaderOfModel('Class_Article')
+         ->whenCalled('findAll')
+         ->answers([$soiree_net, $journee_potager]);
+  }
+
+
+  /** @test */
+  public function articlesByPrefsWithWifiShouldReturnSoireeNet() {
+    $articles = Class_Article::getArticlesByPreferences(['custom_fields' => [5 => 'wifi']]);
+
+    $this->assertEquals(['Soirée internet'],
+                        (new Storm_Model_Collection($articles))->collect('titre')->getArrayCopy());
+  }
+}
+
+
+
+
 class ArticleLoaderGroupByBibWithoutBibTest extends ArticleLoaderGroupByBibTestCase {
   /** @test */
   public function sizeOfArrayShouldBeOne() {
diff --git a/tests/library/ZendAfi/View/Helper/BibViewTest.php b/tests/library/ZendAfi/View/Helper/BibViewTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..21e7276add4311ccb0096bc5b31f595c39158ac9
--- /dev/null
+++ b/tests/library/ZendAfi/View/Helper/BibViewTest.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class BibViewTest extends ViewHelpertestCase {
+  protected
+    $_storm_default_to_volatile = true;
+
+  public function setup() {
+    parent::setup();
+
+    $this->bib_annecy = $this->fixture('Class_Bib', ['id' => 4,
+                                                     'id_zone' => 1,
+                                                     'libelle' => 'Annecy',
+                                                     'aff_zone' => '',
+                                                     'ville' => 'Annecy',
+                                                     'url_web' => 'http://www.annecy.fr',
+                                                     'mail' => 'jp@annecy.com',
+                                                     'telephone' => '04 50 51 32 12',
+                                                     'adresse' => '1 rue Jean Jaures',
+                                                     'visibilite' => Class_Bib::V_DATA]);
+
+
+    $helper = new ZendAfi_View_Helper_BibView();
+    $helper->setView(new ZendAfi_Controller_Action_Helper_View());
+
+    $this->html = $helper->bibView(Class_Bib::find(4), '/back');
+  }
+
+
+  /** @test */
+  public function adressShouldBeDisplayed() {
+    $this->assertXPathContentContains($this->html, '//tr[2]//h2', '1 rue Jean Jaures');
+    $this->assertXPathContentContains($this->html, '//tr[2]//h2', 'Annecy');
+  }
+
+
+  /** @test */
+  public function telephoneShouldBeDisplayed() {
+    $this->assertXPathContentContains($this->html, '//tr[3]//h2', '04 50 51 32 12');
+  }
+
+
+  /** @test */
+  public function mailShouldBeDisplayed() {
+    $this->assertXPathContentContains($this->html, '//tr[4]//h2/a[contains(@href, "mailto:jp@annecy.com")]', 'jp@annecy.com');
+  }
+
+
+  /** @test */
+  public function backLinkShouldBeDisplayed() {
+    $this->assertXPathContentContains($this->html, '//div/a[contains(@href, "/back")]', 'Retour');
+  }
+}
+?>
\ No newline at end of file