diff --git a/Makefile.in b/Makefile.in
index 75cac6a0a647bb20a4c4949e5938524d7b7dd5f6..a7dc66d49201728644a1d060a6b9c0870292ee17 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -420,7 +420,7 @@ install_local: bin/why3config
 
 ifeq (@enable_ide@,yes)
 
-IDE_FILES = gconfig db gmain
+IDE_FILES = gconfig db session gmain 
 
 IDEMODULES = $(addprefix src/ide/, $(IDE_FILES))
 
diff --git a/ROADMAP b/ROADMAP
index fb5ba39b83af64d02a7344ac4f84b42fa069c1b7..a888b7525cb7222647bb16ec73bf7a640762940a 100644
--- a/ROADMAP
+++ b/ROADMAP
@@ -10,6 +10,10 @@
 * Jessie3
 * traceability: Partially done
   (Claude)
+  TODO: traceability des hyp comme path dans le prog (depuis
+  Frama-C en particulier)
+  afficher les explications dans les outils en ligne de
+  commande why3 et why3bench + le path
 * Coq plugin
 * Coq realization of theories
   (Andrei)
@@ -28,6 +32,14 @@
   (?)
 * BD : se passer de sqlite3
   (Claude)
+  Solution: un unique fichier XML, qui est ecrit mais pas
+  tres souvent (pas plus d'une fois par seconde)
+  ne pas oublier neanmoins de mettre une action dans Timeout
+  qui enregistre au bout d'un moment
+  pb: n'est pas independant de l'IDE, peut-on faire un module
+  independant de l'IDE ? qui serait utilisé par why3bench ?
+  
+
 * IDE: avoir des transformations non codees en dur
   (Claude d'abord)
 
@@ -68,6 +80,8 @@
 * IDE: debug "hide proved goals" feature
   ** suggested solution: replace model + filter_model by a custom model
 
+* IDE: debug "remove" et "clean" qui provoquent des segfaults !!
+ 
 * IDE: ajouter "invalid" comme cas de resultats de preuve
   (utiliser call_provers.proof_result dans gmain)
   DONE
diff --git a/src/ide/newmain.ml b/src/ide/newmain.ml
new file mode 100644
index 0000000000000000000000000000000000000000..6a9a61c154097ac1c270692f32fef3a76f2af0b4
--- /dev/null
+++ b/src/ide/newmain.ml
@@ -0,0 +1,2096 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  Copyright (C) 2010-                                                   *)
+(*    François Bobot                                                     *)
+(*    Jean-Christophe Filliâtre                                          *)
+(*    Claude Marché                                                      *)
+(*    Andrei Paskevich                                                    *)
+(*                                                                        *)
+(*  This software is free software; you can redistribute it and/or        *)
+(*  modify it under the terms of the GNU Library General Public           *)
+(*  License version 2.1, with the special exception on linking            *)
+(*  described in file LICENSE.                                            *)
+(*                                                                        *)
+(*  This software is distributed in the hope that it will be useful,      *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)
+(*                                                                        *)
+(**************************************************************************)
+
+
+(* TODO:
+
+* when proof attempt is finished and is it the one currently selected,
+the new output should be displayed on upper-right window
+
+* when returning from edited proofs: should we run the prover again
+   immediately ?
+
+* bug trouve par Johannes:
+
+Pour reproduire le bug :
+
+1) Partir d'un répértoire sans fichier de projet
+2) Lancer why3db, ajouter un fichier
+3) Prouver quelques buts (pas tous)
+4) Choisir "Hide Proved Goals"
+5) Prouver le reste des buts, la fênetre devient vide
+6) Décocher "Hide Proved Goals"
+
+Maintenant, le fichier réapparait dans la liste, mais on ne peut pas le
+déplier, donc accéder au sous-buts, stats des appels de prouvers etc ...
+
+Ce n'est pas un bug très grave, parce qu'il suffit de quitter l'ide,
+puis le relancer, et là on peut de nouveau déplier le fichier.
+
+* Francois :
+
+   - Les temps indiqués sont très bizarre, mais cela doit-être un bug
+   plus profond, au niveau de l'appel des prouveurs (wall time au lieu
+   de cpu time?)
+
+   - Si on modifie le fichier à droite, les buts ne sont pas marqués
+   obsolètes ou ajouté à gauche.
+
+*)
+
+open Format
+
+let () =
+  eprintf "Init the GTK interface...@?";
+  ignore (GtkMain.Main.init ());
+  eprintf " done.@."
+
+
+open Why
+open Whyconf
+open Gconfig
+
+(************************)
+(* parsing command line *)
+(************************)
+
+let includes = ref []
+let file = ref None
+let opt_version = ref false
+
+let spec = Arg.align [
+  ("-I",
+   Arg.String (fun s -> includes := s :: !includes),
+   "<s> add s to loadpath") ;
+(*
+  ("-f",
+   Arg.String (fun s -> input_files := s :: !input_files),
+   "<f> add file f to the project (ignored if it is already there)") ;
+*)
+  ("-v",
+   Arg.Set opt_version,
+   " print version information") ;
+]
+
+let version_msg = sprintf "Why3 IDE, version %s (build date: %s)"
+  Config.version Config.builddate
+
+let usage_str = sprintf
+  "Usage: %s [options] [<file.why>|<project directory>]"
+  (Filename.basename Sys.argv.(0))
+
+let set_file f = match !file with
+  | Some _ ->
+      raise (Arg.Bad "only one parameter")
+  | None ->
+      file := Some f
+
+let () = Arg.parse spec set_file usage_str
+
+let () =
+  if !opt_version then begin
+    printf "%s@." version_msg;
+    exit 0
+  end
+
+let fname = match !file with
+  | None ->
+      Arg.usage spec usage_str;
+      exit 1
+  | Some f ->
+      f
+
+let lang =
+  let main = get_main () in
+  let load_path = Filename.concat (datadir main) "lang" in
+  let languages_manager =
+    GSourceView2.source_language_manager ~default:true
+  in
+  languages_manager#set_search_path
+    (load_path :: languages_manager#search_path);
+  match languages_manager#language "why" with
+    | None ->
+        Format.eprintf "language file for 'why' not found in directory %s@."
+          load_path;
+        exit 1
+    | Some _ as l -> l
+
+let source_text fname =
+  let ic = open_in fname in
+  let size = in_channel_length ic in
+  let buf = String.create size in
+  really_input ic buf 0 size;
+  close_in ic;
+  buf
+
+(********************************)
+(* loading WhyIDE configuration *)
+(********************************)
+
+let gconfig =
+  let c = Gconfig.config in
+  let loadpath = (Whyconf.loadpath (get_main ())) @ List.rev !includes in
+  c.env <- Lexer.create_env loadpath;
+  let provers = Whyconf.get_provers c.Gconfig.config in
+  c.provers <-
+    Util.Mstr.fold (Gconfig.get_prover_data c.env) provers Util.Mstr.empty;
+  c
+
+let () =
+  Whyconf.load_plugins (get_main ())
+
+
+
+(***************)
+(* Main window *)
+(***************)
+
+let exit_function () =
+  eprintf "saving IDE config file@.";
+  save_config ();
+  GMain.quit ()
+
+let w = GWindow.window
+  ~allow_grow:true ~allow_shrink:true
+  ~width:gconfig.window_width
+  ~height:gconfig.window_height
+  ~title:"why GUI with database" ()
+
+let (_ : GtkSignal.id) = w#connect#destroy ~callback:exit_function
+
+let (_ : GtkSignal.id) =
+  w#misc#connect#size_allocate
+    ~callback:
+    (fun {Gtk.width=w;Gtk.height=h} ->
+       gconfig.window_height <- h;
+       gconfig.window_width <- w)
+
+let vbox = GPack.vbox ~packing:w#add ()
+
+(* Menu *)
+
+let menubar = GMenu.menu_bar ~packing:vbox#pack ()
+
+let factory = new GMenu.factory menubar
+
+let accel_group = factory#accel_group
+
+let hb = GPack.hbox ~packing:vbox#add ~border_width:2 ()
+
+let tools_window_vbox =
+  try
+    GPack.vbox ~packing:(hb#pack ~expand:false) ~border_width:2 ()
+  with Gtk.Error _ -> assert false
+
+let context_frame =
+  GBin.frame ~label:"Context"
+    ~packing:(tools_window_vbox#pack ~expand:false) ()
+
+let context_box =
+  GPack.button_box `VERTICAL ~border_width:5 ~spacing:5
+    ~packing:context_frame#add ()
+
+let context_unproved_goals_only = ref true
+
+let () =
+  let b1 = GButton.radio_button
+    ~packing:context_box#add ~label:"Unproved goals" ()
+  in
+  b1#misc#set_tooltip_markup "When selected, tools below are applied\nonly on <b>unproved</b> goals";
+  let (_ : GtkSignal.id) =
+    b1#connect#clicked
+      ~callback:(fun () -> context_unproved_goals_only := true)
+  in
+  let b2 = GButton.radio_button
+    ~group:b1#group ~packing:context_box#add ~label:"All goals" ()
+  in
+  b2#misc#set_tooltip_markup "When selected, tools below are applied\nto all goals";
+  let (_ : GtkSignal.id) =
+    b2#connect#clicked
+      ~callback:(fun () -> context_unproved_goals_only := false)
+  in ()
+
+
+let provers_frame =
+  GBin.frame ~label:"Provers"
+    ~packing:(tools_window_vbox#pack ~expand:false) ()
+
+let provers_box =
+  GPack.button_box `VERTICAL ~border_width:5 ~spacing:5
+  ~packing:provers_frame#add ()
+
+let () = provers_frame#set_resize_mode `PARENT
+
+let transf_frame =
+  GBin.frame ~label:"Transformations"
+    ~packing:(tools_window_vbox#pack ~expand:false) ()
+
+let transf_box =
+  GPack.button_box `VERTICAL ~border_width:5 ~spacing:5
+  ~packing:transf_frame#add ()
+
+let tools_frame =
+  GBin.frame ~label:"Tools"
+    ~packing:(tools_window_vbox#pack ~expand:false) ()
+
+let tools_box =
+  GPack.button_box `VERTICAL ~border_width:5 ~spacing:5
+  ~packing:tools_frame#add ()
+
+let cleaning_frame =
+  GBin.frame ~label:"Cleaning"
+    ~packing:(tools_window_vbox#pack ~expand:false) ()
+
+let cleaning_box =
+  GPack.button_box `VERTICAL ~border_width:5 ~spacing:5
+  ~packing:cleaning_frame#add ()
+
+
+(* horizontal paned *)
+
+let hp = GPack.paned `HORIZONTAL ~packing:hb#add ()
+
+
+(* tree view *)
+let scrollview =
+  try
+    GBin.scrolled_window ~hpolicy:`AUTOMATIC ~vpolicy:`AUTOMATIC
+      ~width:gconfig.tree_width
+      ~packing:hp#add ()
+  with Gtk.Error _ -> assert false
+
+let () = scrollview#set_shadow_type `ETCHED_OUT
+let (_ : GtkSignal.id) =
+  scrollview#misc#connect#size_allocate
+    ~callback:
+    (fun {Gtk.width=w;Gtk.height=_h} ->
+       gconfig.tree_width <- w)
+
+
+(* connecting to the Session model *)
+
+
+(****************)
+(* goals widget *)
+(****************)
+
+let cols = new GTree.column_list
+let name_column = cols#add Gobject.Data.string
+let icon_column = cols#add Gobject.Data.gobject
+let status_column = cols#add Gobject.Data.gobject
+let time_column = cols#add Gobject.Data.string
+  
+let name_renderer = GTree.cell_renderer_text [`XALIGN 0.]
+let renderer = GTree.cell_renderer_text [`XALIGN 0.]
+let image_renderer = GTree.cell_renderer_pixbuf [ ]
+let icon_renderer = GTree.cell_renderer_pixbuf [ ]
+  
+let view_name_column =
+  GTree.view_column ~title:"Theories/Goals" ()
+    
+let () =
+  view_name_column#pack icon_renderer ;
+  view_name_column#add_attribute icon_renderer "pixbuf" icon_column ;
+  view_name_column#pack name_renderer;
+  view_name_column#add_attribute name_renderer "text" name_column;
+  view_name_column#set_resizable true;
+  view_name_column#set_max_width 400;
+  ()
+    
+let view_status_column =
+  GTree.view_column ~title:"Status"
+    ~renderer:(image_renderer, ["pixbuf", status_column])
+    ()
+    
+let view_time_column =
+  GTree.view_column ~title:"Time"
+    ~renderer:(renderer, ["text", time_column]) ()
+    
+let () =
+  view_status_column#set_resizable false;
+  view_status_column#set_visible true;
+  view_time_column#set_resizable false;
+  view_time_column#set_visible true
+    
+
+let goals_model,goals_view =
+  let model = GTree.tree_store cols in
+  let view = GTree.view ~model ~packing:scrollview#add () in
+  (*
+    let () = view#selection#set_mode `SINGLE in
+  *)
+  let () = view#selection#set_mode `MULTIPLE in
+  let () = view#set_rules_hint true in
+  ignore (view#append_column view_name_column);
+  ignore (view#append_column view_status_column);
+  ignore (view#append_column view_time_column);
+  model,view
+    
+let clear model = model#clear ()
+
+let image_of_result ~obsolete result =
+  match result with
+    | Session.Undone -> !image_scheduled (* TODO *)
+    | Session.Scheduled -> !image_scheduled
+    | Session.Running -> !image_running
+    | Session.InternalFailure _ -> !image_failure
+    | Session.Done r -> match r.Call_provers.pr_answer with
+	| Call_provers.Valid ->
+	    if obsolete then !image_valid_obs else !image_valid
+	| Call_provers.Invalid ->
+	    if obsolete then !image_invalid_obs else !image_invalid
+	| Call_provers.Timeout ->
+	    if obsolete then !image_timeout_obs else !image_timeout
+	| Call_provers.Unknown _ ->
+	    if obsolete then !image_unknown_obs else !image_unknown
+	| Call_provers.Failure _ ->
+	    if obsolete then !image_failure_obs else !image_failure
+	| Call_provers.HighFailure ->
+	    if obsolete then !image_failure_obs else !image_failure
+	
+let set_row_status b row =
+  if b then
+    begin
+      goals_view#collapse_row (goals_model#get_path row);
+      goals_model#set ~row ~column:status_column !image_yes;
+    end
+  else
+    begin
+      goals_model#set ~row ~column:status_column !image_unknown;
+    end
+
+let set_proof_state ~obsolete row a =
+  let res = a.M.proof_state in
+  goals_model#set ~row ~column:status_column
+    (image_of_result ~obsolete res);
+  let t = match res with
+    | M.Done { Call_provers.pr_time = time } ->
+	Format.sprintf "%.2f" time
+    | _ -> ""
+  in
+  let t = if obsolete then t ^ " (obsolete)" else t in
+  goals_model#set ~row ~column:Model.time_column t
+
+module M = Session.Make
+  (struct
+     type key = Gtk.tree_iter
+
+     let create ?parent () = goals_model#append ?parent () 
+
+     let notify row = 
+       match goals_model#get ~row ~column:Model.index_column with
+	 | M.Goal g -> 
+	     set_row_status row g.M.proved
+	 | M.Theory th -> 
+	     set_row_status row th.M.verified
+	 | M.File file -> 
+	     set_row_status row file.M.file_verified
+	 | M.Proof_attempt a ->
+	     set_proof_state ~obsolete:false a row
+	 | M.Transformation tr ->
+	     set_row_status row tr.M.transf_proved
+
+     let remove row = 
+       let (_:bool) = goals_model#remove row in ()
+
+     let idle f = 
+       let (_ : GMain.Idle.id) = GMain.Idle.add f in
+       ()
+
+     let timeout ~ms f = 
+       let (_ : GMain.Timeout.id) = GMain.Timeout.add ~ms ~callback:f in
+       ()
+
+   end)
+    
+let index_column : M.any GTree.column = cols#add Gobject.Data.caml
+   
+(********************)
+(* opening database *)
+(********************)
+
+let project_dir, file_to_read =
+  if Sys.file_exists fname then
+    begin
+      if Sys.is_directory fname then
+        begin
+          eprintf "Info: found directory '%s' for the project@." fname;
+          fname, None
+        end
+      else
+        begin
+          eprintf "Info: found regular file '%s'@." fname;
+          let d =
+            try Filename.chop_extension fname
+            with Invalid_argument _ -> fname
+          in
+          eprintf "Info: using '%s' as directory for the project@." d;
+          d, Some (Filename.concat Filename.parent_dir_name
+		     (Filename.basename fname))
+        end
+    end
+  else
+    fname, None
+
+let () =
+  if not (Sys.file_exists project_dir) then
+    begin
+      eprintf "Info: '%s' does not exists. Creating directory of that name \
+ for the project@." project_dir;
+      Unix.mkdir project_dir 0o777
+    end
+
+let () =
+  let dbfname = Filename.concat project_dir "project.xml" in
+  try
+    M.open_session dbfname
+  with e ->
+    eprintf "Error while opening database '%s'@." dbfname;
+    eprintf "Aborting...@.";
+    raise e
+
+
+let read_file fn =
+  let fn = Filename.concat project_dir fn in
+  Env.read_file gconfig.env fn 
+
+
+
+
+
+(* *)
+
+let task_checksum t =
+  fprintf str_formatter "%a@." Pretty.print_task t;
+  let s = flush_str_formatter () in
+(*
+  let tmp = Filename.temp_file "task" "out" in
+  let c = open_out tmp in
+  output_string c s;
+  close_out c;
+*)
+  let sum = Digest.to_hex (Digest.string s) in
+(*
+  eprintf "task %s, sum = %s@." tmp sum;
+*)
+  sum
+
+
+let info_window ?(callback=(fun () -> ())) mt s =
+  let buttons = match mt with
+    | `INFO -> GWindow.Buttons.close
+    | `WARNING -> GWindow.Buttons.close
+    | `QUESTION -> GWindow.Buttons.ok_cancel
+    | `ERROR -> GWindow.Buttons.close
+  in
+  let d = GWindow.message_dialog
+    ~message:s
+    ~message_type:mt
+    ~buttons
+    ~title:"Why3 info or error"
+    ~show:true ()
+  in
+  let (_ : GtkSignal.id) =
+    d#connect#response
+      ~callback:(function x -> d#destroy ();
+		   if x = `OK then callback ())
+  in ()
+
+
+
+
+  let check_file_verified f =
+    let b = List.for_all (fun t -> t.M.verified) f.M.theories in
+    if f.file_verified <> b then
+      begin
+	f.file_verified <- b;
+	set_row_status b f.file_row
+      end
+
+  let check_theory_proved t =
+    let b = List.for_all (fun g -> g.proved) t.goals in
+    if t.verified <> b then
+      begin
+	t.verified <- b;
+	set_row_status b t.theory_row;
+	check_file_verified t.theory_parent
+      end
+
+  let rec check_goal_proved g =
+    let b1 = Hashtbl.fold
+      (fun _ a acc -> acc ||
+	 match a.proof_state with
+	   | Done { Call_provers.pr_answer = Call_provers.Valid} -> true
+	   | _ -> false) g.external_proofs false
+    in
+    let b = Hashtbl.fold
+      (fun _ t acc -> acc || t.transf_proved) g.transformations b1
+    in
+    if g.proved <> b then
+      begin
+	g.proved <- b;
+	set_row_status b g.goal_row;
+	match g.parent with
+          | Theory t -> check_theory_proved t
+          | Transf t -> check_transf_proved t
+      end
+
+  and check_transf_proved t =
+    let b = List.for_all (fun g -> g.proved) t.subgoals in
+    if t.transf_proved <> b then
+      begin
+	t.transf_proved <- b;
+	set_row_status b t.transf_row;
+	check_goal_proved t.parent_goal
+      end
+
+
+  (* deprecated *)
+  let set_file_verified f =
+    f.file_verified <- true;
+    let row = f.file_row in
+    goals_view#collapse_row (goals_model#get_path row);
+    goals_model#set ~row ~column:status_column !image_yes
+(*
+    if !toggle_hide_proved_goals then
+      goals_model#set ~row ~column:visible_column false
+*)
+
+  (* deprecated *)
+  let set_theory_proved ~propagate  t =
+    t.verified <- true;
+    let row = t.theory_row in
+    goals_view#collapse_row (goals_model#get_path row);
+    goals_model#set ~row ~column:status_column !image_yes;
+(*
+    if !toggle_hide_proved_goals then
+      goals_model#set ~row ~column:visible_column false;
+*)
+    let f = t.theory_parent in
+    if propagate then
+      if List.for_all (fun t ->
+(*
+                         let tname = t.theory.Theory.th_name.Ident.id_string in
+                         eprintf "checking theory %s@." tname;
+*)
+                         t.verified) f.theories then
+        set_file_verified f
+
+  let rec set_proved ~propagate g =
+    let row = g.goal_row in
+    g.proved <- true;
+    goals_view#collapse_row (goals_model#get_path row);
+    goals_model#set ~row ~column:status_column !image_yes;
+(*
+    if !toggle_hide_proved_goals then
+      goals_model#set ~row ~column:visible_column false;
+*)
+    if propagate then
+      match g.parent with
+        | Theory t ->
+            if List.for_all (fun g -> g.proved) t.goals then
+              set_theory_proved ~propagate t
+        | Transf t ->
+            if List.for_all (fun g -> g.proved) t.subgoals then
+              begin
+                set_proved ~propagate t.parent_goal;
+              end
+
+  let set_proof_state ~obsolete a res =
+    a.proof_state <- res;
+    let row = a.proof_row in
+    goals_model#set ~row ~column:status_column
+      (image_of_result ~obsolete res);
+
+    let t = match res with
+      | Done { Call_provers.pr_time = time } ->
+          Format.sprintf "%.2f" time
+      | _ -> ""
+    in
+    let t = if obsolete then t ^ " (obsolete)" else t in
+    goals_model#set ~row:a.Model.proof_row ~column:Model.time_column t
+
+
+  let add_external_proof_row ~obsolete ~edit g p db_proof result (*_time*) =
+    let parent = g.goal_row in
+    let name = p.prover_name in
+    let row = goals_model#prepend ~parent () in
+    goals_model#set ~row ~column:icon_column !image_prover;
+    goals_model#set ~row ~column:name_column
+      (name ^ " " ^ p.prover_version);
+(*
+    goals_model#set ~row ~column:visible_column true;
+*)
+    goals_view#expand_row (goals_model#get_path parent);
+    let a = { prover = p;
+              proof_goal = g;
+              proof_row = row;
+              proof_db = db_proof;
+(*
+              status = status;
+*)
+              proof_obsolete = obsolete;
+(*
+              time = time;
+              output = "";
+*)
+	      proof_state = result;
+              edited_as = edit;
+            }
+    in
+    goals_model#set ~row ~column:index_column (Row_proof_attempt a);
+    Hashtbl.add g.external_proofs p.prover_id a;
+    set_proof_state ~obsolete a result;
+    a
+
+
+  let add_goal_row parent name info t db_goal =
+    let parent_row = match parent with
+      | Theory mth -> mth.theory_row
+      | Transf mtr -> mtr.transf_row
+    in
+    let row = goals_model#append ~parent:parent_row () in
+    let goal = { goal_name = name;
+		 parent = parent;
+                 task = t ;
+                 goal_row = row;
+                 goal_db = db_goal;
+                 external_proofs = Hashtbl.create 7;
+                 transformations = Hashtbl.create 3;
+                 proved = false;
+               }
+    in
+    let text = match info with
+      | None -> name
+      | Some s -> s
+    in
+    goals_model#set ~row ~column:name_column text;
+    goals_model#set ~row ~column:icon_column !image_file;
+    goals_model#set ~row ~column:index_column (Row_goal goal);
+(*
+    goals_model#set ~row ~column:visible_column true;
+*)
+    goal
+
+
+  let add_transformation_row g db_transf tr_name =
+    let parent = g.Model.goal_row in
+    let row = goals_model#append ~parent () in
+    let tr = { Model.parent_goal = g;
+               Model.transf_proved = false;
+               Model.transf_row = row;
+               Model.transf_db = db_transf;
+               subgoals = [];
+             }
+    in
+    Hashtbl.add g.Model.transformations tr_name tr;
+    goals_model#set ~row ~column:Model.name_column tr_name;
+    goals_model#set ~row ~column:Model.icon_column !image_transf;
+    goals_model#set ~row ~column:Model.index_column
+      (Model.Row_transformation tr);
+(*
+    goals_model#set ~row ~column:Model.visible_column true;
+*)
+    goals_view#expand_row (goals_model#get_path parent);
+    tr
+
+
+  let add_theory_row mfile th db_theory =
+    let tname = th.Theory.th_name.Ident.id_string in
+    let parent = mfile.file_row in
+    let row = goals_model#append ~parent () in
+    let mth = { theory = th;
+                theory_row = row;
+                theory_db = db_theory;
+                theory_parent = mfile;
+                goals = [] ;
+                verified = false }
+    in
+    goals_model#set ~row ~column:name_column tname;
+    goals_model#set ~row ~column:icon_column !image_directory;
+    goals_model#set ~row ~column:index_column (Row_theory mth);
+(*
+    goals_model#set ~row ~column:visible_column true;
+*)
+    mth
+
+  let add_theory mfile th =
+    let tasks = List.rev (Task.split_theory th None None) in
+    let tname = th.Theory.th_name.Ident.id_string in
+    let db_theory = Db.add_theory mfile.file_db tname in
+    let mth = add_theory_row mfile th db_theory in
+    let goals =
+      List.fold_left
+        (fun acc t ->
+           let id = (Task.task_goal t).Decl.pr_name in
+           let name = id.Ident.id_string in
+           let expl = get_explanation id (Task.task_goal_fmla t) in
+           let sum = task_checksum t in
+           let db_goal = Db.add_goal db_theory name sum in
+           let goal = add_goal_row (Theory mth) name expl t db_goal in
+           goal :: acc)
+        []
+        tasks
+    in
+    mth.goals <- List.rev goals;
+    if goals = [] then set_theory_proved ~propagate:false mth;
+    mth
+
+  let add_file_row f dbfile =
+      let parent = goals_model#append () in
+      let mfile = { file_name = f;
+                    file_row = parent;
+                    file_db = dbfile;
+                    theories = [] ;
+                    file_verified = false }
+      in
+      all_files := !all_files @ [mfile];
+      let name = Filename.basename f in
+      goals_model#set ~row:parent ~column:name_column name;
+      goals_model#set ~row:parent ~column:icon_column !image_directory;
+      goals_model#set ~row:parent ~column:index_column (Row_file mfile);
+(*
+      goals_model#set ~row:parent ~column:visible_column true;
+*)
+      mfile
+
+  let add_file f =
+    let theories = read_file f in
+    let dbfile = Db.add_file f in
+    let mfile = add_file_row f dbfile in
+    let mths =
+      List.fold_left
+        (fun acc (_,thname,t) ->
+           eprintf "Adding theory '%s'@." thname;
+           let mth = add_theory mfile t in
+           mth :: acc
+        )
+        [] theories
+    in
+    mfile.theories <- List.rev mths;
+    if theories = [] then set_file_verified mfile
+
+
+(*********************************)
+(*  read previous data from db   *)
+(*********************************)
+
+type trans =
+  | Trans_one of Task.task Trans.trans
+  | Trans_list of Task.task Trans.tlist
+
+let lookup_trans name =
+  try
+    let t = Trans.lookup_transform name gconfig.env in
+    Trans_one t
+  with Trans.UnknownTrans _ ->
+    let t = Trans.lookup_transform_l name gconfig.env in
+    Trans_list t
+
+let trans_list =
+  ["split_goal"; "inline_goal" ; "introduce_premises" ]
+
+let trans_of_name =
+  let h = Hashtbl.create 13 in
+  List.iter
+    (fun n -> Hashtbl.add h n (lookup_trans n))
+    trans_list;
+  Hashtbl.find h
+
+let split_transformation = trans_of_name "split_goal"
+let inline_transformation = trans_of_name "inline_goal"
+let intro_transformation = trans_of_name "introduce_premises"
+
+
+exception Not_applicable
+
+let apply_trans t task =
+  match t with
+    | Trans_one t ->
+	let t' = Trans.apply t task in
+	if task == t' then raise Not_applicable; [t']
+    | Trans_list t ->
+	match Trans.apply t task with
+	  | [t'] as l -> if task == t' then raise Not_applicable; l
+	  | l -> l
+
+let apply_transformation ~callback t task =
+   match t with
+    | Trans_one t ->
+	let callback t = callback [t] in
+	Gscheduler.apply_transformation ~callback t task
+    | Trans_list t ->
+	Gscheduler.apply_transformation_l ~callback t task
+
+
+let rec reimport_any_goal parent gid gname t db_goal goal_obsolete =
+  let info = get_explanation gid (Task.task_goal_fmla t) in
+  let goal = Helpers.add_goal_row parent gname info t db_goal in
+  let proved = ref false in
+  let external_proofs = Db.external_proofs db_goal in
+  Db.Hprover.iter
+    (fun pid a ->
+       let pname = Db.prover_name pid in
+       try
+         let p = Util.Mstr.find pname gconfig.provers in
+         let s,t,o,edit = Db.status_and_time a in
+         if goal_obsolete && not o then Db.set_obsolete a;
+         let obsolete = goal_obsolete or o in
+         let s = match s with
+           | Db.Undone -> Call_provers.HighFailure
+           | Db.Done r ->
+	       if r = Call_provers.Valid then
+		 if not obsolete then proved := true;
+	       r
+         in
+	 let r = { Call_provers.pr_answer = s;
+		   Call_provers.pr_output = "";
+		   Call_provers.pr_time = t;
+		 }
+	 in
+         let (_pa : Model.proof_attempt) =
+           Helpers.add_external_proof_row ~obsolete ~edit goal p a
+	     (Gscheduler.Done r)
+         in
+         ((* something TODO ?*))
+       with Not_found ->
+         eprintf
+           "Warning: prover %s appears in database but is not installed.@."
+           pname
+    )
+    external_proofs;
+  let transformations = Db.transformations db_goal in
+  Db.Htransf.iter
+    (fun tr_id tr ->
+       let trname = Db.transf_name tr_id in
+       eprintf "Reimporting transformation %s for goal %s @." trname gname;
+       let trans = trans_of_name trname in
+       let subgoals = apply_trans trans t in
+       let mtr = Helpers.add_transformation_row goal tr trname in
+       let db_subgoals = Db.subgoals tr in
+       let reimported_goals,db_subgoals,_ =
+         List.fold_left
+           (fun (acc,db_subgoals,count) subtask ->
+              let id = (Task.task_goal subtask).Decl.pr_name in
+              let subgoal_name = gname ^ "." ^ (string_of_int count) in
+              let sum = task_checksum subtask in
+              let subtask_db,db_subgoals =
+                try
+		  let g = Util.Mstr.find sum db_subgoals in
+		  (* a subgoal has the same check sum *)
+		  (Some g, Util.Mstr.remove sum db_subgoals)
+                with Not_found -> None,db_subgoals
+              in
+              ((count,id,subgoal_name,subtask,sum,subtask_db) :: acc,
+	       db_subgoals,
+	       count+1))
+           ([],db_subgoals,1) subgoals
+       in
+       let other_goals =
+	 Util.Mstr.fold
+	   (fun _ g acc -> (Db.goal_name g,g)::acc)
+	   db_subgoals
+	   []
+       in
+       let other_goals =
+	 List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) other_goals
+       in
+       let rec merge_goals new_goals old_goals proved acc =
+	 match new_goals with
+	   | [] -> acc, proved
+	   | (_,id,subgoal_name,subtask,sum,g_opt)::rem ->
+	       let db_g,subgoal_obsolete,old_goals =
+		 match g_opt with
+		   | Some g -> g,false,old_goals
+		   | None ->
+		       match old_goals with
+			 | [] ->
+			     (* create a new goal in db *)
+			     Db.add_subgoal tr subgoal_name sum,
+			     false, old_goals
+			 | (_goal_name,g) :: r ->
+			     g, true, r
+	       in
+               let subgoal,subgoal_proved =
+                 reimport_any_goal
+                   (Model.Transf mtr) id
+                   subgoal_name subtask db_g subgoal_obsolete
+              in
+              merge_goals rem old_goals (proved && subgoal_proved)
+		(subgoal :: acc)
+       in
+       let goals, subgoals_proved =
+	 merge_goals (List.rev reimported_goals) other_goals true []
+       in
+(*
+       let goals,_,subgoals_proved =
+         List.fold_left
+           (fun (acc,count,proved) subtask ->
+              let _id = (Task.task_goal subtask).Decl.pr_name in
+              let subgoal_name = gname ^ "." ^ (string_of_int count) in
+              let sum = task_checksum subtask in
+              let subtask_db =
+                try Util.Mstr.find sum db_subgoals
+		  (* a subgoal has the same check sum *)
+                with Not_found ->
+		  (* otherwise, create a new one *)
+                  Db.add_subgoal tr subgoal_name sum
+              in
+              let subgoal,subgoal_proved =
+                reimport_any_goal
+                  (Model.Transf mtr) subgoal_name subtask subtask_db
+                  false (* subgoal_obsolete *)
+              in
+              (subgoal :: acc, count+1,proved && subgoal_proved))
+           ([],1,true) subgoals
+       in
+*)
+       mtr.Model.subgoals <- List.rev goals;
+       if subgoals_proved (* TODO : && not obsolete *)
+       then proved := true
+    )
+    transformations;
+  if !proved then Helpers.set_proved ~propagate:false goal;
+  goal,!proved
+
+
+let reimport_root_goal mth tname goals t : Model.goal * bool =
+  (* re-imports DB informations of a goal in theory mth (named tname)
+     goals is a table, indexed by names of DB goals formerly known to be
+     a in theory mth.  returns true whenever the task t is known to be
+     proved *)
+  let id = (Task.task_goal t).Decl.pr_name in
+  let gname = id.Ident.id_string
+  in
+  let sum = task_checksum t in
+  let db_goal,goal_obsolete =
+    try
+      let dbg = Util.Mstr.find gname goals in
+      let db_sum = Db.task_checksum dbg in
+      let goal_obsolete = sum <> db_sum in
+      if goal_obsolete then
+        begin
+          eprintf "Goal %s.%s has changed@." tname gname;
+          Db.change_checksum dbg sum
+        end;
+      dbg,goal_obsolete
+    with Not_found ->
+      let dbg = Db.add_goal mth.Model.theory_db gname sum in
+      dbg,false
+  in
+  reimport_any_goal (Model.Theory mth) id gname t db_goal goal_obsolete
+
+(* reimports all files *)
+let files_in_db = Db.files ()
+
+let () =
+  List.iter
+    (fun (f,fn) ->
+       eprintf "Reimporting file '%s'@." fn;
+       let mfile = Helpers.add_file_row fn f in
+       try
+	 let theories = read_file fn in
+	 let ths = Db.theories f in
+	 let (mths,file_proved) =
+	   List.fold_left
+             (fun (acc,file_proved) (_,tname,th) ->
+		eprintf "Reimporting theory '%s'@."tname;
+		let db_th =
+		  try
+                    Util.Mstr.find tname ths
+		  with Not_found -> Db.add_theory f tname
+		in
+		let mth = Helpers.add_theory_row mfile th db_th in
+		let goals = Db.goals db_th in
+		let tasks = List.rev (Task.split_theory th None None) in
+		let goals,proved = List.fold_left
+		  (fun (acc,proved) t ->
+                     let (g,p) = reimport_root_goal mth tname goals t in
+                     (g::acc,proved && p))
+		  ([],true) tasks
+		in
+		mth.Model.goals <- List.rev goals;
+		(* TODO: what to do with remaining tasks in Db ???
+		   for the moment they remain in the db, but they are not shown
+		*)
+		if proved then Helpers.set_theory_proved ~propagate:false mth;
+		(mth::acc,file_proved && proved))
+             ([],true) theories
+	 in
+	 (* TODO: detecter d'eventuelles vieilles theories, qui seraient donc
+            dans [ths] mais pas dans [theories]
+	 *)
+	 mfile.Model.theories <- List.rev mths;
+	 if file_proved then Helpers.set_file_verified mfile
+      with e ->
+	eprintf "@[Error while reading file@ '%s':@ %a@.@]" fn
+          Exn_printer.exn_printer e;
+	exit 1
+    )
+    files_in_db
+
+(**********************************)
+(* add new file from command line *)
+(**********************************)
+
+let () =
+  match file_to_read with
+    | None -> ()
+    | Some fn ->
+        if List.exists (fun (_,f) -> f = fn) files_in_db then
+          eprintf "Info: file %s already in database@." fn
+        else
+          try
+            Helpers.add_file fn
+          with e ->
+	    eprintf "@[Error while reading file@ '%s':@ %a@.@]" fn
+              Exn_printer.exn_printer e;
+	    exit 1
+
+
+(**********************)
+(* set up scheduler   *)
+(**********************)
+
+let () =
+  begin
+    Gscheduler.maximum_running_proofs := gconfig.max_running_processes
+  end
+
+
+(*****************************************************)
+(* method: run a given prover on each unproved goals *)
+(*****************************************************)
+
+(* q is a queue of proof attempt where to put the new one *)
+let redo_external_proof g a =
+  (* check that the state is not Scheduled or Running *)
+(**)
+  let running = match a.Model.proof_state with
+    | Gscheduler.Scheduled | Gscheduler.Running -> true
+    | Gscheduler.Done _ | Gscheduler.Undone | Gscheduler.InternalFailure _ -> false
+  in
+  if running then ()
+    (* info_window `ERROR "Proof already in progress" *)
+  else
+(**)
+  let p = a.Model.prover in
+  let callback result =
+    Helpers.set_proof_state ~obsolete:false a result (*time*) ;
+    let db_res, time =
+      match result with
+	| Gscheduler.Undone | Gscheduler.Scheduled | Gscheduler.Running ->
+	    Db.Undone, 0.0
+	| Gscheduler.InternalFailure _ ->
+	    Db.Done Call_provers.HighFailure, 0.0
+	| Gscheduler.Done r ->
+	    if r.Call_provers.pr_answer = Call_provers.Valid then
+	      Helpers.set_proved ~propagate:true a.Model.proof_goal;
+	    Db.Done r.Call_provers.pr_answer, r.Call_provers.pr_time
+    in
+    Db.set_status a.Model.proof_db db_res time
+  in
+  let old = if a.Model.edited_as = "" then None else
+    begin
+      eprintf "Info: proving using edited file %s@." a.Model.edited_as;
+      (Some (open_in a.Model.edited_as))
+    end
+  in
+  Gscheduler.schedule_proof_attempt
+    ~debug:(gconfig.verbose > 0) ~timelimit:gconfig.time_limit ~memlimit:0
+    ?old ~command:p.command ~driver:p.driver
+    ~callback
+    g.Model.task
+
+let rec prover_on_goal p g =
+  let id = p.prover_id in
+  let a =
+    try Hashtbl.find g.Model.external_proofs id
+    with Not_found ->
+      let db_prover = Db.prover_from_name id in
+      let db_pa = Db.add_proof_attempt g.Model.goal_db db_prover in
+      Helpers.add_external_proof_row ~obsolete:false ~edit:""
+	g p db_pa Gscheduler.Undone
+  in
+  let () = redo_external_proof g a in
+  Hashtbl.iter
+    (fun _ t -> List.iter (prover_on_goal p) t.Model.subgoals)
+    g.Model.transformations
+
+let rec prover_on_goal_or_children p g =
+  if not (g.Model.proved && !context_unproved_goals_only) then
+    begin
+      let r = ref true in
+      Hashtbl.iter
+	(fun _ t ->
+	   r := false;
+           List.iter (prover_on_goal_or_children p)
+             t.Model.subgoals) g.Model.transformations;
+      if !r then prover_on_goal p g
+    end
+
+let prover_on_selected_goal_or_children pr row =
+  let row = goals_model#get_iter row in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal g ->
+        prover_on_goal_or_children pr g
+    | Model.Row_theory th ->
+        List.iter (prover_on_goal_or_children pr) th.Model.goals
+    | Model.Row_file file ->
+        List.iter
+          (fun th ->
+             List.iter (prover_on_goal_or_children pr) th.Model.goals)
+          file.Model.theories
+    | Model.Row_proof_attempt a ->
+        prover_on_goal_or_children pr a.Model.proof_goal
+    | Model.Row_transformation tr ->
+        List.iter (prover_on_goal_or_children pr) tr.Model.subgoals
+
+let prover_on_selected_goals pr =
+  List.iter
+    (prover_on_selected_goal_or_children pr)
+    goals_view#selection#get_selected_rows
+
+(**********************************)
+(* method: replay obsolete proofs *)
+(**********************************)
+
+let proof_successful a =
+  match a.Model.proof_state with
+    | Gscheduler.Done { Call_provers.pr_answer = Call_provers.Valid }
+      -> true
+    | _ -> false
+
+let rec replay_on_goal_or_children g =
+  Hashtbl.iter
+    (fun _ a ->
+       if a.Model.proof_obsolete then
+         if not !context_unproved_goals_only || proof_successful a
+         then redo_external_proof g a)
+    g.Model.external_proofs;
+  Hashtbl.iter
+    (fun _ t ->
+       List.iter replay_on_goal_or_children
+         t.Model.subgoals)
+    g.Model.transformations
+
+let replay_on_selected_goal_or_children row =
+  let row = goals_model#get_iter row in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal g ->
+        replay_on_goal_or_children g
+    | Model.Row_theory th ->
+        List.iter replay_on_goal_or_children th.Model.goals
+    | Model.Row_file file ->
+        List.iter
+          (fun th ->
+             List.iter replay_on_goal_or_children th.Model.goals)
+          file.Model.theories
+    | Model.Row_proof_attempt a ->
+        replay_on_goal_or_children a.Model.proof_goal
+    | Model.Row_transformation tr ->
+        List.iter replay_on_goal_or_children tr.Model.subgoals
+
+let replay_obsolete_proofs () =
+  List.iter
+    replay_on_selected_goal_or_children
+    goals_view#selection#get_selected_rows
+
+
+
+(*****************************************************)
+(* method: split selected goals *)
+(*****************************************************)
+
+let transformation_on_goal g trans_name trans =
+  if not g.Model.proved then
+    let callback subgoals =
+      let b =
+ 	match subgoals with
+	  | [task] ->
+              let s1 = task_checksum g.Model.task in
+              let s2 = task_checksum task in
+	      (*
+                eprintf "Transformation returned only one task. sum before = %s, sum after = %s@." (task_checksum g.Model.task) (task_checksum task);
+                eprintf "addresses: %x %x@." (Obj.magic g.Model.task) (Obj.magic task);
+	      *)
+              s1 <> s2
+                (* task != g.Model.task *)
+	  | _ -> true
+      in
+      if b then
+	let transf_id = Db.transf_from_name trans_name in
+	let db_transf = Db.add_transformation g.Model.goal_db transf_id	in
+	let tr = Helpers.add_transformation_row g db_transf trans_name in
+	let goal_name = g.Model.goal_name in
+	let fold =
+	  fun (acc,count) subtask ->
+	    let id = (Task.task_goal subtask).Decl.pr_name in
+            let expl =
+              get_explanation id (Task.task_goal_fmla subtask)
+            in
+	    let subgoal_name =
+	      goal_name ^ "." ^ (string_of_int count)
+	    in
+	    let sum = task_checksum subtask in
+	    let subtask_db =
+	      Db.add_subgoal db_transf subgoal_name sum
+	    in
+	    let goal =
+	      Helpers.add_goal_row (Model.Transf tr)
+		subgoal_name expl subtask subtask_db
+	    in
+	    (goal :: acc, count+1)
+	in
+	let goals,_ =
+	  List.fold_left fold ([],1) subgoals
+	in
+	tr.Model.subgoals <- List.rev goals;
+	Hashtbl.add g.Model.transformations trans_name tr
+    in
+    apply_transformation ~callback
+      trans g.Model.task
+
+let split_goal g =
+  Gscheduler.schedule_delayed_action
+    (fun () ->
+       transformation_on_goal g "split_goal" split_transformation)
+
+let inline_goal g = transformation_on_goal g "inline_goal" inline_transformation
+
+let rec split_goal_or_children g =
+  if not g.Model.proved then
+    begin
+      let r = ref true in
+      Hashtbl.iter
+	(fun _ t ->
+	   r := false;
+           List.iter split_goal_or_children
+             t.Model.subgoals) g.Model.transformations;
+      if !r then split_goal g
+    end
+
+let rec inline_goal_or_children g =
+  if not g.Model.proved then
+    begin
+      let r = ref true in
+      Hashtbl.iter
+	(fun _ t ->
+	   r := false;
+           List.iter inline_goal_or_children
+             t.Model.subgoals) g.Model.transformations;
+      if !r then inline_goal g
+    end
+
+let split_selected_goal_or_children row =
+  let row = goals_model#get_iter row in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal g ->
+        split_goal_or_children g
+    | Model.Row_theory th ->
+        List.iter split_goal_or_children th.Model.goals
+    | Model.Row_file file ->
+        List.iter
+          (fun th ->
+             List.iter split_goal_or_children th.Model.goals)
+          file.Model.theories
+    | Model.Row_proof_attempt a ->
+        split_goal_or_children a.Model.proof_goal
+    | Model.Row_transformation tr ->
+        List.iter split_goal_or_children tr.Model.subgoals
+
+
+let inline_selected_goal_or_children row =
+  let row = goals_model#get_iter row in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal g ->
+        inline_goal_or_children g
+    | Model.Row_theory th ->
+        List.iter inline_goal_or_children th.Model.goals
+    | Model.Row_file file ->
+        List.iter
+          (fun th ->
+             List.iter inline_goal_or_children th.Model.goals)
+          file.Model.theories
+    | Model.Row_proof_attempt a ->
+        inline_goal_or_children a.Model.proof_goal
+    | Model.Row_transformation tr ->
+        List.iter inline_goal_or_children tr.Model.subgoals
+
+let split_selected_goals () =
+  List.iter
+    split_selected_goal_or_children
+    goals_view#selection#get_selected_rows
+
+
+let inline_selected_goals () =
+  List.iter
+    inline_selected_goal_or_children
+    goals_view#selection#get_selected_rows
+
+
+(*********************************)
+(* add a new file in the project *)
+(*********************************)
+
+let filter_all_files () =
+  let f = GFile.filter ~name:"All" () in
+  f#add_pattern "*" ;
+  f
+
+let filter_why_files () =
+  GFile.filter
+    ~name:"Why3 source files"
+    ~patterns:[ "*.why"; "*.mlw"] ()
+
+let select_file () =
+  let d = GWindow.file_chooser_dialog ~action:`OPEN
+    ~title:"Why3: Add file in project"
+    ()
+  in
+  d#add_button_stock `CANCEL `CANCEL ;
+  d#add_select_button_stock `OPEN `OPEN ;
+  d#add_filter (filter_why_files ()) ;
+  d#add_filter (filter_all_files ()) ;
+  begin match d#run () with
+  | `OPEN ->
+      begin
+        match d#filename with
+          | None -> ()
+          | Some f ->
+	      let f = Sysutil.relativize_filename project_dir f in
+              eprintf "Adding file '%s'@." f;
+              try
+                Helpers.add_file f
+              with e ->
+	        fprintf str_formatter
+                  "@[Error while reading file@ '%s':@ %a@]" f
+                  Exn_printer.exn_printer e;
+	        let msg = flush_str_formatter () in
+	        info_window `ERROR msg
+      end
+  | `DELETE_EVENT | `CANCEL -> ()
+  end ;
+  d#destroy ()
+
+
+let not_implemented () =
+  info_window `INFO "This feature is not yet implemented, sorry."
+
+(*************)
+(* File menu *)
+(*************)
+
+let file_menu = factory#add_submenu "_File"
+let file_factory = new GMenu.factory file_menu ~accel_group
+
+let (_ : GMenu.image_menu_item) =
+  file_factory#add_image_item ~key:GdkKeysyms._A
+    ~label:"_Add file" ~callback:select_file
+    ()
+
+let (_ : GMenu.image_menu_item) =
+  file_factory#add_image_item ~label:"_Preferences" ~callback:
+    (fun () ->
+       Gconfig.preferences gconfig;
+       Gscheduler.maximum_running_proofs := gconfig.max_running_processes)
+    ()
+
+let refresh_provers = ref (fun () -> ())
+
+let add_refresh_provers f =
+  let rp = !refresh_provers in
+  refresh_provers := (fun () -> rp (); f ())
+
+let (_ : GMenu.image_menu_item) =
+  file_factory#add_image_item ~label:"_Detect provers" ~callback:
+    (fun () -> Gconfig.run_auto_detection gconfig; !refresh_provers () )
+    ()
+
+let (_ : GMenu.image_menu_item) =
+  file_factory#add_image_item ~key:GdkKeysyms._Q ~label:"_Quit"
+    ~callback:exit_function ()
+
+(*************)
+(* View menu *)
+(*************)
+
+let view_menu = factory#add_submenu "_View"
+let view_factory = new GMenu.factory view_menu ~accel_group
+let (_ : GMenu.image_menu_item) =
+  view_factory#add_image_item ~key:GdkKeysyms._E
+    ~label:"Expand all" ~callback:(fun () -> goals_view#expand_all ()) ()
+
+
+
+let rec collapse_proved_goal g =
+  if g.Model.proved then
+    begin
+      let row = g.Model.goal_row in
+      goals_view#collapse_row (goals_model#get_path row);
+    end
+  else
+    Hashtbl.iter
+      (fun _ t -> List.iter collapse_proved_goal t.Model.subgoals)
+      g.Model.transformations
+
+let collapse_verified_theory th =
+  if th.Model.verified then
+    begin
+      let row = th.Model.theory_row in
+      goals_view#collapse_row (goals_model#get_path row);
+    end
+  else
+    List.iter collapse_proved_goal th.Model.goals
+
+let collapse_verified_file f =
+  if f.Model.file_verified then
+    begin
+      let row = f.Model.file_row in
+      goals_view#collapse_row (goals_model#get_path row);
+    end
+  else
+    List.iter collapse_verified_theory f.Model.theories
+
+let collapse_all_verified_things () =
+  List.iter collapse_verified_file !Model.all_files
+
+let (_ : GMenu.image_menu_item) =
+  view_factory#add_image_item ~key:GdkKeysyms._C
+    ~label:"Collapse proved goals"
+    ~callback:collapse_all_verified_things
+    ()
+
+(*
+let rec hide_proved_in_goal g =
+  if g.Model.proved then
+    begin
+      let row = g.Model.goal_row in
+      goals_view#collapse_row (goals_model#get_path row);
+(*
+      goals_model#set ~row ~column:Model.visible_column false
+*)
+    end
+  else
+    Hashtbl.iter
+      (fun _ t -> List.iter hide_proved_in_goal t.Model.subgoals)
+      g.Model.transformations
+
+let hide_proved_in_theory th =
+  if th.Model.verified then
+    begin
+      let row = th.Model.theory_row in
+      goals_view#collapse_row (goals_model#get_path row);
+      goals_model#set ~row ~column:Model.visible_column false
+    end
+  else
+    List.iter hide_proved_in_goal th.Model.goals
+
+let hide_proved_in_file f =
+  if f.Model.file_verified then
+    begin
+      let row = f.Model.file_row in
+      goals_view#collapse_row (goals_model#get_path row);
+      goals_model#set ~row ~column:Model.visible_column false
+    end
+  else
+    List.iter hide_proved_in_theory f.Model.theories
+
+let hide_proved_in_files () =
+  List.iter hide_proved_in_file !Model.all_files
+
+let rec show_all_in_goal g =
+  let row = g.Model.goal_row in
+  goals_model#set ~row ~column:Model.visible_column true;
+  if g.Model.proved then
+    goals_view#collapse_row (goals_model#get_path row)
+  else
+    goals_view#expand_row (goals_model#get_path row);
+  Hashtbl.iter
+    (fun _ t -> List.iter show_all_in_goal t.Model.subgoals)
+    g.Model.transformations
+
+let show_all_in_theory th =
+  let row = th.Model.theory_row in
+  goals_model#set ~row ~column:Model.visible_column true;
+  if th.Model.verified then
+    goals_view#collapse_row (goals_model#get_path row)
+  else
+    begin
+      goals_view#expand_row (goals_model#get_path row);
+      List.iter show_all_in_goal th.Model.goals
+    end
+
+let show_all_in_file f =
+  let row = f.Model.file_row in
+  goals_model#set ~row ~column:Model.visible_column true;
+  if f.Model.file_verified then
+    goals_view#collapse_row (goals_model#get_path row)
+  else
+    begin
+      goals_view#expand_row (goals_model#get_path row);
+      List.iter show_all_in_theory f.Model.theories
+    end
+
+let show_all_in_files () =
+  List.iter show_all_in_file !Model.all_files
+
+
+let (_ : GMenu.check_menu_item) = view_factory#add_check_item
+  ~callback:(fun b ->
+               Model.toggle_hide_proved_goals := b;
+               if b then hide_proved_in_files ()
+               else show_all_in_files ())
+  "Hide proved goals"
+
+*)
+
+(**************)
+(* Tools menu *)
+(**************)
+
+
+let () = add_refresh_provers (fun () ->
+  List.iter (fun item -> item#destroy ()) provers_box#all_children)
+
+let tools_menu = factory#add_submenu "_Tools"
+let tools_factory = new GMenu.factory tools_menu ~accel_group
+
+let () = add_refresh_provers (fun () ->
+  List.iter (fun item -> item#destroy ()) tools_menu#all_children)
+
+let () =
+  let add_item_provers () =
+    Util.Mstr.iter
+      (fun _ p ->
+         let n = p.prover_name ^ " " ^ p.prover_version in
+         let (_ : GMenu.image_menu_item) =
+           tools_factory#add_image_item ~label:n
+             ~callback:(fun () -> prover_on_selected_goals p)
+             ()
+         in
+         let b = GButton.button ~packing:provers_box#add ~label:n () in
+         b#misc#set_tooltip_markup "Click to start this prover\non the <b>selected</b> goal(s)";
+
+(* prend de la place pour rien
+         let i = GMisc.image ~pixbuf:(!image_prover) () in
+         let () = b#set_image i#coerce in
+*)
+         let (_ : GtkSignal.id) =
+           b#connect#pressed
+             ~callback:(fun () -> prover_on_selected_goals p)
+         in ())
+      gconfig.provers
+  in
+  add_refresh_provers add_item_provers;
+  add_item_provers ()
+
+let () =
+  let add_item_split () =
+    ignore(tools_factory#add_image_item
+             ~label:"Split selection"
+             ~callback:split_selected_goals
+             () : GMenu.image_menu_item) in
+  add_refresh_provers add_item_split;
+  add_item_split ()
+
+
+let () =
+  let b = GButton.button ~packing:transf_box#add ~label:"Split" () in
+  b#misc#set_tooltip_markup "Click to apply transformation <tt>split_goal</tt> to the <b>selected goals</b>";
+
+  let i = GMisc.image ~pixbuf:(!image_transf) () in
+  let () = b#set_image i#coerce in
+  let (_ : GtkSignal.id) =
+    b#connect#pressed ~callback:split_selected_goals
+  in ()
+
+let () =
+  let b = GButton.button ~packing:transf_box#add ~label:"Inline" () in
+  b#misc#set_tooltip_markup "Click to apply transformation <tt>inline_goal</tt> to the <b>selected goals</b>";
+(**)
+  let i = GMisc.image ~pixbuf:(!image_transf) () in
+  let () = b#set_image i#coerce in
+(**)
+  let (_ : GtkSignal.id) =
+    b#connect#pressed ~callback:inline_selected_goals
+  in ()
+
+
+
+(*************)
+(* Help menu *)
+(*************)
+
+
+let help_menu = factory#add_submenu "_Help"
+let help_factory = new GMenu.factory help_menu ~accel_group
+
+let (_ : GMenu.image_menu_item) =
+  help_factory#add_image_item
+    ~label:"Legend"
+    ~callback:show_legend_window
+    ()
+
+let (_ : GMenu.image_menu_item) =
+  help_factory#add_image_item
+    ~label:"About"
+    ~callback:show_about_window
+    ()
+
+
+(******************************)
+(* vertical paned on the right*)
+(******************************)
+
+let right_vb = GPack.vbox ~packing:hp#add ()
+
+let vp =
+  try
+    GPack.paned `VERTICAL ~packing:right_vb#add ()
+  with Gtk.Error _ -> assert false
+
+let right_hb = GPack.hbox ~packing:(right_vb#pack ~expand:false) ()
+
+let file_info = GMisc.label ~text:""
+  ~packing:(right_hb#pack ~fill:true) ()
+
+let current_file = ref ""
+
+let set_current_file f =
+  current_file := f;
+  file_info#set_text ("file: " ^ !current_file)
+
+(******************)
+(* goal text view *)
+(******************)
+
+let scrolled_task_view = GBin.scrolled_window
+  ~hpolicy: `AUTOMATIC ~vpolicy: `AUTOMATIC
+  ~packing:vp#add ()
+
+let () = scrolled_task_view#set_shadow_type `ETCHED_OUT
+
+let (_ : GtkSignal.id) =
+  scrolled_task_view#misc#connect#size_allocate
+    ~callback:
+    (fun {Gtk.width=_w;Gtk.height=h} ->
+       gconfig.task_height <- h)
+
+let task_view =
+  GSourceView2.source_view
+    ~editable:false
+    ~show_line_numbers:true
+    ~packing:scrolled_task_view#add
+    ~height:gconfig.task_height
+    ()
+
+let () = task_view#source_buffer#set_language lang
+let () = task_view#set_highlight_current_line true
+
+(***************)
+(* source view *)
+(***************)
+
+let scrolled_source_view = GBin.scrolled_window
+  ~hpolicy: `AUTOMATIC ~vpolicy: `AUTOMATIC
+  ~packing:vp#add
+  ()
+
+let () = scrolled_source_view#set_shadow_type `ETCHED_OUT
+
+let source_view =
+  GSourceView2.source_view
+    ~auto_indent:true
+    ~insert_spaces_instead_of_tabs:true ~tab_width:2
+    ~show_line_numbers:true
+    ~right_margin_position:80 ~show_right_margin:true
+    (* ~smart_home_end:true *)
+    ~packing:scrolled_source_view#add
+    ()
+
+(*
+  source_view#misc#modify_font_by_name font_name;
+*)
+let () = source_view#source_buffer#set_language lang
+let () = source_view#set_highlight_current_line true
+(*
+let () = source_view#source_buffer#set_text (source_text fname)
+*)
+
+let move_to_line (v : GSourceView2.source_view) line =
+  if line <= v#buffer#line_count && line <> 0 then begin
+    let it = v#buffer#get_iter (`LINE line) in
+    let mark = `MARK (v#buffer#create_mark it) in
+    v#scroll_to_mark ~use_align:true ~yalign:0.0 mark
+  end
+
+let orange_bg = source_view#buffer#create_tag
+  ~name:"orange_bg" [`BACKGROUND "orange"]
+
+let erase_color_loc (v:GSourceView2.source_view) =
+  let buf = v#buffer in
+  buf#remove_tag orange_bg ~start:buf#start_iter ~stop:buf#end_iter
+
+let color_loc (v:GSourceView2.source_view) l b e =
+  let buf = v#buffer in
+  let top = buf#start_iter in
+  let start = top#forward_lines (l-1) in
+  let start = start#forward_chars b in
+  let stop = start#forward_chars (e-b) in
+  buf#apply_tag ~start ~stop orange_bg
+
+let scroll_to_id id =
+  match id.Ident.id_origin with
+    | Ident.User loc ->
+        let (f,l,b,e) = Loc.get loc in
+        if f <> !current_file then
+          begin
+            source_view#source_buffer#set_text (source_text f);
+            set_current_file f;
+          end;
+        move_to_line source_view (l-1);
+        erase_color_loc source_view;
+        color_loc source_view l b e
+    | Ident.Fresh ->
+        source_view#source_buffer#set_text
+          "Fresh ident (no position available)\n";
+        set_current_file ""
+    | Ident.Derived _ ->
+        source_view#source_buffer#set_text
+          "Derived ident (no position available)\n";
+        set_current_file ""
+
+let color_loc loc =
+  let f, l, b, e = Loc.get loc in
+  if f = !current_file then color_loc source_view l b e
+
+let rec color_f_locs () f =
+  Util.option_iter color_loc f.Term.f_loc;
+  Term.f_fold color_t_locs color_f_locs () f
+
+and color_t_locs () t =
+  Util.option_iter color_loc t.Term.t_loc;
+  Term.t_fold color_t_locs color_f_locs () t
+
+let scroll_to_source_goal g =
+  let t = g.Model.task in
+  let id = (Task.task_goal t).Decl.pr_name in
+  scroll_to_id id;
+  match t with
+    | Some
+        { Task.task_decl =
+            { Theory.td_node =
+                Theory.Decl { Decl.d_node = Decl.Dprop (Decl.Pgoal, _, f)}}} ->
+        color_f_locs () f
+    | _ ->
+        assert false
+
+let scroll_to_theory th =
+  let t = th.Model.theory in
+  let id = t.Theory.th_name in
+  scroll_to_id id
+
+(* to be run when a row in the tree view is selected *)
+let select_row p =
+  let row = goals_model#get_iter p in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal g ->
+        let t = g.Model.task in
+        let t = match apply_trans intro_transformation t with
+	  | [t] -> t
+	  | _ -> assert false
+	in
+        let task_text = Pp.string_of Pretty.print_task t in
+        task_view#source_buffer#set_text task_text;
+        task_view#scroll_to_mark `INSERT;
+        scroll_to_source_goal g
+    | Model.Row_theory th ->
+        task_view#source_buffer#set_text "";
+        scroll_to_theory th
+    | Model.Row_file _file ->
+        task_view#source_buffer#set_text "";
+        (* scroll_to_file file *)
+    | Model.Row_proof_attempt a ->
+	let o =
+          match a.Model.proof_state with
+	    | Gscheduler.Done r -> r.Call_provers.pr_output;
+	    | _ -> "No information available"
+	in
+	task_view#source_buffer#set_text o;
+        scroll_to_source_goal a.Model.proof_goal
+    | Model.Row_transformation tr ->
+        task_view#source_buffer#set_text "";
+        scroll_to_source_goal tr.Model.parent_goal
+
+
+
+
+(*****************************)
+(* method: edit current goal *)
+(*****************************)
+
+
+let ft_of_th th =
+  (Filename.basename th.Model.theory_parent.Model.file_name,
+   th.Model.theory.Theory.th_name.Ident.id_string)
+
+let rec ft_of_goal g =
+  match g.Model.parent with
+    | Model.Transf tr -> ft_of_goal tr.Model.parent_goal
+    | Model.Theory th -> ft_of_th th
+
+let ft_of_pa a =
+  ft_of_goal a.Model.proof_goal
+
+let edit_selected_row p =
+  let row = goals_model#get_iter p in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal _g ->
+        ()
+    | Model.Row_theory _th ->
+        ()
+    | Model.Row_file _file ->
+        ()
+    | Model.Row_proof_attempt a ->
+        (* check that the state is not Scheduled or Running *)
+        let running = match a.Model.proof_state with
+          | Gscheduler.Scheduled | Gscheduler.Running -> true
+          | Gscheduler.Undone | Gscheduler.Done _ | Gscheduler.InternalFailure _ -> false
+        in
+        if running then
+          info_window `ERROR "Edition already in progress"
+        else
+        let g = a.Model.proof_goal in
+	let t = g.Model.task in
+	let driver = a.Model.prover.driver in
+	let file =
+          match a.Model.edited_as with
+            | "" ->
+		let (fn,tn) = ft_of_pa a in
+		let file = Driver.file_of_task driver
+                  (Filename.concat project_dir fn) tn t
+		in
+		(* Uniquify the filename if it exists on disk *)
+		let i =
+                  try String.rindex file '.'
+                  with _ -> String.length file
+		in
+		let name = String.sub file 0 i in
+		let ext = String.sub file i (String.length file - i) in
+		let i = ref 1 in
+		while Sys.file_exists
+		  (name ^ "_" ^ (string_of_int !i) ^ ext) do
+		    incr i
+		done;
+		let file = name ^ "_" ^ (string_of_int !i) ^ ext in
+		a.Model.edited_as <- file;
+		Db.set_edited_as a.Model.proof_db file;
+		file
+	    | f -> f
+	in
+        let old_status = a.Model.proof_state in
+        let callback res =
+          match res with
+            | Gscheduler.Done _ ->
+                Helpers.set_proof_state ~obsolete:false a old_status
+            | _ ->
+                Helpers.set_proof_state ~obsolete:false a res
+        in
+        let editor =
+          match a.Model.prover.editor with
+            | "" -> gconfig.default_editor
+            | _ -> a.Model.prover.editor
+        in
+        Gscheduler.edit_proof ~debug:false ~editor
+          ~file
+          ~driver
+          ~callback
+          t
+    | Model.Row_transformation _tr ->
+        ()
+
+let edit_current_proof () =
+  match goals_view#selection#get_selected_rows with
+    | [] -> ()
+    | [r] -> edit_selected_row r
+    | _ ->
+	info_window `INFO "Please select exactly one proof to edit"
+
+
+let add_item_edit () =
+  ignore (tools_factory#add_image_item
+            ~label:"Edit current proof"
+            ~callback:edit_current_proof
+            () : GMenu.image_menu_item)
+
+let () =
+  add_refresh_provers add_item_edit;
+  add_item_edit ()
+
+
+let () =
+  let b = GButton.button ~packing:tools_box#add ~label:"Edit" () in
+  b#misc#set_tooltip_markup "Click to edit the <b>selected proof</b>\nwith the appropriate editor";
+
+  let i = GMisc.image ~pixbuf:(!image_editor) () in
+  let () = b#set_image i#coerce in
+  let (_ : GtkSignal.id) =
+    b#connect#pressed ~callback:edit_current_proof
+  in ()
+
+let () =
+  let b = GButton.button ~packing:tools_box#add ~label:"Replay" () in
+  b#misc#set_tooltip_markup "Replay all the <b>successful</b> but <b>obsolete</b> proofs below the current selection";
+
+  let i = GMisc.image ~pixbuf:(!image_replay) () in
+  let () = b#set_image i#coerce in
+  let (_ : GtkSignal.id) =
+    b#connect#pressed ~callback:replay_obsolete_proofs
+  in ()
+
+(*************)
+(* removing  *)
+(*************)
+
+let remove_proof_attempt a =
+  Db.remove_proof_attempt a.Model.proof_db;
+  let (_:bool) = goals_model#remove a.Model.proof_row in
+  let g = a.Model.proof_goal in
+  Hashtbl.remove g.Model.external_proofs a.Model.prover.prover_id;
+  Helpers.check_goal_proved g
+
+let remove_transf t =
+  (* TODO: remove subgoals first !!! *)
+  Db.remove_transformation t.Model.transf_db;
+  let (_:bool) = goals_model#remove t.Model.transf_row in
+  let g = t.Model.parent_goal in
+  Hashtbl.remove g.Model.transformations "split" (* hack !! *);
+  Helpers.check_goal_proved g
+
+
+let confirm_remove_row r =
+  let row = goals_model#get_iter r in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal _g ->
+	info_window `ERROR "Cannot remove a goal"
+    | Model.Row_theory _th ->
+	info_window `ERROR "Cannot remove a theory"
+    | Model.Row_file _file ->
+	info_window `ERROR "Cannot remove a file"
+    | Model.Row_proof_attempt a ->
+	info_window
+	  ~callback:(fun () -> remove_proof_attempt a)
+	  `QUESTION
+	  "Do you really want to remove the selected proof attempt?"
+    | Model.Row_transformation tr ->
+	info_window
+	  ~callback:(fun () -> remove_transf tr)
+	  `QUESTION
+	  "Do you really want to remove the selected transformation
+and all its subgoals?"
+
+let confirm_remove_selection () =
+  match goals_view#selection#get_selected_rows with
+    | [] -> ()
+    | [r] -> confirm_remove_row r
+    | _ ->
+        info_window `INFO "Please select exactly one item to remove"
+
+let () =
+  let b = GButton.button ~packing:cleaning_box#add ~label:"Remove" () in
+  b#misc#set_tooltip_markup "Removes the selected\n<b>proof</b> or <b>transformation</b>";
+  let i = GMisc.image ~pixbuf:(!image_remove) () in
+  let () = b#set_image i#coerce in
+  let (_ : GtkSignal.id) =
+    b#connect#pressed ~callback:confirm_remove_selection
+  in ()
+
+let rec clean_goal g =
+  if g.Model.proved then
+    begin
+      Hashtbl.iter
+        (fun _ a ->
+           if a.Model.proof_obsolete || not (proof_successful a) then
+             remove_proof_attempt a)
+        g.Model.external_proofs;
+      Hashtbl.iter
+        (fun _ t ->
+           if not t.Model.transf_proved then
+             remove_transf t)
+        g.Model.transformations
+    end
+  else
+    Hashtbl.iter
+      (fun _ t -> List.iter clean_goal t.Model.subgoals)
+      g.Model.transformations
+
+
+let clean_row r =
+  let row = goals_model#get_iter r in
+  match goals_model#get ~row ~column:Model.index_column with
+    | Model.Row_goal g -> clean_goal g
+    | Model.Row_theory th ->
+        List.iter clean_goal th.Model.goals
+    | Model.Row_file file ->
+        List.iter
+          (fun th ->
+             List.iter clean_goal th.Model.goals)
+          file.Model.theories
+    | Model.Row_proof_attempt a ->
+        clean_goal a.Model.proof_goal
+    | Model.Row_transformation tr ->
+        List.iter clean_goal tr.Model.subgoals
+
+let clean_selection () =
+  List.iter clean_row goals_view#selection#get_selected_rows
+
+let () =
+  let b = GButton.button ~packing:cleaning_box#add ~label:"Clean" () in
+  b#misc#set_tooltip_markup "Removes non successful proof_attempts\nassociated to a proved goal";
+  let i = GMisc.image ~pixbuf:(!image_cleaning) () in
+  let () = b#set_image i#coerce in
+  let (_ : GtkSignal.id) =
+    b#connect#pressed ~callback:clean_selection
+  in ()
+
+
+(***************)
+(* Bind events *)
+(***************)
+
+(* row selection on tree view on the left *)
+let (_ : GtkSignal.id) =
+  goals_view#selection#connect#after#changed ~callback:
+    begin fun () ->
+      match goals_view#selection#get_selected_rows with
+        | [p] -> select_row p
+        | [] -> ()
+        | _ -> ()
+    end
+
+let () = w#add_accel_group accel_group
+let () = w#show ()
+let () = GMain.main ()
+
+(*
+Local Variables:
+compile-command: "unset LANG; make -C ../.. bin/why3ide.byte"
+End:
+*)
diff --git a/src/ide/session.ml b/src/ide/session.ml
index d947853334efa70ecf6059e2815e8c228377b538..2d701d999da4c69580a0b422825359874447d1ef 100644
--- a/src/ide/session.ml
+++ b/src/ide/session.ml
@@ -19,6 +19,24 @@
 
 
 open Why
+open Format
+
+type prover_data =
+    { prover_id : string;
+      prover_name : string;
+      prover_version : string;
+      command : string;
+      driver_name : string;
+      driver : Driver.driver;
+      mutable editor : string;
+    }
+
+type proof_attempt_status =
+  | Undone
+  | Scheduled (** external proof attempt is scheduled *)
+  | Running (** external proof attempt is in progress *)
+  | Done of Call_provers.prover_result (** external proof done *)
+  | InternalFailure of exn (** external proof aborted by internal error *)
 
 
 module type OBSERVER = sig
@@ -26,19 +44,15 @@ module type OBSERVER = sig
   val create: ?parent:key -> unit -> key
   val notify: key -> unit
   val remove: key -> unit
+
+  val timeout: ms:int -> (unit -> bool) -> unit
+  val idle: (unit -> bool) -> unit
 end
 
 module Make(O : OBSERVER) = struct
 
-type proof_attempt_status =
-  | Undone
-  | Scheduled (** external proof attempt is scheduled *)
-  | Running (** external proof attempt is in progress *)
-  | Done of Call_provers.prover_result (** external proof done *)
-  | InternalFailure of exn (** external proof aborted by internal error *)
-
 type proof_attempt =
-    { prover_id : string;
+    { prover : prover_data;
       proof_goal : goal;
       proof_key : O.key;
       mutable proof_state : proof_attempt_status;
@@ -47,8 +61,8 @@ type proof_attempt =
     }
 
 and goal_parent =
-  | Theory of theory
-  | Transf of transf
+  | Parent_theory of theory
+  | Parent_transf of transf
 
 and goal =
     { goal_name : string;
@@ -83,8 +97,18 @@ and file =
       mutable file_verified : bool;
     }
 
+type any =
+  | File of file
+  | Theory of theory
+  | Goal of goal
+  | Proof_attempt of proof_attempt
+  | Transformation of transf
+
+
 let all_files : file list ref = ref []
 
+let open_session _ = ()
+
 let check_file_verified f =
   let b = List.for_all (fun t -> t.verified) f.theories in
   if f.file_verified <> b then
@@ -117,8 +141,8 @@ let rec check_goal_proved g =
       g.proved <- b;
       O.notify g.goal_key;
       match g.parent with
-        | Theory t -> check_theory_proved t
-        | Transf t -> check_transf_proved t
+        | Parent_theory t -> check_theory_proved t
+        | Parent_transf t -> check_transf_proved t
     end
 
 and check_transf_proved t =
@@ -149,10 +173,10 @@ let rec set_proved ~propagate g =
   O.notify g.goal_key;
   if propagate then
     match g.parent with
-      | Theory t ->
+      | Parent_theory t ->
           if List.for_all (fun g -> g.proved) t.goals then
             set_theory_proved ~propagate t
-      | Transf t ->
+      | Parent_transf t ->
           if List.for_all (fun g -> g.proved) t.subgoals then
             begin
               set_proved ~propagate t.parent_goal;
@@ -163,6 +187,169 @@ let set_proof_state ~obsolete a res =
   a.proof_obsolete <- obsolete;
   O.notify a.proof_key
 
+(*************************)
+(*         Scheduler     *)
+(*************************) 
+
+
+(* timeout handler *)
+
+let maximum_running_proofs = ref 2
+let running_proofs = ref []
+
+let proof_attempts_queue = Queue.create ()
+
+let timeout_handler_activated = ref false
+let timeout_handler_running = ref false
+
+let timeout_handler () =
+  assert (not !timeout_handler_running);
+  timeout_handler_running := true;
+  let l = List.fold_left
+    (fun acc ((callback,call) as c) ->
+       match Call_provers.query_call call with
+	 | None -> c::acc
+	 | Some post ->
+	     let res = post () in callback (Done res);
+	     acc)
+    [] !running_proofs
+  in
+  let l =
+    if List.length l < !maximum_running_proofs then
+      begin try
+	let (callback,pre_call) = Queue.pop proof_attempts_queue in
+	callback Running;
+	let call = pre_call () in
+	(callback,call)::l
+      with Queue.Empty -> l
+      end
+    else l
+  in
+  running_proofs := l;
+  let continue =
+    match l with
+      | [] ->
+(*
+          eprintf "Info: timeout_handler stopped@.";
+*)
+          false
+      | _ -> true
+  in
+  timeout_handler_activated := continue;
+  timeout_handler_running := false;
+  continue
+
+
+let run_timeout_handler () =
+  if !timeout_handler_activated then () else
+    begin
+      timeout_handler_activated := true;
+(*
+      eprintf "Info: timeout_handler started@.";
+*)
+      O.timeout ~ms:100 timeout_handler
+    end
+
+(* idle handler *)
+
+
+type action =
+  | Action_proof_attempt of bool * int * int * in_channel option * string * Driver.driver *
+    (proof_attempt_status -> unit) * Task.task
+  | Action_delayed of (unit -> unit)
+
+let actions_queue = Queue.create ()
+
+let idle_handler_activated = ref false
+
+let idle_handler () =
+  try
+    begin
+      match Queue.pop actions_queue with
+	| Action_proof_attempt(debug,timelimit,memlimit,old,command,driver,
+			       callback,goal) ->
+	    callback Scheduled;
+	    if debug then
+	      Format.eprintf "Task for prover: %a@."
+		(Driver.print_task driver) goal;
+	    let pre_call =
+	      Driver.prove_task ?old ~command ~timelimit ~memlimit driver goal
+	    in
+	    Queue.push (callback,pre_call) proof_attempts_queue;
+	    run_timeout_handler ()
+        | Action_delayed callback -> callback ()
+    end;
+    true
+  with Queue.Empty ->
+    idle_handler_activated := false;
+(*
+    eprintf "Info: idle_handler stopped@.";
+*)
+    false
+
+let run_idle_handler () =
+  if !idle_handler_activated then () else
+    begin
+      idle_handler_activated := true;
+(*
+      eprintf "Info: idle_handler started@.";
+*)
+      O.idle idle_handler
+    end
+
+(* main scheduling functions *)
+
+let schedule_proof_attempt ~debug ~timelimit ~memlimit ?old
+    ~command ~driver ~callback goal =
+  Queue.push
+    (Action_proof_attempt(debug,timelimit,memlimit,old,command,driver,
+			callback,goal))
+    actions_queue;
+  run_idle_handler ()
+
+let schedule_edition command callback =
+  let precall =
+    Call_provers.call_on_buffer ~command ~regexps:[] ~timeregexps:[]
+      ~exitcodes:[(0,Call_provers.Unknown "")] ~filename:"" (Buffer.create 1)
+  in
+  callback Running;
+  running_proofs := (callback, precall ()) :: !running_proofs;
+  run_timeout_handler ()
+
+let schedule_delayed_action callback =
+  Queue.push (Action_delayed callback) actions_queue;
+  run_idle_handler ()
+
+let apply_transformation ~callback transf goal =
+  callback (Trans.apply transf goal)
+
+let apply_transformation_l ~callback transf goal =
+  callback (Trans.apply transf goal)
+
+
+let edit_proof ~debug:_ ~editor ~file ~driver ~callback goal =
+  let old =
+    if Sys.file_exists file
+    then
+      begin
+	let backup = file ^ ".bak" in
+        Sys.rename file backup;
+        Some(open_in backup)
+      end
+    else None
+  in
+  let ch = open_out file in
+  let fmt = formatter_of_out_channel ch in
+  Driver.print_task ?old driver fmt goal;
+  Util.option_iter close_in old;
+  close_out ch;
+  let command = editor ^ " " ^ file in
+  (*
+  let _ = Sys.command command in
+  callback ()
+  *)
+  schedule_edition command callback
+
 
 (*******************************)
 (* explanations *)
@@ -211,7 +398,7 @@ let set_proof_state ~obsolete a res =
 
 let raw_add_external_proof ~obsolete ~edit g p result =
   let key = O.create ~parent:g.goal_key () in
-  let a = { prover_id = p;
+  let a = { prover = p;
             proof_goal = g;
             proof_key = key;
             proof_obsolete = obsolete;
@@ -219,7 +406,7 @@ let raw_add_external_proof ~obsolete ~edit g p result =
             edited_as = edit;
           }
   in
-  Hashtbl.add g.external_proofs p a;
+  Hashtbl.add g.external_proofs p.prover_name a;
   O.notify key;
   (* notify g.goal_key ? *)
   a
@@ -229,8 +416,8 @@ let raw_add_external_proof ~obsolete ~edit g p result =
 *)
 let raw_add_goal parent name expl t =
   let parent_key = match parent with
-    | Theory mth -> mth.theory_key
-    | Transf mtr -> mtr.transf_key
+    | Parent_theory mth -> mth.theory_key
+    | Parent_transf mtr -> mtr.transf_key
   in
   let key = O.create ~parent:parent_key () in
   let goal = { goal_name = name;
@@ -288,7 +475,7 @@ let add_theory mfile th =
          let id = (Task.task_goal t).Decl.pr_name in
          let name = id.Ident.id_string in
          let expl = get_explanation id (Task.task_goal_fmla t) in
-         let goal = raw_add_goal (Theory mth) name expl t in
+         let goal = raw_add_goal (Parent_theory mth) name expl t in
          goal :: acc)
       []
       tasks
@@ -308,7 +495,6 @@ let raw_add_file f =
   mfile
 
 let add_file f theories =
-
   let theories =
     Theory.Mnm.fold
       (fun name th acc ->
@@ -339,9 +525,10 @@ let add_file f theories =
 (* reload a file                  *)
 (**********************************)
 
+(*
 let rec reimport_any_goal parent gid gname t db_goal goal_obsolete =
   let info = get_explanation gid (Task.task_goal_fmla t) in
-  let goal = Helpers.add_goal_row parent gname info t db_goal in
+  let goal = raw_add_goal parent gname info t in
   let proved = ref false in
   let external_proofs = Db.external_proofs db_goal in
   Db.Hprover.iter
@@ -545,200 +732,162 @@ let () =
     )
     files_in_db
 
-(**********************************)
-(* add new file from command line *)
-(**********************************)
-
-let () =
-  match file_to_read with
-    | None -> ()
-    | Some fn ->
-        if List.exists (fun (_,f) -> f = fn) files_in_db then
-          eprintf "Info: file %s already in database@." fn
-        else
-          try
-            Helpers.add_file fn
-          with e ->
-	    eprintf "@[Error while reading file@ '%s':@ %a@.@]" fn
-              Exn_printer.exn_printer e;
-	    exit 1
-
-
-(**********************)
-(* set up scheduler   *)
-(**********************)
-
-let () =
-  begin
-    Gscheduler.maximum_running_proofs := gconfig.max_running_processes
-  end
+*)
 
 
 (*****************************************************)
 (* method: run a given prover on each unproved goals *)
 (*****************************************************)
 
-(* q is a queue of proof attempt where to put the new one *)
 let redo_external_proof g a =
   (* check that the state is not Scheduled or Running *)
-(**)
-  let running = match a.Model.proof_state with
-    | Gscheduler.Scheduled | Gscheduler.Running -> true
-    | Gscheduler.Done _ | Gscheduler.Undone | Gscheduler.InternalFailure _ -> false
+  let running = match a.proof_state with
+    | Scheduled | Running -> true
+    | Done _ | Undone | InternalFailure _ -> false
   in
   if running then ()
     (* info_window `ERROR "Proof already in progress" *)
   else
-(**)
-  let p = a.Model.prover in
-  let callback result =
-    Helpers.set_proof_state ~obsolete:false a result (*time*) ;
-    let db_res, time =
+    let p = a.prover in
+    let callback result =
+      set_proof_state ~obsolete:false a result;
       match result with
-	| Gscheduler.Undone | Gscheduler.Scheduled | Gscheduler.Running ->
-	    Db.Undone, 0.0
-	| Gscheduler.InternalFailure _ ->
-	    Db.Done Call_provers.HighFailure, 0.0
-	| Gscheduler.Done r ->
+	| Done r ->
 	    if r.Call_provers.pr_answer = Call_provers.Valid then
-	      Helpers.set_proved ~propagate:true a.Model.proof_goal;
-	    Db.Done r.Call_provers.pr_answer, r.Call_provers.pr_time
+	      set_proved ~propagate:true a.proof_goal
+	| _ -> ()
     in
-    Db.set_status a.Model.proof_db db_res time
-  in
-  let old = if a.Model.edited_as = "" then None else
-    begin
-      eprintf "Info: proving using edited file %s@." a.Model.edited_as;
-      (Some (open_in a.Model.edited_as))
-    end
-  in
-  Gscheduler.schedule_proof_attempt
-    ~debug:(gconfig.verbose > 0) ~timelimit:gconfig.time_limit ~memlimit:0
-    ?old ~command:p.command ~driver:p.driver
-    ~callback
-    g.Model.task
+    let old = if a.edited_as = "" then None else
+      begin
+	Format.eprintf "Info: proving using edited file %s@." a.edited_as;
+	(Some (open_in a.edited_as))
+      end
+    in
+    schedule_proof_attempt
+      ~debug:false ~timelimit:10 ~memlimit:0
+      ?old ~command:p.command ~driver:p.driver
+      ~callback
+      g.task
 
 let rec prover_on_goal p g =
   let id = p.prover_id in
   let a =
-    try Hashtbl.find g.Model.external_proofs id
+    try Hashtbl.find g.external_proofs id
     with Not_found ->
-      let db_prover = Db.prover_from_name id in
-      let db_pa = Db.add_proof_attempt g.Model.goal_db db_prover in
-      Helpers.add_external_proof_row ~obsolete:false ~edit:""
-	g p db_pa Gscheduler.Undone
+      raw_add_external_proof ~obsolete:false ~edit:"" g p Undone
   in
   let () = redo_external_proof g a in
   Hashtbl.iter
-    (fun _ t -> List.iter (prover_on_goal p) t.Model.subgoals)
-    g.Model.transformations
+    (fun _ t -> List.iter (prover_on_goal p) t.subgoals)
+    g.transformations
 
-let rec prover_on_goal_or_children p g =
-  if not (g.Model.proved && !context_unproved_goals_only) then
+let rec prover_on_goal_or_children ~context_unproved_goals_only p g =
+  if not (g.proved && context_unproved_goals_only) then
     begin
       let r = ref true in
       Hashtbl.iter
 	(fun _ t ->
 	   r := false;
-           List.iter (prover_on_goal_or_children p)
-             t.Model.subgoals) g.Model.transformations;
+           List.iter (prover_on_goal_or_children ~context_unproved_goals_only p)
+             t.subgoals) g.transformations;
       if !r then prover_on_goal p g
     end
 
-let prover_on_selected_goal_or_children pr row =
-  let row = goals_model#get_iter row in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal g ->
-        prover_on_goal_or_children pr g
-    | Model.Row_theory th ->
-        List.iter (prover_on_goal_or_children pr) th.Model.goals
-    | Model.Row_file file ->
+let run_prover ~context_unproved_goals_only pr a =
+  match a with
+    | Goal g -> 
+	prover_on_goal_or_children ~context_unproved_goals_only pr g
+    | Theory th -> 
+	List.iter 
+	  (prover_on_goal_or_children ~context_unproved_goals_only pr) 
+	  th.goals
+    | File file -> 
         List.iter
           (fun th ->
-             List.iter (prover_on_goal_or_children pr) th.Model.goals)
-          file.Model.theories
-    | Model.Row_proof_attempt a ->
-        prover_on_goal_or_children pr a.Model.proof_goal
-    | Model.Row_transformation tr ->
-        List.iter (prover_on_goal_or_children pr) tr.Model.subgoals
-
-let prover_on_selected_goals pr =
-  List.iter
-    (prover_on_selected_goal_or_children pr)
-    goals_view#selection#get_selected_rows
+             List.iter 
+	       (prover_on_goal_or_children ~context_unproved_goals_only pr)
+	       th.goals)
+          file.theories
+    | Proof_attempt a ->
+        prover_on_goal_or_children ~context_unproved_goals_only pr a.proof_goal
+    | Transformation tr ->
+        List.iter 
+	  (prover_on_goal_or_children ~context_unproved_goals_only pr) 
+	  tr.subgoals
 
 (**********************************)
 (* method: replay obsolete proofs *)
 (**********************************)
 
 let proof_successful a =
-  match a.Model.proof_state with
-    | Gscheduler.Done { Call_provers.pr_answer = Call_provers.Valid }
-      -> true
+  match a.proof_state with
+    | Done { Call_provers.pr_answer = Call_provers.Valid } -> true
     | _ -> false
 
-let rec replay_on_goal_or_children g =
+let rec replay_on_goal_or_children ~context_unproved_goals_only g =
   Hashtbl.iter
     (fun _ a ->
-       if a.Model.proof_obsolete then
-         if not !context_unproved_goals_only || proof_successful a
+       if a.proof_obsolete then
+         if not context_unproved_goals_only || proof_successful a
          then redo_external_proof g a)
-    g.Model.external_proofs;
+    g.external_proofs;
   Hashtbl.iter
-    (fun _ t ->
-       List.iter replay_on_goal_or_children
-         t.Model.subgoals)
-    g.Model.transformations
-
-let replay_on_selected_goal_or_children row =
-  let row = goals_model#get_iter row in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal g ->
-        replay_on_goal_or_children g
-    | Model.Row_theory th ->
-        List.iter replay_on_goal_or_children th.Model.goals
-    | Model.Row_file file ->
+    (fun _ t -> 
+       List.iter 
+	 (replay_on_goal_or_children ~context_unproved_goals_only) 
+	 t.subgoals)
+    g.transformations
+
+let replay ~context_unproved_goals_only a =
+  match a with
+    | Goal g ->
+        replay_on_goal_or_children ~context_unproved_goals_only g
+    | Theory th ->
+        List.iter 
+	  (replay_on_goal_or_children ~context_unproved_goals_only)
+	  th.goals
+    | File file ->
         List.iter
           (fun th ->
-             List.iter replay_on_goal_or_children th.Model.goals)
-          file.Model.theories
-    | Model.Row_proof_attempt a ->
-        replay_on_goal_or_children a.Model.proof_goal
-    | Model.Row_transformation tr ->
-        List.iter replay_on_goal_or_children tr.Model.subgoals
-
-let replay_obsolete_proofs () =
-  List.iter
-    replay_on_selected_goal_or_children
-    goals_view#selection#get_selected_rows
-
+             List.iter 
+	       (replay_on_goal_or_children ~context_unproved_goals_only)
+	       th.goals)
+          file.theories
+    | Proof_attempt a ->
+        replay_on_goal_or_children ~context_unproved_goals_only a.proof_goal
+    | Transformation tr ->
+        List.iter 
+	  (replay_on_goal_or_children ~context_unproved_goals_only)
+	  tr.subgoals
 
 
 (*****************************************************)
 (* method: split selected goals *)
 (*****************************************************)
 
+(*
+
 let transformation_on_goal g trans_name trans =
-  if not g.Model.proved then
+  if not g.proved then
     let callback subgoals =
       let b =
  	match subgoals with
 	  | [task] ->
-              let s1 = task_checksum g.Model.task in
+              let s1 = task_checksum g.task in
               let s2 = task_checksum task in
 	      (*
-                eprintf "Transformation returned only one task. sum before = %s, sum after = %s@." (task_checksum g.Model.task) (task_checksum task);
-                eprintf "addresses: %x %x@." (Obj.magic g.Model.task) (Obj.magic task);
+                eprintf "Transformation returned only one task. sum before = %s, sum after = %s@." (task_checksum g.task) (task_checksum task);
+                eprintf "addresses: %x %x@." (Obj.magic g.task) (Obj.magic task);
 	      *)
               s1 <> s2
-                (* task != g.Model.task *)
+                (* task != g.task *)
 	  | _ -> true
       in
       if b then
 	let transf_id = Db.transf_from_name trans_name in
-	let db_transf = Db.add_transformation g.Model.goal_db transf_id	in
+	let db_transf = Db.add_transformation g.goal_db transf_id	in
 	let tr = Helpers.add_transformation_row g db_transf trans_name in
-	let goal_name = g.Model.goal_name in
+	let goal_name = g.goal_name in
 	let fold =
 	  fun (acc,count) subtask ->
 	    let id = (Task.task_goal subtask).Decl.pr_name in
@@ -753,7 +902,7 @@ let transformation_on_goal g trans_name trans =
 	      Db.add_subgoal db_transf subgoal_name sum
 	    in
 	    let goal =
-	      Helpers.add_goal_row (Model.Transf tr)
+	      Helpers.add_goal_row (Transf tr)
 		subgoal_name expl subtask subtask_db
 	    in
 	    (goal :: acc, count+1)
@@ -761,11 +910,11 @@ let transformation_on_goal g trans_name trans =
 	let goals,_ =
 	  List.fold_left fold ([],1) subgoals
 	in
-	tr.Model.subgoals <- List.rev goals;
-	Hashtbl.add g.Model.transformations trans_name tr
+	tr.subgoals <- List.rev goals;
+	Hashtbl.add g.transformations trans_name tr
     in
     apply_transformation ~callback
-      trans g.Model.task
+      trans g.task
 
 let split_goal g =
   Gscheduler.schedule_delayed_action
@@ -775,63 +924,63 @@ let split_goal g =
 let inline_goal g = transformation_on_goal g "inline_goal" inline_transformation
 
 let rec split_goal_or_children g =
-  if not g.Model.proved then
+  if not g.proved then
     begin
       let r = ref true in
       Hashtbl.iter
 	(fun _ t ->
 	   r := false;
            List.iter split_goal_or_children
-             t.Model.subgoals) g.Model.transformations;
+             t.subgoals) g.transformations;
       if !r then split_goal g
     end
 
 let rec inline_goal_or_children g =
-  if not g.Model.proved then
+  if not g.proved then
     begin
       let r = ref true in
       Hashtbl.iter
 	(fun _ t ->
 	   r := false;
            List.iter inline_goal_or_children
-             t.Model.subgoals) g.Model.transformations;
+             t.subgoals) g.transformations;
       if !r then inline_goal g
     end
 
 let split_selected_goal_or_children row =
   let row = goals_model#get_iter row in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal g ->
+  match goals_model#get ~row ~column:index_column with
+    | Row_goal g ->
         split_goal_or_children g
-    | Model.Row_theory th ->
-        List.iter split_goal_or_children th.Model.goals
-    | Model.Row_file file ->
+    | Row_theory th ->
+        List.iter split_goal_or_children th.goals
+    | Row_file file ->
         List.iter
           (fun th ->
-             List.iter split_goal_or_children th.Model.goals)
-          file.Model.theories
-    | Model.Row_proof_attempt a ->
-        split_goal_or_children a.Model.proof_goal
-    | Model.Row_transformation tr ->
-        List.iter split_goal_or_children tr.Model.subgoals
+             List.iter split_goal_or_children th.goals)
+          file.theories
+    | Row_proof_attempt a ->
+        split_goal_or_children a.proof_goal
+    | Row_transformation tr ->
+        List.iter split_goal_or_children tr.subgoals
 
 
 let inline_selected_goal_or_children row =
   let row = goals_model#get_iter row in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal g ->
+  match goals_model#get ~row ~column:index_column with
+    | Row_goal g ->
         inline_goal_or_children g
-    | Model.Row_theory th ->
-        List.iter inline_goal_or_children th.Model.goals
-    | Model.Row_file file ->
+    | Row_theory th ->
+        List.iter inline_goal_or_children th.goals
+    | Row_file file ->
         List.iter
           (fun th ->
-             List.iter inline_goal_or_children th.Model.goals)
-          file.Model.theories
-    | Model.Row_proof_attempt a ->
-        inline_goal_or_children a.Model.proof_goal
-    | Model.Row_transformation tr ->
-        List.iter inline_goal_or_children tr.Model.subgoals
+             List.iter inline_goal_or_children th.goals)
+          file.theories
+    | Row_proof_attempt a ->
+        inline_goal_or_children a.proof_goal
+    | Row_transformation tr ->
+        List.iter inline_goal_or_children tr.subgoals
 
 let split_selected_goals () =
   List.iter
@@ -845,543 +994,50 @@ let inline_selected_goals () =
     goals_view#selection#get_selected_rows
 
 
-(*********************************)
-(* add a new file in the project *)
-(*********************************)
-
-let filter_all_files () =
-  let f = GFile.filter ~name:"All" () in
-  f#add_pattern "*" ;
-  f
-
-let filter_why_files () =
-  GFile.filter
-    ~name:"Why3 source files"
-    ~patterns:[ "*.why"; "*.mlw"] ()
-
-let select_file () =
-  let d = GWindow.file_chooser_dialog ~action:`OPEN
-    ~title:"Why3: Add file in project"
-    ()
-  in
-  d#add_button_stock `CANCEL `CANCEL ;
-  d#add_select_button_stock `OPEN `OPEN ;
-  d#add_filter (filter_why_files ()) ;
-  d#add_filter (filter_all_files ()) ;
-  begin match d#run () with
-  | `OPEN ->
-      begin
-        match d#filename with
-          | None -> ()
-          | Some f ->
-	      let f = Sysutil.relativize_filename project_dir f in
-              eprintf "Adding file '%s'@." f;
-              try
-                Helpers.add_file f
-              with e ->
-	        fprintf str_formatter
-                  "@[Error while reading file@ '%s':@ %a@]" f
-                  Exn_printer.exn_printer e;
-	        let msg = flush_str_formatter () in
-	        info_window `ERROR msg
-      end
-  | `DELETE_EVENT | `CANCEL -> ()
-  end ;
-  d#destroy ()
-
-
-let not_implemented () =
-  info_window `INFO "This feature is not yet implemented, sorry."
-
-(*************)
-(* File menu *)
-(*************)
-
-let file_menu = factory#add_submenu "_File"
-let file_factory = new GMenu.factory file_menu ~accel_group
-
-let (_ : GMenu.image_menu_item) =
-  file_factory#add_image_item ~key:GdkKeysyms._A
-    ~label:"_Add file" ~callback:select_file
-    ()
-
-let (_ : GMenu.image_menu_item) =
-  file_factory#add_image_item ~label:"_Preferences" ~callback:
-    (fun () ->
-       Gconfig.preferences gconfig;
-       Gscheduler.maximum_running_proofs := gconfig.max_running_processes)
-    ()
-
-let refresh_provers = ref (fun () -> ())
-
-let add_refresh_provers f =
-  let rp = !refresh_provers in
-  refresh_provers := (fun () -> rp (); f ())
-
-let (_ : GMenu.image_menu_item) =
-  file_factory#add_image_item ~label:"_Detect provers" ~callback:
-    (fun () -> Gconfig.run_auto_detection gconfig; !refresh_provers () )
-    ()
-
-let (_ : GMenu.image_menu_item) =
-  file_factory#add_image_item ~key:GdkKeysyms._Q ~label:"_Quit"
-    ~callback:exit_function ()
-
-(*************)
-(* View menu *)
-(*************)
-
-let view_menu = factory#add_submenu "_View"
-let view_factory = new GMenu.factory view_menu ~accel_group
-let (_ : GMenu.image_menu_item) =
-  view_factory#add_image_item ~key:GdkKeysyms._E
-    ~label:"Expand all" ~callback:(fun () -> goals_view#expand_all ()) ()
-
-
-
-let rec collapse_proved_goal g =
-  if g.Model.proved then
-    begin
-      let row = g.Model.goal_row in
-      goals_view#collapse_row (goals_model#get_path row);
-    end
-  else
-    Hashtbl.iter
-      (fun _ t -> List.iter collapse_proved_goal t.Model.subgoals)
-      g.Model.transformations
-
-let collapse_verified_theory th =
-  if th.Model.verified then
-    begin
-      let row = th.Model.theory_row in
-      goals_view#collapse_row (goals_model#get_path row);
-    end
-  else
-    List.iter collapse_proved_goal th.Model.goals
-
-let collapse_verified_file f =
-  if f.Model.file_verified then
-    begin
-      let row = f.Model.file_row in
-      goals_view#collapse_row (goals_model#get_path row);
-    end
-  else
-    List.iter collapse_verified_theory f.Model.theories
-
-let collapse_all_verified_things () =
-  List.iter collapse_verified_file !Model.all_files
-
-let (_ : GMenu.image_menu_item) =
-  view_factory#add_image_item ~key:GdkKeysyms._C
-    ~label:"Collapse proved goals"
-    ~callback:collapse_all_verified_things
-    ()
-
-(*
-let rec hide_proved_in_goal g =
-  if g.Model.proved then
-    begin
-      let row = g.Model.goal_row in
-      goals_view#collapse_row (goals_model#get_path row);
-(*
-      goals_model#set ~row ~column:Model.visible_column false
-*)
-    end
-  else
-    Hashtbl.iter
-      (fun _ t -> List.iter hide_proved_in_goal t.Model.subgoals)
-      g.Model.transformations
-
-let hide_proved_in_theory th =
-  if th.Model.verified then
-    begin
-      let row = th.Model.theory_row in
-      goals_view#collapse_row (goals_model#get_path row);
-      goals_model#set ~row ~column:Model.visible_column false
-    end
-  else
-    List.iter hide_proved_in_goal th.Model.goals
-
-let hide_proved_in_file f =
-  if f.Model.file_verified then
-    begin
-      let row = f.Model.file_row in
-      goals_view#collapse_row (goals_model#get_path row);
-      goals_model#set ~row ~column:Model.visible_column false
-    end
-  else
-    List.iter hide_proved_in_theory f.Model.theories
-
-let hide_proved_in_files () =
-  List.iter hide_proved_in_file !Model.all_files
-
-let rec show_all_in_goal g =
-  let row = g.Model.goal_row in
-  goals_model#set ~row ~column:Model.visible_column true;
-  if g.Model.proved then
-    goals_view#collapse_row (goals_model#get_path row)
-  else
-    goals_view#expand_row (goals_model#get_path row);
-  Hashtbl.iter
-    (fun _ t -> List.iter show_all_in_goal t.Model.subgoals)
-    g.Model.transformations
-
-let show_all_in_theory th =
-  let row = th.Model.theory_row in
-  goals_model#set ~row ~column:Model.visible_column true;
-  if th.Model.verified then
-    goals_view#collapse_row (goals_model#get_path row)
-  else
-    begin
-      goals_view#expand_row (goals_model#get_path row);
-      List.iter show_all_in_goal th.Model.goals
-    end
-
-let show_all_in_file f =
-  let row = f.Model.file_row in
-  goals_model#set ~row ~column:Model.visible_column true;
-  if f.Model.file_verified then
-    goals_view#collapse_row (goals_model#get_path row)
-  else
-    begin
-      goals_view#expand_row (goals_model#get_path row);
-      List.iter show_all_in_theory f.Model.theories
-    end
-
-let show_all_in_files () =
-  List.iter show_all_in_file !Model.all_files
-
-
-let (_ : GMenu.check_menu_item) = view_factory#add_check_item
-  ~callback:(fun b ->
-               Model.toggle_hide_proved_goals := b;
-               if b then hide_proved_in_files ()
-               else show_all_in_files ())
-  "Hide proved goals"
-
-*)
-
-(**************)
-(* Tools menu *)
-(**************)
-
-
-let () = add_refresh_provers (fun () ->
-  List.iter (fun item -> item#destroy ()) provers_box#all_children)
-
-let tools_menu = factory#add_submenu "_Tools"
-let tools_factory = new GMenu.factory tools_menu ~accel_group
-
-let () = add_refresh_provers (fun () ->
-  List.iter (fun item -> item#destroy ()) tools_menu#all_children)
-
-let () =
-  let add_item_provers () =
-    Util.Mstr.iter
-      (fun _ p ->
-         let n = p.prover_name ^ " " ^ p.prover_version in
-         let (_ : GMenu.image_menu_item) =
-           tools_factory#add_image_item ~label:n
-             ~callback:(fun () -> prover_on_selected_goals p)
-             ()
-         in
-         let b = GButton.button ~packing:provers_box#add ~label:n () in
-         b#misc#set_tooltip_markup "Click to start this prover\non the <b>selected</b> goal(s)";
-
-(* prend de la place pour rien
-         let i = GMisc.image ~pixbuf:(!image_prover) () in
-         let () = b#set_image i#coerce in
-*)
-         let (_ : GtkSignal.id) =
-           b#connect#pressed
-             ~callback:(fun () -> prover_on_selected_goals p)
-         in ())
-      gconfig.provers
-  in
-  add_refresh_provers add_item_provers;
-  add_item_provers ()
-
-let () =
-  let add_item_split () =
-    ignore(tools_factory#add_image_item
-             ~label:"Split selection"
-             ~callback:split_selected_goals
-             () : GMenu.image_menu_item) in
-  add_refresh_provers add_item_split;
-  add_item_split ()
-
-
-let () =
-  let b = GButton.button ~packing:transf_box#add ~label:"Split" () in
-  b#misc#set_tooltip_markup "Click to apply transformation <tt>split_goal</tt> to the <b>selected goals</b>";
-
-  let i = GMisc.image ~pixbuf:(!image_transf) () in
-  let () = b#set_image i#coerce in
-  let (_ : GtkSignal.id) =
-    b#connect#pressed ~callback:split_selected_goals
-  in ()
-
-let () =
-  let b = GButton.button ~packing:transf_box#add ~label:"Inline" () in
-  b#misc#set_tooltip_markup "Click to apply transformation <tt>inline_goal</tt> to the <b>selected goals</b>";
-(**)
-  let i = GMisc.image ~pixbuf:(!image_transf) () in
-  let () = b#set_image i#coerce in
-(**)
-  let (_ : GtkSignal.id) =
-    b#connect#pressed ~callback:inline_selected_goals
-  in ()
-
-
-
-(*************)
-(* Help menu *)
-(*************)
-
-
-let help_menu = factory#add_submenu "_Help"
-let help_factory = new GMenu.factory help_menu ~accel_group
-
-let (_ : GMenu.image_menu_item) =
-  help_factory#add_image_item
-    ~label:"Legend"
-    ~callback:show_legend_window
-    ()
-
-let (_ : GMenu.image_menu_item) =
-  help_factory#add_image_item
-    ~label:"About"
-    ~callback:show_about_window
-    ()
-
-
-(******************************)
-(* vertical paned on the right*)
-(******************************)
-
-let right_vb = GPack.vbox ~packing:hp#add ()
-
-let vp =
-  try
-    GPack.paned `VERTICAL ~packing:right_vb#add ()
-  with Gtk.Error _ -> assert false
-
-let right_hb = GPack.hbox ~packing:(right_vb#pack ~expand:false) ()
-
-let file_info = GMisc.label ~text:""
-  ~packing:(right_hb#pack ~fill:true) ()
-
-let current_file = ref ""
-
-let set_current_file f =
-  current_file := f;
-  file_info#set_text ("file: " ^ !current_file)
-
-(******************)
-(* goal text view *)
-(******************)
-
-let scrolled_task_view = GBin.scrolled_window
-  ~hpolicy: `AUTOMATIC ~vpolicy: `AUTOMATIC
-  ~packing:vp#add ()
-
-let () = scrolled_task_view#set_shadow_type `ETCHED_OUT
-
-let (_ : GtkSignal.id) =
-  scrolled_task_view#misc#connect#size_allocate
-    ~callback:
-    (fun {Gtk.width=_w;Gtk.height=h} ->
-       gconfig.task_height <- h)
-
-let task_view =
-  GSourceView2.source_view
-    ~editable:false
-    ~show_line_numbers:true
-    ~packing:scrolled_task_view#add
-    ~height:gconfig.task_height
-    ()
-
-let () = task_view#source_buffer#set_language lang
-let () = task_view#set_highlight_current_line true
-
-(***************)
-(* source view *)
-(***************)
-
-let scrolled_source_view = GBin.scrolled_window
-  ~hpolicy: `AUTOMATIC ~vpolicy: `AUTOMATIC
-  ~packing:vp#add
-  ()
-
-let () = scrolled_source_view#set_shadow_type `ETCHED_OUT
-
-let source_view =
-  GSourceView2.source_view
-    ~auto_indent:true
-    ~insert_spaces_instead_of_tabs:true ~tab_width:2
-    ~show_line_numbers:true
-    ~right_margin_position:80 ~show_right_margin:true
-    (* ~smart_home_end:true *)
-    ~packing:scrolled_source_view#add
-    ()
-
-(*
-  source_view#misc#modify_font_by_name font_name;
-*)
-let () = source_view#source_buffer#set_language lang
-let () = source_view#set_highlight_current_line true
-(*
-let () = source_view#source_buffer#set_text (source_text fname)
 *)
 
-let move_to_line (v : GSourceView2.source_view) line =
-  if line <= v#buffer#line_count && line <> 0 then begin
-    let it = v#buffer#get_iter (`LINE line) in
-    let mark = `MARK (v#buffer#create_mark it) in
-    v#scroll_to_mark ~use_align:true ~yalign:0.0 mark
-  end
-
-let orange_bg = source_view#buffer#create_tag
-  ~name:"orange_bg" [`BACKGROUND "orange"]
-
-let erase_color_loc (v:GSourceView2.source_view) =
-  let buf = v#buffer in
-  buf#remove_tag orange_bg ~start:buf#start_iter ~stop:buf#end_iter
-
-let color_loc (v:GSourceView2.source_view) l b e =
-  let buf = v#buffer in
-  let top = buf#start_iter in
-  let start = top#forward_lines (l-1) in
-  let start = start#forward_chars b in
-  let stop = start#forward_chars (e-b) in
-  buf#apply_tag ~start ~stop orange_bg
-
-let scroll_to_id id =
-  match id.Ident.id_origin with
-    | Ident.User loc ->
-        let (f,l,b,e) = Loc.get loc in
-        if f <> !current_file then
-          begin
-            source_view#source_buffer#set_text (source_text f);
-            set_current_file f;
-          end;
-        move_to_line source_view (l-1);
-        erase_color_loc source_view;
-        color_loc source_view l b e
-    | Ident.Fresh ->
-        source_view#source_buffer#set_text
-          "Fresh ident (no position available)\n";
-        set_current_file ""
-    | Ident.Derived _ ->
-        source_view#source_buffer#set_text
-          "Derived ident (no position available)\n";
-        set_current_file ""
-
-let color_loc loc =
-  let f, l, b, e = Loc.get loc in
-  if f = !current_file then color_loc source_view l b e
-
-let rec color_f_locs () f =
-  Util.option_iter color_loc f.Term.f_loc;
-  Term.f_fold color_t_locs color_f_locs () f
-
-and color_t_locs () t =
-  Util.option_iter color_loc t.Term.t_loc;
-  Term.t_fold color_t_locs color_f_locs () t
-
-let scroll_to_source_goal g =
-  let t = g.Model.task in
-  let id = (Task.task_goal t).Decl.pr_name in
-  scroll_to_id id;
-  match t with
-    | Some
-        { Task.task_decl =
-            { Theory.td_node =
-                Theory.Decl { Decl.d_node = Decl.Dprop (Decl.Pgoal, _, f)}}} ->
-        color_f_locs () f
-    | _ ->
-        assert false
-
-let scroll_to_theory th =
-  let t = th.Model.theory in
-  let id = t.Theory.th_name in
-  scroll_to_id id
-
-(* to be run when a row in the tree view is selected *)
-let select_row p =
-  let row = goals_model#get_iter p in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal g ->
-        let t = g.Model.task in
-        let t = match apply_trans intro_transformation t with
-	  | [t] -> t
-	  | _ -> assert false
-	in
-        let task_text = Pp.string_of Pretty.print_task t in
-        task_view#source_buffer#set_text task_text;
-        task_view#scroll_to_mark `INSERT;
-        scroll_to_source_goal g
-    | Model.Row_theory th ->
-        task_view#source_buffer#set_text "";
-        scroll_to_theory th
-    | Model.Row_file _file ->
-        task_view#source_buffer#set_text "";
-        (* scroll_to_file file *)
-    | Model.Row_proof_attempt a ->
-	let o =
-          match a.Model.proof_state with
-	    | Gscheduler.Done r -> r.Call_provers.pr_output;
-	    | _ -> "No information available"
-	in
-	task_view#source_buffer#set_text o;
-        scroll_to_source_goal a.Model.proof_goal
-    | Model.Row_transformation tr ->
-        task_view#source_buffer#set_text "";
-        scroll_to_source_goal tr.Model.parent_goal
-
-
-
 
 (*****************************)
 (* method: edit current goal *)
 (*****************************)
 
+(*
 
 let ft_of_th th =
-  (Filename.basename th.Model.theory_parent.Model.file_name,
-   th.Model.theory.Theory.th_name.Ident.id_string)
+  (Filename.basename th.theory_parent.file_name,
+   th.theory.Theory.th_name.Ident.id_string)
 
 let rec ft_of_goal g =
-  match g.Model.parent with
-    | Model.Transf tr -> ft_of_goal tr.Model.parent_goal
-    | Model.Theory th -> ft_of_th th
+  match g.parent with
+    | Transf tr -> ft_of_goal tr.parent_goal
+    | Theory th -> ft_of_th th
 
 let ft_of_pa a =
-  ft_of_goal a.Model.proof_goal
+  ft_of_goal a.proof_goal
 
 let edit_selected_row p =
   let row = goals_model#get_iter p in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal _g ->
+  match goals_model#get ~row ~column:index_column with
+    | Row_goal _g ->
         ()
-    | Model.Row_theory _th ->
+    | Row_theory _th ->
         ()
-    | Model.Row_file _file ->
+    | Row_file _file ->
         ()
-    | Model.Row_proof_attempt a ->
+    | Row_proof_attempt a ->
         (* check that the state is not Scheduled or Running *)
-        let running = match a.Model.proof_state with
+        let running = match a.proof_state with
           | Gscheduler.Scheduled | Gscheduler.Running -> true
           | Gscheduler.Undone | Gscheduler.Done _ | Gscheduler.InternalFailure _ -> false
         in
         if running then
           info_window `ERROR "Edition already in progress"
         else
-        let g = a.Model.proof_goal in
-	let t = g.Model.task in
-	let driver = a.Model.prover.driver in
+        let g = a.proof_goal in
+	let t = g.task in
+	let driver = a.prover.driver in
 	let file =
-          match a.Model.edited_as with
+          match a.edited_as with
             | "" ->
 		let (fn,tn) = ft_of_pa a in
 		let file = Driver.file_of_task driver
@@ -1400,12 +1056,12 @@ let edit_selected_row p =
 		    incr i
 		done;
 		let file = name ^ "_" ^ (string_of_int !i) ^ ext in
-		a.Model.edited_as <- file;
-		Db.set_edited_as a.Model.proof_db file;
+		a.edited_as <- file;
+		Db.set_edited_as a.proof_db file;
 		file
 	    | f -> f
 	in
-        let old_status = a.Model.proof_state in
+        let old_status = a.proof_state in
         let callback res =
           match res with
             | Gscheduler.Done _ ->
@@ -1414,92 +1070,57 @@ let edit_selected_row p =
                 Helpers.set_proof_state ~obsolete:false a res
         in
         let editor =
-          match a.Model.prover.editor with
+          match a.prover.editor with
             | "" -> gconfig.default_editor
-            | _ -> a.Model.prover.editor
+            | _ -> a.prover.editor
         in
         Gscheduler.edit_proof ~debug:false ~editor
           ~file
           ~driver
           ~callback
           t
-    | Model.Row_transformation _tr ->
+    | Row_transformation _tr ->
         ()
 
-let edit_current_proof () =
-  match goals_view#selection#get_selected_rows with
-    | [] -> ()
-    | [r] -> edit_selected_row r
-    | _ ->
-	info_window `INFO "Please select exactly one proof to edit"
-
-
-let add_item_edit () =
-  ignore (tools_factory#add_image_item
-            ~label:"Edit current proof"
-            ~callback:edit_current_proof
-            () : GMenu.image_menu_item)
-
-let () =
-  add_refresh_provers add_item_edit;
-  add_item_edit ()
-
-
-let () =
-  let b = GButton.button ~packing:tools_box#add ~label:"Edit" () in
-  b#misc#set_tooltip_markup "Click to edit the <b>selected proof</b>\nwith the appropriate editor";
-
-  let i = GMisc.image ~pixbuf:(!image_editor) () in
-  let () = b#set_image i#coerce in
-  let (_ : GtkSignal.id) =
-    b#connect#pressed ~callback:edit_current_proof
-  in ()
-
-let () =
-  let b = GButton.button ~packing:tools_box#add ~label:"Replay" () in
-  b#misc#set_tooltip_markup "Replay all the <b>successful</b> but <b>obsolete</b> proofs below the current selection";
-
-  let i = GMisc.image ~pixbuf:(!image_replay) () in
-  let () = b#set_image i#coerce in
-  let (_ : GtkSignal.id) =
-    b#connect#pressed ~callback:replay_obsolete_proofs
-  in ()
+*)
 
 (*************)
 (* removing  *)
 (*************)
 
+(*
+
 let remove_proof_attempt a =
-  Db.remove_proof_attempt a.Model.proof_db;
-  let (_:bool) = goals_model#remove a.Model.proof_row in
-  let g = a.Model.proof_goal in
-  Hashtbl.remove g.Model.external_proofs a.Model.prover.prover_id;
+  Db.remove_proof_attempt a.proof_db;
+  let (_:bool) = goals_model#remove a.proof_row in
+  let g = a.proof_goal in
+  Hashtbl.remove g.external_proofs a.prover.prover_id;
   Helpers.check_goal_proved g
 
 let remove_transf t =
   (* TODO: remove subgoals first !!! *)
-  Db.remove_transformation t.Model.transf_db;
-  let (_:bool) = goals_model#remove t.Model.transf_row in
-  let g = t.Model.parent_goal in
-  Hashtbl.remove g.Model.transformations "split" (* hack !! *);
+  Db.remove_transformation t.transf_db;
+  let (_:bool) = goals_model#remove t.transf_row in
+  let g = t.parent_goal in
+  Hashtbl.remove g.transformations "split" (* hack !! *);
   Helpers.check_goal_proved g
 
 
 let confirm_remove_row r =
   let row = goals_model#get_iter r in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal _g ->
+  match goals_model#get ~row ~column:index_column with
+    | Row_goal _g ->
 	info_window `ERROR "Cannot remove a goal"
-    | Model.Row_theory _th ->
+    | Row_theory _th ->
 	info_window `ERROR "Cannot remove a theory"
-    | Model.Row_file _file ->
+    | Row_file _file ->
 	info_window `ERROR "Cannot remove a file"
-    | Model.Row_proof_attempt a ->
+    | Row_proof_attempt a ->
 	info_window
 	  ~callback:(fun () -> remove_proof_attempt a)
 	  `QUESTION
 	  "Do you really want to remove the selected proof attempt?"
-    | Model.Row_transformation tr ->
+    | Row_transformation tr ->
 	info_window
 	  ~callback:(fun () -> remove_transf tr)
 	  `QUESTION
@@ -1513,50 +1134,45 @@ let confirm_remove_selection () =
     | _ ->
         info_window `INFO "Please select exactly one item to remove"
 
-let () =
-  let b = GButton.button ~packing:cleaning_box#add ~label:"Remove" () in
-  b#misc#set_tooltip_markup "Removes the selected\n<b>proof</b> or <b>transformation</b>";
-  let i = GMisc.image ~pixbuf:(!image_remove) () in
-  let () = b#set_image i#coerce in
-  let (_ : GtkSignal.id) =
-    b#connect#pressed ~callback:confirm_remove_selection
-  in ()
 
 let rec clean_goal g =
-  if g.Model.proved then
+  if g.proved then
     begin
       Hashtbl.iter
         (fun _ a ->
-           if a.Model.proof_obsolete || not (proof_successful a) then
+           if a.proof_obsolete || not (proof_successful a) then
              remove_proof_attempt a)
-        g.Model.external_proofs;
+        g.external_proofs;
       Hashtbl.iter
         (fun _ t ->
-           if not t.Model.transf_proved then
+           if not t.transf_proved then
              remove_transf t)
-        g.Model.transformations
+        g.transformations
     end
   else
     Hashtbl.iter
-      (fun _ t -> List.iter clean_goal t.Model.subgoals)
-      g.Model.transformations
+      (fun _ t -> List.iter clean_goal t.subgoals)
+      g.transformations
 
 
 let clean_row r =
   let row = goals_model#get_iter r in
-  match goals_model#get ~row ~column:Model.index_column with
-    | Model.Row_goal g -> clean_goal g
-    | Model.Row_theory th ->
-        List.iter clean_goal th.Model.goals
-    | Model.Row_file file ->
+  match goals_model#get ~row ~column:index_column with
+    | Row_goal g -> clean_goal g
+    | Row_theory th ->
+        List.iter clean_goal th.goals
+    | Row_file file ->
         List.iter
           (fun th ->
-             List.iter clean_goal th.Model.goals)
-          file.Model.theories
-    | Model.Row_proof_attempt a ->
-        clean_goal a.Model.proof_goal
-    | Model.Row_transformation tr ->
-        List.iter clean_goal tr.Model.subgoals
+             List.iter clean_goal th.goals)
+          file.theories
+    | Row_proof_attempt a ->
+        clean_goal a.proof_goal
+    | Row_transformation tr ->
+        List.iter clean_goal tr.subgoals
+
+
+*)
 
 end
 
diff --git a/src/ide/session.mli b/src/ide/session.mli
index e6c204f934a161829abd71a223b3ed5d38082018..31b4820f9ae00cb51505dc609575e231c956f5f6 100644
--- a/src/ide/session.mli
+++ b/src/ide/session.mli
@@ -18,13 +18,35 @@
 (**************************************************************************)
 
 
-open Why3
+open Why
+
+type prover_data = private
+    { prover_id : string;
+      prover_name : string;
+      prover_version : string;
+      command : string;
+      driver_name : string;
+      driver : Driver.driver;
+      mutable editor : string;
+    }
+
+type proof_attempt_status = private
+    | Undone
+    | Scheduled (** external proof attempt is scheduled *)
+    | Running (** external proof attempt is in progress *)
+    | Done of Call_provers.prover_result (** external proof done *)
+    | InternalFailure of exn (** external proof aborted by internal error *)
 
 module type OBSERVER = sig
+
   type key
   val create: ?parent:key -> unit -> key
   val notify: key -> unit
   val remove: key -> unit
+
+  val timeout: ms:int -> (unit -> bool) -> unit
+  val idle: (unit -> bool) -> unit
+
 end
 
 module Make(O: OBSERVER) : sig
@@ -35,13 +57,6 @@ module Make(O: OBSERVER) : sig
 (*                           *)
 (*****************************)
 
-  type proof_attempt_status =
-    | Undone
-    | Scheduled (** external proof attempt is scheduled *)
-    | Running (** external proof attempt is in progress *)
-    | Done of Call_provers.prover_result (** external proof done *)
-    | InternalFailure of exn (** external proof aborted by internal error *)
-
   type proof_attempt = private
       { prover : prover_data;
         proof_goal : goal;
@@ -52,11 +67,12 @@ module Make(O: OBSERVER) : sig
       }
 
   and goal_parent =
-    | Theory of theory
-    | Transf of transf
+    | Parent_theory of theory
+    | Parent_transf of transf
 
   and goal = private
       { goal_name : string;
+	goal_expl : string option;
 	parent : goal_parent;
         task: Task.task;
         goal_key : O.key;
@@ -108,22 +124,6 @@ module Make(O: OBSERVER) : sig
         Opening a session must be done prior to any other actions.
         And it cannot be done twice.
 
-        TODO: some scheduling functions might be needed as argument, e.g
-
-        add_idle: (unit -> bool) -> unit
-
-        that will allow to install a handler when context is idle
-
-        add_timeout: ms:int -> (unit -> bool) -> unit
-
-        that will allow to install a handler when a timeout of ms
-        milliseconds occurs
-
-        in both cases, the bool returned indicates whether the handler
-        should be removed or not
-
-        the parameter OBSERVER could also be used for that purpose
-
     *)
 
     (* 
@@ -132,13 +132,16 @@ module Make(O: OBSERVER) : sig
        this is not necessary since the session manager handles this itself
        using add_timeout *)
 
-  val add_file : string -> unit
-    (** adds a new file in the proof session
-    *)
+  val add_file : string -> Theory.theory Theory.Mnm.t -> unit
+    (** [add_file f ths] adds a new file in the proof session, that is
+	a collection of name [f] of theories [ths] *)
+
 
-  val reload_files : unit -> unit 
-    (** reloads all the files in the state, and performs the proper
-        mergind of old proof attemps and transformations *)
+  (*
+    val reload_files : unit -> unit 
+  (** reloads all the files in the state, and performs the proper
+    merging of old proof attemps and transformations *)
+*)
 
 (*****************************)
 (*                           *)
@@ -146,25 +149,26 @@ module Make(O: OBSERVER) : sig
 (*                           *)
 (*****************************)
 
-(* attempt a new proof using an external prover *)
 
-  val add_proof_attempt : goal  -> unit
-    (** TODO: proper arguments missing *)
+  val run_prover : context_unproved_goals_only:bool -> 
+    prover_data -> any -> unit
+    (** [run_prover p a] runs prover [p] on all goals under [a] *)
 
-  val add_transformation : goal -> unit
-    (** TODO: proper arguments missing *)
+  val replay : context_unproved_goals_only:bool -> any -> unit
+    (** [replay a] reruns all valid but obsolete proofs under [a] *)
 
-  val remove_proof_attempf : proof_attempt -> unit
+(*
+
+  val remove_proof_attempt : proof_attempt -> unit
 
   val remove_transformation : transf -> unit
 
   val clean : any -> unit
     (** [clean a] removes failed attempts below [a] where
-        other successful attempts exist *)
-
-  val redo_obsolete : any -> unit
-    (** [redo_obsolete a] rerun obsolete proofs below [a] *)
+        there at least one successful attempt or transformation *)
 
+    *) 
+end