diff --git a/ivette/src/frama-c/kernel/Globals.tsx b/ivette/src/frama-c/kernel/Globals.tsx
index d40b73e253e2c67e5d6008b605c902d0f13504b1..7fb10e1ae010fcb0ff9a99303d517545366841b2 100644
--- a/ivette/src/frama-c/kernel/Globals.tsx
+++ b/ivette/src/frama-c/kernel/Globals.tsx
@@ -31,10 +31,12 @@ import { alpha } from 'dome/data/compare';
 import { Section, Item } from 'dome/frame/sidebars';
 import { Button } from 'dome/controls/buttons';
 import * as Toolbars from 'dome/frame/toolbars';
+import * as ArrayUtils from 'dome/data/arrays';
 
 import * as States from 'frama-c/states';
-import { functions, functionsData } from 'frama-c/kernel/api/ast';
+import * as Kernel from 'frama-c/kernel/api/ast';
 import { computationState } from 'frama-c/plugins/eva/api/general';
+import * as Eva from 'frama-c/plugins/eva/api/general';
 
 // --------------------------------------------------------------------------
 // --- Global Search Hints
@@ -51,7 +53,7 @@ function makeFunctionHint(fct: functionsData): Toolbars.Hint {
 
 async function lookupGlobals(pattern: string): Promise<Toolbars.Hint[]> {
   const lookup = pattern.toLowerCase();
-  const fcts = States.getSyncArray(functions).getArray();
+  const fcts = States.getSyncArray(Kernel.functions).getArray();
   return fcts.filter((fn) => (
     0 <= fn.name.toLowerCase().indexOf(lookup)
   )).map(makeFunctionHint);
@@ -96,13 +98,18 @@ function FctItem(props: FctItemProps): JSX.Element {
 // --- Globals Section(s)
 // --------------------------------------------------------------------------
 
+type functionsData =
+  Kernel.functionsData | (Kernel.functionsData & Eva.functionsData)
+
 export default function Globals(): JSX.Element {
 
   // Hooks
   const [selection, updateSelection] = States.useSelection();
-  const fcts = States.useSyncArray(functions).getArray().sort(
+  const kernelFcts = States.useSyncArray(Kernel.functions).getArray().sort(
     (f, g) => alpha(f.name, g.name),
   );
+  const evaFcts = States.useSyncArray(Eva.functions).getArray();
+  const fcts = ArrayUtils.mergeArraysByKey(kernelFcts, evaFcts);
   const { useFlipSettings } = Dome;
   const [stdlib, flipStdlib] =
     useFlipSettings('ivette.globals.stdlib', false);
@@ -132,7 +139,8 @@ export default function Globals(): JSX.Element {
       (stdlib || !fct.stdlib)
       && (builtin || !fct.builtin)
       && (undef || fct.defined)
-      && (!evaOnly || !evaComputed || (fct.eva_analyzed === true))
+      && (!evaOnly || !evaComputed ||
+        ('eva_analyzed' in fct && fct.eva_analyzed === true))
       && (!selected || !multipleSelectionActive || isSelected(fct));
     return visible || (!!current && fct.name === current);
   }
diff --git a/ivette/src/frama-c/kernel/api/ast/index.ts b/ivette/src/frama-c/kernel/api/ast/index.ts
index 70b14dd814e7cb57c693dff3a5a86b5515feed05..932488fecae57980244f4ec7f97e0d99a4db764a 100644
--- a/ivette/src/frama-c/kernel/api/ast/index.ts
+++ b/ivette/src/frama-c/kernel/api/ast/index.ts
@@ -367,8 +367,6 @@ export interface functionsData {
   stdlib?: boolean;
   /** Is the function a Frama-C builtin? */
   builtin?: boolean;
-  /** Has the function been analyzed by Eva */
-  eva_analyzed?: boolean;
   /** Source location */
   sloc: source;
 }
@@ -384,7 +382,6 @@ export const jFunctionsData: Json.Loose<functionsData> =
     defined: Json.jBoolean,
     stdlib: Json.jBoolean,
     builtin: Json.jBoolean,
-    eva_analyzed: Json.jBoolean,
     sloc: jSourceSafe,
   });
 
@@ -397,7 +394,7 @@ export const byFunctionsData: Compare.Order<functionsData> =
   Compare.byFields
     <{ key: Json.key<'#functions'>, name: string, signature: string,
        main?: boolean, defined?: boolean, stdlib?: boolean,
-       builtin?: boolean, eva_analyzed?: boolean, sloc: source }>({
+       builtin?: boolean, sloc: source }>({
     key: Compare.string,
     name: Compare.alpha,
     signature: Compare.string,
@@ -405,7 +402,6 @@ export const byFunctionsData: Compare.Order<functionsData> =
     defined: Compare.defined(Compare.boolean),
     stdlib: Compare.defined(Compare.boolean),
     builtin: Compare.defined(Compare.boolean),
-    eva_analyzed: Compare.defined(Compare.boolean),
     sloc: bySource,
   });
 
diff --git a/ivette/src/frama-c/plugins/eva/api/general/index.ts b/ivette/src/frama-c/plugins/eva/api/general/index.ts
index 3ed2ea6b595d436fd82035130a5f13647d828103..0cc4595adf33d3b1fd1d4afe1a6329010a34775d 100644
--- a/ivette/src/frama-c/plugins/eva/api/general/index.ts
+++ b/ivette/src/frama-c/plugins/eva/api/general/index.ts
@@ -123,6 +123,83 @@ export const getCallers: Server.GetRequest<
   [ Json.key<'#fct'>, Json.key<'#stmt'> ][]
   >= getCallers_internal;
 
+/** Data for array rows [`functions`](#functions)  */
+export interface functionsData {
+  /** Entry identifier. */
+  key: Json.key<'#functions'>;
+  /** Has the function been analyzed by Eva */
+  eva_analyzed?: boolean;
+}
+
+/** Loose decoder for `functionsData` */
+export const jFunctionsData: Json.Loose<functionsData> =
+  Json.jObject({
+    key: Json.jFail(Json.jKey<'#functions'>('#functions'),
+           '#functions expected'),
+    eva_analyzed: Json.jBoolean,
+  });
+
+/** Safe decoder for `functionsData` */
+export const jFunctionsDataSafe: Json.Safe<functionsData> =
+  Json.jFail(jFunctionsData,'FunctionsData expected');
+
+/** Natural order for `functionsData` */
+export const byFunctionsData: Compare.Order<functionsData> =
+  Compare.byFields
+    <{ key: Json.key<'#functions'>, eva_analyzed?: boolean }>({
+    key: Compare.string,
+    eva_analyzed: Compare.defined(Compare.boolean),
+  });
+
+/** Signal for array [`functions`](#functions)  */
+export const signalFunctions: Server.Signal = {
+  name: 'plugins.eva.general.signalFunctions',
+};
+
+const reloadFunctions_internal: Server.GetRequest<null,null> = {
+  kind: Server.RqKind.GET,
+  name:   'plugins.eva.general.reloadFunctions',
+  input:  Json.jNull,
+  output: Json.jNull,
+  signals: [],
+};
+/** Force full reload for array [`functions`](#functions)  */
+export const reloadFunctions: Server.GetRequest<null,null>= reloadFunctions_internal;
+
+const fetchFunctions_internal: Server.GetRequest<
+  number,
+  { pending: number, updated: functionsData[],
+    removed: Json.key<'#functions'>[], reload: boolean }
+  > = {
+  kind: Server.RqKind.GET,
+  name:   'plugins.eva.general.fetchFunctions',
+  input:  Json.jNumber,
+  output: Json.jObject({
+            pending: Json.jFail(Json.jNumber,'Number expected'),
+            updated: Json.jList(jFunctionsData),
+            removed: Json.jList(Json.jKey<'#functions'>('#functions')),
+            reload: Json.jFail(Json.jBoolean,'Boolean expected'),
+          }),
+  signals: [],
+};
+/** Data fetcher for array [`functions`](#functions)  */
+export const fetchFunctions: Server.GetRequest<
+  number,
+  { pending: number, updated: functionsData[],
+    removed: Json.key<'#functions'>[], reload: boolean }
+  >= fetchFunctions_internal;
+
+const functions_internal: State.Array<Json.key<'#functions'>,functionsData> = {
+  name: 'plugins.eva.general.functions',
+  getkey: ((d:functionsData) => d.key),
+  signal: signalFunctions,
+  fetch: fetchFunctions,
+  reload: reloadFunctions,
+  order: byFunctionsData,
+};
+/** AST Functions */
+export const functions: State.Array<Json.key<'#functions'>,functionsData> = functions_internal;
+
 /** Unreachable and non terminating statements. */
 export interface deadCode {
   /** List of unreachable statements. */
diff --git a/src/plugins/eva/api/general_requests.ml b/src/plugins/eva/api/general_requests.ml
index eb76164294fca8a88a3e39f3c1937a952a9308e1..09b052ace96ce3190cad0681fae8243a912b5787 100644
--- a/src/plugins/eva/api/general_requests.ml
+++ b/src/plugins/eva/api/general_requests.ml
@@ -71,10 +71,34 @@ let () = Request.register ~package
 
 (* ----- Functions ---------------------------------------------------------- *)
 
-let () =
-  Analysis.register_computation_hook
-    (fun _ -> States.reload Kernel_ast.Functions.array)
-
+module Functions =
+struct
+  let key kf = Printf.sprintf "kf#%d" (Kernel_function.get_id kf)
+
+  let iter f =
+    Globals.Functions.iter
+      (fun kf ->
+         let name = Kernel_function.get_name kf in
+         if not (Ast_info.is_frama_c_builtin name) then f kf)
+
+  let _array : kernel_function States.array =
+    let model = States.model () in
+
+    States.column model
+      ~name:"eva_analyzed"
+      ~descr:(Markdown.plain "Has the function been analyzed by Eva")
+      ~data:(module Data.Jbool)
+      ~default:false
+      ~get:Results.is_called;
+
+    States.register_array model
+      ~package ~key
+      ~name:"functions"
+      ~descr:(Markdown.plain "AST Functions")
+      ~iter
+      ~add_reload_hook:(fun f ->
+          Analysis.register_computation_hook (fun _ -> f () ))
+end
 
 (* ----- Dead code: unreachable and non-terminating statements -------------- *)
 
diff --git a/src/plugins/server/kernel_ast.ml b/src/plugins/server/kernel_ast.ml
index 9b0ee6e61e2565b834785548bda0bec8c4e89dd2..a50aeb4f09d790b283cb68bf813a6ca8b6b7ae71 100644
--- a/src/plugins/server/kernel_ast.ml
+++ b/src/plugins/server/kernel_ast.ml
@@ -508,9 +508,6 @@ struct
     let vi = Kernel_function.get_vi kf in
     Cil.is_in_libc vi.vattr
 
-  let is_eva_analyzed kf =
-    if Db.Value.is_computed () then !Db.Value.is_called kf else false
-
   let iter f =
     Globals.Functions.iter
       (fun kf ->
@@ -554,12 +551,6 @@ struct
         ~data:(module Data.Jbool)
         ~default:false
         ~get:is_builtin;
-      States.column model
-        ~name:"eva_analyzed"
-        ~descr:(Md.plain "Has the function been analyzed by Eva")
-        ~data:(module Data.Jbool)
-        ~default:false
-        ~get:is_eva_analyzed;
       States.column model
         ~name:"sloc"
         ~descr:(Md.plain "Source location")