let switch env e cases p_def =
    let rec add_id ids new_id = match ids with [] -> [new_id]
      | id::other_ids -> let cmp =  WpAnnot.compare_prop_id new_id id in
          if cmp = 0 then ids (* new_id already in *)
          else if cmp < 0 then new_id::ids
          else id::(add_id other_ids new_id)
    in
    let collect_id ids g = add_id ids g.g_id in
    let collect_ids ids (_, lp) = List.fold_left collect_id ids lp in
    let ids = List.map (fun g -> g.g_id) p_def in
    let ids = List.fold_left collect_ids ids cases in
      (* we now have all the ids found in all the lists *)
    let get_p_id id goals =
      try
        let g =
          List.find (fun g -> WpAnnot.compare_prop_id id g.g_id = 0) goals
        in g.g_prop
      with Not_found -> W.empty
    in
    let get_descr_id id =
      let add_goal acc g =
        if WpAnnot.compare_prop_id id g.g_id = 0 then g.g_descr::acc
        else acc
      in
      let add_goals = List.fold_left add_goal in
      let acc = add_goals [] p_def in
        List.fold_left (fun acc (_, gs) -> add_goals acc gs) acc cases
    in
    let process_id id =
      let id_p_def = get_p_id id p_def in
      let id_cases =
        List.map (fun (cond, lp) -> (cond, get_p_id id lp)) cases
      in
      let f () = W.switch env e id_cases id_p_def in
      let d = get_descr_id id in
        make_goal id f d
    in List.map process_id ids