diff --git a/test/should_work/appli_para_pre.lus b/test/should_work/appli_para_pre.lus
new file mode 100644
index 0000000000000000000000000000000000000000..91e04523f14e43c7f453c6521e91374926324462
--- /dev/null
+++ b/test/should_work/appli_para_pre.lus
@@ -0,0 +1,223 @@
+
+(*
+partage du boulot entre :
+- CGEN: le compilo 'classique' Lustre, indépendant d'un choix
+	d'implem parallele particilier ; l'idée générale
+	est d'avoir un code à 'trous' que le générateur de glue 'para'	doit remplir.
+	TODO ce code peut être à base de :
+	- fonctions (le 'collage' se fait dynamiquement)
+	- macros (le collage PEUT se faire à compile-time)
+	=> on regarde les 2 solutions, tant qu'on a pas fait de choix on 
+	parle de 'hook' sans prciser si c'est un fonction ou une macro
+- PGEN: le générateur de glue 'parallele' qui récupère les infos
+	du compilo est remplit les trous suivant le mode de parallelisme
+	choisi
+
+IMPORTANT: Les nodes utilisés dans un 'para' DOIVENT être compilés
+en mode '-2ch', i.e. :
+- passage de paramètre via le contexte 
+- step avec un seul argument (le pointeur sur l'instance)
+Pour simplifier ici, on compile tout en '-2ch'
+IMPORTANT: Ici on compile en --no-prefix pour avoir du code + lisible
+*)
+
+node D(x: int) returns (o: int); 
+let
+	o = 0 -> (x - pre x) / 2;
+tel
+
+node A(x: int) returns (o: int);
+let
+	o = x + (0 -> pre o);
+tel
+
+node C(x, y: int) returns (o: int);
+let
+	o = 0 -> pre (x + y);
+tel
+
+
+(*
+D, A, C n'ont pas de para, on génère le code classique :
+- struct: 'D_ctx_type' (avec champs x i(in) et o (out))
+- step: void D_step(D_ctx_type* ctx)
+
+Si A ou D sont utilisé par ailleurs dans un 'para' on a besoin d'une interface
+'para' générique abstraite, que le PGEN devra défénir :
+- un type abstrait 'D_TASK' (une valeur de base, e.g. un entier, un pointeur
+	qui identifie de manière unique l'instance de la task)
+- un hook
+	D_TASK_INIT()
+qui renvoie une valeur de type 'task_D' qui sera utilisée dans tout les autres hook
+- un hook par input, ici 
+	D_TASK_SETIN_x(tD, v)
+- 2 hooks
+	D_TASK_START(tD)
+	D_TASK_JOIN(tD)
+- un hook par output, ici 
+	D_TASK_GETOUT_o(tD, v)
+- un hook 
+	D_TASK_RESET_D(tD)
+*)
+
+
+node B(x: int) returns (o: int);
+var l, d : int;
+let
+	l = A(5 * x - 12);
+	d = %MT:task1% D(x); --para
+	o = 3 * d - l;
+tel
+
+(*
+B contient une instance  para de D :
+- dans B_ctx_type, au lieu de réserver un
+	un contexte séquentiel classique de type 'D_ctx_type',
+	on réserve un 'D_task'
+
+typedef struct {
+   /*INPUTS*/
+   _integer x;
+   /*OUTPUTS*/
+   _integer o;
+   /*INSTANCES*/
+   D_TASK D_TASK_tab[1];
+   A_ctx_type A_ctx_tab[1];
+} B_ctx_type;
+
+
+- WARNING en séquentiel, on a une seule fonction 'reset'
+	qui sert de 'init', en para il faut les DEUX ! 
+	- init qui doit être appelée un seule fois au début 
+	- reset qui peut être appelé n'imoprte quand pour remattre le temps à 0
+
+void B_ctx_reset(B_ctx_type* ctx){
+  int _i;
+	D_TASK_RESET_D(tx->D_TASK_tab[0])
+	A_ctx_reset(&ctx->A_ctx_tab[0]);
+}
+
+void B_ctx_init(B_ctx_type* ctx){
+  int _i;
+	ctx->D_TASK_tab[0] = D_TASK_INIT();
+	B_ctx_reset(ctx);
+}
+
+La génération du step (le tri topo) est modifiée pour placer
+correctement les appels des hooks :
+
+
+void B_step(B_ctx_type* ctx){
+   _integer _X_5;
+   _integer _X_4;
+   _integer _X_3;
+   _integer l;
+   _integer d;
+
+	// tri topo -> on lance D_task au plus tôt
+	//n.b. avant: ctx->D_ctx_tab[0].x = ctx->x;
+	D_TASK_SETIN_x(&ctx->D_TASK_tab[0], ctx->x;)
+	D_TASK_START(ctx->D_TASK_tab[0]);
+
+
+  _X_3 = 5 * ctx->x;
+  _X_4 = _X_3 - 12;
+  ctx->A_ctx_tab[0].x = _X_4;
+  A_step(&ctx->A_ctx_tab[0]);
+  l = ctx->A_ctx_tab[0].o;
+
+	//n.b. avant: 
+  	//D_step(&ctx->D_ctx_tab[0]);
+  	//d = ctx->D_ctx_tab[0].o;
+	D_TASK_JOIN(ctx->D_task_tab[0]);
+	D_TASK_GETOUT_o(d);
+	//WARNING: c'est une version 'macro'
+	// il y a un choix à faire, e.g.
+	// peut-etre D_TASK_GETOUT_o(&d),
+	// voire d = D_TASK_GETOUT_o()
+
+  _X_5 = 3 * d;
+  ctx->o = _X_5 - l;
+
+} // End of B_step
+
+N.B. Pour la compil modulaire, les nodes qui utilisent 
+B DOIVENT SAVOIR QUE B 'utilise une D_task 
+*)
+
+node appli_para_pre(
+	z, y : int
+) returns (
+	o : int
+);
+var a, b1, b2: int;
+let
+	a = A(z);
+	b1 = B(y);
+	b2 = B(b1);
+	o = C(a,b1);
+tel
+
+(*
+top utilise un 'para', donc on créé une A_task (comme pour B avec sa task D) 
+de plus il 'hérite' des tasks des 2 instances de B 
+
+typedef struct {
+   /*INPUTS*/
+   _integer x;
+   _integer y;
+   /*OUTPUTS*/
+   _integer o;
+   /*INSTANCES*/
+   B_ctx_type B_ctx_tab[2];
+   A_TASK A_TASK_tab[1];
+} top_ctx_type;
+
+void top_ctx_reset(top_ctx_type* ctx){
+  int _i;
+
+    B_ctx_reset(&ctx->B_ctx_tab[0]);
+    B_ctx_reset(&ctx->B_ctx_tab[1]);
+    A_TASK_reset(&ctx->A_TASK_tab[0]);
+}
+
+void top_ctx_init(top_ctx_type* ctx){
+  int _i;
+
+    B_ctx_init(&ctx->B_ctx_tab[0]);
+    B_ctx_init(&ctx->B_ctx_tab[1]);
+    &ctx->A_TASK_tab[0] = A_TASK_init();
+	top_ctx_reset(ctx);
+}
+
+void top_step(top_ctx_type* ctx){
+   _integer a;
+   _integer b1;
+   _integer b2;
+
+  //avant:
+  //ctx->A_ctx_tab[0].x = ctx->x;
+  //A_step(&ctx->A_ctx_tab[0]);
+	A_TASK_SETIN_x(&ctx->A_TASK_tab[0], ctx->x;)
+	A_TASK_START(ctx->A_TASK_tab[0]);
+
+  ctx->B_ctx_tab[0].x = ctx->y;
+  B_step(&ctx->B_ctx_tab[0]);
+  b1 = ctx->B_ctx_tab[0].o;
+
+  ctx->B_ctx_tab[1].x = b1;
+  B_step(&ctx->B_ctx_tab[1]);
+  b2 = ctx->B_ctx_tab[1].o;
+
+  //avant:
+  //a = ctx->A_ctx_tab[0].o;
+	A_TASK_JOIN(ctx->A_TASK_tab[0]);
+	A_TASK_GETOUT_o(a);
+	
+  C_ctx.x = a;
+  C_ctx.y = b1;
+  C_step();
+  ctx->o = C_ctx.o;
+
+}
+*)