diff --git a/ecrire/exec/admin_tech.php b/ecrire/exec/admin_tech.php
index cf20d8884ff0677a66771ef3d9dd22cc2222901e..3464056b03c20e322efc039e59ad688b758e42e7 100644
--- a/ecrire/exec/admin_tech.php
+++ b/ecrire/exec/admin_tech.php
@@ -66,8 +66,8 @@ function exec_admin_tech_dist()
  else
    $dir_img = _DIR_IMG;
 
- echo "<TABLE BORDER='0' CELLSPACING='0' CELLPADDING='5' WIDTH=\"100%\">",
-   "<tr><td BGCOLOR='", $couleur_foncee, "' background=''><b>",
+ echo "<table border='0' cellspacing='0' cellpadding='5' width=\"100%\">",
+   "<tr><td bgcolor='", $couleur_foncee, "' background=''><b>",
    "<font face='Verdana,Arial,Sans,sans-serif' size='3' color='#FFFFFF'>",
    _T('texte_sauvegarde'),
    "</font></b></td></tr><tr><td class='serif'>",
@@ -76,25 +76,25 @@ function exec_admin_tech_dist()
    http_img_pack('warning.gif', _T('info_avertissement'), "width='48' height='48' align='right'"),
    _T('texte_admin_tech_01',
      array('dossier' => '<i>'.$dir_dump.'</i>', 'img'=>'<i>'.$dir_img.'</i>')),
-   "<p>",
-   _T('texte_admin_tech_02');
+   _T('texte_admin_tech_02'),
+  "</p>";
 
 if ($flag_gz) {
-	echo "\n<p align='justify'>"._T('texte_admin_tech_03')."<p>";
-	echo "\n<INPUT TYPE='radio' NAME='gz' VALUE='1' id='gz_on' CHECKED><label for='gz_on'> "._T('bouton_radio_sauvegarde_compressee',
-	array('fichier'=>'<b>'.$zfile.'</b>'))." </label><BR>\n";
-	echo "\n<INPUT TYPE='radio' NAME='gz' VALUE='0' id='gz_off'><label for='gz_off'> "._T('bouton_radio_sauvegarde_non_compressee',
-	array('fichier'=>'<b>'.$file.'</b>'))." </label><BR>\n";
+	echo "\n<p align='justify'>"._T('texte_admin_tech_03')."</p>\n<p>";
+	echo "\n<input type='radio' name='gz' value='1' id='gz_on' checked='checked' /><label for='gz_on'> "._T('bouton_radio_sauvegarde_compressee',
+	array('fichier'=>'<b>'.$zfile.'</b>'))." </label><br />\n";
+	echo "\n<input type='radio' name='gz' value='0' id='gz_off' /><label for='gz_off'> "._T('bouton_radio_sauvegarde_non_compressee',
+	array('fichier'=>'<b>'.$file.'</b>'))." </label><br /></p>\n";
 }
 else {
 	echo "\n<p align='justify'>"._T('texte_sauvegarde_compressee', array('fichier'=>'<b>'.$file.'</b>'));
-	echo "\n<INPUT TYPE='hidden' NAME='gz' VALUE='0' />";
+	echo "\n<input type='hidden' name='gz' value='0' />";
 }
 
-echo "\n<div align='right'><input class='fondo' type='submit' VALUE='"._T('texte_sauvegarde_base')."'></div></form>";
+echo "\n<div align='right'><input class='fondo' type='submit' value='"._T('texte_sauvegarde_base')."' /></div></form>";
 
 echo "</td></tr>";
-echo "</TABLE>";
+echo "</table>";
 
 
 //
@@ -107,8 +107,8 @@ echo "</TABLE>";
  	$liste_choix = "<p><ul>"; 
  	foreach($liste_dump as $key=>$fichier){
  		$affiche_fichier = substr($fichier,strlen(_DIR_DUMP));
- 		$liste_choix.="<li><input type='radio' name='archive' value='$affiche_fichier' id='dump_$key' ".
- 			(($fichier==$selected)?"checked='checked' ":"")."/><label for='dump_$key'>$affiche_fichier</label></li>\n";
+ 		$liste_choix.="\n<li><input type='radio' name='archive' value='$affiche_fichier' id='dump_$key' ".
+ 			(($fichier==$selected)?"checked='checked' ":"")."/>\n<label for='dump_$key'>$affiche_fichier</label></li>";
  	}
  	
 	if ($flag_gz) {
@@ -119,22 +119,31 @@ echo "</TABLE>";
 		$texte_compresse = _T('texte_non_compresse')."&nbsp;";
 	}
 
-	echo	"<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=8 WIDTH=\"100%\">",
-	"<TR><TD BGCOLOR='#EEEECC' BACKGROUND=''><B>",
-	"<FONT FACE='Verdana,Arial,Sans,sans-serif' SIZE=3 COLOR='#000000'>",
-	_T('texte_restaurer_base')."</FONT></B></TD></TR>",
-	"<TR><td class='serif'>\n",
+	echo	"\n<table border='0' cellspacing='1' cellpadding='8' width=\"100%\">",
+	"<tr><td bgcolor='#eeeecc' background=''><b>",
+	"<font face='Verdana,Arial,Sans,sans-serif' size='3' color='#000000'>",
+	_T('texte_restaurer_base')."</font></b></td></tr>",
+	"<tr><td class='serif'>\n",
 	generer_url_post_ecrire("import_all"),
 	"\n<p align='justify'> ",
 	_T('texte_restaurer_sauvegarde', array('dossier' => '<i>'.$dir_dump.'</i>')),
-	"\n<p>",
+	  '</p>',
 	_T('entree_nom_fichier', array('texte_compresse' => $texte_compresse)),
 	$liste_choix,
-	"<li><input type='radio' name='archive' value='' />",
-	"\n<FONT SIZE=3><INPUT TYPE='text' NAME='archive_perso' VALUE='$fichier_defaut' SIZE='30'></FONT></li></ul>",
-	"\n<p><DIV align='right'><INPUT CLASS='fondo' TYPE='submit' VALUE='"._T('bouton_restaurer_base')."'></DIV></FORM>",
-	"\n</td></tr>",
-	"</TABLE>";
+	"\n<li><input type='radio' name='archive' value='' />",
+	"\n<font size='3'><input type='text' name='archive_perso' value='$fichier_defaut' size='30' /></font></li></ul>";
+	  
+	debut_cadre_relief();
+	echo  "<p><input name='insertion' type='radio' />&nbsp;",
+	  _L('Fusionner la base actuelle et la sauvegarde'),
+	  '</p>';
+	fin_cadre_relief();
+
+	echo "\n</p><div align='right'><input class='fondo' type='submit' value='",
+	  _T('bouton_restaurer_base'),
+	  "' /></div></form>",
+	  "\n</td></tr>",
+	  "</table>";
 
  }
 
@@ -145,29 +154,25 @@ echo "</TABLE>";
 if ($options == "avancees" AND 	$connect_toutes_rubriques) {
 	$res = spip_mysql_version();
 	if ($res >= '3.23.14') {
-		echo "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=8 WIDTH=\"100%\">";
-		echo "<TR><TD BGCOLOR='#EEEECC' BACKGROUND=''><B>";
-		echo "<FONT FACE='Verdana,Arial,Sans,sans-serif' SIZE=3 COLOR='#000000'>";
+		echo "<table border='0' cellspacing='1' cellpadding='8' width=\"100%\">";
+		echo "<tr><td bgcolor='#eeeecc' background=''><b>";
+		echo "<font face='Verdana,Arial,Sans,sans-serif' size='3' COLOR='#000000'>";
 		echo _T('texte_recuperer_base'),
-			"</FONT></B></TD></TR>",
-			"<TR><TD class='serif'>",
+			"</font></b></td></tr>",
+			"<tr><td class='serif'>",
 			generer_url_post_ecrire("admin_repair"),
 			"\n<p align='justify'>"._T('texte_crash_base'),
-			"\n<p><DIV align='right'><INPUT CLASS='fondo' TYPE='submit' VALUE='",
+			"\n</p><div align='right'><input class='fondo' type='submit' value='",
 		 	_T('bouton_tenter_recuperation'),
-			"'></DIV></FORM>",
-			"</TD></TR>",
-			"</TABLE>";
+			"' /></div></form>",
+			"</td></tr>",
+			"</table>";
 	}
 }
 
-
 fin_cadre_relief();
 
-echo "<BR>";
-
-
-
+echo "<br />";
 
 echo fin_page();
 }
diff --git a/ecrire/exec/import_all.php b/ecrire/exec/import_all.php
index 868df437067720a4b5f5df3703074db3746715e1..f01260ed764f370f4b6a92398c8a21fcd424b856 100644
--- a/ecrire/exec/import_all.php
+++ b/ecrire/exec/import_all.php
@@ -98,6 +98,7 @@ function exec_import_all_dist()
 	if (!$GLOBALS['meta']["debut_restauration"]) {
 	// cas de l'appel apres demande de confirmation
 		$archive=_request('archive');
+		$insertion=_request('insertion');
 		if (!strlen($archive)) $archive=_request('archive_perso');
 		if ($archive) {
 			$action = _T('info_restauration_sauvegarde', array('archive' => $archive));
@@ -105,9 +106,11 @@ function exec_import_all_dist()
 		}
 
 		// au tout premier appel, on ne revient pas de debut_admin
-		debut_admin(generer_url_post_ecrire("import_all","archive=$archive"), $action, $commentaire);
 
-		// on est revenu: l'authentification ftp est ok
+		debut_admin(generer_url_post_ecrire("import_all","archive=$archive&insertion=$insertion"), $action, $commentaire);
+
+		// si on est revenu c'est que l'authentification ftp est ok
+		// sinon il reste le meta request_restau; a ameliorer.
 		fin_admin($action);
 		// dire qu'on commence
 		ecrire_meta("request_restauration", serialize($_REQUEST));
@@ -120,17 +123,6 @@ function exec_import_all_dist()
 	}
 
 	// au rappel, on commence (voire on continue)
-	import_all_continue();
-	include_spip('inc/rubriques');
-	calculer_rubriques();
-}
-
-
-// http://doc.spip.org/@import_all_continue
-function import_all_continue()
-{
-	global $meta, $flag_gz, $buf, $abs_pos, $my_pos, $connect_toutes_rubriques;
-	global $affiche_progression_pourcent;
 	@ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure
 	// utiliser une version fraiche des metas (ie pas le cache)
 	include_spip('inc/meta');
@@ -138,14 +130,71 @@ function import_all_continue()
 	include_spip('inc/import');
 	@ignore_user_abort(1);
 
-	$request = unserialize($meta['request_restauration']);
+	$commencer_page = charger_fonction('commencer_page', 'inc');
+	echo $commencer_page(_T('titre_page_index'), "accueil", "accueil");
+
+	debut_gauche();
+
+	debut_droite();
+	$request = unserialize($GLOBALS['meta']['request_restauration']);
+	spip_log("import_all " . $GLOBALS['meta']['request_restauration']);
+	$dir = import_queldir();
+	$r = import_tables($request, $dir);
+
+	if ($r) {
+		spip_log("Erreur: $r");
+	}
+	else {
+		if ($request['insertion']== 'on') {
+			$request['insertion'] = 'passe2';
+			ecrire_meta("request_restauration", serialize($request));
+			ecrire_meta("debut_restauration", "debut");
+			ecrire_meta("status_restauration", "0");
+			ecrire_metas();
+			spip_log("import_all passe 2");
+			$trans = translate_init($request);
+			$r = import_tables($request, $dir, $trans);
+			if ($r) spip_log("Erreur: $r");
+			spip_query("DROP TABLE spip_translate");
+		} 
+		ecrire_acces();	// Mise a jour du fichier htpasswd
+		detruit_restaurateur();
+		if ($charset = $GLOBALS['meta']['charset_restauration']) {
+				ecrire_meta('charset', $charset);
+				ecrire_metas();
+		}
+		import_fin();
+		include_spip('inc/rubriques');
+		calculer_rubriques();
+	}
+	echo "</body></html>\n";
+}
+
+function import_fin() {
+
+	effacer_meta("charset_restauration");
+	effacer_meta("status_restauration");
+	effacer_meta("debut_restauration");
+	effacer_meta("date_optimisation");
+	effacer_meta('request_restauration');
+	effacer_meta('fichier_restauration');
+	effacer_meta('version_archive_restauration');
+	effacer_meta('tag_archive_restauration');
+	ecrire_metas();
+}
+
+// http://doc.spip.org/@import_all_continue
+function import_queldir()
+{
+	global $connect_toutes_rubriques;
+
 	if ($connect_toutes_rubriques) {
 		$repertoire = _DIR_DUMP;
 		if(!@file_exists($repertoire)) {
 			$repertoire = preg_replace(','._DIR_TMP.',', '', $repertoire);
 			$repertoire = sous_repertoire(_DIR_TMP, $repertoire);
 		}
-		$dir = $repertoire;
+		return $repertoire;
 	} else {
 		$repertoire = _DIR_TRANSFERT;
 		if(!@file_exists($repertoire)) {
@@ -155,75 +204,8 @@ function import_all_continue()
 		if(!@file_exists($repertoire.$connect_login)) {
 			$sous_rep = sous_repertoire($repertoire, $connect_login);
 		}
-		$dir = $sous_rep . '/';
+		return $sous_rep . '/';
 	}
-	$archive = $dir . $request['archive'];
-	$affiche_progression_pourcent = @filesize($archive);
 
-	$commencer_page = charger_fonction('commencer_page', 'inc');
-	echo $commencer_page(_T('titre_page_index'), "accueil", "accueil");
-
-	debut_gauche();
-
-	debut_droite();
-
-	// attention : si $request['archive']=="", alors archive='data/' 
-	// le test is_readable n'est donc pas suffisant
-	if (!@is_readable($archive)||is_dir($archive) || !$affiche_progression_pourcent) {
-		$texte_boite = _T('info_erreur_restauration');
-		echo debut_boite_alerte();
-		echo "<font face='Verdana,Arial,Sans,sans-serif' size='4' color='black'><b>$texte_boite</b></font>";
-		echo fin_boite_alerte();
-
-		// faut faire quelque chose, sinon le site est mort :-)
-		// a priori on reset les meta de restauration car rien n'a encore commence
-		effacer_meta('request_restauration');
-		effacer_meta('fichier_restauration');
-		effacer_meta('version_archive_restauration');
-		effacer_meta('tag_archive_restauration');
-		effacer_meta('status_restauration');
-		effacer_meta('debut_restauration');
-		effacer_meta('charset_restauration');
-		ecrire_metas();
-		exit;
-	}
-
-	$my_pos = $meta["status_restauration"];
-
-	if (ereg("\.gz$", $archive)) {
-			$affiche_progression_pourcent = false;
-			$taille = taille_en_octets($my_pos);
-			$gz = true;
-	} else {
-			$taille = floor(100 * $my_pos / $affiche_progression_pourcent)." %";
-			$gz = false;
-		}
-	$texte_boite = _T('info_base_restauration')."<p>
-		<form name='progression'><center><input type='text' size=10 style='text-align:center;' name='taille' value='$taille'><br>
-		<input type='text' class='forml' name='recharge' value='"._T('info_recharger_page')."'></center></form>";
-
-	echo debut_boite_alerte();
-	echo "<font FACE='Verdana,Arial,Sans,sans-serif' SIZE=4 color='black'><B>$texte_boite</B></font>";
-	echo fin_boite_alerte();
-	$max_time = ini_get('max_execution_time')*1000;
-	echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".self()."\";',$max_time);</script>\n");
-
-	if ($GLOBALS['flag_ob_flush']) ob_flush();
-	flush();
-
-	$_fopen = ($gz) ? 'gzopen' : 'fopen';
-	$f = $_fopen($archive, "rb");
-	$buf = "";
-	$r = import_tables($f, $gz);
-	if ($r) {
-		spip_log("Erreur: $r");
-	}
-	else {
-		if ($charset = $GLOBALS['meta']['charset_restauration'])
-			ecrire_meta('charset', $charset);
-	}
-
-	import_fin();
-	echo "</body></html>\n";
 }
 ?>
diff --git a/ecrire/inc/import.php b/ecrire/inc/import.php
index 6018be3369763f8de1d316dbfbad03695d09ec2f..32be47c3bf694cf24a7b8fe01a1861ce94a6f1ff 100644
--- a/ecrire/inc/import.php
+++ b/ecrire/inc/import.php
@@ -117,20 +117,6 @@ function import_debut($f, $gz=false) {
 $tables_trans = array(
 );
 
-// http://doc.spip.org/@import_fin
-function import_fin() {
-
-	effacer_meta("charset_restauration");
-	effacer_meta("status_restauration");
-	effacer_meta("debut_restauration");
-	effacer_meta("date_optimisation");
-	effacer_meta('request_restauration');
-	effacer_meta('fichier_restauration');
-	effacer_meta('version_archive_restauration');
-	effacer_meta('tag_archive_restauration');
-	ecrire_metas();
-}
-
 // http://doc.spip.org/@import_init_tables
 function import_init_tables()
 {
@@ -145,41 +131,95 @@ function import_init_tables()
 	}
 
 	// Bidouille pour garder l'acces admin actuel pendant toute la restauration
-	spip_query("UPDATE spip_auteurs SET id_auteur=0 WHERE id_auteur=$connect_id_auteur");
+	spip_query("UPDATE spip_auteurs SET id_auteur=0, extra=$connect_id_auteur WHERE id_auteur=$connect_id_auteur");
 	spip_query("DELETE FROM spip_auteurs WHERE id_auteur!=0");
 
 	return $tables;
 }
 
+// Effacement de la bidouille ci-dessus
+// Toutefois si la table des auteurs ne contient plus qu'elle
+// c'est que la sauvegarde etait incomplete et on restaure le compte
+// pour garder la connection au site (mais il doit pas etre bien beau)
+
+// http://doc.spip.org/@detruit_restaurateur
+function detruit_restaurateur()
+{
+	$r = spip_fetch_array(spip_query("SELECT COUNT(*) AS n FROM spip_auteurs"));
+	if ($r['n'] > 1)
+		spip_query("DELETE FROM spip_auteurs WHERE id_auteur=0");
+	else {
+	  	spip_query("UPDATE spip_auteurs SET id_auteur=extra WHERE id_auteur=0");
+	}
+}
+
 // http://doc.spip.org/@import_tables
-function import_tables($f, $gz=false) {
+function import_tables($request, $dir, $trans=array()) {
 	global $import_ok, $abs_pos, $my_pos;
+	global $affiche_progression_pourcent;
 	static $time_javascript;
 
+	$my_pos = $GLOBALS['meta']["status_restauration"];
+	$archive = $dir . ($request['archive'] ? $request['archive'] : $request['archive_perso']);
+	$size = @filesize($archive);
+
+	// attention : si $request['archive']=="", alors archive='data/' 
+	// le test is_readable n'est donc pas suffisant
+	if (!@is_readable($archive)||is_dir($archive) || !$size) {
+		$texte_boite = _T('info_erreur_restauration');
+		echo debut_boite_alerte();
+		echo "<font face='Verdana,Arial,Sans,sans-serif' size='4' color='black'><b>$texte_boite</b></font>";
+		echo fin_boite_alerte();
+// renvoyer True pour effacer les meta sans refaire calculer_rubriques:
+// la restauration n'a pas encore commence, on peut eviter de tout casser
+		return $texte_boite;
+	}
+
+	if (ereg("\.gz$", $archive)) {
+			$size = false;
+			$taille = taille_en_octets($my_pos);
+			$_fopen = 'gzopen';
+			$gz = true;
+	} else {
+			$taille = floor(100 * $my_pos / $size)." %";
+			$_fopen = 'fopen';
+			$gz = false;
+	}
+
+	import_affiche_javascript($taille);
+
+	if ($GLOBALS['flag_ob_flush']) ob_flush();
+	flush();
+
 	list($my_date) = spip_fetch_array(spip_query("SELECT UNIX_TIMESTAMP(maj) AS d FROM spip_meta WHERE nom='debut_restauration'"), SPIP_NUM);
 
 	if (!$my_date) return false;
 
+	if ($request['insertion']=='on') {
+		$request['init'] = 'insere_1_init';
+		$request['boucle'] = 'import_insere';
+	} elseif ($request['insertion']=='passe2') {
+		$request['init'] = 'insere_2_init';
+		$request['boucle'] = 'import_translate';
+	} else {
+		$request['init'] = 'import_init';
+		$request['boucle'] = 'import_replace';
+	}
+
+	$f = $_fopen($archive, "rb");
 	$my_pos = (!isset($GLOBALS['meta']["status_restauration"])) ? 0 :
 		$GLOBALS['meta']["status_restauration"];
+
 	if ($my_pos==0) {
-		// par defaut pour les anciens sites
-		// il est contenu dans le xml d'import et sera reecrit dans import_debut
+// par defaut pour les anciens sites
+// il est contenu dans le xml d'import et sera reecrit dans import_debut
 		ecrire_meta('charset_restauration', 'iso-8859-1'); 
-		// Debut de l'importation
-		$fimport = false;
 		if ($r = import_debut($f, $gz)) {
 // tag ouvrant :
 // 'SPIP' pour un dump xml spip, nom de la base source pour un dump phpmyadmin
 			$tag_archive = $r[0];
 			$version_archive = $r[1]['version_archive'];
-			$fimport = import_charge_version($version_archive);
 		}
-		// Normalement c'est controle par import_all auparavant
-		if (!$fimport) {
-			return _T('avis_archive_incorrect');
-		}
-
 		ecrire_meta('version_archive_restauration', $version_archive);
 		ecrire_meta('tag_archive_restauration', $tag_archive);
 		ecrire_metas();
@@ -189,18 +229,24 @@ function import_tables($f, $gz=false) {
 		$_fseek($f, $my_pos);
 		$version_archive = $GLOBALS['meta']['version_archive_restauration'];
 		$tag_archive = $GLOBALS['meta']['tag_archive_restauration'];
-		$fimport = import_charge_version($version_archive);
-		$tables = import_table_choix();
+		// a completer pour les insertions
+		$request['init'] = 'import_table_choix';
 	}
 
-	while ($table = $fimport($f, $gz)) {
+	$fimport = import_charge_version($version_archive);
+
+	// Normalement c'est controle par import_all auparavant
+	// c'est pour se proteger des reprises avortees
+	if (!$fimport) return _T('avis_archive_incorrect');
+
+	while ($table = $fimport($f, $request, $gz, $trans)) {
 	// Pas d'ecriture SQL car sinon le temps double.
 	// Il faut juste faire attention a bien lire_metas()
 	// au debut de la restauration
 		ecrire_meta("status_restauration", "$abs_pos");
 
 		if (time() - $time_javascript > 3) {	// 3 secondes
-			affiche_progression_javascript($abs_pos,$table);
+			affiche_progression_javascript($abs_pos,$size,$table);
 			$time_javascript = time();
 		}
 
@@ -209,51 +255,55 @@ function import_tables($f, $gz=false) {
 
 	if (!$import_ok) return  _T('avis_archive_invalide');
 
-	// Mise a jour du fichier htpasswd
-
-	ecrire_acces();
-
-	detruit_restaurateur();
-
-	affiche_progression_javascript('100 %');
+	affiche_progression_javascript('100 %', $size);
 
 	return false;
 }
 
-// Destruction des entrees non restaurees
-
-// http://doc.spip.org/@detruit_restaurateur
-function detruit_restaurateur()
+function import_affiche_javascript($taille)
 {
-	spip_query("DELETE FROM spip_auteurs WHERE id_auteur=0");
+	$max_time = ini_get('max_execution_time')*1000;
+	echo debut_boite_alerte(),
+	  "<font face='Verdana,Arial,Sans,sans-serif' size='4' color='black'><b>",
+	  _T('info_base_restauration'),
+	  "</b></font>",
+	  "<form name='progression'><center><input type='text' size='10' style='text-align:center;' name='taille' value='",
+	  $taille,
+	  "'><br /><input type='text' class='forml' name='recharge' value='"._T('info_recharger_page')."'></center></form>",
+	  fin_boite_alerte(),
+	  "<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"",
+	  self(),
+	  "\";',",
+	  $max_time,
+	  ");</script>\n";
 }
 
 
+
 // http://doc.spip.org/@affiche_progression_javascript
-function affiche_progression_javascript($abs_pos,$table="") {
-	global $affiche_progression_pourcent;
+function affiche_progression_javascript($abs_pos,$size, $table="") {
 	include_spip('inc/charsets');
 	if ($GLOBALS['flag_ob_flush']) ob_flush();
 	flush();
 	echo "\n<script type='text/javascript'><!--\n";
 
 	if ($abs_pos == '100 %') {
-		$taille = $abs_pos;
-		if ($GLOBALS['erreur_restauration'])
-			echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('avis_erreur')))."';\n";
+
+		if ($x = $GLOBALS['erreur_restauration'])
+			echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('avis_erreur'))).": $x ';\n";
 		else
 			echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('info_fini')))."';\n";
-		echo "document.progression.taille.value='$taille';\n";
+		echo "document.progression.taille.value='$abs_pos';\n";
 		echo "//--></script>\n";
 		echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".self()."\";',0);</script>\n");
 	}
 	else {
 		if (trim($table))
 			echo "document.progression.recharge.value='$table';\n";
-		if (! $affiche_progression_pourcent)
+		if (!$size)
 			$taille = ereg_replace("&nbsp;", " ", taille_en_octets($abs_pos));
 		else
-			$taille = floor(100 * $abs_pos / $affiche_progression_pourcent)." %";
+			$taille = floor(100 * $abs_pos / $size)." %";
 		echo "document.progression.taille.value='$taille';\n";
 		echo "//--></script>\n<!--\n";
 	}
diff --git a/ecrire/inc/import_0_0.php b/ecrire/inc/import_0_0.php
index 52699d2994756b38f19967bcc736f6d7d07e5bea..6872ad2885cb7ca01816a659e04284743b2c9b69 100644
--- a/ecrire/inc/import_0_0.php
+++ b/ecrire/inc/import_0_0.php
@@ -15,7 +15,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return;
 // pour le support des vieux dump
 // pff ou vous l'avez trouve ce dump ?
 // http://doc.spip.org/@inc_import_0_0_dist
-function inc_import_0_0_dist($f, $gz=false) {
+function inc_import_0_0_dist($f, $request, $gz=false, $t='') {
 	global $import_ok, $abs_pos, $my_pos;
 
 	// detruire les tables a restaurer
diff --git a/ecrire/inc/import_1_2.php b/ecrire/inc/import_1_2.php
index e6cd8cd9b6895c8a30bc47d59e29dbd1e34feddc..ae8ecc2277b07163b4aeaedc379ed4f56b9cf05e 100644
--- a/ecrire/inc/import_1_2.php
+++ b/ecrire/inc/import_1_2.php
@@ -38,7 +38,7 @@ function description_table($nom){
 
 // pour le support des vieux dump
 // http://doc.spip.org/@inc_import_1_2_dist
-function inc_import_1_2_dist($f, $gz=false) {
+function inc_import_1_2_dist($f, $request, $gz=false, $t='') {
   global $import_ok, $abs_pos, $my_pos;
 	static $field_desc = array ();
 
diff --git a/ecrire/inc/import_1_3.php b/ecrire/inc/import_1_3.php
index 1561a1e052d7add820356df6be6a666a7efd2b50..3df4cda5b3617ecb6df29cb185c678218f90671a 100644
--- a/ecrire/inc/import_1_3.php
+++ b/ecrire/inc/import_1_3.php
@@ -36,76 +36,177 @@ function description_table($nom){
 	return array($nom,array());
 }
 
+function import_init($request, $my_pos) {
+
+	// au premier appel destruction des tables a restaurer
+	return (!$my_pos) ? import_init_tables() : import_table_choix();
+}
+
+function insere_2_init($request, $my_pos) {
+
+	// l'insertion ne porte que sur les tables principales
+	$t = array_keys($GLOBALS['tables_principales']);
+	// mais pas cette table car elle n'est pas extensible
+	// (si on essaye ==> duplication sur la cle secondaire)
+	unset($t[array_search('spip_types_documents', $t)]);
+	// ni celle-ci a cause de la duplication des login 
+	unset($t[array_search('spip_auteurs', $t)]);
+	return $t;
+}
+
+function insere_1_init($request, $my_pos) {
+
+  //  preparation de la table des translations
+	$spip_translate = array(
+		"type" 	     =>  "VARCHAR(16) NOT NULL",
+                "id_old"     => "BIGINT (21) DEFAULT '0' NOT NULL",
+                "id_new"    => "BIGINT (21) DEFAULT '0' NOT NULL");
+
+	$spip_translate_key = array(
+                "PRIMARY KEY"   => "id_old, id_new, type",
+                "KEY id_old"        => "id_old");
+
+	include_spip('base/create');
+	spip_create_table('spip_translate', $spip_translate, $spip_translate_key, true);
+	// au cas ou la derniere fois ce serait terminee anormalement
+	spip_query("DELETE FROM spip_translate");
+	return insere_2_init($request, $my_pos);
+}
+
+function translate_init($request, $my_pos=0) {
+  /* 
+   construire le tableau PHP de la table spip_translate
+   (on l'a mis en table pour pouvoir reprendre apres interruption
+   mais cette reprise n'est pas encore programmee)
+  */
+	$q = spip_query("SELECT * FROM spip_translate");
+	$trans = array();
+	while ($r = spip_fetch_array($q)) {
+		$trans[$r['type']][$r['id_old']] = $r['id_new'];
+	}
+	return $trans;
+}
 
 // http://doc.spip.org/@inc_import_1_3_dist
-function inc_import_1_3_dist($f, $gz=false) {
-  global $import_ok, $abs_pos, $my_pos;
+function inc_import_1_3_dist($lecteur, $request, $gz=false, $trans=array()) {
+	global $import_ok, $abs_pos, $my_pos, $tables_trans;
 	static $tables = '';
+	static $phpmyadmin, $fin;
 	static $field_desc = array ();
+	static $defaut = array('field' => array());
+
+	// au premier appel, init des invariants de boucle 
+
+	if (!$tables OR $trans) {
+		$init = $request['init'];
+		$tables = $init($request, $my_pos);
+		$phpmyadmin = preg_match("{^phpmyadmin::}is",
+			$GLOBALS['meta']['version_archive_restauration'])
+			? array(array('&quot;','&gt;'),array('"','>'))
+			: false;
+		$fin = '/' . $GLOBALS['meta']['tag_archive_restauration'];
+	}
 
-	global $tables_trans;
-	static $primary_table;
-	static $relation_liste;
-	global $tables_principales;
-	global $tables_auxiliaires;
+	$b = '';
 
-	// au premier appel, detruire les tables a restaurer
+	if (!($table = xml_fetch_tag($lecteur, $b, $gz))) return false;
+	if ($table == $fin) return !($import_ok = true);
+	$new = isset($tables_trans[$table]) ? $tables_trans[$table]: $table; 
 
-	if (!$tables)
-		$tables = (!$my_pos) ? import_init_tables() : import_table_choix();
+	// indique a la fois la fonction a appliquer
+	// et les infos qu'il faut lui communiquer
+	$boucle = $request['boucle'];
 
-	$phpmyadmin = preg_match("{^phpmyadmin::}is", $GLOBALS['meta']['version_archive_restauration']);
-	$tag_fermant = $GLOBALS['meta']['tag_archive_restauration'];
-	$import_ok = false;
+	if (!in_array($new,$tables))
+		$field_desc[$boucle][$table] = $desc = $defaut;
+	elseif (isset($field_desc[$boucle][$table]))
+		$desc = $field_desc[$boucle][$table];
+	else {
+// recuperer la description de la table pour connaitre ses champs valides
+		list($nom,$desc) = description_table($table);
+		if (!isset($desc['field']))
+			$desc = $defaut;
+		else {
+			if ($request['insertion']=='on') {
+// Ne memoriser que la cle primaire pour le premier tour de l'insertion.
+// car les autres valeurs rentreraient en conflit avec les presentes
+				$p = $desc['key']["PRIMARY KEY"];
+				$desc['field'] = array($p => $desc['field'][$p]);
+			}
+		}
+		$field_desc[$boucle][$table] = $desc;
+	}
 
-	$b = '';
-	// Lire le type d'objet
-	if (!($table = xml_fetch_tag($f, $b, $gz))) return false;
-	if ($table == ('/'.$tag_fermant)) return !($import_ok = true);
-	#spip_log("import_objet_1_3 : table $table");
+	$values = import_lire_champs($lecteur,
+				     $desc['field'],
+				     $gz,
+				     $phpmyadmin,
+				     '/' . $table);
+	
+	if ($values === false) return  ($import_ok = false);
+	if ($values) {
+		if (!$boucle($values, $new, $desc, $trans)) {
+			$GLOBALS['erreur_restauration'] = spip_sql_error();
+		}
+	}
 
-	if (!isset($field_desc[$table])){
-		// recuperer la description de la table pour connaitre ses champs valides
-		list($nom,$desc) = description_table($table);
-		if (isset($desc['field']))
-			$field_desc[$table] = $desc['field'];
-		else
-			$field_desc[$table] = NULL;
+	return $import_ok = $new;
+}
+
+function import_replace($values, $table, $desc, $trans) {
+	return spip_query("REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .join(',',$values) . ')');
+}
+
+function import_insere($values, $table, $desc, $trans) {
+	// reserver une place dans les tables principales
+	$n = spip_abstract_insert($table, '', '()');
+	// et memoriser la correspondance dans la table auxilaire
+	if ($n) {
+		$type_id = $desc['key']["PRIMARY KEY"];
+		$n = spip_abstract_insert('spip_translate',
+			"(id_old, id_new, type)",
+			"(". $values[$type_id] .",$n,'$type_id')");
+	}
+	return $n;
+}
+
+function import_translate($values, $table, $desc, $trans) {
+	$vals = '';
+
+	foreach ($values as $k => $v) {
+
+		if ($k=='id_parent' OR $k=='id_secteur') $k = 'id_rubrique';
+
+		if (isset($trans[$k]) AND isset($trans[$k][$v])) {
+			$v = $trans[$k][$v];
+		}
+		$vals .= ",$v";
 	}
-	$fields = $field_desc[$table];
+	return spip_query("REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .substr($vals,1) . ')');
+}
 
-	// Lire les champs de l'objet
+function import_lire_champs($f, $fields, $gz, $phpmyadmin, $table)
+{
+	$values = array();
 	for (;;) {
 		$b = '';
 		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
-		if ($col == '/'.$table) break;
-		if (substr($col,0,1) == '/')
-		{ // tag fermant ici : probleme erreur de format
-			spip_log("restauration : table $table tag fermant $col innatendu");
-		  break;
+		if ($col[0] == '/') { 
+			if ($col != $table) 
+		    // autre tag fermant ici est une erreur de format
+				spip_log("restauration : table $table tag fermant $col innatendu");
+			break;
 		}
 		$value = '';
 		if (!xml_fetch_tag($f, $value, $gz)) return false;
 
-		if ( ($col != 'maj')
-			&& ($fields==NULL or isset($fields[$col])) ) {
+		if ( ($col != 'maj') AND (isset($fields[$col])) ) {
 			if ($phpmyadmin)
-				$value = str_replace(array('&quot;','&gt;'),array('"','>'),$value);
-			$values[$col] = _q($value);
+				$value = str_replace($phpmyadmin[0],$phpmyadmin[1],$value);
+			$values[$col]= _q($value);
 		}
 	}
-	
-	if (isset($tables_trans[$table])) $table = $tables_trans[$table];
-#	spip_log("import_objet_1_3 : $table " . in_array($table,$tables));
-	if (in_array($table,$tables)){
-
-		if (!spip_query("REPLACE $table (" . join(',', array_keys($values)) . ') VALUES (' . join(',', $values) . ')')) {
-			echo "--><br><font color='red'><b>"._T('avis_erreur_mysql')."</b></font>\n<font color='black'><tt>".spip_sql_error()."</tt></font>\n<!--";
-			$GLOBALS['erreur_restauration'] = true;
-		}
-	}
-
 
-	return $import_ok = " $table ";
+	return $values;
 }
 ?>
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index fba72239bfe707823b0aa201c31a9c0db812f5b8..d2d0be01575dd7149e89824b3cce3adcf81c6358 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -225,8 +225,8 @@ function spip_query($query, $serveur='') {
 
 // a demenager dans base/abstract_sql a terme
 // http://doc.spip.org/@_q
-function _q($arg_sql) {
-	return (is_int($arg_sql)) ? $arg_sql : ("'" . addslashes($arg_sql) . "'");
+function _q($a) {
+	return (is_numeric($a)) ? strval($a) : ("'" . addslashes($a) . "'");
 }
 
 // Renvoie le _GET ou le _POST emis par l'utilisateur