diff --git a/ecrire/exec/admin_tech.php b/ecrire/exec/admin_tech.php
index 022fc5822e5ed11184e92a1d626e9a88a025743e..72f8bb4b6b90435dfdfe20d60d55d9b781797b15 100644
--- a/ecrire/exec/admin_tech.php
+++ b/ecrire/exec/admin_tech.php
@@ -145,6 +145,10 @@ echo "</table>";
 	echo  "<p><input name='insertion' type='radio' />&nbsp;",
 	  _L('Fusionner la base actuelle et la sauvegarde'),
 	  '</p>';
+	echo  "<p>",
+	  _L("Eventuellement, URL du site d'origine&nbsp;:"),
+	  "<input name='url_site' type='texte' />",
+	  '</p>';
 	fin_cadre_relief();
 
 	echo "\n</p><div align='right'><input class='fondo' type='submit' value='",
diff --git a/ecrire/exec/import_all.php b/ecrire/exec/import_all.php
index 9fbae317cf140d108f4a49f42f962c74fcd7578a..0a295ffdeef9b501ec1e5d92398b886494e4cc07 100644
--- a/ecrire/exec/import_all.php
+++ b/ecrire/exec/import_all.php
@@ -116,39 +116,43 @@ function exec_import_all_dist()
 	// precaution inutile I think (esj)
 	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) {
-
-		global $trans;
-		if ($request['insertion'] == 'passe2') {
-			include_spip('inc/import_insere');
-			$trans = translate_init($request);
-		} else $trans = array();
-
-		$res = import_tables($request, $dir);
-	}
+	$res = $my_date ? import_all_milieu($request, $dir) : '';
 
 	echo $res, "</body></html>\n";
 
-	if ($request['insertion'] == 'on') {
+	if ($request['insertion'] == 'on' AND $res) {
 			$request['insertion'] = 'passe2';
+			if ($request['url_site']
+			AND substr($request['url_site'],-1) != '/')
+				$request['url_site'] .= '/';
 			import_all_debut($request);
-			redirige_par_entete('./');
-	} else if ($request['insertion']) 
-			spip_query("DROP TABLE spip_translate");
-	  
+			$res = import_all_milieu($request, $dir);
+	}
+ 
 	if ($charset = $GLOBALS['meta']['charset_restauration']) {
 			ecrire_meta('charset', $charset);
 			ecrire_metas();
 	}
 
 	detruit_restaurateur();
-	import_all_fin();
+	import_all_fin($request);
 	include_spip('inc/rubriques');
 	calculer_rubriques();
 
 	if (!$res) ecrire_acces();	// Mise a jour du fichier htpasswd
 }
 
+function import_all_milieu($request, $dir)
+{
+	global $trans;
+	if ($request['insertion'] == 'passe2') {
+		include_spip('inc/import_insere');
+		$trans = translate_init($request);
+	} else $trans = array();
+
+	return import_tables($request, $dir);
+}
+
 // http://doc.spip.org/@import_all_debut
 function import_all_debut($request) {
 	ecrire_meta("request_restauration", serialize($request));
@@ -158,7 +162,7 @@ function import_all_debut($request) {
 }
 
 // http://doc.spip.org/@import_all_fin
-function import_all_fin() {
+function import_all_fin($request) {
 
 	effacer_meta("charset_restauration");
 	effacer_meta("charset_insertion");
@@ -169,6 +173,9 @@ function import_all_fin() {
 	effacer_meta('version_archive_restauration');
 	effacer_meta('tag_archive_restauration');
 	ecrire_metas();
+	if ($request['insertion'] == 'passe2') 
+		spip_query("DROP TABLE spip_translate");
+	 
 }
 
 // http://doc.spip.org/@import_queldir
diff --git a/ecrire/inc/import.php b/ecrire/inc/import.php
index a06e0a97f4e1588556ed6910a8c054eeeff17824..bb0d6056648a55bac3d85dd515f631f9689ecee9 100644
--- a/ecrire/inc/import.php
+++ b/ecrire/inc/import.php
@@ -121,9 +121,6 @@ function import_debut($f, $gz='fread') {
 			return $r;
 		}
 	}
-	// improbable: fichier correct avant debut_admin et plus apres
-	import_all_fin();
-	die(_T('info_erreur_restauration'));
 }
 
 // on conserve ce tableau pour faire des translations
@@ -180,7 +177,8 @@ function import_tables($request, $dir) {
 
 	if ($request['insertion']=='on') {
 		include_spip('inc/import_insere');
-		$request['init'] = (!$abs_pos) ? 'insere_1_init' : 'insere_2_init';		$request['boucle'] = 'import_insere';
+		$request['init'] = (!$abs_pos) ? 'insere_1_init' : 'insere_1bis_init';
+		$request['boucle'] = 'import_insere';
 	} elseif ($request['insertion']=='passe2') {
 		$request['init'] = 'insere_2_init';
 		$request['boucle'] = 'import_translate';
@@ -205,6 +203,8 @@ function import_tables($request, $dir) {
 
 	if ($abs_pos==0) {
 		list($tag, $r, $charset) = import_debut($file, $gz);
+	// improbable: fichier correct avant debut_admin et plus apres
+		if (!$tag) return !($import_ok = true);
 // tag ouvrant du Dump:
 // 'SPIP' si fait par spip, nom de la base source si fait par  phpmyadmin
 		$version_archive = $r['version_archive'];
@@ -230,18 +230,25 @@ function import_tables($request, $dir) {
 	flush();
 
 	$oldtable ='';
+	$cpt = 0;
+	$pos = $abs_pos;
 	while ($table = $fimport($file, $request, $gz)) {
 	  // memoriser pour pouvoir reprendre en cas d'interrupt,
 	  // mais pas d'ecriture sur fichier, ca ralentit trop
 		ecrire_meta("status_restauration", "$abs_pos");
 		if ($oldtable != $table) {
-			spip_log("Restauration de $table (commence en $abs_pos)");
+			if ($oldtable) spip_log("$cpt entrees");
+			spip_log("Analyse de $table (commence en $pos)");
 			affiche_progression_javascript($abs_pos,$size,$table);
 			$oldtable = $table;
-		}
+			$cpt = 0;
+			$pos = $abs_pos;
+		} 
+		$cpt++;
 	}
+	spip_log("$cpt entrees");
 
-	if (!$import_ok) 
+	if (!$import_imok) 
 		$res =  _T('avis_archive_invalide');
 	else {
 		$res = '';
diff --git a/ecrire/inc/import_1_3.php b/ecrire/inc/import_1_3.php
index b4a559dd6f7f7130ff3072429f2b3e3ad233a1cd..971c49930541c20582800d4968c6f3c0c4a57122 100644
--- a/ecrire/inc/import_1_3.php
+++ b/ecrire/inc/import_1_3.php
@@ -78,7 +78,7 @@ function inc_import_1_3_dist($lecteur, $request, $gz='fread') {
 			if ($request['insertion']=='on') {
 // Au premier tour de l'insertion, ne memoriser que le strict necessaire 
 // pour pouvoir identifier avec l'existant.
-
+// (Faudrait convenir d'une structure de donnees, c'est lourd & inextensible)
 				$b = array();
 				if (isset($desc['field'][$p='titre']))
 					$b[$p]= $desc['field'][$p];
@@ -86,6 +86,13 @@ function inc_import_1_3_dist($lecteur, $request, $gz='fread') {
 					$b[$p]= $desc['field'][$p];
 				if (isset($desc['field'][$p='id_parent']))
 					$b[$p]= $desc['field'][$p];
+				if (isset($desc['field'][$p='id_rubrique']))
+					$b[$p]= $desc['field'][$p];
+				if (isset($desc['field'][$p='fichier'])) {
+					$b[$p]= $desc['field'][$p];
+					$b['taille']= $desc['field']['taille'];
+					spip_log("pass1 " . join(',', array_keys($b)));
+				}
 				$p = $desc['key']["PRIMARY KEY"];
 				$b[$p] = $desc['field'][$p];
 				$desc['field'] = $b; 
diff --git a/ecrire/inc/import_insere.php b/ecrire/inc/import_insere.php
index 30ef76ccbe9dc489887b476df3cb974f00997d69..0d01682ceb8529f3f39e52837daecd127fa892e1 100644
--- a/ecrire/inc/import_insere.php
+++ b/ecrire/inc/import_insere.php
@@ -12,27 +12,6 @@
 
 if (!defined("_ECRIRE_INC_VERSION")) return;
 
-// http://doc.spip.org/@insere_2_init
-function insere_2_init($request) {
-
-	// l'insertion porte 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)]);
-	// et les tables auxiliaires sur les mots car on sait les identifier
-	$t[]= 'spip_mots_articles';
-	$t[]= 'spip_mots_breves';
-	$t[]= 'spip_mots_rubriques';
-	$t[]= 'spip_mots_syndic';
-	$t[]= 'spip_mots_forum';
-	$t[]= 'spip_mots_documents';
-
-	return $t;
-}
-
 // http://doc.spip.org/@insere_1_init
 function insere_1_init($request) {
 
@@ -52,7 +31,38 @@ function insere_1_init($request) {
 	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);
+	return insere_1bis_init($request);
+}
+
+// http://doc.spip.org/@insere_2_init
+function insere_1bis_init($request) {
+
+	// l'insertion porte 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;
+}
+
+// En passe 2, relire les tables principales et les tables auxiliaires 
+// sur les mots et les documents car on sait les identifier
+
+function insere_2_init($request) {
+	$t = insere_1bis_init($request);
+
+	$t[]= 'spip_mots_articles';
+	$t[]= 'spip_mots_breves';
+	$t[]= 'spip_mots_rubriques';
+	$t[]= 'spip_mots_syndic';
+	$t[]= 'spip_mots_forum';
+	$t[]= 'spip_mots_documents';
+	$t[]= 'spip_documents_articles';
+	$t[]= 'spip_documents_rubriques';
+
+	return $t;
 }
 
 //   construire le tableau PHP de la table spip_translate
@@ -88,56 +98,93 @@ function import_insere($values, $table, $desc, $request) {
 		}
 		$ajout = 1;
 	}
-	// et memoriser la correspondance dans la table auxiliaire
-	// si different et pas de recherche dessus plus tard
-	if (($n != $values[$type_id]) OR $type_id == 'id_groupe') {
-		if (is_array($n))
-		  list($id, $titre) = $n; 
-		else {$id = $n; $titre = "";}
-		spip_abstract_insert('spip_translate',
+
+	if (is_array($n))
+		list($id, $titre) = $n; 
+	else {$id = $n; $titre = "";}
+	spip_abstract_insert('spip_translate',
 				"(id_old, id_new, titre, type, ajout)",
 				     "(". $values[$type_id] .",$id, " . _q($titre) . ", '$type_id', '$ajout')");
-	}
 }
 
 // Renumerotation des entites collectees
-// Le tableau de correspondance est passe en reference pour que le nouveau
-// numero d'une entite soit calcule une seule fois, a sa premiere occurrence.
-// Si une allocation est finalement necessaire, la renumerotation
-// est repercutee sur la table SQL temporaire pour qu'en cas de reprise
-// sur Time-Out il n'y ait pas reallocation.
-// Autrement on evite cet acces SQL, quitte a recalculer le nouveau numero
-// si une autre occurrence est rencontree a la reprise. Pas dramatique.
+// Appelle la fonction specifique a la table, ou a defaut la std.
+// Le tableau de correspondance est global, et permet qu'un numero
+// d'une entite soit calcule une seule fois, a sa premiere occurrence.
+// (Mais des requetes avec jointures eviteraient sa construction. A voir)
 
 // http://doc.spip.org/@import_translate
 function import_translate($values, $table, $desc, $request) {
+
+	if (!function_exists($f = 'import_translate_' . $table))
+	  $f = 'import_translate_std';
+	$f($values, $table, $desc, $request);
+}
+
+// La fonction d'insertion apres renumerotation.
+// Afin qu'inserer une 2e fois la meme sauvegarde ne change pas la base,
+// chaque entree de la sauvegarde est ignoree s'il existe une entree
+// de meme titre avec le meme contexte (parent etc) dans la base installee.
+// Une synchronisation plus fine serait preferable, cf [8002]
+
+function import_inserer_translate($values, $table, $desc, $request, $vals) {
 	global $trans;
+	$p = $desc['key']["PRIMARY KEY"];
+	$v = $values[$p];
+	if (!isset($trans[$p]) OR !isset($trans[$p][$v]) OR $trans[$p][$v][2])
+		spip_query("REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .substr($vals,1) . ')');
+}
+
+// Insertion avec renumerotation, y compris des raccourcis.
+function import_translate_std($values, $table, $desc, $request) {
+
 	$vals = '';
 
 	foreach ($values as $k => $v) {
-		if ($k=='id_parent' OR $k=='id_secteur') $k = 'id_rubrique';
+		if (($k=='chapo') AND preg_match(',^=(\d+)(.*)$,', $v, $m))
+			$v = '=' . importe_translate_maj('id_article',$m[1]).$m[2];
+		else {
+			if ($k=='id_parent' OR $k=='id_secteur')
+				$k = 'id_rubrique';
+			$v = importe_raccourci($k,importe_translate_maj($k, $v));
+		}
+		$vals .= "," . _q($v);
+	}
+	import_inserer_translate($values, $table, $desc, $request, $vals);
+}
 
-		$v = importe_translate_maj($k, $v);
+function import_translate_spip_documents($values, $table, $desc, $request) {
 
-		if (preg_match_all(_RACCOURCI_LIEN, $v, $m, PREG_SET_ORDER)) {
-			foreach ($m as $regs) {
-				$v = importe_raccourci($regs, $k, $v);
-			}
-		}
 
-		$vals .= "," . _q($v);
+	if (isset($request['url_site'])) {
+		$distancer = ($values['distant'] == 'non');
+		$url = $request['url_site'];
+	} else  $distancer = false;
+
+	$values['distant']= 'oui';
+
+	$vals = '';
+	foreach ($values as $k => $v) {
+	  if ($distancer AND $k=='fichier')
+	    $v = $url .$v;
+	  else $v = importe_raccourci($k,importe_translate_maj($k, $v));
+	  $vals .= "," . _q($v);
 	}
-	// pas la peine d'ecraser avec les memes valeurs si rien de neuf
-	$p = $desc['key']["PRIMARY KEY"];
-	$v = $values[$p];
-	if (!isset($trans[$p]) OR !isset($trans[$p][$v]) OR $trans[$p][$v][2])
-		spip_query($q = "REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .substr($vals,1) . ')');
+	import_inserer_translate($values, $table, $desc, $request, $vals);
 }
 
+// Fonction de renumerotation, par delegation aux fonction specialisees
+// Si une allocation est finalement necessaire, celles-ci doivent repercuter
+// la renumerotation sur la table SQL temporaire pour qu'en cas de reprise
+// sur Time-Out il n'y ait pas reallocation.
+// En l'absence d'allocation, cet acces SQL peut etre omis, quitte a 
+// recalculer le nouveau numero  si une autre occurrence est rencontree
+// a la reprise. Pas dramatique.
+
 // http://doc.spip.org/@importe_translate_maj
 function importe_translate_maj($k, $v)
 {
-  global $trans;
+	global $trans;
 	if (!(isset($trans[$k]) AND isset($trans[$k][$v]))) return $v;
 
 	list($g, $titre, $ajout) = $trans[$k][$v];
@@ -154,27 +201,41 @@ function importe_translate_maj($k, $v)
 }
 
 // http://doc.spip.org/@importe_raccourci
-function importe_raccourci($regs, $k, $v)
+function importe_raccourci($k, $v)
 {
-	$lien = vider_url($regs[3]); # supprimer 'http://' ou 'mailto:'
-
-	if (!$match = typer_raccourci($lien)) return $v;
-
-	list($f,$objet,$id,$params,$ancre) = $match;
-
-	$k = 'id_' . $f;
-	$g = importe_translate_maj($k, $id);
-
-	if ($g == $id) return $v;
+	if (preg_match_all(_RACCOURCI_LIEN, $v, $m, PREG_SET_ORDER)) {
+		foreach ($m as $regs) {
+		  // supprimer 'http://' ou 'mailto:'
+		  	$lien = vider_url($regs[3]);
+			if ($match = typer_raccourci($lien)) {
+				list($f,$objet,$id,$params,$ancre) = $match;
+				$k = 'id_' . $f;
+				$g = importe_translate_maj($k, $id);
+				if ($g != $id) {
+
+				  $rac = '[' . $regs[1] . '->' . $reg[2] . $objet . $g . $params . $ancre .']';
+				  $v = str_replace($regs[0], $rac, $v);
+				}
+			}
+		}
+	}
+	return $v;
+}
 
-	$rac = '[' . $regs[1] . '->' . $reg[2] . $objet . $g . $params . $ancre .']';
-	return str_replace($regs[0], $rac, $v);
+// un document importe est considere comme identique a un document present
+// s'ils ont meme taille et meme nom
+function import_identifie_id_document($values, $table, $desc, $request) {
+	$t = $values['taille'];
+	$f = $values['fichier'];
+	$h = $request['url_site'] . $f;
+	$r = spip_fetch_array(spip_query($q="SELECT id_document, fichier FROM spip_documents WHERE taille=" . _q($t) . " AND (fichier=" . _q($f) . " OR fichier= " . _q($h) . ')'), SPIP_NUM);
+	return $r;
 }
 
 // deux groupes de mots ne peuvent avoir le meme titre ==> identification
 // http://doc.spip.org/@import_identifie_id_groupe
 function import_identifie_id_groupe($values, $table, $desc, $request)  {
-	$r = spip_fetch_array(spip_query($q = "SELECT id_groupe, titre FROM spip_groupes_mots WHERE titre=" . _q($values['titre'])), SPIP_NUM);
+	$r = spip_fetch_array(spip_query("SELECT id_groupe, titre FROM spip_groupes_mots WHERE titre=" . _q($values['titre'])), SPIP_NUM);
 	return $r;
 }
 
@@ -185,11 +246,11 @@ function import_identifie_id_mot($values, $table, $desc, $request) {
 	return array((0 - $values['id_groupe']), $values['titre']);
 }
 
-// mot de meme titre et de meme groupe ==> identification
+// Passe 2: mot de meme titre et de meme groupe ==> identification
 // http://doc.spip.org/@import_identifie_parent_id_mot
 function import_identifie_parent_id_mot($id_groupe, $titre, $v)
 {
-  global $trans;
+	global $trans;
 	$titre = _q($titre);
 	$id_groupe = 0-$id_groupe;
 	if (isset($trans['id_groupe'])
@@ -201,9 +262,30 @@ function import_identifie_parent_id_mot($id_groupe, $titre, $v)
 	$r = spip_abstract_insert('spip_mots', '', '()');
 	spip_query("REPLACE spip_translate (id_old, id_new, titre, type, ajout) VALUES ($v,$r,$titre,'id_mot',1)");
 	return $r;
+}
+
+// idem pour les articles
+function import_identifie_id_article($values, $table, $desc, $request) {
+	return array((0 - $values['id_rubrique']), $values['titre']);
+}
+
+// Passe 2 des articles comme pour les mots
+
+function import_identifie_parent_id_article($id_parent, $titre, $v)
+{
+	$id_parent = importe_translate_maj('id_rubrique', (0 - $id_parent));
 
+	$titre = _q($titre);
+	$r = spip_fetch_array(spip_query("SELECT id_article FROM spip_articles WHERE titre=$titre AND id_rubrique=$id_parent" ));
+
+	if ($r) return (0 - $r['id_article']);
+
+	$r = spip_abstract_insert('spip_articles', '', '()');
+	spip_query("REPLACE spip_translate (id_old, id_new, titre, type, ajout) VALUES ($v,$r,$titre,'id_article',1)");
+	return $r;
 }
 
+
 // pour une rubrique le titre est insuffisant, il faut l'identite du parent
 // Memoriser ces 2 infos et le signaler a import_translate grace a 1 negatif
 // http://doc.spip.org/@import_identifie_id_rubrique
@@ -211,7 +293,7 @@ function import_identifie_id_rubrique($values, $table, $desc, $request) {
 	return array((0 - $values['id_parent']), $values['titre']);
 }
 
-// renumerotation en cascade. 
+// Passe 2 des rubriques, renumerotation en cascade. 
 // rubrique de meme titre et de meme parent ==> identification
 // http://doc.spip.org/@import_identifie_parent_id_rubrique
 function import_identifie_parent_id_rubrique($id_parent, $titre, $v)
@@ -256,5 +338,4 @@ function import_alloue_id_rubrique($id_parent, $titre, $v) {
 	spip_query("REPLACE spip_translate (id_old, id_new, titre, type, ajout) VALUES ($v,$r,$titre,'id_rubrique',1)");
 	return $r;
 }
-
 ?>