diff --git a/src/plugins/value/engine/iterator.ml b/src/plugins/value/engine/iterator.ml
index b22c6f12e9f4e828c71980ed072f00ee33f5af0d..a7f9573a00e766c65e71cf51f6b8b1fb6c1ce82d 100644
--- a/src/plugins/value/engine/iterator.ml
+++ b/src/plugins/value/engine/iterator.ml
@@ -407,34 +407,32 @@ module Make_Dataflow
       end
 
   let process_partitioning_transitions (v1 : vertex) (v2 : vertex)
-      (transition : vertex transition) (f : flow) : unit =
+      (transition : vertex transition) (flow : flow) : flow =
     (* Split return *)
-    begin match transition with
-      | Return (return_exp, _) ->
-        Partition.split_return f return_exp
-      | _ -> ()
-    end;
+    let flow = match transition with
+      | Return (return_exp, _) -> Partition.split_return flow return_exp
+      | _ -> flow
+    in
     (* Loop transitions *)
     let the_stmt v = Extlib.the v.vertex_start_of in
-    let enter_loop v =
-      Partition.transfer (lift (Domain.enter_loop (the_stmt v))) f;
-      Partition.enter_loop f (the_stmt v)
-    and leave_loop v =
-      Partition.transfer (lift (Domain.leave_loop (the_stmt v))) f;
-      Partition.leave_loop f (the_stmt v)
-    and incr_loop_counter v =
-      Partition.transfer (lift (Domain.incr_loop_counter (the_stmt v))) f;
-      Partition.next_loop_iteration f (the_stmt v)
+    let enter_loop f v =
+      let f = Partition.enter_loop f (the_stmt v) in
+      Partition.transfer (lift (Domain.enter_loop (the_stmt v))) f
+    and leave_loop f v =
+      let f = Partition.leave_loop f (the_stmt v) in
+      Partition.transfer (lift (Domain.leave_loop (the_stmt v))) f
+    and incr_loop_counter f v =
+      let f = Partition.next_loop_iteration f (the_stmt v) in
+      Partition.transfer (lift (Domain.incr_loop_counter (the_stmt v))) f
     in
     let loops_left, loops_entered =
       Interpreted_automata.get_wto_index_diff kf v1 v2
     and loop_incr =
       Interpreted_automata.is_back_edge kf (v1,v2)
     in
-    List.iter leave_loop loops_left;
-    List.iter enter_loop loops_entered;
-    if loop_incr then
-      incr_loop_counter v2
+    let flow = List.fold_left leave_loop flow loops_left in
+    let flow = List.fold_left enter_loop flow loops_entered in
+    if loop_incr then incr_loop_counter flow v2 else flow
 
   let process_edge (v1,e,v2 : G.edge) : flow =
     let {edge_transition=transition; edge_kinstr=kinstr} = e in
@@ -444,8 +442,8 @@ module Make_Dataflow
     check_signals ();
     current_ki := kinstr;
     Cil.CurrentLoc.set e.edge_loc;
-    Partition.transfer (transfer_transition transition) flow;
-    process_partitioning_transitions v1 v2 transition flow;
+    let flow = Partition.transfer (transfer_transition transition) flow in
+    let flow = process_partitioning_transitions v1 v2 transition flow in
     if not (Partition.is_empty_flow flow) then
       edge_info.fireable <- true;
     flow
@@ -476,45 +474,44 @@ module Make_Dataflow
     (* Get vertex store *)
     let store = get_vertex_store v in
     (* Join incoming s tates *)
-    let f = Partition.join sources store in
-    begin match v.vertex_start_of with
+    let flow = Partition.join sources store in
+    let flow =
+      match v.vertex_start_of with
       | Some stmt ->
         (* Callbacks *)
-        call_statement_callbacks stmt f;
+        call_statement_callbacks stmt flow;
         (* Transfer function associated to the statement *)
-        Partition.transfer (transfer_statement stmt) f;
+        let flow = Partition.transfer (transfer_statement stmt) flow in
         (* Output slevel related things *)
         let store_size = Partition.store_size store in
         output_slevel store_size;
         (* Debug informations *)
         Value_parameters.debug ~dkey ~current:true
           "reached statement %d with %d / %d eternal states, %d to propagate"
-          stmt.sid store_size (slevel stmt) (Partition.flow_size f);
-      | _ -> ()
-    end;
+          stmt.sid store_size (slevel stmt) (Partition.flow_size flow);
+        flow
+      | _ -> flow
+    in
     (* Widen if necessary *)
-    let stable =
-      if Partition.is_empty_flow f then
-        true
-      else if widening then begin
-        let stable = Partition.widen (get_vertex_widening v) f in
+    let flow =
+      if widening && not (Partition.is_empty_flow flow) then begin
+        let flow = Partition.widen (get_vertex_widening v) flow in
         (* Try to correct over-widenings *)
         let correct_over_widening stmt =
           (* Do *not* record the status after interpreting the annotation
              here. Possible unproven assertions have already been recorded
              when the assertion has been interpreted the first time higher
              in this function. *)
-          Partition.transfer (transfer_annotations stmt ~record:false) f
+          Partition.transfer (transfer_annotations stmt ~record:false) flow
         in
-        Extlib.may correct_over_widening v.vertex_start_of;
-        stable
+        Extlib.may_map correct_over_widening ~dft:flow v.vertex_start_of
       end else
-        false
+        flow
     in
     (* Dispatch to successors *)
-    List.iter (fun into -> Partition.fill f ~into) (get_succ_tanks v);
-    (* Return wether the iterator should stop or not *)
-    stable
+    List.iter (fun into -> Partition.fill flow ~into) (get_succ_tanks v);
+    (* Return whether the iterator should stop or not *)
+    Partition.is_empty_flow flow
 
   let process_vertex ?(widening : bool = false) (v : vertex) : bool =
     (* Process predecessors *)
diff --git a/src/plugins/value/engine/trace_partitioning.ml b/src/plugins/value/engine/trace_partitioning.ml
index 96c8bc8f5afb1c72207353101382a350536a074a..eaa7a3ca361da88cfb2f72b946342221f87eb983 100644
--- a/src/plugins/value/engine/trace_partitioning.ml
+++ b/src/plugins/value/engine/trace_partitioning.ml
@@ -50,9 +50,7 @@ struct
     mutable store_size : int;
   }
 
-  type flow = {
-    mutable flow_states : Flow.t;
-  }
+  type flow = Flow.t
 
   type tank = {
     mutable tank_states : state partition;
@@ -85,8 +83,7 @@ struct
       store_size = 0;
     }
 
-  let empty_flow () : flow =
-    { flow_states = Flow.empty }
+  let empty_flow : flow = Flow.empty
 
   let empty_tank () : tank =
     { tank_states = Partition.empty }
@@ -109,8 +106,8 @@ struct
   let pretty_store (fmt : Format.formatter) (s : store) : unit =
     Partition.iter (fun _key state -> Domain.pretty fmt state) s.store_partition
 
-  let pretty_flow (fmt : Format.formatter) (p : flow) =
-    Flow.iter (Domain.pretty fmt) p.flow_states
+  let pretty_flow (fmt : Format.formatter) (flow : flow) =
+    Flow.iter (Domain.pretty fmt) flow
 
 
   (* Accessors *)
@@ -123,14 +120,14 @@ struct
     | [] -> `Bottom
     | v1 :: l -> `Value (List.fold_left Domain.join v1 l)
 
-  let contents (f : flow) : state list =
-    Flow.to_list f.flow_states
+  let contents (flow : flow) : state list =
+    Flow.to_list flow
 
   let is_empty_store (s : store) : bool =
     Partition.is_empty s.store_partition
 
-  let is_empty_flow (f : flow) : bool =
-    Flow.is_empty f.flow_states
+  let is_empty_flow (flow : flow) : bool =
+    Flow.is_empty flow
 
   let is_empty_tank (t : tank) : bool =
     Partition.is_empty t.tank_states
@@ -138,8 +135,8 @@ struct
   let store_size (s : store) : int =
     s.store_size
 
-  let flow_size (f : flow) : int =
-    Flow.size f.flow_states
+  let flow_size (flow : flow) : int =
+    Flow.size flow
 
   let tank_size (t : tank) : int =
     Partition.size t.tank_states
@@ -147,27 +144,24 @@ struct
 
   (* Partition transfer functions *)
 
-  let transfer_action p action =
-    p.flow_states <- Flow.transfer_keys p.flow_states action
-
-  let enter_loop (p : flow) (i : stmt) : unit =
-    transfer_action p (Enter_loop (unroll i))
+  let enter_loop (flow : flow) (i : stmt) : flow =
+    Flow.transfer_keys flow (Enter_loop (unroll i))
 
-  let leave_loop (p : flow) (_i : stmt) : unit =
-    transfer_action p Leave_loop
+  let leave_loop (flow : flow) (_i : stmt) : flow =
+    Flow.transfer_keys flow Leave_loop
 
-  let next_loop_iteration (p : flow) (_i : stmt) : unit =
-    transfer_action p Incr_loop
+  let next_loop_iteration (flow : flow) (_i : stmt) : flow =
+    Flow.transfer_keys flow Incr_loop
 
   let empty_rationing = new_rationing ~limit:0 ~merge:false
 
-  let split_return (flow : flow) (return_exp : exp option) : unit =
+  let split_return (flow : flow) (return_exp : exp option) : flow =
     let strategy = Split_return.kf_strategy kf in
-    if strategy <> Split_strategy.FullSplit
-    then
+    if strategy = Split_strategy.FullSplit
+    then flow
+    else
       let apply action =
-        let f = Flow.transfer_keys flow.flow_states action in
-        flow.flow_states <- Flow.join_duplicate_keys f
+        Flow.join_duplicate_keys (Flow.transfer_keys flow action)
       in
       match Split_return.kf_strategy kf with
       (* SplitAuto already transformed into SplitEqList. *)
@@ -187,9 +181,6 @@ struct
     let is_eternal key _state = not (Key.exceed_rationing key) in
     s.store_partition <- Partition.filter is_eternal s.store_partition
 
-  let reset_flow (f : flow) : unit =
-    f.flow_states <- Flow.empty
-
   let reset_tank (t : tank) : unit =
     t.tank_states <- Partition.empty
 
@@ -206,21 +197,20 @@ struct
   (* Operators *)
 
   let drain (t : tank) : flow =
-    let flow_states = Flow.of_partition t.tank_states in
+    let flow = Flow.of_partition t.tank_states in
     t.tank_states <- Partition.empty;
-    { flow_states }
+    flow
 
-  let fill ~(into : tank) (f : flow) : unit =
+  let fill ~(into : tank) (flow : flow) : unit =
     let erase _key dest src =
       if Extlib.has_some src
       then src
       else dest
     in
-    let new_states = Flow.to_partition f.flow_states in
+    let new_states = Flow.to_partition flow in
     into.tank_states <- Partition.merge erase into.tank_states new_states
 
-  let transfer (f : state -> state list) (p : flow) : unit =
-    p.flow_states <- Flow.transfer_states f p.flow_states
+  let transfer = Flow.transfer_states
 
   let join (sources : (branch*flow) list) (dest : store) : flow =
     let is_loop_head =
@@ -231,11 +221,11 @@ struct
     (* Get every source flow *)
     let sources_states =
       match sources with
-      | [(_,p)] -> [p.flow_states]
+      | [(_,flow)] -> [flow]
       | sources ->
         (* Several branches -> partition according to the incoming branch *)
-        let get (b,p) =
-          Flow.transfer_keys p.flow_states (Branch (b,history_size))
+        let get (b,flow) =
+          Flow.transfer_keys flow (Branch (b,history_size))
         in
         List.map get sources
     in
@@ -282,11 +272,10 @@ struct
       Extlib.opt_filter (fun s -> Index.add s dest.store_index) state
     in
     let flow = Flow.join_duplicate_keys flow_states in
-    let flow = Flow.filter_map update flow in
-    { flow_states = flow }
+    Flow.filter_map update flow
 
 
-  let widen (w : widening) (f : flow) : bool =
+  let widen (w : widening) (flow : flow) : flow =
     let stmt = w.widening_stmt in
     (* Auxiliary function to update the result *)
     let update key widening_state =
@@ -341,8 +330,6 @@ struct
           };
         Some curr
     in
-    let flow = Flow.join_duplicate_keys f.flow_states in
-    let flow = Flow.filter_map widen_one flow in
-    f.flow_states <- flow;
-    Flow.is_empty f.flow_states
+    let flow = Flow.join_duplicate_keys flow in
+    Flow.filter_map widen_one flow
 end
diff --git a/src/plugins/value/engine/trace_partitioning.mli b/src/plugins/value/engine/trace_partitioning.mli
index dd9dfaadeec26b40da00c3d0e4e6728f5a78de84..584134d4d145952e501942657a1b92985b788e11 100644
--- a/src/plugins/value/engine/trace_partitioning.mli
+++ b/src/plugins/value/engine/trace_partitioning.mli
@@ -29,14 +29,15 @@ module Make
 sig
   type state = Abstract.Dom.t     (** The states being partitioned *)
   type store       (** The storage of all states ever met at a control point *)
+  type tank        (** The set of states that remains to propagate from a
+                       control point. *)
   type flow        (** A set of states which are currently propagated *)
-  type tank        (** An organized temporary accumulation of flows *)
-  type widening    (** Widening informations *)
+  type widening    (** Widening information *)
 
   (* --- Constructors --- *)
 
   val empty_store : stmt:Cil_types.stmt option -> store
-  val empty_flow : unit -> flow
+  val empty_flow : flow
   val empty_tank : unit -> tank
   val empty_widening : stmt:Cil_types.stmt option -> widening
 
@@ -65,7 +66,6 @@ sig
   (* These functions reset the part of the state of the analysis which has
      been obtained after a widening. *)
   val reset_store : store -> unit
-  val reset_flow : flow -> unit
   val reset_tank : tank -> unit
   val reset_widening : widening -> unit
 
@@ -77,10 +77,10 @@ sig
 
   (* --- Partition transfer functions --- *)
 
-  val enter_loop : flow -> Cil_types.stmt -> unit
-  val leave_loop : flow -> Cil_types.stmt -> unit
-  val next_loop_iteration : flow -> Cil_types.stmt -> unit
-  val split_return : flow -> Cil_types.exp option -> unit
+  val enter_loop : flow -> Cil_types.stmt -> flow
+  val leave_loop : flow -> Cil_types.stmt -> flow
+  val next_loop_iteration : flow -> Cil_types.stmt -> flow
+  val split_return : flow -> Cil_types.exp option -> flow
 
   (* --- Operators --- *)
 
@@ -88,12 +88,11 @@ sig
       created by [empty_tank] *)
   val drain : tank -> flow
 
-  (** Fill the states of the flow into the tank, modifying [into] inplace but
-      letting the flow unchanged *)
+  (** Fill the states of the flow into the tank, modifying [into] inplace. *)
   val fill : into:tank -> flow -> unit
 
   (** Apply a transfer function to all the states of a propagation. *)
-  val transfer : (state -> state list) -> flow -> unit
+  val transfer : (state -> state list) -> flow -> flow
 
   (** Join all incoming propagations into the given store. This function returns
       a set of states which still need to be propagated past the store.
@@ -110,10 +109,7 @@ sig
   val join : (Partition.branch * flow) list -> store -> flow
 
   (** Widen a flow. The widening object keeps track of the previous widenings
-      and previous propagated states to ensure termination. The result is true
-      when it is correct to end the propagation here, i.e. when the flow
-      object is only containng states which are included into already propagated
-      states. *)
-  val widen : widening -> flow -> bool
+      and previous propagated states to ensure termination. *)
+  val widen : widening -> flow -> flow
 
 end