diff --git a/src/annotations.ml b/src/annotations.ml
new file mode 100644
index 0000000000000000000000000000000000000000..ef7ca11e1fea3640de7dd2322d4e552aa366e72a
--- /dev/null
+++ b/src/annotations.ml
@@ -0,0 +1,22 @@
+(********************************************************************)
+(*                                                                  *)
+(*  The LustreC compiler toolset   /  The LustreC Development Team  *)
+(*  Copyright 2012 -    --   ONERA - CNRS - INPT                    *)
+(*                                                                  *)
+(*  LustreC is free software, distributed WITHOUT ANY WARRANTY      *)
+(*  under the terms of the GNU Lesser General Public License        *)
+(*  version 2.1.                                                    *)
+(*                                                                  *)
+(********************************************************************)
+
+open LustreSpec
+
+
+(* Associate to each annotation key the pair (node, expr tag) *)
+let expr_annotations : (string list, ident * tag) Hashtbl.t=  Hashtbl.create 13
+let node_annotations : (string list, ident) Hashtbl.t=  Hashtbl.create 13
+
+let add_expr_ann node_id expr_tag key = Hashtbl.add expr_annotations key (node_id, expr_tag)
+let add_node_ann node_id key = Hashtbl.add node_annotations key node_id
+
+let get_expr_annotations key = Hashtbl.find_all expr_annotations key
diff --git a/src/corelang.ml b/src/corelang.ml
index 603873d491dd324870e86da2b3ce7f0f11ffb427..799f09a227bb3e8bda2d5e0bb8082a80e2e48192 100755
--- a/src/corelang.ml
+++ b/src/corelang.ml
@@ -167,7 +167,10 @@ let merge_expr_annot ann1 ann2 =
       annot_loc = ann1.annot_loc
     }
 
-let update_expr_annot e annot =
+let update_expr_annot node_id e annot =
+  List.iter (fun (key, _) -> 
+    Annotations.add_expr_ann node_id e.expr_tag key
+  ) annot.annots;
   { e with expr_annot = merge_expr_annot e.expr_annot (Some annot) }
 
 
diff --git a/src/corelang.mli b/src/corelang.mli
index 4215eb70b45a61538937f16bf0f8ff98ef94fe4b..ef7603e78b515a83c98e8c71a027f9a5e7064ad5 100755
--- a/src/corelang.mli
+++ b/src/corelang.mli
@@ -116,7 +116,6 @@ val eq_replace_rhs_var: (ident -> bool) -> (ident -> ident) -> eq -> eq
 (** rename_prog f_node f_var f_const prog *)
 val rename_prog: (ident -> ident) -> (ident -> ident) -> (ident -> ident) -> program -> program
 
-val update_expr_annot: expr -> LustreSpec.expr_annot -> expr
 
 val substitute_expr: var_decl list -> eq list -> expr -> expr
 
@@ -124,7 +123,7 @@ val substitute_expr: var_decl list -> eq list -> expr -> expr
 val mkeexpr: Location.t ->  expr -> eexpr
 val merge_node_annot: node_annot -> node_annot -> node_annot 
 val extend_eexpr: (quantifier_type * var_decl list) list -> eexpr -> eexpr
-val update_expr_annot: expr -> expr_annot -> expr
+val update_expr_annot: ident -> expr -> LustreSpec.expr_annot -> expr
 (* val mkpredef_call: Location.t -> ident -> eexpr list -> eexpr*)
 
 (* Local Variables: *)
diff --git a/src/inliner.ml b/src/inliner.ml
index f948549ead30a9fdbe7ed5cd43ff843b342b55d0..0756ee85ac9358f5a84039be706a2509abed124b 100644
--- a/src/inliner.ml
+++ b/src/inliner.ml
@@ -11,6 +11,16 @@
 
 open LustreSpec
 open Corelang
+open Utils
+
+(* Local annotations are declared with the following key /inlining/: true *)
+let keyword = ["inlining"]
+
+let is_inline_expr expr = 
+match expr.expr_annot with
+| Some ann -> 
+  List.exists (fun (key, value) -> key = keyword) ann.annots
+| None -> false
 
 let check_node_name id = (fun t -> 
   match t.top_decl_desc with 
@@ -90,7 +100,9 @@ let inline_call orig_expr args reset locals node =
    variables and the code of called node instance added to new_eqs
 
 *)
-let rec inline_expr expr locals nodes =
+let rec inline_expr ?(selection_on_annotation=false) expr locals nodes =
+  let inline_expr = inline_expr ~selection_on_annotation:selection_on_annotation in
+  let inline_node = inline_node ~selection_on_annotation:selection_on_annotation in
   let inline_tuple el = 
     List.fold_right (fun e (el_tail, locals, eqs, asserts) -> 
       let e', locals', eqs', asserts' = inline_expr e locals nodes in
@@ -109,13 +121,17 @@ let rec inline_expr expr locals nodes =
     | [e1'; e2'; e3'] -> e1', e2', e3', l', eqs', asserts'
     | _ -> assert false
   in
-    
+  
   match expr.expr_desc with
   | Expr_appl (id, args, reset) ->
     let args', locals', eqs', asserts' = inline_expr args locals nodes in 
-    if List.exists (check_node_name id) nodes then 
+    if List.exists (check_node_name id) nodes && (* the current node call is provided
+						    as arguments nodes *)
+      (not selection_on_annotation || is_inline_expr expr) (* and if selection on annotation is activated, 
+							      it is explicitely inlined here *)
+    then 
       (* The node should be inlined *)
-      (* let _ =     Format.eprintf "Inlining call to %s@." id in *)
+       let _ =     Format.eprintf "Inlining call to %s@." id in 
       let node = try List.find (check_node_name id) nodes 
 	with Not_found -> (assert false) in
       let node = node_of_top node in
@@ -164,7 +180,8 @@ let rec inline_expr expr locals nodes =
     let el, l', eqs', asserts' = inline_tuple (List.map snd branches) in
     let branches' = List.map2 (fun (label, _) v -> label, v) branches el in
     { expr with expr_desc = Expr_merge (id, branches') }, l', eqs', asserts'
-and inline_node nd nodes = 
+and inline_node ?(selection_on_annotation=false) nd nodes = 
+  let inline_expr = inline_expr ~selection_on_annotation:selection_on_annotation in
   let new_locals, eqs, asserts = 
     List.fold_left (fun (locals, eqs, asserts) eq ->
       let eq_rhs', locals', new_eqs', asserts' = 
@@ -319,6 +336,23 @@ let global_inline basename prog type_env clock_env =
   );
   res
 
+let local_inline basename prog type_env clock_env =
+  let local_anns = Annotations.get_expr_annotations keyword in
+  if local_anns != [] then (
+    let nodes_with_anns = List.fold_left (fun accu (k, _) -> ISet.add k accu) ISet.empty local_anns in
+    ISet.iter (fun node_id -> Format.eprintf "Node %s has local expression annotations@." node_id) nodes_with_anns;
+    List.fold_right (fun top accu -> 
+      ( match top.top_decl_desc with
+      | Node nd when ISet.mem nd.node_id nodes_with_anns ->
+	{ top with top_decl_desc = Node (inline_node ~selection_on_annotation:true nd prog) }
+      | _ -> top
+      )::accu) prog []
+    
+)
+ else
+  prog
+
+
 (* Local Variables: *)
 (* compile-command:"make -C .." *)
 (* End: *)
diff --git a/src/main_lustre_compiler.ml b/src/main_lustre_compiler.ml
index 72416348418445bafbc58202e010dd58f92dca57..6332d662f959dc9724681e635242857c5d15cc9f 100644
--- a/src/main_lustre_compiler.ml
+++ b/src/main_lustre_compiler.ml
@@ -127,12 +127,12 @@ let rec compile_source dirname basename extension =
     if !Options.global_inline &&
       (match !Options.main_node with | "" -> false | _ -> true) then
       Inliner.global_inline basename prog type_env clock_env
-    else
-      prog
+    else (* if !Option.has_local_inline *)
+      Inliner.local_inline basename prog type_env clock_env
   in
 
   (* Delay calculus *)
-  (*
+  (* TO BE DONE LATER (Xavier)
     if(!Options.delay_calculus)
     then
     begin
@@ -146,18 +146,7 @@ let rec compile_source dirname basename extension =
     raise exc
     end;
   *)
-  (*
-    eprintf "Causality analysis@.@?";
-    (* Causality analysis *)
-    begin
-    try
-    Causality.check_causal_prog prog
-    with (Causality.Cycle v) as exc ->
-    Causality.pp_error err_formatter v;
-    raise exc
-    end;
-  *)
-
+  
   (* Creating destination directory if needed *)
   create_dest_dir ();
 
diff --git a/src/parserLustreSpec.mly b/src/parserLustreSpec.mly
index 17fb13120b88b9b53c0b07784ac8095de20294ac..9b798551cb78bf46ce537d2ec598550909cc5687 100644
--- a/src/parserLustreSpec.mly
+++ b/src/parserLustreSpec.mly
@@ -73,7 +73,7 @@
 %nonassoc UMINUS
 
 %start lustre_annot
-%type <LustreSpec.expr_annot> lustre_annot
+%type <LustreSpec.ident -> LustreSpec.expr_annot> lustre_annot
 
 %start lustre_spec
 %type <LustreSpec.node_annot> lustre_spec
@@ -287,7 +287,7 @@ const:
 | STRING {Const_string $1}
 
 lustre_annot:
-lustre_annot_list EOF { $1 }
+lustre_annot_list EOF { fun node_id -> $1 }
 
 lustre_annot_list:
   { [] } 
diff --git a/src/parser_lustre.mly b/src/parser_lustre.mly
index 69af04db6187ba8c47cfc41d0fd83a1ae7bf08e0..314e9c889043bac1c747d26b39c248fae8d1f25e 100755
--- a/src/parser_lustre.mly
+++ b/src/parser_lustre.mly
@@ -37,6 +37,12 @@ let mkdim_ite i t e = mkdim_ite (get_loc ()) i t e
 
 let mkannots annots = { annots = annots; annot_loc = get_loc () }
 
+let node_stack : ident list ref = ref []
+let debug_calls () = Format.eprintf "call stack: %a@.@?" (Utils.fprintf_list ~sep:", " Format.pp_print_string) !node_stack
+let push_node nd =  node_stack:= nd :: !node_stack
+let pop_node () = try node_stack := List.tl !node_stack with _ -> assert false
+let get_current_node () = try List.hd !node_stack with _ -> assert false
+
 %}
 
 %token <int> INT
@@ -118,6 +124,9 @@ node_ident:
   UIDENT { $1 }
 | IDENT  { $1 }
 
+node_ident_decl:
+ node_ident { push_node $1; $1 }
+
 vdecl_ident:
   UIDENT { $1 }
 | IDENT  { $1 }
@@ -176,6 +185,7 @@ top_decl_header:
 				  nodei_prototype = $13;
 				  nodei_in_lib = $14;})
      in
+     pop_node ();
      (*add_imported_node $3 nd;*) [nd] }
 
 prototype_opt:
@@ -188,27 +198,35 @@ in_lib_opt:
 
 top_decl:
 | CONST cdecl_list { List.rev ($2 false) }
-| nodespec_list state_annot node_ident LPAR vdecl_list SCOL_opt RPAR RETURNS LPAR vdecl_list SCOL_opt RPAR SCOL_opt locals LET stmt_list TEL 
-    {let stmts, asserts, annots = $16 in
-     let nd = mktop_decl false (Node
-				  {node_id = $3;
-				   node_type = Types.new_var ();
-				   node_clock = Clocks.new_var true;
-				   node_inputs = List.rev $5;
-				   node_outputs = List.rev $10;
-				   node_locals = List.rev $14;
-				   node_gencalls = [];
-				   node_checks = [];
-				   node_asserts = asserts; 
-				   node_stmts = stmts;
-				   node_dec_stateless = $2;
-				   node_stateless = None;
-				   node_spec = $1;
-				   node_annot = annots})
-     in
+| nodespec_list state_annot node_ident_decl LPAR vdecl_list SCOL_opt RPAR RETURNS LPAR vdecl_list SCOL_opt RPAR SCOL_opt locals LET stmt_list TEL 
+    {
+      let stmts, asserts, annots = $16 in
+      (* Declaring eqs annots *)
+      List.iter (fun ann -> 
+	List.iter (fun (key, _) -> 
+	  Annotations.add_node_ann $3 key
+	) ann.annots
+      ) annots;
+     (* Building the node *)
+      let nd = mktop_decl false (Node
+				   {node_id = $3;
+				    node_type = Types.new_var ();
+				    node_clock = Clocks.new_var true;
+				    node_inputs = List.rev $5;
+				    node_outputs = List.rev $10;
+				    node_locals = List.rev $14;
+				    node_gencalls = [];
+				    node_checks = [];
+				    node_asserts = asserts; 
+				    node_stmts = stmts;
+				    node_dec_stateless = $2;
+				    node_stateless = None;
+				    node_spec = $1;
+				    node_annot = annots})
+      in
      (*add_node $3 nd;*) [nd] }
-
-nodespec_list:
+    
+ nodespec_list:
  { None }
 | NODESPEC nodespec_list { 
   (function 
@@ -350,7 +368,7 @@ expr:
 | IDENT { mkexpr (Expr_ident $1) }
 | tag_ident { mkexpr (Expr_ident $1) (*(Expr_const (Const_tag $1))*) }
 | LPAR ANNOT expr RPAR
-    {update_expr_annot $3 $2}
+    {update_expr_annot (get_current_node ()) $3 $2}
 | LPAR expr RPAR
     {$2}
 | LPAR tuple_expr RPAR