diff --git a/ChangeLog b/ChangeLog
index 8f039fa5444140ed214db07806c6434a13a9e1c7..fb719bc77986672184c9e1251861316335efd3f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -42,6 +42,7 @@ For developers:
 - Updated wiki documentation.
 - Better W3C standard.
 - Can add data provided with a module.
+- Can fix some corruptions in database by calling the update page with action=repair
 
 
 ***** Changelog for 2.6 compared to 2.5 *****
diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php
index 4399b24cbafffbc01b8547695c17872c9e5493de..b893364223a66531d7acf3274f1d8f338ff982da 100644
--- a/htdocs/install/upgrade.php
+++ b/htdocs/install/upgrade.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2009 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2009 Regis Houssin        <regis@dolibarr.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -19,10 +19,11 @@
  */
 
 /**
-        \file       htdocs/install/upgrade.php
-        \brief      Run migration script
-        \version    $Id$
-*/
+ *		\file       htdocs/install/upgrade.php
+ *      \brief      Run migration script
+ *      \version    $Id$
+ * 		\remarks	Can be also called directly with http://mydolibarr/install/upgrade.php?action=repair
+ */
 
 include_once("./inc.php");
 if (file_exists($conffile)) include_once($conffile);
@@ -60,14 +61,22 @@ dolibarr_install_syslog("upgrade: Entering upgrade.php page");
 if (! is_object($conf)) dolibarr_install_syslog("upgrade2: conf file not initialized",LOG_ERR);
 
 
+/*
+ * View
+ */
+
 pHeader($langs->trans("DatabaseMigration"),"upgrade2","upgrade");
 
+$actiondone=0;
 
-if (! isset($_GET["action"]) || $_GET["action"] == "upgrade")
+// Action to launch the repair or migrate script
+if (! isset($_GET["action"]) || $_GET["action"] == "upgrade" || $_GET["action"] == "repair")
 {
+	$actiondone=1;
+
 	print '<h3>'.$langs->trans("DatabaseMigration").'<h3>';
 
-	if (! $versionfrom && ! $versionto)
+	if ($_GET["action"] != "repair" && ! $versionfrom && ! $versionto)
 	{
 		print '<div class="error">Parameter versionfrom or version to missing.</div>';
 		exit;
@@ -138,131 +147,137 @@ if (! isset($_GET["action"]) || $_GET["action"] == "upgrade")
 	print '<tr><td colspan="2">'.$langs->trans("PleaseBePatient").'</td></tr>';
 	flush();
 
-	// Delete duplicates in table categorie_association
-	$couples=array();
-	$filles=array();
-	$sql = "SELECT fk_categorie_mere, fk_categorie_fille";
-	$sql.= " FROM ".MAIN_DB_PREFIX."categorie_association";
-	dolibarr_install_syslog("upgrade: search duplicate sql=".$sql);
-	$resql = $db->query($sql);
-	if ($resql)
+
+	if ($_GET["action"] != "repair")
 	{
-		$num=$db->num_rows($resql);
-		while ($obj=$db->fetch_object($resql))
+		/*
+		 * Delete duplicates in table categorie_association
+		 */
+		$couples=array();
+		$filles=array();
+		$sql = "SELECT fk_categorie_mere, fk_categorie_fille";
+		$sql.= " FROM ".MAIN_DB_PREFIX."categorie_association";
+		dolibarr_install_syslog("upgrade: search duplicate sql=".$sql);
+		$resql = $db->query($sql);
+		if ($resql)
 		{
-			if (! isset($filles[$obj->fk_categorie_fille]))	// Only one record as child (a child has only on parent).
+			$num=$db->num_rows($resql);
+			while ($obj=$db->fetch_object($resql))
 			{
-				if ($obj->fk_categorie_mere != $obj->fk_categorie_fille)
+				if (! isset($filles[$obj->fk_categorie_fille]))	// Only one record as child (a child has only on parent).
 				{
-					$filles[$obj->fk_categorie_fille]=1;	// Set record for this child
-					$couples[$obj->fk_categorie_mere.'_'.$obj->fk_categorie_fille]=array('mere'=>$obj->fk_categorie_mere, 'fille'=>$obj->fk_categorie_fille);
+					if ($obj->fk_categorie_mere != $obj->fk_categorie_fille)
+					{
+						$filles[$obj->fk_categorie_fille]=1;	// Set record for this child
+						$couples[$obj->fk_categorie_mere.'_'.$obj->fk_categorie_fille]=array('mere'=>$obj->fk_categorie_mere, 'fille'=>$obj->fk_categorie_fille);
+					}
 				}
 			}
-		}
 
-		dolibarr_install_syslog("upgrade: result is num=".$num." sizeof(couples)=".sizeof($couples));
+			dolibarr_install_syslog("upgrade: result is num=".$num." sizeof(couples)=".sizeof($couples));
 
-		// If there is duplicates couples or child with two parents
-		if (sizeof($couples) > 0 && $num > sizeof($couples))
-		{
-			$error=0;
+			// If there is duplicates couples or child with two parents
+			if (sizeof($couples) > 0 && $num > sizeof($couples))
+			{
+				$error=0;
 
-			$db->begin();
+				$db->begin();
 
-			$sql="DELETE FROM ".MAIN_DB_PREFIX."categorie_association";
-			dolibarr_install_syslog("upgrade: delete association sql=".$sql);
-			$resqld=$db->query($sql);
-			if ($resqld)
-			{
-				foreach($couples as $key => $val)
+				$sql="DELETE FROM ".MAIN_DB_PREFIX."categorie_association";
+				dolibarr_install_syslog("upgrade: delete association sql=".$sql);
+				$resqld=$db->query($sql);
+				if ($resqld)
 				{
-					$sql ="INSERT INTO ".MAIN_DB_PREFIX."categorie_association(fk_categorie_mere,fk_categorie_fille)";
-					$sql.=" VALUES(".$val['mere'].", ".$val['fille'].")";
-					dolibarr_install_syslog("upgrade: insert association sql=".$sql);
-					$resqli=$db->query($sql);
-					if (! $resqli) $error++;
+					foreach($couples as $key => $val)
+					{
+						$sql ="INSERT INTO ".MAIN_DB_PREFIX."categorie_association(fk_categorie_mere,fk_categorie_fille)";
+						$sql.=" VALUES(".$val['mere'].", ".$val['fille'].")";
+						dolibarr_install_syslog("upgrade: insert association sql=".$sql);
+						$resqli=$db->query($sql);
+						if (! $resqli) $error++;
+					}
 				}
-			}
 
-			if (! $error)
-			{
-				print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>';
-				print '<td align="right">'.$langs->trans("Success").' ('.$num.'=>'.sizeof($couples).')</td></tr>';
-				$db->commit();
-			}
-			else
-			{
-				print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>';
-				print '<td align="right">'.$langs->trans("Failed").'</td></tr>';
-				$db->rollback();
+				if (! $error)
+				{
+					print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>';
+					print '<td align="right">'.$langs->trans("Success").' ('.$num.'=>'.sizeof($couples).')</td></tr>';
+					$db->commit();
+				}
+				else
+				{
+					print '<tr><td>'.$langs->trans("RemoveDuplicates").'</td>';
+					print '<td align="right">'.$langs->trans("Failed").'</td></tr>';
+					$db->rollback();
+				}
 			}
 		}
-	}
-	else
-	{
-		print '<div class="error">'.$langs->trans("Error").'</div>';
-	}
-
+		else
+		{
+			print '<div class="error">'.$langs->trans("Error").'</div>';
+		}
 
-	if ($ok)
-	{
-		$versioncommande=split('\.','4.0');
-		if (sizeof($versioncommande) && sizeof($versionarray)
-			&& versioncompare($versioncommande,$versionarray) <= 0)	// Si mysql >= 4.0
+		/*
+		 * Remove deprecated indexes and constraints
+		 */
+		if ($ok)
 		{
-			// Suppression vieilles contraintes sans noms et en doubles
-			// Les contraintes indesirables ont un nom qui commence par 0_ ou se termine par ibfk_999
-/*			$listtables=array(  'llx_product_fournisseur_price',
-								'llx_fichinter',
-								'llx_facture_fourn',
-								'llx_propal',
-								'llx_socpeople',
-								'llx_telephonie_adsl_fournisseur',
-								'llx_telephonie_client_stats',
-								'llx_telephonie_contact_facture',
-								'llx_telephonie_societe_ligne',
-								'llx_telephonie_tarif_client');
-*/
-			$listtables = $db->DDLListTables($conf->db->name,'');
-		    foreach ($listtables as $val)
+			$versioncommande=split('\.','4.0');
+			if (sizeof($versioncommande) && sizeof($versionarray)
+				&& versioncompare($versioncommande,$versionarray) <= 0)	// Si mysql >= 4.0
 			{
-				//print "x".$val."<br>";
-				$sql = "SHOW CREATE TABLE ".$val;
-				$resql = $db->query($sql);
-				if ($resql)
+				// Suppression vieilles contraintes sans noms et en doubles
+				// Les contraintes indesirables ont un nom qui commence par 0_ ou se termine par ibfk_999
+				/* $listtables=array(  'llx_product_fournisseur_price',
+									'llx_fichinter',
+									'llx_facture_fourn',
+									'llx_propal',
+									'llx_socpeople',
+									'llx_telephonie_adsl_fournisseur',
+									'llx_telephonie_client_stats',
+									'llx_telephonie_contact_facture',
+									'llx_telephonie_societe_ligne',
+									'llx_telephonie_tarif_client');
+				*/
+				$listtables = $db->DDLListTables($conf->db->name,'');
+			    foreach ($listtables as $val)
 				{
-					$values=$db->fetch_array($resql);
-					$i=0;
-					$createsql=$values[1];
-					while (eregi('CONSTRAINT `(0_[0-9a-zA-Z]+|[_0-9a-zA-Z]+_ibfk_[0-9]+)`',$createsql,$reg) && $i < 100)
+					//print "x".$val."<br>";
+					$sql = "SHOW CREATE TABLE ".$val;
+					$resql = $db->query($sql);
+					if ($resql)
 					{
-						$sqldrop="ALTER TABLE ".$val." DROP FOREIGN KEY ".$reg[1];
-						$resqldrop = $db->query($sqldrop);
-						if ($resqldrop)
+						$values=$db->fetch_array($resql);
+						$i=0;
+						$createsql=$values[1];
+						while (eregi('CONSTRAINT `(0_[0-9a-zA-Z]+|[_0-9a-zA-Z]+_ibfk_[0-9]+)`',$createsql,$reg) && $i < 100)
 						{
-							print '<tr><td colspan="2">'.$sqldrop.";</td></tr>\n";
+							$sqldrop="ALTER TABLE ".$val." DROP FOREIGN KEY ".$reg[1];
+							$resqldrop = $db->query($sqldrop);
+							if ($resqldrop)
+							{
+								print '<tr><td colspan="2">'.$sqldrop.";</td></tr>\n";
+							}
+							$createsql=eregi_replace('CONSTRAINT `'.$reg[1].'`','XXX',$createsql);
+							$i++;
 						}
-						$createsql=eregi_replace('CONSTRAINT `'.$reg[1].'`','XXX',$createsql);
-						$i++;
+						$db->free($resql);
 					}
-					$db->free($resql);
-				}
-				else
-				{
-					if ($db->lasterrno() != 'DB_ERROR_NOSUCHTABLE')
+					else
 					{
-						print '<tr><td colspan="2"><font  class="error">'.$sql.' : '.$db->lasterror()."</font></td></tr>\n";
+						if ($db->lasterrno() != 'DB_ERROR_NOSUCHTABLE')
+						{
+							print '<tr><td colspan="2"><font  class="error">'.$sql.' : '.$db->lasterror()."</font></td></tr>\n";
+						}
 					}
 				}
 			}
 		}
 	}
 
-	/***************************************************************************************
-	*
-	* Chargement fichiers dans migration
-	*
-	***************************************************************************************/
+	/*
+	 *	Load sql files
+	 */
 	if ($ok)
 	{
 		if ($choix==1) $dir = "../../mysql/migration/";
@@ -284,16 +299,29 @@ if (! isset($_GET["action"]) || $_GET["action"] == "upgrade")
 		}
 		sort($filesindir);
 
-		# Determine les fichiers sql a passer
-		foreach($filesindir as $file)
+		# Define which file to run
+		if ($_GET["action"] != "repair")
 		{
-			if (eregi($from,$file))
+			foreach($filesindir as $file)
 			{
-				$filelist[]=$file;
+				if (eregi($from,$file))
+				{
+					$filelist[]=$file;
+				}
+				else if (eregi($to,$file))	// First test may be false if we migrate from x.y.* to x.y.*
+				{
+					$filelist[]=$file;
+				}
 			}
-			else if (eregi($to,$file))	// First test may be false if we migrate from x.y.* to x.y.*
+		}
+		else
+		{
+			foreach($filesindir as $file)
 			{
-				$filelist[]=$file;
+				if (eregi('repair',$file))
+				{
+					$filelist[]=$file;
+				}
 			}
 		}
 
@@ -314,7 +342,9 @@ if (! isset($_GET["action"]) || $_GET["action"] == "upgrade")
 
 	if ($db->connected) $db->close();
 }
-else
+
+
+if (empty($actiondone))
 {
     print '<div class="error">'.$langs->trans("ErrorWrongParameters").'</div>';
 }
diff --git a/mysql/migration/2.6.0-2.7.0.sql b/mysql/migration/2.6.0-2.7.0.sql
index 6f8b34db8005e0f9ce630eaba21d2bb521190bca..be52ec38a375b228282a9f20aaf77db8a07488d9 100644
--- a/mysql/migration/2.6.0-2.7.0.sql
+++ b/mysql/migration/2.6.0-2.7.0.sql
@@ -172,8 +172,3 @@ alter table llx_commande_fournisseur add column   ref_supplier        varchar(30
 alter table llx_mailing add column bgcolor  varchar(8) after body;
 alter table llx_mailing add column bgimage  varchar(255) after bgcolor;
 
-
--- Request to clean corrupted database
-delete from llx_facture where facnumber = '(PROV)';
-delete from llx_commande where ref = '(PROV)';
-delete from llx_propal where ref = '(PROV)';
diff --git a/mysql/migration/repair.sql b/mysql/migration/repair.sql
new file mode 100644
index 0000000000000000000000000000000000000000..e8ed4eba1f62371648fedb8d0d568caca2e2f86c
--- /dev/null
+++ b/mysql/migration/repair.sql
@@ -0,0 +1,13 @@
+--
+-- $Id$
+--
+-- Script to repair some fatal errors due to database corruption
+-- 
+-- when current version is 2.6.0 or higher. 
+--
+
+
+-- Request to clean corrupted database
+delete from llx_facture where facnumber = '(PROV)';
+delete from llx_commande where ref = '(PROV)';
+delete from llx_propal where ref = '(PROV)';