diff --git a/Makefile.in b/Makefile.in
index b312b4940db6733fb2305adfcbf6c6a24d8cebd6..87d5fe4c5e5f3dae851ea81d98add0c561bc738b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -390,12 +390,12 @@ $(PGMCMO) $(PGMCMX): INCLUDES += -I src/programs
 byte: bin/why3ml.byte
 opt:  bin/why3ml.opt
 
-bin/why3ml.opt: src/why3.cmxa $(PGMCMX) src/main.cmx
+bin/why3ml.opt: src/why3.cmxa $(PGMCMX) $(MLWCMX) src/main.cmx
 	$(if $(QUIET), @echo 'Linking  $@' &&) \
 	    $(OCAMLOPT) $(OFLAGS) -o $@ $(EXTCMXA) $^
 	$(STRIP) $@
 
-bin/why3ml.byte: src/why3.cma $(PGMCMO) src/main.cmo
+bin/why3ml.byte: src/why3.cma $(PGMCMO) $(MLWCMO) src/main.cmo
 	$(if $(QUIET),@echo 'Linking  $@' &&) \
 	    $(OCAMLC) $(BFLAGS) -o $@ $(EXTCMA) $^
 
@@ -573,12 +573,12 @@ bin/why3ide.opt bin/why3ide.byte: INCLUDES += -I @LABLGTK2LIB@
 bin/why3ide.opt bin/why3ide.byte: EXTOBJS +=
 bin/why3ide.opt bin/why3ide.byte: EXTLIBS += lablgtk lablgtksourceview2
 
-bin/why3ide.opt: src/why3.cmxa $(PGMCMX) $(IDECMX)
+bin/why3ide.opt: src/why3.cmxa $(PGMCMX) $(MLWCMX) $(IDECMX)
 	$(if $(QUIET), @echo 'Linking  $@' &&) \
 	    $(OCAMLOPT) $(OFLAGS) -o $@ $(EXTCMXA) $^
 	$(STRIP) $@
 
-bin/why3ide.byte: src/why3.cma $(PGMCMO) $(IDECMO)
+bin/why3ide.byte: src/why3.cma $(PGMCMO) $(MLWCMO) $(IDECMO)
 	$(if $(QUIET),@echo 'Linking  $@' &&) \
 	    $(OCAMLC) $(BFLAGS) -o $@ $(EXTCMA) $^
 
diff --git a/src/core/env.ml b/src/core/env.ml
index c05a1ea8e67e75c98bde35a872ec15d8a6f7ac86..63c3f089ae7bf394e21da69edec54878873b7d52 100644
--- a/src/core/env.ml
+++ b/src/core/env.ml
@@ -179,8 +179,6 @@ let read_lib_theory lib path th =
   try Mstr.find th mth with Not_found ->
   raise (TheoryNotFound (path,th))
 
-let read_lib_file lib path = fst (read_lib_file lib path)
-
 let register_format name exts read =
   if Hashtbl.mem read_format_table name then raise (KnownFormat name);
   let getlib = Wenv.memoize 5 (mk_library read exts) in
diff --git a/src/core/env.mli b/src/core/env.mli
index f51eb93f9ae2bbed4c97d785934785885e941cf9..86371cd5c9e4998ceb53026c02a2fb7478578100 100644
--- a/src/core/env.mli
+++ b/src/core/env.mli
@@ -114,7 +114,7 @@ val env_of_library : 'a library -> env
 val list_formats : unit -> (fformat * extension list) list
 (** [list_formats ()] returns the list of registered formats *)
 
-val read_lib_file : 'a library -> pathname -> 'a
+val read_lib_file : 'a library -> pathname -> 'a * theory Mstr.t
 (** [read_lib_file lib path] retrieves the contents of a library file
 
     @raise LibFileNotFound [path] if the library file was not found *)
diff --git a/src/core/theory.ml b/src/core/theory.ml
index de7cbf7aafa7d0b928fbdd78083e2cf2dce359c4..a0cf52910da19ca57473a1ad79c7eef6a11d16d6 100644
--- a/src/core/theory.ml
+++ b/src/core/theory.ml
@@ -663,7 +663,6 @@ let is_empty_sm sm =
   Mls.is_empty sm.sm_ls &&
   Mpr.is_empty sm.sm_pr
 
-
 (** Meta properties *)
 
 let get_meta_arg_type = function
diff --git a/src/core/theory.mli b/src/core/theory.mli
index 0328fbcc170f88d4a45f09da14f3d3a83f03d471..6a0f4202fcabb0ac3c18d46337f7ae7275ca39f7 100644
--- a/src/core/theory.mli
+++ b/src/core/theory.mli
@@ -124,6 +124,7 @@ val close_theory  : theory_uc -> theory
 
 val open_namespace  : theory_uc -> theory_uc
 val close_namespace : theory_uc -> bool -> string option -> theory_uc
+  (* the Boolean indicates [import]; the string option indicates [as T] *)
 
 val get_namespace : theory_uc -> namespace
 val get_known : theory_uc -> known_map
diff --git a/src/parser/parser.mly b/src/parser/parser.mly
index e06389e5458c84d035425178489736580423691a..8fc923868370dd6ba84e9ec2beda6a084ca27b46 100644
--- a/src/parser/parser.mly
+++ b/src/parser/parser.mly
@@ -62,6 +62,7 @@ module Incremental = struct
   let new_use_clone d =
     let env = ref_get env_ref in let lenv = ref_get lenv_ref in
     ref_set uc_ref (Typing.add_use_clone env lenv (ref_get uc_ref) d)
+
 end
 
   open Ptree
@@ -184,6 +185,9 @@ end
       | Term.IConstBinary  s -> int_of_string ("0b"^s)
     with Failure _ -> raise Parsing.Parse_error
 
+  let qualid_last = function
+    | Qident x | Qdot (_, x) -> x.id
+
 %}
 
 /* Tokens */
@@ -316,7 +320,7 @@ namespace_import:
 ;
 
 namespace_name:
-| uident      { Some $1 }
+| uident      { Some $1.id }
 | UNDERSCORE  { None }
 ;
 
@@ -354,17 +358,17 @@ use_clone:
 
 use:
 | imp_exp tqualid
-    { { use_theory = $2; use_as = None; use_imp_exp = $1 } }
+    { { use_theory = $2; use_as = Some (qualid_last $2); use_imp_exp = $1 } }
 | imp_exp tqualid AS uident
-    { { use_theory = $2; use_as = Some (Some $4); use_imp_exp = $1 } }
+    { { use_theory = $2; use_as = Some $4.id; use_imp_exp = $1 } }
 | imp_exp tqualid AS UNDERSCORE
-    { { use_theory = $2; use_as = Some None; use_imp_exp = $1 } }
+    { { use_theory = $2; use_as = None; use_imp_exp = $1 } }
 ;
 
 imp_exp:
-| IMPORT        { Import }
-| EXPORT        { Export }
-| /* epsilon */ { Nothing }
+| IMPORT        { Some true }
+| EXPORT        { None }
+| /* epsilon */ { Some false }
 ;
 
 clone_subst:
@@ -378,13 +382,13 @@ list1_comma_subst:
 ;
 
 subst:
-| NAMESPACE ns     EQUAL ns     { CSns   ($2, $4) }
-| TYPE      qualid EQUAL qualid { CStsym ($2, $4) }
-| CONSTANT  qualid EQUAL qualid { CSfsym ($2, $4) }
-| FUNCTION  qualid EQUAL qualid { CSfsym ($2, $4) }
-| PREDICATE qualid EQUAL qualid { CSpsym ($2, $4) }
-| LEMMA     qualid              { CSlemma $2 }
-| GOAL      qualid              { CSgoal  $2 }
+| NAMESPACE ns     EQUAL ns     { CSns   (floc (), $2, $4) }
+| TYPE      qualid EQUAL qualid { CStsym (floc (), $2, $4) }
+| CONSTANT  qualid EQUAL qualid { CSfsym (floc (), $2, $4) }
+| FUNCTION  qualid EQUAL qualid { CSfsym (floc (), $2, $4) }
+| PREDICATE qualid EQUAL qualid { CSpsym (floc (), $2, $4) }
+| LEMMA     qualid              { CSlemma (floc (), $2) }
+| GOAL      qualid              { CSgoal  (floc (), $2) }
 ;
 
 ns:
@@ -1062,9 +1066,9 @@ opt_semicolon:
 
 use_module:
 | imp_exp MODULE tqualid
-    { Duse ($3, $1, None) }
+    { Duse ($3, $1, Some (qualid_last $3)) }
 | imp_exp MODULE tqualid AS uident
-    { Duse ($3, $1, Some $5) }
+    { Duse ($3, $1, Some $5.id) }
 ;
 
 list1_recfun_sep_and:
diff --git a/src/parser/ptree.ml b/src/parser/ptree.ml
index 09a03cfb1c010626d5af0d774183c491898c7d5a..102905ab51138afe7e0820df8d41dc40802fbd60 100644
--- a/src/parser/ptree.ml
+++ b/src/parser/ptree.ml
@@ -94,22 +94,21 @@ type plogic_type =
   | PPredicate of pty list
   | PFunction  of pty list * pty
 
-type imp_exp =
-  | Import | Export | Nothing
-
 type use = {
   use_theory  : qualid;
-  use_as      : ident option option;
-  use_imp_exp : imp_exp;
+  use_as      : string option;
+    (* None = as _, Some id = as id *)
+  use_imp_exp : bool option;
+    (* None = export, Some false = default, Some true = import *)
 }
 
 type clone_subst =
-  | CSns    of qualid option * qualid option
-  | CStsym  of qualid * qualid
-  | CSfsym  of qualid * qualid
-  | CSpsym  of qualid * qualid
-  | CSlemma of qualid
-  | CSgoal  of qualid
+  | CSns    of loc * qualid option * qualid option
+  | CStsym  of loc * qualid * qualid
+  | CSfsym  of loc * qualid * qualid
+  | CSpsym  of loc * qualid * qualid
+  | CSlemma of loc * qualid
+  | CSgoal  of loc * qualid
 
 type is_mutable = bool
 
@@ -246,8 +245,8 @@ type program_decl =
   | Dparam  of ident * type_v
   | Dexn    of ident * pty option
   (* modules *)
-  | Duse    of qualid * imp_exp * (*as:*) ident option
-  | Dnamespace of loc * ident option * (* import: *) bool * program_decl list
+  | Duse    of qualid * bool option * (*as:*) string option
+  | Dnamespace of loc * string option * (* import: *) bool * program_decl list
 
 type theory = {
   pth_name   : ident;
diff --git a/src/parser/typing.ml b/src/parser/typing.ml
index 5ddc1b07454fc0fea59bbf16096d8211e0296bd4..572d940b3ab24e787ea8fd71edf81b31e546d4e8 100644
--- a/src/parser/typing.ml
+++ b/src/parser/typing.ml
@@ -31,7 +31,6 @@ open Denv
 
 (** errors *)
 
-exception Message of string
 exception DuplicateTypeVar of string
 exception TypeArity of qualid * int * int
 exception Clash of string
@@ -47,28 +46,15 @@ exception UnboundTypeVar of string
 exception UnboundType of string list
 exception UnboundSymbol of string list
 
-let error ?loc e = match loc with
-  | None -> raise e
-  | Some loc -> raise (Loc.Located (loc,e))
-
-let errorm ?loc f =
-  let buf = Buffer.create 512 in
-  let fmt = Format.formatter_of_buffer buf in
-  Format.kfprintf
-    (fun _ ->
-       Format.pp_print_flush fmt ();
-       let s = Buffer.contents buf in
-       Buffer.clear buf;
-       error ?loc (Message s))
-    fmt f
+let error = Loc.error
+
+let errorm = Loc.errorm
 
 let rec print_qualid fmt = function
   | Qident s -> fprintf fmt "%s" s.id
   | Qdot (m, s) -> fprintf fmt "%a.%s" print_qualid m s.id
 
 let () = Exn_printer.register (fun fmt e -> match e with
-  | Message s ->
-      fprintf fmt "%s" s
   | DuplicateTypeVar s ->
       fprintf fmt "duplicate type parameter %s" s
   | TypeArity (id, a, n) ->
@@ -1135,6 +1121,44 @@ let add_decl th = function
 let add_decl th d =
   if Debug.test_flag debug_parse_only then th else add_decl th d
 
+let type_inst th t s =
+  let add_inst s = function
+    | CSns (loc,p,q) ->
+      let find ns x = find_namespace_ns x ns in
+      let ns1 = option_fold find t.th_export p in
+      let ns2 = option_fold find (get_namespace th) q in
+      clone_ns loc t.th_local ns2 ns1 s
+    | CStsym (loc,p,q) ->
+      let ts1 = find_tysymbol_ns p t.th_export in
+      let ts2 = find_tysymbol q th in
+      if Mts.mem ts1 s.inst_ts
+      then error ~loc (Clash ts1.ts_name.id_string);
+      { s with inst_ts = Mts.add ts1 ts2 s.inst_ts }
+    | CSfsym (loc,p,q) ->
+      let ls1 = find_fsymbol_ns p t.th_export in
+      let ls2 = find_fsymbol q th in
+      if Mls.mem ls1 s.inst_ls
+      then error ~loc (Clash ls1.ls_name.id_string);
+      { s with inst_ls = Mls.add ls1 ls2 s.inst_ls }
+    | CSpsym (loc,p,q) ->
+      let ls1 = find_psymbol_ns p t.th_export in
+      let ls2 = find_psymbol q th in
+      if Mls.mem ls1 s.inst_ls
+      then error ~loc (Clash ls1.ls_name.id_string);
+      { s with inst_ls = Mls.add ls1 ls2 s.inst_ls }
+    | CSlemma (loc,p) ->
+      let pr = find_prop_ns p t.th_export in
+      if Spr.mem pr s.inst_lemma || Spr.mem pr s.inst_goal
+      then error ~loc (Clash pr.pr_name.id_string);
+      { s with inst_lemma = Spr.add pr s.inst_lemma }
+    | CSgoal (loc,p) ->
+      let pr = find_prop_ns p t.th_export in
+      if Spr.mem pr s.inst_lemma || Spr.mem pr s.inst_goal
+      then error ~loc (Clash pr.pr_name.id_string);
+      { s with inst_goal = Spr.add pr s.inst_goal }
+  in
+  List.fold_left add_inst empty_inst s
+
 let add_use_clone env lenv th (loc, use, subst) =
   if Debug.test_flag debug_parse_only then th else
   let q, id = split_qualid use.use_theory in
@@ -1145,65 +1169,17 @@ let add_use_clone env lenv th (loc, use, subst) =
       | TheoryNotFound _ -> error ~loc (UnboundTheory use.use_theory)
   in
   let use_or_clone th = match subst with
-    | None ->
-      use_export th t
-    | Some s ->
-      let add_inst s = function
-        | CSns (p,q) ->
-          let find ns x = find_namespace_ns x ns in
-          let ns1 = option_fold find t.th_export p in
-          let ns2 = option_fold find (get_namespace th) q in
-          clone_ns loc t.th_local ns2 ns1 s
-        | CStsym (p,q) ->
-          let ts1 = find_tysymbol_ns p t.th_export in
-          let ts2 = find_tysymbol q th in
-          if Mts.mem ts1 s.inst_ts
-          then error ~loc (Clash ts1.ts_name.id_string);
-          { s with inst_ts = Mts.add ts1 ts2 s.inst_ts }
-        | CSfsym (p,q) ->
-          let ls1 = find_fsymbol_ns p t.th_export in
-          let ls2 = find_fsymbol q th in
-          if Mls.mem ls1 s.inst_ls
-          then error ~loc (Clash ls1.ls_name.id_string);
-          { s with inst_ls = Mls.add ls1 ls2 s.inst_ls }
-        | CSpsym (p,q) ->
-          let ls1 = find_psymbol_ns p t.th_export in
-          let ls2 = find_psymbol q th in
-          if Mls.mem ls1 s.inst_ls
-          then error ~loc (Clash ls1.ls_name.id_string);
-          { s with inst_ls = Mls.add ls1 ls2 s.inst_ls }
-        | CSlemma p ->
-          let pr = find_prop_ns p t.th_export in
-          if Spr.mem pr s.inst_lemma || Spr.mem pr s.inst_goal
-          then error ~loc (Clash pr.pr_name.id_string);
-          { s with inst_lemma = Spr.add pr s.inst_lemma }
-        | CSgoal p ->
-          let pr = find_prop_ns p t.th_export in
-          if Spr.mem pr s.inst_lemma || Spr.mem pr s.inst_goal
-          then error ~loc (Clash pr.pr_name.id_string);
-          { s with inst_goal = Spr.add pr s.inst_goal }
-      in
-      let s = List.fold_left add_inst empty_inst s in
-      clone_export th t s
-  in
-  let n = match use.use_as with
-    | None -> Some t.th_name.id_string
-    | Some (Some x) -> Some x.id
-    | Some None -> None
+    | None -> use_export th t
+    | Some s -> clone_export th t (type_inst th t s)
   in
   begin try match use.use_imp_exp with
-    | Nothing ->
-            (* use T = namespace T use_export T end *)
-      let th = open_namespace th in
-      let th = use_or_clone th in
-      close_namespace th false n
-    | Import ->
-            (* use import T = namespace T use_export T end import T *)
-      let th = open_namespace th in
-      let th = use_or_clone th in
-      close_namespace th true n
-    | Export ->
-      use_or_clone th
+    | Some imp ->
+        (* use T = namespace T use_export T end *)
+        let th = open_namespace th in
+        let th = use_or_clone th in
+        close_namespace th imp use.use_as
+    | None ->
+        use_or_clone th
     with ClashSymbol s -> error ~loc (Clash s)
   end
 
@@ -1214,13 +1190,12 @@ let close_theory loc lenv th =
   if Mstr.mem id lenv then error ~loc (ClashTheory id);
   Mstr.add id th lenv
 
-let close_namespace loc import name th =
-  let id = option_map (fun id -> id.id) name in
+let close_namespace loc import id th =
   try close_namespace th import id
   with ClashSymbol s -> error ~loc (Clash s)
 
 (*
 Local Variables:
-compile-command: "unset LANG; make -C ../.. test"
+compile-command: "unset LANG; make -C ../.."
 End:
 *)
diff --git a/src/parser/typing.mli b/src/parser/typing.mli
index 773404733fa59fb1802c41ca1aef747de008427a..4cf4d90f5bf55e71028ea83174b9da46d39e63d0 100644
--- a/src/parser/typing.mli
+++ b/src/parser/typing.mli
@@ -35,7 +35,7 @@ val add_use_clone :
   unit Env.library -> theory Mstr.t -> theory_uc -> Ptree.use_clone -> theory_uc
 
 val close_namespace :
-  Loc.position -> bool -> Ptree.ident option -> theory_uc -> theory_uc
+  Loc.position -> bool -> string option -> theory_uc -> theory_uc
 
 val close_theory : Loc.position -> theory Mstr.t -> theory_uc -> theory Mstr.t
 
@@ -95,3 +95,4 @@ val list_fields: theory_uc ->
   (** check that the given fields all belong to the same record type
       and do not appear several times *)
 
+val type_inst: theory_uc -> theory -> Ptree.clone_subst list -> th_inst
diff --git a/src/programs/pgm_typing.ml b/src/programs/pgm_typing.ml
index 33ef5704187ac294ec9c47d03a4a465cfc83502b..ab3fef54fdaadef0fd504dba65e88a1c3d80a894 100644
--- a/src/programs/pgm_typing.ml
+++ b/src/programs/pgm_typing.ml
@@ -2262,7 +2262,7 @@ let find_module penv lmod q id = match q with
       Mstr.find id lmod
   | _ :: _ ->
       (* module in file f *)
-      Mstr.find id (Env.read_lib_file penv q)
+      Mstr.find id (fst (Env.read_lib_file penv q))
 
 (* env  = to retrieve theories and modules from the loadpath
    lmod = local modules *)
@@ -2346,22 +2346,13 @@ let rec decl ~wp env ltm lmod uc = function
         with Not_found ->
           errorm ~loc "@[unbound module %a@]" print_qualid qid
       in
-      let n = match use_as with
-        | None -> Some (m.m_name.id_string)
-        | Some x -> Some x.id
-      in
       begin try match imp_exp with
-        | Nothing ->
+        | Some imp ->
             (* use T = namespace T use_export T end *)
             let uc = open_namespace uc in
             let uc = use_export uc m in
-            close_namespace uc false n
-        | Import ->
-            (* use import T = namespace T use_export T end import T *)
-            let uc = open_namespace uc in
-            let uc = use_export uc m in
-            close_namespace uc true n
-        | Export ->
+            close_namespace uc imp use_as
+        | None ->
             use_export uc m
       with ClashSymbol s ->
         errorm ~loc "clash with previous symbol %s" s
@@ -2369,7 +2360,6 @@ let rec decl ~wp env ltm lmod uc = function
   | Ptree.Dnamespace (loc, id, import, dl) ->
       let uc = open_namespace uc in
       let uc = List.fold_left (decl ~wp env ltm lmod) uc dl in
-      let id = option_map (fun id -> id.id) id in
       begin try close_namespace uc import id
       with ClashSymbol s -> errorm ~loc "clash with previous symbol %s" s end
   | Ptree.Dlogic (TypeDecl d) ->
diff --git a/src/util/exn_printer.mli b/src/util/exn_printer.mli
index ce5fb7353a894dac02817abc75c520e79da2e65f..39adba7a7026740e2f65c0ffc47258e03fe56952 100644
--- a/src/util/exn_printer.mli
+++ b/src/util/exn_printer.mli
@@ -26,5 +26,5 @@ val register : exn_printer -> unit
 (* Register a formatter of exception *)
 
 val exn_printer : exn_printer
-(* exn_printer fmt exn : print the exception using all the previously
-   registered printer and return *)
+(* [exn_printer fmt exn] prints exception [exn] using all previously
+   registered printers and returns *)
diff --git a/src/util/loc.ml b/src/util/loc.ml
index fa2d2665d38a416ba3c490e6304bc8c27cc74ad0..1b3fdd96f1984e4c66c40574131296840c36ae8c 100644
--- a/src/util/loc.ml
+++ b/src/util/loc.ml
@@ -54,8 +54,6 @@ let user_position fname lnum cnum1 cnum2 = (fname,lnum,cnum1,cnum2)
 
 let get loc = loc
 
-exception Located of position * exn
-
 let dummy_position = ("",0,0,0)
 
 let join (f1,l1,b1,e1) (f2,_,b2,e2) =
@@ -77,9 +75,44 @@ let gen_report_position fmt (f,l,b,e) =
 
 let report_position fmt = fprintf fmt "%a:@\n" gen_report_position
 
+(* located exceptions *)
+
+exception Located of position * exn
+
+let try1 loc f x =
+  try f x with Located _ as e -> raise e | e -> raise (Located (loc, e))
+let try2 loc f x y =
+  try f x y with Located _ as e -> raise e | e -> raise (Located (loc, e))
+let try3 loc f x y z =
+  try f x y z with Located _ as e -> raise e | e -> raise (Located (loc, e))
+let try4 loc f x y z t =
+  try f x y z t with Located _ as e -> raise e | e -> raise (Located (loc, e))
+
+let error ?loc e = match loc with
+  | None -> raise e
+  | Some loc -> raise (Located (loc, e))
+
+(* located messages *)
+
+exception Message of string
+
+let errorm ?loc f =
+  let buf = Buffer.create 512 in
+  let fmt = Format.formatter_of_buffer buf in
+  Format.kfprintf
+    (fun _ ->
+       Format.pp_print_flush fmt ();
+       let s = Buffer.contents buf in
+       Buffer.clear buf;
+       error ?loc (Message s))
+    fmt f
+
 let () = Exn_printer.register
   (fun fmt exn -> match exn with
     | Located (loc,e) ->
         fprintf fmt "%a%a" report_position loc Exn_printer.exn_printer e
-    | _ -> raise exn)
+    | Message s ->
+        fprintf fmt "%s" s
+    | _ ->
+        raise exn)
 
diff --git a/src/util/loc.mli b/src/util/loc.mli
index 1b9f35a4fca80ea88e71c936cfd42e9d7e1786a9..dabe4715317ffdb36244fab973632110708952af 100644
--- a/src/util/loc.mli
+++ b/src/util/loc.mli
@@ -34,8 +34,6 @@ type position
 val extract : Lexing.position * Lexing.position -> position
 val join : position -> position -> position
 
-exception Located of position * exn
-
 val dummy_position : position
 
 val user_position : string -> int -> int -> int -> position
@@ -50,3 +48,19 @@ val gen_report_position : formatter -> position -> unit
 
 val report_position : formatter -> position -> unit
 
+(* located exceptions *)
+
+exception Located of position * exn
+
+val try1: position -> ('a -> 'b) -> 'a -> 'b
+val try2: position -> ('a -> 'b -> 'c) -> 'a -> 'b -> 'c
+val try3: position -> ('a -> 'b -> 'c -> 'd) -> 'a -> 'b -> 'c -> 'd
+val try4: position -> ('a -> 'b -> 'c -> 'd -> 'e) -> 'a -> 'b -> 'c -> 'd -> 'e
+
+val error: ?loc:position -> exn -> 'a
+
+(* messages *)
+
+exception Message of string
+
+val errorm: ?loc:position -> ('a, Format.formatter, unit, 'b) format4 -> 'a
diff --git a/src/whyml/mlw_typing.ml b/src/whyml/mlw_typing.ml
index 6288bb5dab4635c17dae4cc61b23b7617385c4b1..7434c011d89754b8f3461ea6e318df05988cb79d 100644
--- a/src/whyml/mlw_typing.ml
+++ b/src/whyml/mlw_typing.ml
@@ -19,6 +19,7 @@
 
 open Why3
 open Util
+open Ident
 open Theory
 open Env
 open Ptree
@@ -28,23 +29,94 @@ type mlw_contents = modul Mstr.t
 type mlw_library = mlw_contents library
 type mlw_file = mlw_contents * Theory.theory Mstr.t
 
-    (* let type_only = Debug.test_flag Typing.debug_type_only in *)
+(* TODO: let type_only = Debug.test_flag Typing.debug_type_only in *)
 
-let add_theory _lib path mt m =
+let find_theory loc lib path s =
+  (* search first in .mlw files (using lib) *)
+  let thm =
+    try Some (Env.read_lib_theory lib path s)
+    with LibFileNotFound _ | TheoryNotFound _ -> None
+  in
+  (* search also in .why files *)
+  let th =
+    try Some (Env.find_theory (Env.env_of_library lib) path s)
+    with LibFileNotFound _ | TheoryNotFound _ -> None
+  in
+  match thm, th with
+    | Some _, Some _ ->
+        Loc.errorm ~loc
+          "a module/theory %s is defined both in Why and WhyML libraries" s
+    | None, None -> Loc.error ~loc (Env.TheoryNotFound (path, s))
+    | None, Some t | Some t, None -> t
+
+let find_theory loc lib mt path s = match path with
+  | [] -> (* local theory *)
+      begin try Mstr.find s mt with Not_found -> find_theory loc lib [] s end
+  | _ :: _ -> (* theory in file path *)
+      find_theory loc lib path s
+
+type theory_or_module = Theory of Theory.theory | Module of modul
+
+let find_module loc lib path s =
+  (* search first in .mlw files *)
+  let m, thm =
+    try
+      let mm, mt = Env.read_lib_file lib path in
+      Mstr.find_option s mm, Mstr.find_option s mt
+    with
+      | LibFileNotFound _ -> None, None
+  in
+  (* search also in .why files *)
+  let th =
+    try Some (Env.find_theory (Env.env_of_library lib) path s)
+    with LibFileNotFound _ | TheoryNotFound _ -> None
+  in
+  match m, thm, th with
+    | Some _, None, _ -> assert false
+    | _, Some _, Some _ ->
+        Loc.errorm ~loc
+          "a module/theory %s is defined both in Why and WhyML libraries" s
+    | None, None, None -> Loc.error ~loc (Env.TheoryNotFound (path, s))
+    | Some m, Some _, None -> Module m
+    | None, Some t, None | None, None, Some t -> Theory t
+
+let find_module loc lib mt mm path s = match path with
+  | [] -> (* local module/theory *)
+      begin try Module (Mstr.find s mm)
+        with Not_found -> begin try Theory (Mstr.find s mt)
+          with Not_found -> find_module loc lib [] s end end
+  | _ :: _ -> (* module/theory in file path *)
+      find_module loc lib path s
+
+let add_theory lib path mt m =
   let id = m.pth_name in
   let loc = id.id_loc in
   let uc = Theory.create_theory ~path (Denv.create_user_id id) in
   let rec add_decl uc = function
-    | Duseclone (_loc, _use, None) (* use *) ->
-        assert false (*TODO*)
-    | Duseclone (_loc, _use, Some _s) (* clone *) ->
-       assert false (*TODO*)
+    | Duseclone (loc, use, inst) ->
+        let path, s = Typing.split_qualid use.use_theory in
+        let th = find_theory loc lib mt path s in
+        (* open namespace, if any *)
+        let uc =
+          if use.use_imp_exp <> None then Theory.open_namespace uc else uc in
+        (* use or clone *)
+        let uc = match inst with
+          | None -> Theory.use_export uc th
+          | Some inst ->
+              let inst = Typing.type_inst uc th inst in
+              Theory.clone_export uc th inst
+        in
+        (* close namespace, if any *)
+        begin match use.use_imp_exp with
+          | None -> uc
+          | Some imp -> Theory.close_namespace uc imp use.use_as
+        end
     | Dlogic d ->
         Typing.add_decl uc d
     | Dnamespace (loc, name, import, dl) ->
         let uc = Theory.open_namespace uc in
         let uc = List.fold_left add_decl uc dl in
-        Typing.close_namespace loc import name uc
+        Loc.try3 loc Theory.close_namespace uc import name
     | Dlet _ | Dletrec _ | Dparam _ | Dexn _ | Duse _ ->
         assert false
   in
diff --git a/tests/test-pgm-jcf.mlx b/tests/test-pgm-jcf.mlx
new file mode 100644
index 0000000000000000000000000000000000000000..479850aee6c6009e13e44fdd735c736a329eeaf1
--- /dev/null
+++ b/tests/test-pgm-jcf.mlx
@@ -0,0 +1,11 @@
+
+theory T
+  type t = int
+  goal G : forall x: t. x=0
+end
+
+(*
+Local Variables:
+compile-command: "unset LANG; ../bin/why3ide test-pgm-jcf.mlx"
+End:
+*)