let removeUnusedTransitionsAndStates () =
  (* Step 1 : computation of reached states and crossed transitions *)
  let crossedTransitions = ref (Array.make(getNumberOfTransitions()) falsein
  let reachedStates = ref (Array.make(getNumberOfStates()) falsein
  let addHash htbl =
    Hashtbl.iter
      (fun _ (_,tr) ->
         crossedTransitions:= bool_array_or !crossedTransitions tr;
      )
      htbl
  in

  let addHash_bycase htbl_bc =
    let htbl = Hashtbl.create (Hashtbl.length htbl_bc) in
    Hashtbl.iter
      (fun key dbaa ->
         Hashtbl.add htbl key (Spec_tools.pre_flattening dbaa)
      )
      htbl_bc;
    addHash htbl
  in

  addHash pre_status;
(*   addHash post_status; *)
  addHash_bycase post_status_bycase;

  addHash_bycase loop_ext_pre_bycase;
  addHash_bycase loop_int_pre_bycase;
(*   addHash_bycase loop_ext_post_bycase;  Always empty*)
 addHash_bycase loop_int_post_bycase;

  List.iter
    (fun tr ->
       if !crossedTransitions.(tr.numt) then
         begin
           !reachedStates.(tr.start.nums)<-true;
           !reachedStates.(tr.stop.nums)<-true
         end
    )
    (snd !automata);

(* Verification pass because of a plugin limitation *)
(*  List.iter
    (fun tr ->
       if not !reachedStates.(tr.start.nums) && !crossedTransitions.(tr.numt) then
         begin
           Format.printf "Aorai plugin internal error. Status : States/Transitions simplification try to remove an unreachable state wich is the starting point for a crossable transition. \n";
           assert false
         end
    )
    (snd !automata);
*)



(* DEBUG : Displaying information *)
(*  Format.printf "\n\n Used states and transitions:\n";
  debug_display_stmt_all_pre (!reachedStates,!crossedTransitions) ;
  Format.printf "\n\n" ;*)


(* Step 2 : computation of translation tables *)
  let newNbTrans = Array.fold_left
    (fun nb tr -> if tr then nb+1 else nb ) 0 !crossedTransitions in
  let newNbStates =
    Array.fold_left (fun nb st -> if st then nb+1 else nb ) 0 !reachedStates
  in
  let replaceTransitions = Array.make(getNumberOfTransitions()) 0 in
  let replaceStates = Array.make(getNumberOfStates()) 0 in
  let nextTr = ref 0 in
  let nextSt = ref 0 in
  Array.iteri
    (fun i _ -> if !crossedTransitions.(i) then
       begin
         replaceTransitions.(i) <- !nextTr;
         nextTr:=!nextTr+1
       end
     else
       replaceTransitions.(i) <- (-1)
    )
    replaceTransitions;
  Array.iteri
    (fun i _ -> if !reachedStates.(i) then
       begin
         replaceStates.(i) <- !nextSt;
         nextSt:=!nextSt+1
       end
     else
       replaceStates.(i) <- (-1)
    )
    replaceStates ;


(* DEBUG : Displaying information *)
  (* Format.printf "\n\n New nb trans :%d \n New nb states :%d  \n" newNbTrans newNbStates; *)
  (* Format.printf "\n\n Transitions replacement:\n"; *)
  (* Array.iteri *)
  (*   (fun i v -> *)
  (*      Format.printf "   tr%s ~> tr%s\n" (string_of_int i) (string_of_int v) *)
  (*   ) *)
  (*   replaceTransitions; *)
  (* Format.printf "\n\n States replacement:\n"; *)
  (* Array.iteri *)
  (*   (fun i v -> *)
  (*      Format.printf "   st%s ~> st%s\n" (string_of_int i) (string_of_int v) *)
  (*   ) *)
  (*   replaceStates; *)
  (* Format.printf "\n\n"; *)


(* Step 3 : rewriting stored information *)
  (* Rewriting automata and parameterized conditions *)
  let sts =
    List.filter (fun st -> replaceStates.(st.nums) <> -1) (fst !automata)
  in
  let trs =
    List.filter (fun tr -> replaceTransitions.(tr.numt) <> -1) (snd !automata)
  in
  let cds = Array.make (newNbTrans) [[]] in
  (match sts with
      [] ->
        Aorai_option.abort
          "No states left after simplification: the code is not compatible with the automaton";
    | _ ->
      (* [VP] we sort the states by their name, giving results that are
         more robust wrt internal changes, especially for regression tests.
       *)

      let sts =
        List.sort (fun x1 x2 -> String.compare x1.name x2.name) sts
      in
      Extlib.iteri
        (fun i st -> replaceStates.(st.nums) <- i; st.nums <- i) sts
  );
  (* Now, sort transitions according to their start and stop state *)
  let trs =
    List.sort
      (fun tr1 tr2 ->
        match Aorai_state.compare tr1.start tr2.start with
          | 0 -> Aorai_state.compare tr1.stop tr2.stop
          | n -> n)
      trs
  in
  Extlib.iteri
    (fun i tr ->
      replaceTransitions.(tr.numt) <- i;
      cds.(i) <- !cond_of_parametrizedTransitions.(tr.numt);
      tr.numt <- i)
    trs;
  automata:= (sts,trs);
  check_states();
  cond_of_parametrizedTransitions := cds;
  (* Rewriting size of automata cached in Spec_tools *)
  setNumberOfStates newNbStates;
  setNumberOfTransitions newNbTrans;

  (* Rewritting pre/post conditions and loops specification *)
  let rewriteHashtblSpec htbl =
    Hashtbl.iter
      (fun key (ost,otr) ->
         let nst,ntr=mk_empty_pre_or_post () in
         Array.iteri (fun i b -> if b then nst.(replaceStates.(i))<-true) ost;
         Array.iteri (fun i b -> if b then ntr.(replaceTransitions.(i))<-true) otr;
         Hashtbl.replace htbl key (nst,ntr)
      )
      htbl
  in
  let rewriteHashtblSpec_bycase htbl =
    Hashtbl.iter
      (fun key (ost,otr) ->
         let nst,ntr=mk_empty_pre_or_post_bycase () in
         Array.iteri
           (fun iniSt sp ->
              let newIniSt = replaceStates.(iniSt) in
              if newIniSt <> -1 then
                Array.iteri
                  (fun i b -> if b then nst.(newIniSt).(replaceStates.(i))<-true)
                  sp
           )
           ost;
         Array.iteri
           (fun iniSt sp ->
              let newIniSt = replaceStates.(iniSt) in
              if newIniSt <> -1 then
                Array.iteri
                  (fun i b -> if b then ntr.(newIniSt).(replaceTransitions.(i))<-true)
                  sp
           )
           otr;
         Hashtbl.replace htbl key (nst,ntr)
      )
      htbl
  in

  rewriteHashtblSpec pre_status;
(*   rewriteHashtblSpec post_status; *)
  rewriteHashtblSpec_bycase post_status_bycase;

(*   rewriteHashtblSpec loop_ext_pre; *)
(*   rewriteHashtblSpec loop_int_pre; *)
(*   rewriteHashtblSpec loop_ext_post; *)
(*   rewriteHashtblSpec loop_int_post; *)

  rewriteHashtblSpec_bycase loop_ext_pre_bycase;
  rewriteHashtblSpec_bycase loop_int_pre_bycase;
(*   rewriteHashtblSpec_bycase loop_ext_post_bycase; *)
  rewriteHashtblSpec_bycase loop_int_post_bycase