let cleanup_overwritten_bindings
      ?(extend_left=true) ?(extend_right=true)
      same_values (bi,ei as i) new_vv m =
    (* if not (extend_right && extend_left) then
      Format.printf "left:%b right:%b@\n" extend_left extend_right; *)

    let concerned_intervals =
      concerned_intervals Int_Interv.fuzzy_order i m
    in
    let result = match concerned_intervals with
    | [] ->
        let acc,new_bi =
          enlarge_to_left ~extend_left same_values bi new_vv m in
        let acc,new_ei =
          enlarge_to_right ~extend_right same_values ei new_vv acc in
        Some(new_bi, new_ei, acc)
    | [((bi1, ei1) as i1, vv1) as binding1] ->
        let cond_start = Int.le bi1 bi in
        let cond_end = Int.ge ei1 ei in
        let cond_same = same_values vv1 new_vv in
        if (cond_start && cond_end && cond_same && extend_right && extend_left)
        then None   (* nothing to do, the new interval is included in the
                    previous one and the old and new values are the same*)

        else begin
          let result1 = remove i1 m in
          let result2,new_bi =
            handle_leftmost_itv
              same_values ~extend_left bi new_vv binding1 result1
          in
          let result3,new_ei =
            handle_rightmost_itv
              ~extend_right
              same_values ei new_vv binding1 result2
          in
          Some(new_bi, new_ei, result3)
        end
    | ((_bi1, _ei1), _vv1 as binding1)::tail ->
        let result1 =
          List.fold_right
            (fun (i1,_) acc -> remove i1 acc)
            concerned_intervals
            m
        in
        (* part of the last interval might remain on the right *)
        let result2,new_ei =
          handle_rightmost_itv
            ~extend_right
            same_values ei new_vv binding1 result1
        in
        let rec f l acc =
          match l with
          | [] -> assert false
              (* at least 2 elements in [concerned_intervals] *)
          | [(_bi1, _ei1), _vv1 as binding1] ->
              (* part of the first interval might remain on the left *)
              handle_leftmost_itv ~extend_left
                same_values bi new_vv binding1 acc
          | ((_bi1, _ei1), _vv1)::tail ->
              (* the middle intervals are completely covered : ignore
                 former values *)

              f tail acc
        in
        let result3,new_bi = f tail result2 in
        Some(new_bi, new_ei, result3)
  in
  (* if not (extend_right && extend_left) then
    (match result with None -> Format.printf "Cleanup...NONE@\n"
     | Some (new_bi,new_ei,_) ->
         Format.printf "Cleanup...new_bi:%a new_ei:%a@\n" Int.pretty new_bi
           Int.pretty new_ei);*)

    result