let doStmt (s: stmt) (d: t) =
    let states = !(d.value) in
    d.value := State_set.empty;
    let kinstr = Kstmt s in


    let changed =
      Current_table.update_and_tell_if_changed 
        current_table 
        kinstr
        states
    in

    if (not changed) then
      Dataflow.SDefault
    else begin

        let annots_before, contract =
          Annotations.single_fold_stmt
            (fun a (before, spec as acc) -> match a with
            | Before
                (User { annot_content = AStmtSpec spec' }
                | AI (_,{annot_content = AStmtSpec spec' }) )
              ->
                let spec = match spec with
                | None -> spec'
                | Some s -> Logic_utils.merge_funspec s spec'; s
                in
                (before, Some spec)
            | Before (AI (_, b) | User b) -> b :: before, spec
            | After _ -> acc)
            s
            ([], None)
        in

        CilE.start_stmt kinstr;
        let states = 
          List.fold_left
            (fun states annot -> interp_annot states s annot)
            states
            annots_before
        in
        let states =
          match contract with
            Some spec ->
              check_preconditions (current_kf()) kinstr
                ~slevel "statement" states spec
          | None -> states 
        in
        CilE.end_stmt ();

        let curr_wcounter, curr_wstate = 
          Current_table.find_widening_info current_table kinstr in
        let d =
          if d.counter_unroll >= AnalysisParam.slevel
          then begin
              let state = State_set.join states in
              let joined =
                Relations_type.Model.join
                  curr_wstate
                  state
              in
              let r =
                if (AnalysisParam.is_natural_loop s) &&
                  (curr_wcounter = 0)
                then
                  let wh_key_set, wh_hints = getWidenHints s in
                  let widen_hints =
                    true, wh_key_set(* no longer used thanks to 0/1 widening*),
                    wh_hints
                  in
                  let _,result = Relations_type.Model.widen
                    widen_hints
                    curr_wstate
                    joined
                  in
                  result
                else
                  joined
              in
              let new_widening =
                if curr_wcounter = 0
                then 1
                else pred curr_wcounter
              in
              Current_table.update_widening_info
                current_table
                kinstr
                new_widening
                r;
              {
                counter_unroll = d.counter_unroll;
                value = ref (State_set.singleton r);
              }

            end
          else { d with value = ref states }
        in
        Current_table.update_current current_table kinstr !(d.value);

        match s.skind with
        | Return _ ->
            Dataflow.SUse d
        | Loop _ ->
            if d.counter_unroll >= AnalysisParam.slevel
            then
              Value_parameters.result ~once:true ~current:true
                "entering loop for the first time";
            Dataflow.SUse d
        | UnspecifiedSequence seq ->
            CilE.start_stmt kinstr;
            State_set.iter
              (fun state -> check_unspecified_sequence state seq) states;
            CilE.end_stmt ();
            Dataflow.SUse d
        | _ -> Dataflow.SUse d
      end