diff --git a/src/plugins/region/Region.ml b/src/plugins/region/Region.ml
index fe4352cc959f36b1c87ef12f103476dbd992e1d7..b16d41ed66f3665af3b98c7c2296825a839aed73 100644
--- a/src/plugins/region/Region.ml
+++ b/src/plugins/region/Region.ml
@@ -27,118 +27,232 @@
 
 open Cil_types
 
-type region = Memory.region
 
-module R : Qed.Collection.S with type t = region =
-  Qed.Collection.Make(struct
-    type t = region
-    let hash r = Memory.id r.Memory.node
-    let equal r1 r2 = (hash r1 == hash r2)
-    let compare r1 r2 = (hash r1) - (hash r2)
-  end)
+module Node = struct
 
+  type node = Memory.node
+  type map = Code.domain
 
-type map = Code.domain
 
 
+  (* API GETTERS *)
+  let get_map (f:kernel_function) : map = Code.domain f
 
-(* API GETTERS *)
-let get_map (f:kernel_function) : map = Code.domain f
 
+  let get_id map node = Memory.id (Memory.node map.Code.map node)
+  let get_node map id = Memory.node map.Code.map @@ Memory.forge id
 
 
-let get_id _map region = Memory.id region.Memory.node
-let get_region map id =
-  try Some (Memory.region map.Code.map @@ Memory.forge id)
-  with Not_found -> None
 
+  let cvar (map:map) (var:varinfo) =
+    Memory.node map.Code.map (Memory.lval map.Code.map ((Var var), NoOffset))
 
+  let field (map:map) (node:node) (field:fieldinfo) =
+    Memory.node map.Code.map
+    @@ Memory.offset map.Code.map node (Field (field, NoOffset))
 
-let cvar (map:map) (var:varinfo) =
-  try Some (Memory.region map.Code.map (Memory.lval map.Code.map ((Var var), NoOffset)))
-  with Not_found -> None
+  let shift (_map:map) node (_ty:typ) = (* TODO *) node
 
-let field (map:map) (region:region) (field:fieldinfo) =
-  try Some (Memory.region map.Code.map (Memory.offset map.Code.map region.node (Field (field, NoOffset))))
-  with Not_found -> None
 
-let shift (_map:map) region (_ty:typ) = (* TODO *)
-  try Some region
-  with Not_found -> None
+  let base_addr _map node = (* TODO *) node
 
 
-let base_addr _map region = (* TODO *) region
 
+  (* API POINTERS *)
+  let points_to (map:map) (node:node) : node option =
+    Option.map (Memory.node map.Code.map)
+    @@ Memory.cpointed map.map node
 
+  let pointed_by (map:map) (node:node) : node list =
+    List.map (Memory.node map.Code.map)
+    @@ Memory.cpointed_by map.Code.map node
 
-(* API POINTERS *)
-let points_to (map:map) (region:region) : region option =
-  Option.map (Memory.region map.Code.map) @@ Memory.cpointed map.map region.Memory.node
 
-let pointed_by (map:map) (region:region) : region list =
-  List.map (Memory.region map.Code.map) @@ Memory.cpointed_by map.Code.map region.Memory.node
+  (* COMPARATOR *)
+  let equal map r1 r2 = Memory.eq_node map.Code.map r1 r2
 
 
-(* COMPARATOR *)
-let equal map r1 r2 = get_id map r1 == get_id map r2
+  module Reachable = struct
 
+    module Imap = Map.Make(Int)
 
-module Reachable = struct
+    let is_reachable map source target : bool =
+      let q = Queue.create () in
+      let exception Reached in
+      try
+        let push r =
+          if equal map target r then raise Reached else Queue.push r q
+        in
+        push source ;
+        let visited = ref Imap.empty in
+        while true do (*not !accessible && not @@ Queue.is_empty q do *)
+          let node = Queue.pop q in
+          if equal map target node then raise Exit else
+          if not @@ Imap.mem (get_id map node) !visited then begin
+            visited := Imap.add (get_id map node) node !visited ;
+            List.iter push (Memory.parents map.Code.map node)
+          end
+        done ;
+        false
+      with
+      | Queue.Empty -> false
+      | Reached -> true
 
-  module Imap = Map.Make(Int)
+  end
 
-  let is_reachable map source target =
-    let accessible = ref false in
-    let q = Queue.create () in
-    Queue.push source q ;
-    let visited = ref Imap.empty in
-    while not !accessible && not @@ Queue.is_empty q do
-      let region = Queue.pop q in
-      if not @@ Imap.mem (get_id map region) !visited then begin
-        visited := Imap.add (get_id map region) region !visited ;
-        List.iter (fun r -> Queue.push (Memory.region map r) q) region.Memory.parents ;
-        accessible := equal map target region ;
-      end
-    done;
-    !accessible
+  let included map r1 r2 : bool = Reachable.is_reachable map r1 r2
 
+
+  let separated map r1 r2 =
+    not (Reachable.is_reachable map r1 r2)
+    && not (Reachable.is_reachable map r2 r1)
+
+
+
+  (* API ITERATOR *)
+  let iter (map:map) (f:node -> unit) : unit =
+    Memory.iter_node map.map f
+
+
+  (* API PRINTER *)
+  let pp_node fmt node : unit = Memory.pp_node fmt node
+
+
+
+
+  (* API ACCESS *)
+  type acs = {
+    acs_read  : typ list;
+    acs_write : typ list;
+    acs_shift : typ list;
+  }
+  let empty_acs = {
+    acs_read  = [];
+    acs_write = [];
+    acs_shift = [];
+  }
+
+  let accesses (m: map) (r:node) : acs =
+    let acs_read, acs_write, acs_shift = Memory.accesses m.Code.map r in
+    { acs_read ; acs_write ; acs_shift }
 end
 
-let included map r1 r2 : bool = Reachable.is_reachable map.Code.map r1 r2
+
+module Region = struct
+  type region = Memory.region
+
+
+  type map = Code.domain
+
+
+
+  (* API GETTERS *)
+  let get_map (f:kernel_function) : map = Code.domain f
+
+
+
+  let get_id map region = Node.get_id map region.Memory.node
+  let get_region map id =
+    try Some (Memory.region map.Code.map @@ Node.get_node map id)
+    with Not_found -> None
 
 
-let separated map r1 r2 =
-  not (Reachable.is_reachable map.Code.map r1 r2)
-  && not (Reachable.is_reachable map.Code.map r2 r1)
 
+  let cvar (map:map) (var:varinfo) =
+    try Some (Memory.region map.Code.map @@ Node.cvar map var)
+    with Not_found -> None
 
+  let field (map:map) (region:region) (field:fieldinfo) =
+    try Some (Memory.region map.Code.map @@ Node.field map region.Memory.node field)
+    with Not_found -> None
 
-(* API ITERATOR *)
-let iter (map:map) (f:region -> unit) : unit =
-  Memory.iter map.map f
+  let shift (map:map) region (ty:typ) = (* TODO *)
+    try Some (Memory.region map.Code.map @@ Node.shift map region.Memory.node ty)
+    with Not_found -> None
 
 
-(* API PRINTER *)
-let pp_region fmt region : unit = Memory.pp_region fmt region
+  let base_addr _map region = (* TODO *) region
 
 
 
+  (* API POINTERS *)
+  let points_to (map:map) (region:region) : region option =
+    Option.map (Memory.region map.Code.map)
+    @@ Memory.cpointed map.map region.Memory.node
 
-(* API ACCESS *)
-type acs = {
-  acs_read  : typ list;
-  acs_write : typ list;
-  acs_shift : typ list;
-}
-let empty_acs = {
-  acs_read  = [];
-  acs_write = [];
-  acs_shift = [];
-}
+  let pointed_by (map:map) (region:region) : region list =
+    List.map (Memory.region map.Code.map)
+    @@ Memory.cpointed_by map.Code.map region.Memory.node
 
-let accesses (region:region) : acs =
-  {
-    acs_read  = List.map Access.typeof region.Memory.reads ;
-    acs_write = List.map Access.typeof region.Memory.writes ;
-    acs_shift = List.map Access.typeof region.Memory.shifts ;
+
+  (* COMPARATOR *)
+  let equal map r1 r2 = Node.equal map r1.Memory.node r2.Memory.node
+
+
+  module Reachable = struct
+
+    module Imap = Map.Make(Int)
+
+    let is_reachable map source target : bool =
+      let q = Queue.create () in
+      let exception Reached in
+      try
+        let push r =
+          if equal map target r then raise Reached else Queue.push r q
+        in
+        push source ;
+        let visited = ref Imap.empty in
+        while true do (*not !accessible && not @@ Queue.is_empty q do *)
+          let region = Queue.pop q in
+          if equal map target region then raise Exit else
+          if not @@ Imap.mem (get_id map region) !visited then begin
+            visited := Imap.add (get_id map region) region !visited ;
+            List.iter (fun r -> push (Memory.region map.Code.map r)) region.Memory.parents
+          end
+        done ;
+        false
+      with
+      | Queue.Empty -> false
+      | Reached -> true
+
+  end
+
+  let included map r1 r2 : bool = Reachable.is_reachable map r1 r2
+
+
+  let separated map r1 r2 =
+    not (Reachable.is_reachable map r1 r2)
+    && not (Reachable.is_reachable map r2 r1)
+
+
+
+  (* API ITERATOR *)
+  let iter (map:map) (f:region -> unit) : unit =
+    Memory.iter map.map f
+
+
+  (* API PRINTER *)
+  let pp_region fmt region : unit = Memory.pp_region fmt region
+
+
+
+
+  (* API ACCESS *)
+  type acs = {
+    acs_read  : typ list;
+    acs_write : typ list;
+    acs_shift : typ list;
+  }
+  let empty_acs = {
+    acs_read  = [];
+    acs_write = [];
+    acs_shift = [];
   }
+
+  let accesses (region:region) : acs =
+    {
+      acs_read  = List.map Access.typeof region.Memory.reads ;
+      acs_write = List.map Access.typeof region.Memory.writes ;
+      acs_shift = List.map Access.typeof region.Memory.shifts ;
+    }
+end
diff --git a/src/plugins/region/Region.mli b/src/plugins/region/Region.mli
index 2382e98dc2c239fe8c65d1ebfdf49999e49af7df..8630768bdae1d984baee2740a27002d0313abe6a 100644
--- a/src/plugins/region/Region.mli
+++ b/src/plugins/region/Region.mli
@@ -26,47 +26,99 @@
 open Cil_types
 
 
+(* Lower level API - more efficient *)
+module Node : sig
+  (* General type *)
+    type node
+    type map
+
+    (* API GETTERS *)
+    val get_map : kernel_function -> map
+
+    val get_id : map -> node -> int
+    val get_node : map -> int -> node
+
+    val cvar : map -> varinfo -> node
+    val field : map -> node -> fieldinfo -> node
+    val shift : map -> node -> typ -> node
+
+    val base_addr : map -> node -> node
+
+
+    (* API POINTERS *)
+    val points_to : map -> node -> node option
+    val pointed_by : map -> node -> node list
+
+
+    (* COMPARATOR *)
+    val separated : map -> node -> node -> bool
+    val included : map -> node -> node -> bool
+    val equal : map -> node -> node -> bool
+
+    (* API ITERATOR *)
+    val iter : map -> (node -> unit) -> unit
+
+
+    (* API PRINTER *)
+    val pp_node : Format.formatter -> node -> unit
+
+
+    (* API ACCESS *)
+    type acs = {
+      acs_read  : typ list;
+      acs_write : typ list;
+      acs_shift : typ list;
+    }
+    val empty_acs : acs
+    val accesses : map -> node -> acs
+end
+
+
+
+
+(* High level API *)
+module Region : sig
 (* General type *)
-type region
-module R : Qed.Collection.S with type t = region
-type map
+  type region
+  type map
 
-(* API GETTERS *)
-val get_map : kernel_function -> map
+  (* API GETTERS *)
+  val get_map : kernel_function -> map
 
-val get_id : map -> region -> int
-val get_region : map -> int -> region option
+  val get_id : map -> region -> int
+  val get_region : map -> int -> region option
 
-val cvar : map -> varinfo -> region option
-val field : map -> region -> fieldinfo -> region option
-val shift : map -> region -> typ -> region option
+  val cvar : map -> varinfo -> region option
+  val field : map -> region -> fieldinfo -> region option
+  val shift : map -> region -> typ -> region option
 
-val base_addr : map -> region -> region
+  val base_addr : map -> region -> region
 
 
-(* API POINTERS *)
-val points_to : map -> region -> region option
-val pointed_by : map -> region -> region list
+  (* API POINTERS *)
+  val points_to : map -> region -> region option
+  val pointed_by : map -> region -> region list
 
 
-(* COMPARATOR *)
-val separated : map -> region -> region -> bool
-val included : map -> region -> region -> bool
-val equal : map -> region -> region -> bool
+  (* COMPARATOR *)
+  val separated : map -> region -> region -> bool
+  val included : map -> region -> region -> bool
+  val equal : map -> region -> region -> bool
 
-(* API ITERATOR *)
-val iter : map -> (region -> unit) -> unit
+  (* API ITERATOR *)
+  val iter : map -> (region -> unit) -> unit
 
 
-(* API PRINTER *)
-val pp_region : Format.formatter -> region -> unit
+  (* API PRINTER *)
+  val pp_region : Format.formatter -> region -> unit
 
 
-(* API ACCESS *)
-type acs = {
-  acs_read  : typ list;
-  acs_write : typ list;
-  acs_shift : typ list;
-}
-val empty_acs : acs
-val accesses : region -> acs
+  (* API ACCESS *)
+  type acs = {
+    acs_read  : typ list;
+    acs_write : typ list;
+    acs_shift : typ list;
+  }
+  val empty_acs : acs
+  val accesses : region -> acs
+end
diff --git a/src/plugins/region/memory.ml b/src/plugins/region/memory.ml
index 75e38fe59f741ce83d5372aa25de9312107470a2..99689473aa6378639597b8926bb6343c2a131695 100644
--- a/src/plugins/region/memory.ml
+++ b/src/plugins/region/memory.ml
@@ -344,11 +344,32 @@ let iter (m:map) (f: region -> unit) =
   let h = Hashtbl.create 0 in
   Vmap.iter (fun _x n -> walk h m f n) m.roots
 
+  let rec walk_node h m (f: node -> unit) n =
+    let n = Ufind.find m.store n in
+    let id = Store.id n in
+    try Hashtbl.find h id with Not_found ->
+      Hashtbl.add h id () ;
+      f n ;
+      let r = Ufind.get m.store n in
+      match r.clayout with
+      | Blob -> ()
+      | Cell(_,p) -> Option.iter (walk_node h m f) p
+      | Compound(_,_,rg) -> Ranges.iter (walk_node h m f) rg
+
+  let iter_node (m:map) (f: node -> unit) =
+    let h = Hashtbl.create 0 in
+    Vmap.iter (fun _x n -> walk_node h m f n) m.roots
+
 let regions map =
   let pool = ref [] in
   iter map (fun r -> pool := r :: !pool) ;
   List.rev !pool
 
+
+let parents (m: map) (r: node) =
+  let node = Ufind.get m.store r in
+  nodes m node.cparents
+
 (* -------------------------------------------------------------------------- *)
 (* --- Merge                                                              --- *)
 (* -------------------------------------------------------------------------- *)
@@ -535,13 +556,27 @@ let cpointed_by m r =
   let rg = Ufind.get m.store r in
   rg.cpointed_by
 
+let cvar (m: map) (v: varinfo) : node =
+  Ufind.find m.store @@ Vmap.find v m.roots
+
+let field (m: map) (r: node) (fd: fieldinfo) : node =
+  if fd.fcomp.cstruct then
+    let _, rgs = cranges m r in
+    let (p,w) = Cil.fieldBitsOffset fd in
+    let rg = Ranges.find p rgs in
+    if rg.offset <= p && p+w <= rg.offset + rg.length then
+      Ufind.find m.store rg.data
+    else raise Not_found
+  else r
+
+
 let rec lval (m: map) (lv: lval) : node =
   let h = host m (fst lv) in
   offset m h (snd lv)
 
 and host (m: map) (h: lhost) : node =
   match h with
-  | Var x -> Ufind.find m.store @@ Vmap.find x m.roots
+  | Var x -> cvar m x
   | Mem e ->
     match exp m e with
     | None -> raise Not_found
@@ -551,13 +586,7 @@ and offset (m: map) (r: node) (ofs: offset) : node =
   match ofs with
   | NoOffset -> Ufind.find m.store r
   | Field (fd, ofs) ->
-    if fd.fcomp.cstruct then
-      let _, rgs = cranges m r in
-      let (p,w) = Cil.fieldBitsOffset fd in
-      let rg = Ranges.find p rgs in
-      if rg.offset <= p && p+w <= rg.offset + rg.length then
-        offset m rg.data ofs
-      else raise Not_found
+    if fd.fcomp.cstruct then offset m (field m r fd) ofs
     else r
   | Index (_, ofs) ->
     let s, rgs = cranges m r in
@@ -577,3 +606,12 @@ and exp (m: map) (e: exp) : node option =
   | UnOp (_, _, _) | BinOp (_, _, _, _) -> None
 
 (* -------------------------------------------------------------------------- *)
+
+
+let eq_node (m: map) = Ufind.eq m.store
+
+let accesses (m : map) (r:node) =
+  let node = Ufind.get m.store r in
+  List.map Access.typeof @@ Access.Set.elements node.creads,
+  List.map Access.typeof @@ Access.Set.elements node.cwrites,
+  List.map Access.typeof @@ Access.Set.elements node.cshifts
diff --git a/src/plugins/region/memory.mli b/src/plugins/region/memory.mli
index e7679c176ebb9fb064217f3c9dcda0f27aac43d0..a9f9ac08fe8062cc57f147f265bf4bb01603728e 100644
--- a/src/plugins/region/memory.mli
+++ b/src/plugins/region/memory.mli
@@ -70,8 +70,10 @@ val node : map -> node -> node
 val nodes : map -> node list -> node list
 
 val iter : map -> (region -> unit) -> unit
+val iter_node : map -> (node -> unit) -> unit
 val region : map -> node -> region
 val regions : map -> region list
+val parents : map -> node -> node list
 
 val new_chunk : map -> ?size:int -> ?ptr:node -> ?ptrby:node -> unit -> node
 val add_root : map -> Cil_types.varinfo -> node
@@ -97,3 +99,11 @@ val cpointed_by : map -> node -> node list
 
 (** @raise Not_found *)
 val exp : map -> exp -> node option
+
+(** @raise Not_found *)
+val field : map -> node -> fieldinfo -> node
+val cvar : map -> varinfo -> node
+
+val eq_node : map -> node -> node -> bool
+
+val accesses : map -> node -> typ list * typ list * typ list