diff --git a/src/kernel_services/analysis/interpreted_automata.ml b/src/kernel_services/analysis/interpreted_automata.ml
index 8d7d1cad9f432b1ea2d05a3d8eefb54e6110dc26..6f45565db717af3e6a4c5e1021b47067240d340b 100644
--- a/src/kernel_services/analysis/interpreted_automata.ml
+++ b/src/kernel_services/analysis/interpreted_automata.ml
@@ -30,10 +30,21 @@ type info =
   | NoneInfo
   | LoopHead of int (* level *)
 
+type 'a control =
+  | Edges (* control flow is only given by vertex edges *)
+  | Loop of 'a (* start vertex of a Loop stmt with breaking vertex *)
+  | If of { cond: exp; vthen: 'a; velse: 'a }
+  (* edges are guaranteed to be two guards `Then` else `Else`
+     with the given condition and successor vertices. *)
+  | Switch of { value: exp; cases: (exp * 'a) list; default: 'a }
+  (* edges are guaranteed to be issued from a `switch()` statement with
+     the given cases and default vertices. *)
+
 type vertex = {
   vertex_key : int;
   mutable vertex_start_of : Cil_types.stmt option;
   mutable vertex_info : info;
+  mutable vertex_control : vertex control;
 }
 
 type assert_kind =
@@ -73,6 +84,7 @@ let dummy_vertex = {
   vertex_key = -1;
   vertex_start_of = None;
   vertex_info = NoneInfo;
+  vertex_control = Edges;
 }
 
 let dummy_edge = {
@@ -246,10 +258,10 @@ let build_automaton ~annotations kf =
       vertex_key = !next_vertex;
       vertex_start_of = None;
       vertex_info = NoneInfo;
+      vertex_control = Edges;
     } in
     incr next_vertex;
-    G.add_vertex g v;
-    v
+    G.add_vertex g v; v
   and add_edge src dest edge_kinstr edge_transition edge_loc =
     let e = {
       edge_key = !next_edge;
@@ -278,19 +290,26 @@ let build_automaton ~annotations kf =
     in
     fold_transition src l
   in
-  let build_stmt_transition src dest stmt succ transition =
-    (* Get the list of exited and enterd group *)
+  let build_stmt_next src dest stmt succ transition =
+    (* Also returns the successor of the required transition. *)
+    (* Inserts between next and dest the list of exited and enterd group. *)
     let exited_blocks = Kernel_function.blocks_closed_by_edge stmt succ
     and entered_blocks = Kernel_function.blocks_opened_by_edge stmt succ
     in
     let l =
-      transition ::
       List.map (fun b -> Leave b) exited_blocks @
       List.map (fun b -> Enter b) entered_blocks
-    and kinstr = Kstmt stmt
+    and kinstr = Kstmt stmt and loc = stmt_loc stmt
     in
-    build_transitions src dest kinstr (stmt_loc stmt) l
+    if l = [] then
+      ( add_edge src dest kinstr transition loc ; dest )
+    else
+      let v = add_vertex () in
+      add_edge src v kinstr transition loc ;
+      build_transitions v dest kinstr loc l ; v
   in
+  let build_stmt_transition src dest stmt succ transition =
+    ignore (build_stmt_next src dest stmt succ transition) in
 
   let rec do_list do_one control labels = function
     | [] -> assert false
@@ -326,7 +345,6 @@ let build_automaton ~annotations kf =
   and do_stmt control (labels:vertex labels) stmt =
     let kinstr = Kstmt stmt
     and loc = stmt_loc stmt in
-    let source = fst loc in
     let do_annot control labels (annot: code_annotation) : unit =
       let labels = LabelMap.add_builtin Here control.src labels in
       let annotation = make_annotation kf stmt annot labels in
@@ -395,6 +413,9 @@ let build_automaton ~annotations kf =
         add_edge control.src else_point kinstr else_transition loc;
         do_block {control with src=then_point} kinstr labels then_block;
         do_block {control with src=else_point} kinstr labels else_block;
+        control.src.vertex_control <- If {
+            cond = exp ; vthen = then_point; velse = else_point
+          };
         control.dest
 
       | Switch (exp1, block, cases, _) ->
@@ -411,6 +432,7 @@ let build_automaton ~annotations kf =
         do_block block_control kinstr labels block;
         (* Then link the cases *)
         let default_case : (vertex * Cil_types.stmt) option ref = ref None in
+        let value_cases : (Cil_types.exp * vertex) list ref = ref [] in
         (* For all statements *)
         let values = List.fold_left
             begin fun values case_stmt ->
@@ -420,7 +442,9 @@ let build_automaton ~annotations kf =
                 begin fun values -> function
                   | Case (exp2,_) ->
                     let guard = build_guard exp2 Then in
-                    build_stmt_transition control.src dest stmt case_stmt guard;
+                    let v2 =
+                      build_stmt_next control.src dest stmt case_stmt guard in
+                    value_cases := (exp2,v2) :: !value_cases ;
                     exp2 :: values
                   | Default (_) ->
                     default_case := Some (dest,case_stmt);
@@ -444,11 +468,18 @@ let build_automaton ~annotations kf =
         and add_last_edge src transition =
           match !default_case with
           | None ->
-            add_edge src control.dest kinstr transition loc
+            add_edge src control.dest kinstr transition loc ;
+            control.dest
           | Some (case_vertex, case_stmt) ->
-            build_stmt_transition src case_vertex stmt case_stmt transition
+            build_stmt_transition src case_vertex stmt case_stmt transition ;
+            case_vertex
         in
-        add_default_edge control.src values;
+        let default_vertex = add_default_edge control.src values in
+        control.src.vertex_control <- Switch {
+            value = exp1;
+            cases = List.rev !value_cases;
+            default = default_vertex;
+          };
         control.dest
 
       | Loop (_annotations, block, _, _, _) ->
@@ -487,6 +518,7 @@ let build_automaton ~annotations kf =
         in
         do_block loop_control kinstr labels block;
         decr loop_level;
+        control.src.vertex_control <- Loop control.dest ;
         control.dest
 
       | Block block ->
@@ -499,7 +531,7 @@ let build_automaton ~annotations kf =
         control.dest
 
       | Throw _ | TryCatch _ | TryFinally _ | TryExcept _
-        -> Kernel.not_yet_implemented ~source
+        -> Kernel.not_yet_implemented ~source:(fst loc)
              "[interpreted_automata] exception handling"
     in
     (* Update statement table *)
@@ -875,7 +907,6 @@ end
 (* --- States                                                         --- *)
 (* ---------------------------------------------------------------------- *)
 
-
 module AutomatonState = Kernel_function.Make_Table (Automaton)
     (struct
       let size = 97
@@ -885,7 +916,6 @@ module AutomatonState = Kernel_function.Make_Table (Automaton)
 
 let get_automaton = AutomatonState.memo (build_automaton ~annotations:false)
 
-
 module WTOState = Kernel_function.Make_Table (WTO)
     (struct
       let size = 97
@@ -940,9 +970,9 @@ module UnrollUnnatural  = struct
     include Datatype.Make_with_collections(struct
         include Datatype.Undefined
         include Vertex.Set
-
         let name = "Interpreted_automata.OnlyHead.Vertex_Set"
-        let pretty fmt m = Pretty_utils.pp_iter ~sep:",@ " Vertex.Set.iter Vertex.pretty fmt m
+        let pretty fmt m = Pretty_utils.pp_iter ~sep:",@ "
+            Vertex.Set.iter Vertex.pretty fmt m
         let reprs = [Vertex.Set.empty]
       end)
 
@@ -972,18 +1002,17 @@ module UnrollUnnatural  = struct
   module OldG = G
 
   module G = struct
-    include Graph.Imperative.Digraph.ConcreteBidirectionalLabeled (Version)
-        (Edge)
+    include
+      Graph.Imperative.Digraph.ConcreteBidirectionalLabeled(Version)(Edge)
 
     let pretty : t Pretty_utils.formatter = fun fmt g ->
       Pretty_utils.pp_iter iter_vertex ~pre:"@[" ~suf:"@]" ~sep:";@ "
         (fun fmt v ->
            Format.fprintf fmt "@[<2>@[%a ->@]@ %a@]"
              Version.pretty v
-             (Pretty_utils.pp_iter (fun f -> iter_succ f g) ~sep:",@ " Version.pretty)
-             v
-        )
-        fmt g
+             (Pretty_utils.pp_iter
+                (fun f -> iter_succ f g) ~sep:",@ " Version.pretty) v
+        ) fmt g
   end
 
   module WTO = struct
@@ -1001,7 +1030,10 @@ module UnrollUnnatural  = struct
 
 
   module GDot =
-    MakeDot(struct include Version let start_of (v,_) = v.vertex_start_of end)(G)
+    MakeDot(struct
+      include Version
+      let start_of (v,_) = v.vertex_start_of
+    end)(G)
 
   let output_to_dot out_channel ?number ?wto g =
     GDot.output_to_dot  out_channel ?number ?wto g
@@ -1032,8 +1064,10 @@ module UnrollUnnatural  = struct
           let labels = LabelMap.map (fun v2 ->
               let v2l = Compute.get_wto_index index v2 in
               let d1,d2 = Compute.wto_index_diff nl v2l in
-              let version2 = List.fold_left (fun acc e -> Vertex.Set.remove e acc) version d1 in
-              let version2 = List.fold_left (fun acc e -> Vertex.Set.add e acc) version2 d2 in
+              let version2 = List.fold_left
+                  (fun acc e -> Vertex.Set.remove e acc) version d1 in
+              let version2 = List.fold_left
+                  (fun acc e -> Vertex.Set.add e acc) version2 d2 in
               let version2 = Vertex.Set.remove v2 version2 in
               (v2,version2)
             ) a.labels in
@@ -1049,8 +1083,10 @@ module UnrollUnnatural  = struct
       OldG.iter_succ_e (fun (_,e,v2) ->
           let v2l = Compute.get_wto_index index v2 in
           let d1,d2 = Compute.wto_index_diff nl v2l in
-          let version2 = List.fold_left (fun acc e -> Vertex.Set.remove e acc) version d1 in
-          let version2 = List.fold_left (fun acc e -> Vertex.Set.add e acc) version2 d2 in
+          let version2 = List.fold_left
+              (fun acc e -> Vertex.Set.remove e acc) version d1 in
+          let version2 = List.fold_left
+              (fun acc e -> Vertex.Set.add e acc) version2 d2 in
           let version2 = Vertex.Set.remove v2 version2 in
           let e = convert_edge nl version e in
           G.add_edge_e g' (n',e,(v2,version2));
@@ -1083,7 +1119,6 @@ module UnrollUnnatural  = struct
 
 end
 
-
 (* ---------------------------------------------------------------------- *)
 (* --- Dataflow computation                                           --- *)
 (* ---------------------------------------------------------------------- *)
diff --git a/src/kernel_services/analysis/interpreted_automata.mli b/src/kernel_services/analysis/interpreted_automata.mli
index c04c8b027b571f3c97f98622caa47f3341307195..6a4dc438b2d74ab6dee92a90ce9d527c2a992c56 100644
--- a/src/kernel_services/analysis/interpreted_automata.mli
+++ b/src/kernel_services/analysis/interpreted_automata.mli
@@ -40,6 +40,17 @@ type info =
   | NoneInfo
   | LoopHead of int (* level *)
 
+(** Control flow informations for outgoing edges, if any. *)
+type 'a control =
+  | Edges (** control flow is only given by vertex edges. *)
+  | Loop of 'a (** start of a Loop stmt, with breaking vertex. *)
+  | If of { cond: exp; vthen: 'a; velse: 'a }
+  (** edges are guaranteed to be two guards `Then` else `Else`
+      with the given condition and successor vertices. *)
+  | Switch of { value: exp; cases: (exp * 'a) list; default: 'a }
+  (** edges are guaranteed to be issued from a `switch()` statement with
+      the given cases and default vertices. *)
+
 (** Vertices are control points. When a vertice is the *start* of a statement,
     this statement is kept in vertex_stmt. Currently, this statement is kept for
     two reasons: to know when callbacks should be called and when annotations
@@ -49,6 +60,7 @@ type vertex = private {
   vertex_key : int;
   mutable vertex_start_of : Cil_types.stmt option;
   mutable vertex_info : info;
+  mutable vertex_control : vertex control;
 }
 
 type assert_kind =
@@ -134,7 +146,7 @@ module WTO : sig
   include Datatype.S with type t = wto
 end
 
-(** Get the interpreted automaton for the given kernel_function without annotations *)
+(** Get the automaton for the given kernel_function without annotations *)
 val get_automaton : Cil_types.kernel_function -> automaton
 (** Get the wto for the automaton of the given kernel_function *)
 val get_wto : Cil_types.kernel_function -> wto
@@ -142,8 +154,8 @@ val get_wto : Cil_types.kernel_function -> wto
     vertices lead outside the wto without passing through the head. *)
 val exit_strategy : graph -> vertex Wto.component -> wto
 (** Output the automaton in dot format *)
-val output_to_dot : out_channel -> ?number:[`Stmt|`Vertex] -> ?wto:wto -> automaton -> unit
-
+val output_to_dot : out_channel -> ?number:[`Stmt|`Vertex] -> ?wto:wto ->
+  automaton -> unit
 
 (** the position of a statement in a wto given as the list of
     component heads *)
@@ -187,7 +199,8 @@ module Compute: sig
       vertices lead outside the wto without passing through the head. *)
   val exit_strategy : graph -> vertex Wto.component -> wto
   (** Output the automaton in dot format *)
-  val output_to_dot : out_channel -> ?number:[`Stmt|`Vertex] -> ?wto:wto -> automaton -> unit
+  val output_to_dot : out_channel -> ?number:[`Stmt|`Vertex] -> ?wto:wto ->
+    automaton -> unit
 
 
   type wto_index_table
@@ -219,9 +232,10 @@ end
 module UnrollUnnatural : sig
   (** Could enter a loop only by head nodes *)
 
-
-  module Vertex_Set : Datatype.S_with_collections with type t = Vertex.Set.t
-  module Version :Datatype.S_with_collections with type t = Vertex.t * Vertex.Set.t
+  module Vertex_Set:
+    Datatype.S_with_collections with type t = Vertex.Set.t
+  module Version:
+    Datatype.S_with_collections with type t = Vertex.t * Vertex.Set.t
 
   module G : sig
     include Graph.Sig.I