diff --git a/VERSIONS b/VERSIONS
index a7295e81071a327a4b5aae5e4957eb9b3eab5be3..f3ecb13e66d917b88d4452059abb8213dcf48c1f 100644
--- a/VERSIONS
+++ b/VERSIONS
@@ -1,3 +1,8 @@
+23/11/2016 - v7.7.18
+
+ - ticket #50500 : Indexation : correction d'une erreur lorsqu'un niveau thesaurus dépassait 9999 éléments
+
+
 18/11/2016 - v7.7.17
 
  - ticket #47691 : Administration : le rôle rédacteur bibliothèque peut choisir son thème admin
diff --git a/cosmogramme/php/integration/domaines.php b/cosmogramme/php/integration/domaines.php
index 86d8f781dedd7a613826f8b228030621ad5cee6b..ec2cbd6179f52576816301656611f8713be17684 100644
--- a/cosmogramme/php/integration/domaines.php
+++ b/cosmogramme/php/integration/domaines.php
@@ -1,4 +1,4 @@
-<?PHP
+<?php
 /**
  * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
  *
@@ -18,55 +18,47 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-/////////////////////////////////////////////////////////////////////////
-// INTEGRATION DES RESERVATIONS
-/////////////////////////////////////////////////////////////////////////
-require_once("classe_transaction.php");
-setVariable("traitement_phase","Indexation des domaines");
+
+setVariable('traitement_phase', 'Indexation des domaines');
+
 if ($phase==16) {
-	$log->ecrire("<h4>Indexation des domaines</h4>");
-	unset($phase_data);
-	$reprise=false;
-	$phase_data["nombre"]=0;
-	$phase_data["nb_fic"]=0;
-	$phase_data["timeStart"]=time();
-	$phase_data["pointeur"]=0;
-	$phase_data["domaine"]=0;
+  $log->ecrire('<h4>Indexation des domaines</h4>');
+  unset($phase_data);
+  $reprise = false;
+  $phase_data['nombre'] = 0;
+  $phase_data['nb_fic'] = 0;
+  $phase_data['timeStart'] = time();
+  $phase_data['pointeur'] = 0;
+  $phase_data['domaine'] = 0;
 
-	$phase=17;
+  $phase=17;
 }
 
 if ($phase==17) {
-	$position_domaine=$phase_data["domaine"];
-// Indexation des catalogues dynamiques
-	$catalogues = array_slice(Class_Catalogue::findAllCataloguesAIndexer(),$position_domaine);
+  if ($mode_cron) {
+    $position_domaine = $phase_data['domaine'];
+    $catalogues = array_slice(Class_Catalogue::findAllCataloguesAIndexer(),
+                              $position_domaine);
 
-	foreach ($catalogues as $catalogue) {
-		$page=$phase_data["pointeur"];
-		$log->ecrire("Indexation du domaine : ".$catalogue->getLibelle()."<br/>");
-    $catalogue->index($page,
-                      function(&$phase_data) use ($page)
-                      {
-                        $phase_data['pointeur'] = $page;
-                      });
+    foreach ($catalogues as $catalogue) {
+      $page = $phase_data['pointeur'];
+      $log->ecrire('Indexation du domaine : '.$catalogue->getLibelle().'<br/>');
+      $catalogue->index($page);
 
-		$position_domaine++;
-		$phase_data["domaine"]=$position_domaine;
-		$phase_data["pointeur"]=0;
-	}
+      $position_domaine++;
+      $phase_data['domaine'] = $position_domaine;
+      $phase_data['pointeur'] = 0;
+    }
 
-	if ($mode_cron) {
-		$log->ecrire('<h4>Indexation des paniers dans les domaines</h4>');
-		Class_PanierNotice::indexAll();
+    $log->ecrire('<h4>Indexation des paniers dans les domaines</h4>');
+    Class_PanierNotice::indexAll();
 
-		$log->ecrire("<h4>Indexation des articles dans les domaines</h4>");
-		Class_Article::indexAll();
-
-		$log->ecrire("<h4>Indexation des sitothèques dans les domaines</h4>");
-		Class_Sitotheque::indexAll();
-	} else {
-		$log->ecrire("<h4>Les indexations des paniers, articles et sitothèques dans les domaines ne sont traitées qu'en mode cron</h4>");
-	}
-}
+    $log->ecrire('<h4>Indexation des articles dans les domaines</h4>');
+    Class_Article::indexAll();
 
-?>
\ No newline at end of file
+    $log->ecrire('<h4>Indexation des sitothèques dans les domaines</h4>');
+    Class_Sitotheque::indexAll();
+  } else {
+    $log->ecrire('<h4>Les indexations des domaines, des paniers, articles et sitothèques dans les domaines ne sont traitées qu\'en mode cron</h4>');
+  }
+}
\ No newline at end of file
diff --git a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
index 70ceb22dd5deba2f3765e91b682891bfe1cc9ce4..7e48a68c4580289b5c14c0c3a1ac6cf3d1506152 100644
--- a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
@@ -217,8 +217,15 @@ class KohaRecordIntegrationVagabondWithThesaurusOn702DollarATest extends KohaRec
                     'code' => 'summary'
                    ]);
 
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 6,
+                    'libelle' => 'Test',
+                    'id_thesaurus' => 'TEST',
+                    'id_origine' => null,
+                    'code' => 'TEST',
+                    'rules' => '{"label":"610$a"}']);
 
-		$loader = Storm_Test_ObjectWrapper::onLoaderOfModel('Class_CodifThesaurus');
+		$loader = $this->onLoaderOfModel('Class_CodifThesaurus');
 		$loader
 			->whenCalled('findFirstBy')
 			->with(['code' => 'authors',
@@ -243,12 +250,14 @@ class KohaRecordIntegrationVagabondWithThesaurusOn702DollarATest extends KohaRec
 		$this->assertEquals('Vagabond n° 4', $this->_notice->getTitrePrincipal());
 	}
 
+
   /** @test */
   public function noSumm0002ShouldBeCreated() {
     $entry = Class_CodifThesaurus::findAllBy(['libelle' => 'd\'après l\'oeuvre d\'Eiji Yoshikawa, "Miyamoto Musashi"']);
 		$this->assertCount(1, $entry);
   }
 
+
   /** @test */
 	public function facetsShouldContainsHAUTH0001() {
 		$this->assertContains('HAUTH0001', $this->_notice->getFacetCodes());
@@ -268,6 +277,7 @@ class KohaRecordIntegrationVagabondWithThesaurusOn702DollarATest extends KohaRec
 													$this->_notice->getFacettes());
 	}
 
+
   /** @test */
 	public function entryForYoshikawaShouldBeCreated() {
 		$entry = Class_CodifThesaurus::findFirstBy(['id_thesaurus' => 'AUTH0002']);
@@ -276,6 +286,101 @@ class KohaRecordIntegrationVagabondWithThesaurusOn702DollarATest extends KohaRec
 												$entry->getLibelle());
 	}
 
+
+  /** @test */
+  public function shouldCreateThesaurusFor610_a() {
+    $this->assertNotNull(Class_CodifThesaurus::findFirstBy(['id_thesaurus' => 'TEST0001',
+                                                            'libelle' => 'Manga']));
+  }
 }
 
-?>
\ No newline at end of file
+
+
+class KohaRecordIntegrationVagabondWithTooMany610aTest extends KohaRecordIntegrationTestCase {
+	public function setUp() {
+		parent::setUp();
+
+		$this->fixture('Class_CodifThesaurus',
+									 ['id' => 1,
+										'libelle' => 'Author',
+										'id_thesaurus' => 'AUTH',
+										'id_origine' => null,
+										'code' => 'authors',
+										'rules' => '{"label":"702$a"}']);
+
+
+		$marcel = $this->fixture('Class_CodifThesaurus',
+									 ['id' => 2,
+										'libelle' => 'Marcel',
+										'id_thesaurus' => 'AUTH0001',
+										'id_origine' => 'MARCEL',
+										'code' => 'authors',
+										'rules' => null]);
+
+
+		$docu = $this->fixture('Class_CodifThesaurus',
+													 ['id' => 3,
+														'libelle' => 'Document',
+														'id_thesaurus' => 'DOCU',
+														'id_origine' => null,
+														'code' => 'document',
+														'rules' => '{"label":" 99$t "}']);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 4,
+                    'libelle' => 'Summary',
+                    'id_thesaurus' => 'SUMM',
+                    'id_origine' => null,
+                    'code' => 'summary',
+                    'rules' => '{"label":" 200$g "}']);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 5,
+                    'libelle' => 'd\'après l\'oeuvre d\'Eiji Yoshikawa, "Miyamoto Musashi"',
+                    'id_thesaurus' => 'SUMM0001',
+                    'id_origine' => 'D\'APRèS L\'OEUVRE D\'E',
+                    'code' => 'summary'
+                   ]);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 6,
+                    'libelle' => 'Test',
+                    'id_thesaurus' => 'TEST',
+                    'id_origine' => null,
+                    'code' => 'TEST',
+                    'rules' => '{"label":"610$a"}']);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id_thesaurus' => 'TEST9999',
+                    'id_origine' => 'RIME',
+                    'libelle' => 'rime',
+                    'code' => 'TEST',
+                    'id' => 10722,
+                    'libelle_facette' => 'rime',
+                    'rules' => null]);
+
+		$loader = $this->onLoaderOfModel('Class_CodifThesaurus');
+		$loader
+			->whenCalled('findFirstBy')
+			->with(['code' => 'authors',
+							'where' => 'id_thesaurus like "AUTH%"',
+							'order' => 'id_thesaurus desc'])
+			->answers($marcel)
+
+			->whenCalled('findFirstBy')
+			->with(['code' => 'document',
+							'where' => 'id_thesaurus like "DOCU%"',
+							'order' => 'id_thesaurus desc'])
+			->answers($docu);
+
+
+		$this->loadNotice('unimarc_vagabond');
+		$this->_notice = Class_Notice::find(1);
+	}
+
+
+  /** @test */
+  public function shouldNotCreateThesaurusFor610_a() {
+    $this->assertNull(Class_CodifThesaurus::findFirstBy(['libelle' => 'Manga']));
+  }
+}
\ No newline at end of file
diff --git a/library/Class/CodifThesaurus.php b/library/Class/CodifThesaurus.php
index c42b55c3222769643b7ca1c529bfcc371a180259..2f5679df1b690f91f8f0fb88f7971cb605722e4b 100644
--- a/library/Class/CodifThesaurus.php
+++ b/library/Class/CodifThesaurus.php
@@ -353,6 +353,7 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
     CODE_ROOT = 'root',
 
     COLUMN_ORIGIN_SIZE = 20,
+    ID_KEY_LENGTH = 4,
 
     CODE_FACETTE = 'H',
 
@@ -419,7 +420,6 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
 
 
   public function newChildEntry() {
-    $loader = $this->getLoader();
     $code = $this->getCode();
     return Class_CodifThesaurus::getLoader()->newInstance(['code' => $code,
                                                            'id_thesaurus' => Class_CodifThesaurus::getLoader()->findNextThesaurusChildId(
@@ -441,9 +441,8 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
       ->newChildEntry()
       ->updateAttributes(['id_origine' => $id_origine,
                           'libelle' => $label]);
-    $entry->assertSave();
 
-    return $entry;
+    return $entry->save() ? $entry : null;
   }
 
 
@@ -461,7 +460,9 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
 
 
   public function validate() {
-    $this->check('' != $this->getLibelle(), $this->_('Vous devez définir le libellé'));
+    $this->_validateIdThesaurus();
+
+    $this->checkAttribute('libelle', '' != $this->getLibelle(), $this->_('Vous devez définir le libellé'));
     if (!$this->getRules())
       return true;
 
@@ -472,6 +473,17 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
   }
 
 
+  protected function _validateIdThesaurus() {
+    $my_key = substr($this->getIdThesaurus(), -self::ID_KEY_LENGTH);
+    $empty_key = str_repeat('0', self::ID_KEY_LENGTH);
+
+    $this->checkAttribute('id_thesaurus',
+                          $my_key != $empty_key,
+                          $this->_('Nombre maximum d\'élément à ce niveau déjà atteint (%s)',
+                                   str_repeat('9', self::ID_KEY_LENGTH)));
+  }
+
+
   public function deleteMeAndMyChildren() {
     $this->cleanRecords();
     $this->getLoader()->deleteAllFrom($this);
diff --git a/library/Class/Indexation/PseudoNotice/FacettesVisitor.php b/library/Class/Indexation/PseudoNotice/FacettesVisitor.php
index 18ace745434a3f164185c3637408fb1c2af6b318..b4ebb7757f62ba609921ed04a71606fc9fdfb759 100644
--- a/library/Class/Indexation/PseudoNotice/FacettesVisitor.php
+++ b/library/Class/Indexation/PseudoNotice/FacettesVisitor.php
@@ -154,9 +154,9 @@ class Class_Indexation_PseudoNotice_FacettesVisitor extends Class_Indexation_Pse
       return;
 
     foreach($value->getValueAsArray() as $one_value) {
-      $thesaurus = $this
-        ->_ensureThesaurusUnderWithValue($this->_ensureThesaurusFor($field),
-                                       $one_value);
+      if (!$thesaurus = $this->_ensureThesaurusUnderWithValue($this->_ensureThesaurusFor($field),
+                                                              $one_value))
+        continue;
       $this->_facettes[] = $thesaurus->getFacetteIndex();
     }
   }
diff --git a/library/ZendAfi/View/Helper/RenderForm.php b/library/ZendAfi/View/Helper/RenderForm.php
index 1ca12ab53fa6980a646cb455864bc730d63ea37f..f159cecb0460ca059692ba2291cad7b9b41fe237 100644
--- a/library/ZendAfi/View/Helper/RenderForm.php
+++ b/library/ZendAfi/View/Helper/RenderForm.php
@@ -47,7 +47,9 @@ class ZendAfi_View_Helper_RenderForm extends ZendAfi_View_Helper_BaseHelper {
       ->addAdminScript('controle_maj')
       ->addJQueryReady('$("form input").change(function(){setFlagMaj(true)})');
 
-    return $form->render() . $this->_buttonsFor($form, $buttons);
+    return $form->render()
+      . $this->_buttonsFor($form, $buttons)
+      . $this->_cloneButtons();
   }
 
 
diff --git a/library/startup.php b/library/startup.php
index 2f23eefba8bd436d2cdf513e02d28a4c01bc10cc..350f5d54df508d7d94fa5729bcdbbf11c1c2b3c7 100644
--- a/library/startup.php
+++ b/library/startup.php
@@ -83,7 +83,7 @@ class Bokeh_Engine {
 
   function setupConstants() {
     defineConstant('BOKEH_MAJOR_VERSION','7.7');
-    defineConstant('BOKEH_RELEASE_NUMBER', BOKEH_MAJOR_VERSION . '.17');
+    defineConstant('BOKEH_RELEASE_NUMBER', BOKEH_MAJOR_VERSION . '.18');
 
     defineConstant('BOKEH_REMOTE_FILES', 'http://git.afi-sa.fr/afi/opacce/');
 
diff --git a/public/opac/css/global.css b/public/opac/css/global.css
index 2ff9bfc3dc63df882995a33e8992de230c4ac29b..aaf892e0f4168c446c120f0e0774f1b30308f6ca 100644
--- a/public/opac/css/global.css
+++ b/public/opac/css/global.css
@@ -3458,6 +3458,7 @@ th.actions {
     position: fixed !important;
 }
 
+
 .saving-process {
     text-align: center;
 }
@@ -3465,4 +3466,5 @@ th.actions {
 .loading-img {
     display: block;
     margin: 1em auto;
-}
\ No newline at end of file
+}
+
diff --git a/tests/application/modules/admin/controllers/CmsControllerCustomFieldsTest.php b/tests/application/modules/admin/controllers/CmsControllerCustomFieldsTest.php
index 31ce10e0d4faaaecc1b51b32dab1655b065a5206..fbe0ea2577e5e35dd829ab6abcd47e3c1de83bdd 100644
--- a/tests/application/modules/admin/controllers/CmsControllerCustomFieldsTest.php
+++ b/tests/application/modules/admin/controllers/CmsControllerCustomFieldsTest.php
@@ -173,6 +173,51 @@ class CmsControllerCustomFieldsAndIndexationPostEditActionTest
 
 
 
+
+class CmsControllerCustomFieldsAndIndexationPostEditWithTooManyValueActionTest
+  extends CmsControllerCustomFieldsTestCase {
+  protected
+    $_record,
+    $_field_thesaurus,
+    $_value_thesaurus;
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id_thesaurus' => 'CFCF00019999',
+                    'id_origine' => 'newbies',
+                    'libelle' => 'newbies',
+                    'code' => Class_CodifThesaurus::fixedCodeOf('CustomField'),
+                    'id' => 10722,
+                    'libelle_facette' => 'newbies',
+                    'rules' => null]);
+
+    $this->postDispatch('admin/cms/edit/id/1',
+                        ['titre' => 'News Article',
+                         'contenu' => 'Welcome',
+                         'indexation' => 1,
+                         'status' => Class_Article::STATUS_VALIDATED,
+                         'field_5' => 'Hardcore gamers',
+                         'debut' => '',
+                         'fin' => '',
+                         'events_debut' => '',
+                         'events_fin' => '']);
+
+    $this->_value_thesaurus = Class_CodifThesaurus::findFirstBy(['libelle' => 'Hardcore gamers']);
+  }
+
+
+  /** @test */
+  public function shouldNotCreateNewThesaurus() {
+    $this->assertNull($this->_value_thesaurus);
+  }
+}
+
+
+
+
 class CmsControllerCustomFieldsNotIndexableMetaPostEditActionTest
   extends CmsControllerCustomFieldsTestCase {
 
diff --git a/tests/application/modules/admin/controllers/CmsControllerListModeTest.php b/tests/application/modules/admin/controllers/CmsControllerListModeTest.php
index 37867fd569a70e3779d69f918a8723c2b21240b1..cb5139dccfcff7440034869427d43a9fac0ffbf0 100644
--- a/tests/application/modules/admin/controllers/CmsControllerListModeTest.php
+++ b/tests/application/modules/admin/controllers/CmsControllerListModeTest.php
@@ -429,5 +429,4 @@ class CmsControllerListModeEditPostTest extends CmsControllerListModeTestCase {
     $this->postDispatch('/admin/cms/edit/id/4/id_cat/34', $this->_datas);
     $this->assertNotContains('id_cat', $this->getResponseLocation());
   }
-
-}
\ No newline at end of file
+}
diff --git a/tests/library/Class/CodifThesaurusTest.php b/tests/library/Class/CodifThesaurusTest.php
index 55df116b0c4075feea942257046f67800f2916fa..6e9a199bafe46b045aee70a977a756fdee0fc33e 100644
--- a/tests/library/Class/CodifThesaurusTest.php
+++ b/tests/library/Class/CodifThesaurusTest.php
@@ -181,4 +181,46 @@ class CodifThesaurusGetIndicesRootTest extends ModelTestCase {
                         'order' => 'id_thesaurus'];
     $this->assertEquals($expected_params, Class_CodifThesaurus::getFirstAttributeForLastCallOn('findAllBy'));
   }
-}
\ No newline at end of file
+}
+
+
+
+
+/** @see http://forge.afi-sa.fr/issues/50500 */
+class CodifThesaurusTooManyValuesTest extends ModelTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id_thesaurus' => 'TEST',
+                    'id_origine' => null,
+                    'libelle' => 'test',
+                    'code' => 'TEST',
+                    'id' => 723,
+                    'libelle_facette' => 'test',
+                    'rules' => '{"label":"610$a"}']);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id_thesaurus' => 'TEST9999',
+                    'id_origine' => 'RIME',
+                    'libelle' => 'rime',
+                    'code' => 'TEST',
+                    'id' => 10722,
+                    'libelle_facette' => 'rime',
+                    'rules' => null]);
+  }
+
+
+  /** @test */
+  public function shouldNotInsertMoreThan9999Child() {
+    Class_CodifThesaurus::find(723)
+      ->getOrCreateChild(strtoupper('métiers de la recherche'),
+                         'métiers de la recherche');
+
+    $this->assertEquals(2, Class_CodifThesaurus::count(),
+                        Class_CodifThesaurus::findFirstBy(['order' => 'id desc'])
+                        ->getIdThesaurus());
+  }
+}