diff --git a/src/kernel_internals/parsing/logic_lexer.mll b/src/kernel_internals/parsing/logic_lexer.mll
index 8d36a9ae0639b136a5d96aaea84d455ad2ac9a84..994df65e3914915e3ca57c10eb57b876b2d457e0 100644
--- a/src/kernel_internals/parsing/logic_lexer.mll
+++ b/src/kernel_internals/parsing/logic_lexer.mll
@@ -190,22 +190,25 @@
       with Not_found ->
         let res =
           match Logic_env.extension_category ~plugin s with
-          | exception Not_found -> None
-          | Cil_types.Ext_contract -> Some (EXT_CONTRACT (s, plugin))
-          | Cil_types.Ext_global ->
+          | exception Not_found ->
             begin
-              match Logic_env.is_extension_block ~plugin s with
-              | false -> Some (EXT_GLOBAL (s, plugin))
-              | true -> Some (EXT_GLOBAL_BLOCK (s, plugin))
+              match Logic_env.is_importer ~plugin s, plugin with
+              | false, _ -> None
+              | true, None -> Some (EXT_IMPORTER s)
+              | true, Some _ -> Some (EXT_IMPORTER_PLUGIN (s, plugin))
             end
+          | Cil_types.Ext_contract -> Some (EXT_CONTRACT (s, plugin))
+          | Cil_types.Ext_global ->
+              if Logic_env.is_extension_block ~plugin s
+              then Some (EXT_GLOBAL_BLOCK (s, plugin))
+              else Some (EXT_GLOBAL (s, plugin))
           | Cil_types.Ext_code_annot _ -> Some (EXT_CODE_ANNOT (s, plugin))
         in
         match res with
         | None ->
           if Logic_env.typename_status s then TYPENAME s
           else
-            (try
-               Hashtbl.find type_kw s
+            (try Hashtbl.find type_kw s
              with Not_found -> IDENTIFIER s)
         | Some lex -> lex
     ),
@@ -325,6 +328,24 @@
            syntax \\kernel::%s" s s;
       tok
     | _ -> raise Parsing.Parse_error
+
+  let check_ext_importer source plugin tok =
+    match tok with
+    | IDENTIFIER s ->
+      if Plugin.is_present plugin then
+        Kernel.warning ~once:true ~wkey:Kernel.wkey_extension_unknown ~source
+          "Ignoring unregistered importer extension '%s' of plug-in %s" s plugin
+      else
+        Kernel.warning ~once:true ~wkey:Kernel.wkey_plugin_not_loaded ~source
+          "Ignoring importer extension '%s' for unloaded plug-in %s" s plugin;
+      IDENTIFIER_IMPORTER s
+    | EXT_IMPORTER_PLUGIN (s, _) ->
+      if String.equal plugin "kernel" then
+        Kernel.abort ~source
+          "Extension importer '%s' from frama-c's kernel should not be used \
+           with the syntax \\kernel::%s" s s;
+      tok
+    | _ -> raise Parsing.Parse_error
 }
 
 let space = [' ' '\t' '\012' '\r' '@' ]
@@ -372,6 +393,12 @@ rule token = parse
            then comment lexbuf
            else lex_error lexbuf "unexpected block-comment opening"
          }
+  | '\\' (rIdentifier as plugin) "::" (rIdentifier as name) ":" {
+     let loc = Lexing.(lexeme_start_p lexbuf, lexeme_end_p lexbuf) in
+     let cabsloc = Cil_datatype.Location.of_lexing_loc loc in
+     let tok = identifier ~plugin:(Some plugin) name cabsloc in
+     check_ext_importer (fst cabsloc) plugin tok
+     }
   | '\\' (rIdentifier as plugin) "::" (rIdentifier as name) {
      let loc = Lexing.(lexeme_start_p lexbuf, lexeme_end_p lexbuf) in
      let cabsloc = Cil_datatype.Location.of_lexing_loc loc in
diff --git a/src/kernel_internals/parsing/logic_parser.mly b/src/kernel_internals/parsing/logic_parser.mly
index 6c6b4e299cb7a36a29d660f1138608b092c77163..d7671bfea024fd176d960bd4739990fa536ce3dc 100644
--- a/src/kernel_internals/parsing/logic_parser.mly
+++ b/src/kernel_internals/parsing/logic_parser.mly
@@ -269,7 +269,7 @@
 
 %token EXT_SPEC_MODULE EXT_SPEC_FUNCTION EXT_SPEC_CONTRACT EXT_SPEC_INCLUDE
 %token EXT_SPEC_AT EXT_SPEC_LET
-%token <string> LONGIDENT IDENTIFIER TYPENAME IDENTIFIER_EXT
+%token <string> LONGIDENT IDENTIFIER TYPENAME IDENTIFIER_EXT IDENTIFIER_IMPORTER
 %token <bool*string> STRING_LITERAL
 %token <string> INT_CONSTANT
 %token <string> FLOAT_CONSTANT
@@ -290,7 +290,8 @@
 %token CHECK_ENSURES CHECK_EXITS CHECK_CONTINUES CHECK_BREAKS CHECK_RETURNS
 %token ADMIT_REQUIRES ADMIT_LOOP ADMIT_INVARIANT ADMIT_LEMMA
 %token ADMIT_ENSURES ADMIT_EXITS ADMIT_CONTINUES ADMIT_BREAKS ADMIT_RETURNS
-%token <string * string option> EXT_CODE_ANNOT EXT_GLOBAL EXT_GLOBAL_BLOCK EXT_CONTRACT
+%token <string> EXT_IMPORTER
+%token <string * string option> EXT_CODE_ANNOT EXT_GLOBAL EXT_GLOBAL_BLOCK EXT_CONTRACT EXT_IMPORTER_PLUGIN
 %token EXITS BREAKS CONTINUES RETURNS
 %token VOLATILE READS WRITES
 %token LOGIC PREDICATE INDUCTIVE AXIOM LEMMA LBRACE RBRACE
@@ -952,7 +953,10 @@ full_identifier:
 | id = EXT_CONTRACT { fst id }
 | id = EXT_GLOBAL { fst id }
 | id = EXT_GLOBAL_BLOCK { fst id }
+| id = EXT_IMPORTER { id }
+| id = EXT_IMPORTER_PLUGIN { fst id }
 | id = IDENTIFIER_EXT { id }
+| id = IDENTIFIER_IMPORTER { id }
 ;
 
 %inline unknown_extension:
@@ -1695,9 +1699,9 @@ logic_def:
     { LDimport(None,mId,None) }
 | IMPORT mId = module_name AS id = IDENTIFIER SEMICOLON
     { LDimport(None,mId,Some id) }
-| IMPORT drv = IDENTIFIER COLON mId = module_name SEMICOLON
+| IMPORT drv = ext_importer mId = module_name SEMICOLON
     { LDimport(Some drv,mId,None) }
-| IMPORT drv = IDENTIFIER COLON mId = module_name AS id = IDENTIFIER SEMICOLON
+| IMPORT drv = ext_importer mId = module_name AS id = IDENTIFIER SEMICOLON
     { LDimport(Some drv,mId,Some id) }
 | TYPE poly_id_type_add_typename EQUAL typedef SEMICOLON
         { let (id,tvars) = $2 in
@@ -1715,6 +1719,17 @@ push_module_name:
 | module_name { push_module_types () ; $1 }
 ;
 
+ext_importer:
+| IDENTIFIER COLON {
+    Kernel.warning ~once:true ~wkey:Kernel.wkey_extension_unknown
+      ~source:(fst (loc $sloc))
+      "Ignoring unregistered importer extension '%s'" $1;
+    raise Unknown_ext
+  }
+| EXT_IMPORTER COLON { $1, None }
+| EXT_IMPORTER_PLUGIN { $1 }
+| IDENTIFIER_IMPORTER { raise Unknown_ext }
+
 deprecated_logic_decl:
 /* OBSOLETE: logic function declaration */
 | LOGIC logic_rt_type poly_id opt_parameters SEMICOLON
@@ -1982,7 +1997,10 @@ is_acsl_decl_or_code_annot:
 | EXT_CODE_ANNOT { fst $1 }
 | EXT_GLOBAL { fst $1 }
 | EXT_GLOBAL_BLOCK { fst $1 }
+| EXT_IMPORTER { $1 }
+| EXT_IMPORTER_PLUGIN { fst $1 }
 | IDENTIFIER_EXT { $1 }
+| IDENTIFIER_IMPORTER { $1 }
 | ASSUMES   { "assumes" }
 | ASSERT    { "assert" }
 | CHECK     { "check" }
diff --git a/src/kernel_services/ast_data/cil_types.ml b/src/kernel_services/ast_data/cil_types.ml
index 7b9f5506e3435bef060c446572af72728c942a58..4949133967a9d2a340ee5337b33e46943e73cd53 100644
--- a/src/kernel_services/ast_data/cil_types.ml
+++ b/src/kernel_services/ast_data/cil_types.ml
@@ -1801,8 +1801,8 @@ and global_annotation =
       * attributes * location
   (** associated terms, reading function, writing function *)
   | Daxiomatic of string * global_annotation list * attributes * location
-  (** last string option is the external importer responsible for the module *)
-  | Dmodule of string * global_annotation list * attributes * string option * location
+  (** last option is the external importer responsible for the module *)
+  | Dmodule of string * global_annotation list * attributes * (string * string option) option * location
   | Dtype of logic_type_info * location (** declaration of a logic type. *)
   | Dlemma of
       string * logic_label list * string list *
diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml
index 6692b163091c1b5337634b6603e2a18c949c2980..dd224e225f3691e432aefc9c2f7f76597645c007 100644
--- a/src/kernel_services/ast_printing/cil_printer.ml
+++ b/src/kernel_services/ast_printing/cil_printer.ml
@@ -3284,6 +3284,14 @@ class cil_printer () = object (self)
       (self#typ None) mfi.mi_base_type
       (self#logic_type (Some print_decl)) mfi.mi_field_type
 
+  method private pp_driver fmt (name, plugin) =
+    match plugin with
+    | None -> pp_print_string fmt name
+    | Some plugin ->
+      if Datatype.String.equal plugin "kernel"
+      then pp_print_string fmt name
+      else fprintf fmt "\\%s::%s" plugin name
+
   method global_annotation fmt = function
     | Dtype_annot (a,_) ->
       let old_label = current_label in
@@ -3415,15 +3423,16 @@ class cil_printer () = object (self)
         decls
     | Dmodule(id, _, _, Some drv, _)
       when not Kernel.(is_debug_key_enabled dkey_print_imported_modules) ->
-      fprintf fmt "@[<hov 2>%a %s: %s %a _ ;@]@\n"
-        self#pp_acsl_keyword "import" drv id
+      fprintf fmt "@[<hov 2>%a %a: %s %a _ ;@]@\n"
+        self#pp_acsl_keyword "import"
+        self#pp_driver drv id
         self#pp_acsl_keyword "\\as"
     | Dmodule(id, decls, _attr, driver, _) ->
       begin
         (* attributes are meant to be purely internal for now. *)
         fprintf fmt "@[<v 2>@[" ;
         if Kernel.(is_debug_key_enabled dkey_print_imported_modules) then
-          Option.iter (fprintf fmt "// import %s:@\n") driver ;
+          Option.iter (fprintf fmt "// import %a:@\n" self#pp_driver) driver ;
         fprintf fmt "%a %a {@]"
           self#pp_acsl_keyword "module" self#logic_name id ;
         try
diff --git a/src/kernel_services/ast_printing/cil_types_debug.ml b/src/kernel_services/ast_printing/cil_types_debug.ml
index 28e5f9448921c6a07afd5f6ef8cc835e82c7a3fb..7a6e715c929f712d992c9600cd5c01ef952027f2 100644
--- a/src/kernel_services/ast_printing/cil_types_debug.ml
+++ b/src/kernel_services/ast_printing/cil_types_debug.ml
@@ -972,9 +972,14 @@ and pp_global_annotation fmt = function
       (pp_list pp_global_annotation) global_annotation_list
       pp_attributes attributes  pp_location location
   | Dmodule(string,global_annotation_list,attributes,driver,location) ->
+    let pp_driver fmt (name, plugin) =
+      Format.fprintf fmt "(%s, %a)" name (pp_option pp_string) plugin
+    in
     Format.fprintf fmt "Dmodule(%a,%a,%a,%a,%a)"  pp_string string
       (pp_list pp_global_annotation) global_annotation_list
-      pp_attributes attributes (pp_option pp_string) driver pp_location location
+      pp_attributes attributes
+      (pp_option pp_driver) driver
+      pp_location location
   | Dtype(logic_type_info,location) ->
     Format.fprintf fmt "Dtype(%a,%a)"  pp_logic_type_info logic_type_info  pp_location location
   | Dlemma(string,logic_label_list,string_list,predicate,attributes,location) ->
diff --git a/src/kernel_services/ast_printing/logic_print.ml b/src/kernel_services/ast_printing/logic_print.ml
index d38113e34761974fe117d869378c99da211d2e46..b0a6758cb071b5df4a2373e495b84f03f099385d 100644
--- a/src/kernel_services/ast_printing/logic_print.ml
+++ b/src/kernel_services/ast_printing/logic_print.ml
@@ -376,8 +376,16 @@ let rec print_decl fmt d =
     fprintf fmt "@[<2>module@ %s@ {@\n%a@]@\n}" name
       (pp_list ~sep:"@\n" print_decl) ds
   | LDimport (drv,mId,asId) ->
+    let pp_driver fmt (name, plugin) =
+      match plugin with
+      | None -> pp_print_string fmt name
+      | Some plugin ->
+        if Datatype.String.equal plugin "kernel"
+        then pp_print_string fmt name
+        else fprintf fmt "\\%s::%s" plugin name
+    in
     fprintf fmt "@[<2>import" ;
-    Option.iter (fprintf fmt "@ %s:") drv ;
+    Option.iter (fprintf fmt "%a:" pp_driver) drv ;
     fprintf fmt "@ %s" mId ;
     Option.iter (fprintf fmt "@ \\as %s") asId ;
     fprintf fmt ";@]@\n}"
diff --git a/src/kernel_services/ast_queries/acsl_extension.ml b/src/kernel_services/ast_queries/acsl_extension.ml
index f5c221bc25b35440e4ce852ccbddce486aaf7169..df980b11d676df3a7e51aa22485d997902dec094 100644
--- a/src/kernel_services/ast_queries/acsl_extension.ml
+++ b/src/kernel_services/ast_queries/acsl_extension.ml
@@ -39,6 +39,8 @@ type extension_printer =
   acsl_extension_kind -> unit
 type extension_same =
   acsl_extension_kind -> acsl_extension_kind -> Ast_diff.is_same_env -> bool
+type extension_module_importer =
+  module_builder -> location -> string list -> unit
 
 type register_extension =
   plugin:string -> string ->
@@ -75,8 +77,10 @@ type extension_common = {
   plugin: string;
   is_same_ext: extension_same;
 }
-type extension_module_importer =
-  module_builder -> location -> string list -> unit
+type extension_importer = {
+  plugin: string;
+  importer: extension_module_importer;
+}
 
 let default_printer printer fmt = function
   | Ext_id i -> Format.pp_print_int fmt i
@@ -128,6 +132,9 @@ let make_block
   { preprocessor; typer; status; plugin},
   { category; visitor; printer; short_printer; plugin; is_same_ext }
 
+let make_importer ~plugin importer : extension_importer =
+  { plugin; importer }
+
 module Extensions = struct
   (* Hash table for extension_common. A name can be use by different plugins to
      register an extension so we keep a list. *)
@@ -144,8 +151,10 @@ module Extensions = struct
   let ext_block_tbl : (string, extension_block list) Hashtbl.t =
     Hashtbl.create 5
 
-  (* Hash table for module importers. *)
-  let ext_module_importer = Hashtbl.create 5
+  (* Hash table for extension_importer. A name can be use by different plugins
+     to register an extension so we keep a list. *)
+  let ext_importer_tbl : (string, extension_importer list) Hashtbl.t =
+    Hashtbl.create 5
 
   let add_to_list tbl key value =
     match Hashtbl.find_opt tbl key with
@@ -200,10 +209,11 @@ module Extensions = struct
 
   (* Generic function for find functions, catch Not_found and throw a fatal
      instead. *)
-  let find_gen ~get_plugin tbl ~plugin name =
+  let find_gen ~get_plugin data tbl ~plugin name =
     try find ~get_plugin ~plugin tbl name
     with Not_found ->
-      Kernel.fatal ~current:true "Unsupported clause extension named '%a%s'"
+      Kernel.fatal ~current:true "Unsupported %s extension named '%a%s'"
+        data
         (Pretty_utils.pp_opt ~pre:"\\" ~suf:"::" Format.pp_print_string) plugin
         name
 
@@ -213,25 +223,33 @@ module Extensions = struct
 
   let get_plugin_block (e : extension_block) = e.plugin
 
-  let find_single = find_gen ~get_plugin:get_plugin_single ext_single_tbl
+  let get_plugin_importer (e : extension_importer) = e.plugin
+
+  let find_single =
+    find_gen ~get_plugin:get_plugin_single "clause" ext_single_tbl
 
-  let find_common = find_gen ~get_plugin:get_plugin_common ext_tbl
+  let find_common =
+    find_gen ~get_plugin:get_plugin_common "clause" ext_tbl
 
-  let find_block = find_gen ~get_plugin:get_plugin_block ext_block_tbl
+  let find_block =
+    find_gen ~get_plugin:get_plugin_block "clause" ext_block_tbl
 
-  let find_importer name : extension_module_importer =
-    try Hashtbl.find ext_module_importer name with Not_found ->
-      Kernel.fatal ~current:true "Unsupported module importer '%s'" name
+  let find_importer =
+    find_gen ~get_plugin:get_plugin_importer "importer" ext_importer_tbl
 
   (* [Logic_lexer] can ask for something that is not a category, which is not
      a fatal error so we do not caught the Not_found exception. *)
   let category ~plugin name =
     (find ~get_plugin:get_plugin_common ext_tbl ~plugin name).category
 
+  let importer ~plugin name = (find_importer ~plugin name).importer
+
   let is_extension = mem ~get_plugin:get_plugin_common ext_tbl
 
   let is_extension_block = mem ~get_plugin:get_plugin_block ext_block_tbl
 
+  let is_importer = mem ~get_plugin:get_plugin_importer ext_importer_tbl
+
   let register_gen ~make ~tbl cat ~plugin name
       ?preprocessor typer ?visitor ?printer ?short_printer ?is_same_ext status =
     let info1,info2 =
@@ -259,13 +277,20 @@ module Extensions = struct
 
   let register_block = register_gen ~make:make_block ~tbl:ext_block_tbl
 
-  let register_module_importer name loader =
-    if Hashtbl.mem ext_module_importer name then
+  let register_module_importer ~plugin name loader =
+    if is_importer ~plugin:(Some "kernel") name then
       Kernel.warning ~wkey:Kernel.wkey_acsl_extension
-        "Trying to register module importer %s twice. Ignoring second importer"
-        name
+        "Trying to register importer extension %s reserved by frama-c. \
+         Rename to avoid conflict with the kernel. Ignored module importer" name
     else
-      Hashtbl.add ext_module_importer name loader
+      begin
+        if is_importer ~plugin:(Some plugin) name then
+          Kernel.warning ~wkey:Kernel.wkey_acsl_extension
+            "Trying to register importer extension %s twice with plugin %s. \
+             Ignoring the second extension" name plugin
+        else
+          add_to_list ext_importer_tbl name (make_importer ~plugin loader)
+      end
 
   let preprocess ~plugin name = (find_single ~plugin name).preprocessor
 
@@ -300,7 +325,7 @@ module Extensions = struct
 
   let print ~plugin name printer fmt kind =
     let ext_common = find_common ~plugin name in
-    let plugin = ext_common.plugin in
+    let plugin = get_plugin_common ext_common in
     let full_name =
       if Datatype.String.equal plugin "kernel"
       then name
@@ -347,6 +372,7 @@ let () =
   Logic_env.set_extension_handler
     ~category:Extensions.category
     ~is_extension: Extensions.is_extension
+    ~is_importer:Extensions.is_importer
     ~preprocess: Extensions.preprocess
     ~is_extension_block: Extensions.is_extension_block
     ~preprocess_block: Extensions.preprocess_block;
@@ -354,7 +380,7 @@ let () =
     ~is_extension: Extensions.is_extension
     ~typer: Extensions.typing
     ~typer_block: Extensions.typing_block
-    ~importer: Extensions.find_importer;
+    ~importer: Extensions.importer;
   Cil.set_extension_handler
     ~visit: Extensions.visit ;
   Cil_printer.set_extension_handler
diff --git a/src/kernel_services/ast_queries/acsl_extension.mli b/src/kernel_services/ast_queries/acsl_extension.mli
index 937f8c65cb097bdedc77aaf615c28ab6c662da90..ba981fb9e2bb33d628638fac8c3c6058a678c406 100644
--- a/src/kernel_services/ast_queries/acsl_extension.mli
+++ b/src/kernel_services/ast_queries/acsl_extension.mli
@@ -46,6 +46,9 @@ type extension_preprocessor_block =
 type extension_typer_block =
   typing_context -> location -> string * extended_decl list -> acsl_extension_kind
 
+type extension_module_importer =
+  module_builder -> location -> string list -> unit
+
 (** Pretty printers for ACSL extensions *)
 type extension_printer =
   Printer_api.extensible_printer_type -> Format.formatter ->
@@ -58,9 +61,6 @@ type extension_printer =
 type extension_same =
   acsl_extension_kind -> acsl_extension_kind -> Ast_diff.is_same_env -> bool
 
-type extension_module_importer =
-  module_builder -> location -> string list -> unit
-
 (** type of functions that register new ACSL extensions to be used in place of
     various kinds of ACSL annotations.
 
@@ -161,11 +161,11 @@ val register_code_annot_next_both: register_extension
    Module importer extensions allow extending the import clause with external
    loaders. For instance, consider the following declaration:
    {[
-     //@ import A: foo::bar;
+     //@ import \myplugin::A: foo::bar;
    ]}
 
    This import clause will invoke an external module importer named ["A"]
-   provided it has been properly registered.
+   provided it has been properly registered by plugin [myplugin].
 
    A module importer extension is a function that receives a [module_builder]
    parameter to be populated with contents of the module. The module name is
@@ -180,4 +180,5 @@ val register_code_annot_next_both: register_extension
    external module importers might use memoization internally, the provided
    module builder shall be populated on every call.
 *)
-val register_module_importer : string -> extension_module_importer -> unit
+val register_module_importer :
+  plugin:string -> string -> extension_module_importer -> unit
diff --git a/src/kernel_services/ast_queries/logic_env.ml b/src/kernel_services/ast_queries/logic_env.ml
index 0f46da80c6c6c039755525713315af574154d4c9..58795159bcea99c6d6f1db51eb7ffd8f63852e63 100644
--- a/src/kernel_services/ast_queries/logic_env.ml
+++ b/src/kernel_services/ast_queries/logic_env.ml
@@ -27,15 +27,17 @@ open Cil_types
 module Extensions = struct
   let initialized = ref false
   let ref_is_extension = ref (fun ~plugin:_ _ -> assert false)
+  let ref_is_importer = ref (fun ~plugin:_ _ -> assert false)
   let ref_category = ref (fun ~plugin:_ _ -> assert false)
   let ref_preprocess = ref (fun ~plugin:_ _ -> assert false)
   let ref_is_extension_block = ref (fun ~plugin:_ _ -> assert false)
   let ref_preprocess_block = ref (fun ~plugin:_ _ -> assert false)
 
-  let set_extension_handler ~category ~is_extension ~preprocess
+  let set_extension_handler ~category ~is_extension ~is_importer ~preprocess
       ~is_extension_block ~preprocess_block =
     assert (not !initialized) ;
     ref_is_extension := is_extension ;
+    ref_is_importer := is_importer ;
     ref_category := category ;
     ref_preprocess := preprocess ;
     ref_is_extension_block := is_extension_block;
@@ -45,6 +47,7 @@ module Extensions = struct
 
   let is_extension ~plugin name = !ref_is_extension ~plugin name
   let is_extension_block ~plugin name = !ref_is_extension_block ~plugin name
+  let is_importer ~plugin name = !ref_is_importer ~plugin name
   let category ~plugin name = !ref_category ~plugin name
   let preprocess ~plugin name = !ref_preprocess ~plugin name
   let preprocess_block ~plugin name = !ref_preprocess_block ~plugin name
@@ -52,6 +55,7 @@ end
 let set_extension_handler = Extensions.set_extension_handler
 let is_extension = Extensions.is_extension
 let is_extension_block = Extensions.is_extension_block
+let is_importer = Extensions.is_importer
 let extension_category = Extensions.category
 let preprocess_extension = Extensions.preprocess
 let preprocess_extension_block = Extensions.preprocess_block
@@ -154,7 +158,10 @@ module Axiomatics =
 
 module ModuleOccurence =
   Datatype.Pair
-    (Datatype.Option(Datatype.String)) (* external driver *)
+    (Datatype.Option
+       (Datatype.Pair
+          (Datatype.String) (* external driver name *)
+          (Datatype.Option(Datatype.String)))) (* external driver plugin *)
     (Cil_datatype.Location)
 
 module Modules =
diff --git a/src/kernel_services/ast_queries/logic_env.mli b/src/kernel_services/ast_queries/logic_env.mli
index 3f9907cc2d11921174c81c99a81f662becd021a2..9bbc0a67a17d9c6c9c767d5ce51614b1837413c1 100644
--- a/src/kernel_services/ast_queries/logic_env.mli
+++ b/src/kernel_services/ast_queries/logic_env.mli
@@ -40,6 +40,11 @@ val is_extension: plugin:string option -> string -> bool
 *)
 val is_extension_block: plugin:string option -> string -> bool
 
+(** Return [true] if a module importer is registered for the given plugin.
+    @since Frama-C+dev
+*)
+val is_importer: plugin:string option -> string -> bool
+
 (** Return the extension category.
     @raise Not_Found if the extension is not registered
     @before Frama-C+def the function took one less argument, [plugin], which is
@@ -87,7 +92,8 @@ module Axiomatics: State_builder.Hashtbl
 (** @since Frama-C+dev *)
 module Modules: State_builder.Hashtbl
   with type key = string
-   and type data = string option * Cil_types.location (* driver, loc *)
+   (* driver (name, plugin), location *)
+   and type data = (string * string option) option * Cil_types.location
 
 val builtin_states: State.t list
 
@@ -257,7 +263,7 @@ val set_extension_handler:
     If your name is not [Acsl_extension], do not call this.
     @since 21.0-Scandium
     @before Frama-C+dev functions did not take a [plugin] parameter.
-    [get_plugins] did not exist
+    [get_plugins] and [is_importer] did not exist
 *)
 
 val init_dependencies: State.t -> unit
diff --git a/src/kernel_services/ast_queries/logic_typing.ml b/src/kernel_services/ast_queries/logic_typing.ml
index 0ae28b248b04b083e023ff1fd016d04aded356cb..be1aba8f1e6e22ad4abeadc211da317a6e12f8f4 100644
--- a/src/kernel_services/ast_queries/logic_typing.ml
+++ b/src/kernel_services/ast_queries/logic_typing.ml
@@ -538,7 +538,7 @@ module Extensions = struct
   let ref_is_extension = ref (fun ~plugin:_ _ -> assert false)
   let ref_typer = ref (fun ~plugin:_ _ _ _ _ -> assert false)
   let ref_typer_block = ref (fun ~plugin:_ _ _ _ _ -> assert false)
-  let ref_importer = ref (fun _ _ _ _ -> assert false)
+  let ref_importer = ref (fun ~plugin:_ _ _ _ _ -> assert false)
 
   let set_handler ~is_extension ~typer ~typer_block ~importer =
     assert (not !initialized) ;
@@ -556,8 +556,8 @@ module Extensions = struct
   let typer_block ~plugin name ~typing_context:typing_context ~loc =
     !ref_typer_block ~plugin name typing_context loc
 
-  let importer name ~builder ~loc (moduleId: string list) : unit =
-    !ref_importer name builder loc moduleId
+  let importer ~plugin name ~builder ~loc (moduleId: string list) : unit =
+    !ref_importer ~plugin name builder loc moduleId
 
 end
 let set_extension_handler = Extensions.set_handler
@@ -4330,24 +4330,27 @@ struct
     | LDimport(None,name,alias) ->
       add_import ?alias name ; None
 
-    | LDimport(Some driver as drv,name,alias) ->
+    | LDimport(Some (driver, plugin) as drv,name,alias) ->
       let annot =
         match Logic_env.Modules.find name with
         | None, oldloc ->
           C.error loc
             "Module %s already defined (at %a)"
             name Cil_printer.pp_location oldloc
-        | Some odrv, oldloc ->
-          if odrv <> driver then
+        | Some (driver', plugin'), oldloc ->
+          if plugin <> plugin' || driver <> driver' then
             C.error loc
-              "Module %s already imported with driver %s (at %a)"
-              name odrv Cil_printer.pp_location oldloc
+              "Module %s already imported with driver %a%s (at %a)"
+              name
+              (Pretty_utils.pp_opt ~pre:"\\" ~suf:"::" Format.pp_print_string) plugin'
+              driver'
+              Cil_printer.pp_location oldloc
           else None
         | exception Not_found ->
           let decls = ref [] in
           let builder = make_module_builder decls name in
           let path = Logic_utils.longident name in
-          Extensions.importer driver ~builder ~loc path ;
+          Extensions.importer ~plugin driver ~builder ~loc path ;
           Logic_env.Modules.add name (drv,loc) ;
           Some (Dmodule(name,List.rev !decls,[],drv,loc))
       in add_import ?alias name ; annot
diff --git a/src/kernel_services/ast_queries/logic_typing.mli b/src/kernel_services/ast_queries/logic_typing.mli
index ecb26959fabe1d5a168ffb2d9c9928e07c0a45c4..930fc3f881d86b0a4fa26f3bd720a1139e492fde 100644
--- a/src/kernel_services/ast_queries/logic_typing.mli
+++ b/src/kernel_services/ast_queries/logic_typing.mli
@@ -318,7 +318,8 @@ val set_extension_handler:
   typer_block:(plugin:string option -> string -> typing_context -> location ->
                string * Logic_ptree.extended_decl list ->
                bool * Cil_types.acsl_extension_kind) ->
-  importer:(string -> module_builder -> location -> string list -> unit) ->
+  importer: (plugin:string option -> string -> module_builder -> location ->
+             string list -> unit) ->
   unit
 (** Used to setup references related to the handling of ACSL extensions.
     If your name is not [Acsl_extension], do not call this
@@ -349,7 +350,11 @@ val get_typer_block:
   string * Logic_ptree.extended_decl list ->
   bool * Cil_types.acsl_extension_kind
 
+(** Load the given extension importer.
+    @since Frama-C+dev
+*)
 val get_importer:
+  plugin:string option ->
   string ->
   builder:module_builder ->
   loc:Logic_ptree.location ->
diff --git a/src/kernel_services/parsetree/logic_ptree.ml b/src/kernel_services/parsetree/logic_ptree.ml
index 7fbcc3cde091a58741bb1fec8fccc73149fdc916..5c8c065d59f80ba1562fec2299436ae04de28c47 100644
--- a/src/kernel_services/parsetree/logic_ptree.ml
+++ b/src/kernel_services/parsetree/logic_ptree.ml
@@ -250,7 +250,7 @@ and decl_node =
   | LDmodule of string * decl list
   (** [LDmodule(id,decls)]
       represents a module of axiomatic definitions.*)
-  | LDimport of string option * string * string option
+  | LDimport of (string * string option) option * string * string option
   (** [LDimport(driver,module,alias)]
       imports symbols from module using the specified driver,
       with optional alias.*)