diff --git a/ivette/src/dome/renderer/controls/gallery.json b/ivette/src/dome/renderer/controls/gallery.json
index 0dd269297ccd8edd04b9e7075a272b0ad0b03bba..f2da558a323bb611f7579cf52b4d8973d767c5fc 100644
--- a/ivette/src/dome/renderer/controls/gallery.json
+++ b/ivette/src/dome/renderer/controls/gallery.json
@@ -185,6 +185,11 @@
     "viewBox": "0 0 16 16",
     "path": "M16 6.204l-5.528-0.803-2.472-5.009-2.472 5.009-5.528 0.803 4 3.899-0.944 5.505 4.944-2.599 4.944 2.599-0.944-5.505 4-3.899z"
   },
+  "SPINNER": {
+    "section": "Signs",
+    "viewBox": "0 0 32 32",
+    "path": "M32 16c-0.040-2.089-0.493-4.172-1.331-6.077-0.834-1.906-2.046-3.633-3.533-5.060-1.486-1.428-3.248-2.557-5.156-3.302-1.906-0.748-3.956-1.105-5.981-1.061-2.025 0.040-4.042 0.48-5.885 1.292-1.845 0.809-3.517 1.983-4.898 3.424s-2.474 3.147-3.193 4.994c-0.722 1.846-1.067 3.829-1.023 5.79 0.040 1.961 0.468 3.911 1.254 5.694 0.784 1.784 1.921 3.401 3.316 4.736 1.394 1.336 3.046 2.391 4.832 3.085 1.785 0.697 3.701 1.028 5.598 0.985 1.897-0.040 3.78-0.455 5.502-1.216 1.723-0.759 3.285-1.859 4.574-3.208 1.29-1.348 2.308-2.945 2.977-4.67 0.407-1.046 0.684-2.137 0.829-3.244 0.039 0.002 0.078 0.004 0.118 0.004 1.105 0 2-0.895 2-2 0-0.056-0.003-0.112-0.007-0.167h0.007zM28.822 21.311c-0.733 1.663-1.796 3.169-3.099 4.412s-2.844 2.225-4.508 2.868c-1.663 0.646-3.447 0.952-5.215 0.909-1.769-0.041-3.519-0.429-5.119-1.14-1.602-0.708-3.053-1.734-4.25-2.991s-2.141-2.743-2.76-4.346c-0.621-1.603-0.913-3.319-0.871-5.024 0.041-1.705 0.417-3.388 1.102-4.928 0.683-1.541 1.672-2.937 2.883-4.088s2.642-2.058 4.184-2.652c1.542-0.596 3.192-0.875 4.832-0.833 1.641 0.041 3.257 0.404 4.736 1.064 1.48 0.658 2.82 1.609 3.926 2.774s1.975 2.54 2.543 4.021c0.57 1.481 0.837 3.064 0.794 4.641h0.007c-0.005 0.055-0.007 0.11-0.007 0.167 0 1.032 0.781 1.88 1.784 1.988-0.195 1.088-0.517 2.151-0.962 3.156z"
+  },
   "TRASH": {
     "section": "Desktop",
     "title": "Trash",
diff --git a/ivette/src/frama-c/kernel/Globals.tsx b/ivette/src/frama-c/kernel/Globals.tsx
index 819ee2b202dfe6d3f117795ddaf4d2815bce7d60..71b6a277da8e93d1f8d43ce467b592a7942d815c 100644
--- a/ivette/src/frama-c/kernel/Globals.tsx
+++ b/ivette/src/frama-c/kernel/Globals.tsx
@@ -211,7 +211,7 @@ type functionsData =
 
 type FctKey = Json.key<'#functions'>;
 
-function computeFcts(
+export function computeFcts(
   ker: States.ArrayProxy<FctKey, Ast.functionsData>,
   eva: States.ArrayProxy<FctKey, Eva.functionsData>,
 ): functionsData[] {
diff --git a/ivette/src/frama-c/plugins/eva/EvaDefinitions.tsx b/ivette/src/frama-c/plugins/eva/EvaDefinitions.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..6a4a7aaed321679e7681e158effaf7d673ac4529
--- /dev/null
+++ b/ivette/src/frama-c/plugins/eva/EvaDefinitions.tsx
@@ -0,0 +1,179 @@
+/* ************************************************************************ */
+/*                                                                          */
+/*   This file is part of Frama-C.                                          */
+/*                                                                          */
+/*   Copyright (C) 2007-2024                                                */
+/*     CEA (Commissariat à l'énergie atomique et aux énergies               */
+/*          alternatives)                                                   */
+/*                                                                          */
+/*   you can redistribute it and/or modify it under the terms of the GNU    */
+/*   Lesser General Public License as published by the Free Software        */
+/*   Foundation, version 2.1.                                               */
+/*                                                                          */
+/*   It 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.  See the          */
+/*   GNU Lesser General Public License for more details.                    */
+/*                                                                          */
+/*   See the GNU Lesser General Public License version 2.1                  */
+/*   for more details (enclosed in the file licenses/LGPLv2.1).             */
+/*                                                                          */
+/* ************************************************************************ */
+
+import * as Forms from 'dome/layout/forms';
+
+export type KeyVal<A> = {[key: string]: A}
+
+export interface buttonFieldInfo {
+  value: boolean,
+  label: string,
+}
+
+export type ButtonList = KeyVal<buttonFieldInfo>
+
+export interface OptionsButtonProps {
+  name: string,
+  label: string,
+  fieldState: Forms.FieldState<KeyVal<boolean>>,
+}
+
+export type RadioList = KeyVal<string>
+
+export interface RadioFieldListProps {
+  classeName?: string;
+  state: Forms.FieldState<string>;
+  values: RadioList;
+  fieldProps: Forms.GenericFieldProps;
+}
+
+export interface ButtonFieldListProps {
+  classeName?: string;
+  state: Forms.FieldState<KeyVal<boolean>>;
+  fieldProps: Forms.GenericFieldProps;
+}
+
+export type fieldsName =
+  "precision" |
+  "main" |
+  "libEntry" |
+  "domains" |
+  "iLevel" |
+  "WideningDelay" |
+  "ArrayPrecisionLevel" |
+  "LinearLevel" |
+  "EqualityCall" |
+  "OctagonCall" |
+  "sLevel" |
+  "MinLoopUnroll" |
+  "AutoLoopUnroll" |
+  "HistoryPartitioning" |
+  "SplitReturn" |
+  "AllocReturnsNull" |
+  "WarnPointerComparison"
+
+export interface EvaField {
+  label: string,
+  step?: number,
+  min?: number,
+  max?: number,
+  optionRadio?: KeyVal<string>,
+  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
+  state: Forms.FieldState<any>
+}
+
+export type EvaFormProps =  {[key in fieldsName]: EvaField};
+
+/* ************************************************************************ *
+ * Option Eva Forms
+ * ************************************************************************ */
+export const fieldsPrecisionDependent: fieldsName[] = [
+  "MinLoopUnroll",
+  "AutoLoopUnroll",
+  "WideningDelay",
+  "HistoryPartitioning",
+  "sLevel",
+  "iLevel",
+  "ArrayPrecisionLevel",
+  "LinearLevel",
+  "domains",
+  "SplitReturn",
+  "EqualityCall",
+  "OctagonCall"
+];
+
+export const fieldsAlwaysVisible:fieldsName[] = [
+  "precision",
+  "main",
+  "libEntry",
+  "domains",
+  "sLevel",
+  "iLevel",
+  "AutoLoopUnroll",
+  "SplitReturn",
+  "AllocReturnsNull",
+  "WarnPointerComparison",
+];
+
+export const formEvaDomains: KeyVal<boolean> = {
+  'equality': false,
+  'symbolic-locations': false,
+  'octagon': false,
+  'gauges': false,
+  'cvalue': false,
+};
+export const formEvaSplitReturn: KeyVal<string> = {
+  '': 'None',
+  'full': 'Full',
+  'auto': 'Auto'
+};
+
+export const formEvaPointerComparison: KeyVal<string> = {
+  '': 'None',
+  'pointer': 'Pointer',
+  'all': 'All'
+};
+
+export const formEvaEqualityCall: KeyVal<string> = {
+  'none': 'None',
+  'formals': 'Formals',
+  'all': 'All'
+};
+
+export const domainsToKeyVal = (value: string[]): KeyVal<boolean> => {
+  const domains = { ...formEvaDomains };
+  for (const domain of value) { domains[domain] = true; }
+  return domains;
+};
+
+export const KeyValToDomains = (value: KeyVal<boolean>):string[] => {
+  return Object.entries(value).reduce(function (acc: string[], cur) {
+    if(cur[1]) acc.push(cur[0]);
+    return acc;
+  }, []);
+};
+
+export function buttonListEquality(
+  a: KeyVal<boolean>, b: KeyVal<boolean>
+): boolean {
+  const _a = Object.entries(a);
+  const _b = Object.entries(b);
+
+  if(_a.length !== _b.length) return false;
+  for (const [aKey, aValue] of _a.values()) {
+    const bProperty = _b.find(([bkey, ]) => bkey === aKey);
+    if(bProperty === undefined) return false;
+
+    const [, bValue] = bProperty;
+    if(aValue !== bValue) return false;
+  }
+  return true;
+}
+
+export function domainsEquality(
+  a: string[], b: string[]
+): boolean {
+  return buttonListEquality(
+    domainsToKeyVal(a),
+    domainsToKeyVal(b)
+  );
+}
diff --git a/ivette/src/frama-c/plugins/eva/EvaSidebar.tsx b/ivette/src/frama-c/plugins/eva/EvaSidebar.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..8fd99f1dd9c1f89060648848f6daf776bcbd8922
--- /dev/null
+++ b/ivette/src/frama-c/plugins/eva/EvaSidebar.tsx
@@ -0,0 +1,163 @@
+/* ************************************************************************ */
+/*                                                                          */
+/*   This file is part of Frama-C.                                          */
+/*                                                                          */
+/*   Copyright (C) 2007-2024                                                */
+/*     CEA (Commissariat à l'énergie atomique et aux énergies               */
+/*          alternatives)                                                   */
+/*                                                                          */
+/*   you can redistribute it and/or modify it under the terms of the GNU    */
+/*   Lesser General Public License as published by the Free Software        */
+/*   Foundation, version 2.1.                                               */
+/*                                                                          */
+/*   It 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.  See the          */
+/*   GNU Lesser General Public License for more details.                    */
+/*                                                                          */
+/*   See the GNU Lesser General Public License version 2.1                  */
+/*   for more details (enclosed in the file licenses/LGPLv2.1).             */
+/*                                                                          */
+/* ************************************************************************ */
+
+import React from 'react';
+import * as Forms from 'dome/layout/forms';
+import * as Ivette from 'ivette';
+import { useServerField } from 'frama-c/states';
+import * as EVA from 'frama-c/plugins/eva/api/general';
+import * as EvaDef from 'frama-c/plugins/eva/EvaDefinitions';
+import { EvaFormOptions } from 'frama-c/plugins/eva/components/Form';
+import EvaTools from './components/Tools';
+
+
+export function EvaSideBar(): JSX.Element {
+  const remote = Forms.useController();
+
+  /* eslint-disable max-len */
+  const precision = Forms.useBuffer(remote, useServerField(EVA.precision, 0));
+  const main = Forms.useBuffer(remote, useServerField(EVA.main, ""));
+  const libEntry = Forms.useBuffer(remote, useServerField(EVA.libEntry, false));
+  const domains = Forms.useBuffer(remote, useServerField(EVA.Domains, ["cvalue"]));
+  const domainsFiltered = Forms.useFilter(
+    domains,
+    EvaDef.domainsToKeyVal,
+    EvaDef.KeyValToDomains,
+    EvaDef.formEvaDomains
+  );
+  const WideningDelay = Forms.useBuffer(remote, useServerField(EVA.WideningDelay, 0));
+  const ArrayPrecisionLevel = Forms.useBuffer(remote, useServerField(EVA.ArrayPrecisionLevel, 0));
+  const LinearLevel = Forms.useBuffer(remote, useServerField(EVA.LinearLevel, 0));
+  const EqualityCall = Forms.useBuffer(remote, useServerField(EVA.EqualityCall, "none"));
+  const OctagonCall = Forms.useBuffer(remote, useServerField(EVA.OctagonCall, false));
+  const sLevel = Forms.useBuffer(remote, useServerField(EVA.slevel, 0));
+  const iLevel = Forms.useBuffer(remote, useServerField(EVA.ilevel, 0));
+  const AutoLoopUnroll = Forms.useBuffer(remote, useServerField(EVA.AutoLoopUnroll, 0));
+  const MinLoopUnroll = Forms.useBuffer(remote, useServerField(EVA.MinLoopUnroll, 0));
+  const SplitReturn = Forms.useBuffer(remote, useServerField(EVA.SplitReturn, "none"));
+  const HistoryPartitioning = Forms.useBuffer(remote, useServerField(EVA.HistoryPartitioning, 0));
+  const AllocReturnsNull = Forms.useBuffer(remote, useServerField(EVA.AllocReturnsNull, false));
+  const WarnPointerComparison = Forms.useBuffer(remote, useServerField(EVA.WarnPointerComparison, "none"));
+  /* eslint-enable max-len */
+
+  const evaFields = {
+    "precision": {
+      label: "Precision",
+      step: 1, min: -1, max: 11,
+      state: precision
+    },
+    "main": {
+      label: "Main",
+      state: main
+    },
+    "libEntry": {
+      label: "LibEntry",
+      state: libEntry
+    },
+    "domains": {
+      label: "Domains",
+      state: domainsFiltered
+    },
+    "sLevel": {
+      label: "Slevel",
+      step: 100, min: 0, max: 5000,
+      state: sLevel
+    },
+    "iLevel": {
+      label: "Ilevel",
+      step: 10, min: 0, max: 256,
+      state: iLevel
+    },
+    "AutoLoopUnroll": {
+      label: "Auto loop unroll",
+      step: 50, min: 0, max: 1024,
+      state: AutoLoopUnroll
+    },
+    "SplitReturn": {
+      label: "Split return",
+      optionRadio: EvaDef.formEvaSplitReturn,
+      state: SplitReturn
+    },
+    "AllocReturnsNull": {
+      label: "Alloc returns null",
+      state: AllocReturnsNull
+    },
+    "WarnPointerComparison": {
+      label: "Warn pointer comparison",
+      optionRadio: EvaDef.formEvaPointerComparison,
+      state: WarnPointerComparison
+    },
+    "MinLoopUnroll": {
+      label: "Min loop unroll",
+      step: 1, min: 0, max: 4,
+      state: MinLoopUnroll
+    },
+    "WideningDelay": {
+      label: "Widening delay",
+      step: 1, min: 1, max: 6,
+      state: WideningDelay
+    },
+    "HistoryPartitioning": {
+      label: "History partitioning",
+      step: 1, min: 0, max: 2,
+      state: HistoryPartitioning
+    },
+    "ArrayPrecisionLevel": {
+      label: "PLevel",
+      step: 100, min: 0, max: 5000,
+      state: ArrayPrecisionLevel
+    },
+    "LinearLevel": {
+      label: "Linear level",
+      step: 5, min: 0, max: 220,
+      state: LinearLevel
+    },
+    "EqualityCall": {
+      label: "Equality call",
+      optionRadio: EvaDef.formEvaEqualityCall,
+      state: EqualityCall
+    },
+    "OctagonCall": {
+      label: "Octagon call",
+      state: OctagonCall
+    },
+  };
+
+  return (
+    <>
+      <EvaTools
+        remote={remote}
+        iconSize={18}
+      />
+      <EvaFormOptions
+        fields={evaFields}
+      />
+    </>
+  );
+}
+
+Ivette.registerSidebar({
+  id: 'frama-c.plugins.eva_sidebar',
+  label: 'EVA',
+  title: 'Eva Sidebar',
+  children: <EvaSideBar />,
+});
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 c37d5121b0b153e16622f7c4a2a01e83b54d3c20..3fa6e0e86bc025c8e8e05475ba9e9ad8c75cb4f6 100644
--- a/ivette/src/frama-c/plugins/eva/api/general/index.ts
+++ b/ivette/src/frama-c/plugins/eva/api/general/index.ts
@@ -42,6 +42,8 @@ import { byDecl } from 'frama-c/kernel/api/ast';
 //@ts-ignore
 import { byMarker } from 'frama-c/kernel/api/ast';
 //@ts-ignore
+import { bySource } from 'frama-c/kernel/api/ast';
+//@ts-ignore
 import { decl } from 'frama-c/kernel/api/ast';
 //@ts-ignore
 import { declDefault } from 'frama-c/kernel/api/ast';
@@ -50,10 +52,16 @@ import { jDecl } from 'frama-c/kernel/api/ast';
 //@ts-ignore
 import { jMarker } from 'frama-c/kernel/api/ast';
 //@ts-ignore
+import { jSource } from 'frama-c/kernel/api/ast';
+//@ts-ignore
 import { marker } from 'frama-c/kernel/api/ast';
 //@ts-ignore
 import { markerDefault } from 'frama-c/kernel/api/ast';
 //@ts-ignore
+import { source } from 'frama-c/kernel/api/ast';
+//@ts-ignore
+import { sourceDefault } from 'frama-c/kernel/api/ast';
+//@ts-ignore
 import { byTag } from 'frama-c/kernel/api/data';
 //@ts-ignore
 import { jTag } from 'frama-c/kernel/api/data';
@@ -760,4 +768,663 @@ export const getStates: Server.GetRequest<
   [ string, string, string ][]
   >= getStates_internal;
 
+const getCurrentLoc_internal: Server.GetRequest<null,source> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getCurrentLoc',
+  input: Json.jNull,
+  output: jSource,
+  fallback: sourceDefault,
+  signals: [],
+};
+/** Get current location */
+export const getCurrentLoc: Server.GetRequest<null,source>= getCurrentLoc_internal;
+
+/** Signal for state [`eva`](#eva)  */
+export const signalEva: Server.Signal = {
+  name: 'plugins.eva.general.signalEva',
+};
+
+const getEva_internal: Server.GetRequest<null,boolean> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getEva',
+  input: Json.jNull,
+  output: Json.jBoolean,
+  fallback: false,
+  signals: [],
+};
+/** Getter for state [`eva`](#eva)  */
+export const getEva: Server.GetRequest<null,boolean>= getEva_internal;
+
+const setEva_internal: Server.SetRequest<boolean,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setEva',
+  input: Json.jBoolean,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`eva`](#eva)  */
+export const setEva: Server.SetRequest<boolean,null>= setEva_internal;
+
+const eva_internal: State.State<boolean> = {
+  name: 'plugins.eva.general.eva',
+  signal: signalEva,
+  getter: getEva,
+  setter: setEva,
+};
+/** Eva enabled */
+export const eva: State.State<boolean> = eva_internal;
+
+/** Signal for state [`precision`](#precision)  */
+export const signalPrecision: Server.Signal = {
+  name: 'plugins.eva.general.signalPrecision',
+};
+
+const getPrecision_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getPrecision',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`precision`](#precision)  */
+export const getPrecision: Server.GetRequest<null,number>= getPrecision_internal;
+
+const setPrecision_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setPrecision',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`precision`](#precision)  */
+export const setPrecision: Server.SetRequest<number,null>= setPrecision_internal;
+
+const precision_internal: State.State<number> = {
+  name: 'plugins.eva.general.precision',
+  signal: signalPrecision,
+  getter: getPrecision,
+  setter: setPrecision,
+};
+/** Precision value */
+export const precision: State.State<number> = precision_internal;
+
+/** Signal for state [`slevel`](#slevel)  */
+export const signalSlevel: Server.Signal = {
+  name: 'plugins.eva.general.signalSlevel',
+};
+
+const getSlevel_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getSlevel',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`slevel`](#slevel)  */
+export const getSlevel: Server.GetRequest<null,number>= getSlevel_internal;
+
+const setSlevel_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setSlevel',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`slevel`](#slevel)  */
+export const setSlevel: Server.SetRequest<number,null>= setSlevel_internal;
+
+const slevel_internal: State.State<number> = {
+  name: 'plugins.eva.general.slevel',
+  signal: signalSlevel,
+  getter: getSlevel,
+  setter: setSlevel,
+};
+/** slevel value */
+export const slevel: State.State<number> = slevel_internal;
+
+/** Signal for state [`main`](#main)  */
+export const signalMain: Server.Signal = {
+  name: 'plugins.eva.general.signalMain',
+};
+
+const getMain_internal: Server.GetRequest<null,string> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getMain',
+  input: Json.jNull,
+  output: Json.jString,
+  fallback: '',
+  signals: [],
+};
+/** Getter for state [`main`](#main)  */
+export const getMain: Server.GetRequest<null,string>= getMain_internal;
+
+const setMain_internal: Server.SetRequest<string,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setMain',
+  input: Json.jString,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`main`](#main)  */
+export const setMain: Server.SetRequest<string,null>= setMain_internal;
+
+const main_internal: State.State<string> = {
+  name: 'plugins.eva.general.main',
+  signal: signalMain,
+  getter: getMain,
+  setter: setMain,
+};
+/** main function */
+export const main: State.State<string> = main_internal;
+
+/** Signal for state [`libEntry`](#libentry)  */
+export const signalLibEntry: Server.Signal = {
+  name: 'plugins.eva.general.signalLibEntry',
+};
+
+const getLibEntry_internal: Server.GetRequest<null,boolean> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getLibEntry',
+  input: Json.jNull,
+  output: Json.jBoolean,
+  fallback: false,
+  signals: [],
+};
+/** Getter for state [`libEntry`](#libentry)  */
+export const getLibEntry: Server.GetRequest<null,boolean>= getLibEntry_internal;
+
+const setLibEntry_internal: Server.SetRequest<boolean,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setLibEntry',
+  input: Json.jBoolean,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`libEntry`](#libentry)  */
+export const setLibEntry: Server.SetRequest<boolean,null>= setLibEntry_internal;
+
+const libEntry_internal: State.State<boolean> = {
+  name: 'plugins.eva.general.libEntry',
+  signal: signalLibEntry,
+  getter: getLibEntry,
+  setter: setLibEntry,
+};
+/** slevel value */
+export const libEntry: State.State<boolean> = libEntry_internal;
+
+/** Signal for state [`Domains`](#domains)  */
+export const signalDomains: Server.Signal = {
+  name: 'plugins.eva.general.signalDomains',
+};
+
+const getDomains_internal: Server.GetRequest<null,string[]> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getDomains',
+  input: Json.jNull,
+  output: Json.jArray(Json.jString),
+  fallback: [],
+  signals: [],
+};
+/** Getter for state [`Domains`](#domains)  */
+export const getDomains: Server.GetRequest<null,string[]>= getDomains_internal;
+
+const setDomains_internal: Server.SetRequest<string[],null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setDomains',
+  input: Json.jArray(Json.jString),
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`Domains`](#domains)  */
+export const setDomains: Server.SetRequest<string[],null>= setDomains_internal;
+
+const Domains_internal: State.State<string[]> = {
+  name: 'plugins.eva.general.Domains',
+  signal: signalDomains,
+  getter: getDomains,
+  setter: setDomains,
+};
+/** domains value */
+export const Domains: State.State<string[]> = Domains_internal;
+
+/** Signal for state [`ilevel`](#ilevel)  */
+export const signalIlevel: Server.Signal = {
+  name: 'plugins.eva.general.signalIlevel',
+};
+
+const getIlevel_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getIlevel',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`ilevel`](#ilevel)  */
+export const getIlevel: Server.GetRequest<null,number>= getIlevel_internal;
+
+const setIlevel_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setIlevel',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`ilevel`](#ilevel)  */
+export const setIlevel: Server.SetRequest<number,null>= setIlevel_internal;
+
+const ilevel_internal: State.State<number> = {
+  name: 'plugins.eva.general.ilevel',
+  signal: signalIlevel,
+  getter: getIlevel,
+  setter: setIlevel,
+};
+/** ilevel value */
+export const ilevel: State.State<number> = ilevel_internal;
+
+/** Signal for state [`MinLoopUnroll`](#minloopunroll)  */
+export const signalMinLoopUnroll: Server.Signal = {
+  name: 'plugins.eva.general.signalMinLoopUnroll',
+};
+
+const getMinLoopUnroll_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getMinLoopUnroll',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`MinLoopUnroll`](#minloopunroll)  */
+export const getMinLoopUnroll: Server.GetRequest<null,number>= getMinLoopUnroll_internal;
+
+const setMinLoopUnroll_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setMinLoopUnroll',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`MinLoopUnroll`](#minloopunroll)  */
+export const setMinLoopUnroll: Server.SetRequest<number,null>= setMinLoopUnroll_internal;
+
+const MinLoopUnroll_internal: State.State<number> = {
+  name: 'plugins.eva.general.MinLoopUnroll',
+  signal: signalMinLoopUnroll,
+  getter: getMinLoopUnroll,
+  setter: setMinLoopUnroll,
+};
+/** Min loop unroll value */
+export const MinLoopUnroll: State.State<number> = MinLoopUnroll_internal;
+
+/** Signal for state [`AutoLoopUnroll`](#autoloopunroll)  */
+export const signalAutoLoopUnroll: Server.Signal = {
+  name: 'plugins.eva.general.signalAutoLoopUnroll',
+};
+
+const getAutoLoopUnroll_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getAutoLoopUnroll',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`AutoLoopUnroll`](#autoloopunroll)  */
+export const getAutoLoopUnroll: Server.GetRequest<null,number>= getAutoLoopUnroll_internal;
+
+const setAutoLoopUnroll_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setAutoLoopUnroll',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`AutoLoopUnroll`](#autoloopunroll)  */
+export const setAutoLoopUnroll: Server.SetRequest<number,null>= setAutoLoopUnroll_internal;
+
+const AutoLoopUnroll_internal: State.State<number> = {
+  name: 'plugins.eva.general.AutoLoopUnroll',
+  signal: signalAutoLoopUnroll,
+  getter: getAutoLoopUnroll,
+  setter: setAutoLoopUnroll,
+};
+/** Auto loop unroll value */
+export const AutoLoopUnroll: State.State<number> = AutoLoopUnroll_internal;
+
+/** Signal for state [`WideningDelay`](#wideningdelay)  */
+export const signalWideningDelay: Server.Signal = {
+  name: 'plugins.eva.general.signalWideningDelay',
+};
+
+const getWideningDelay_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getWideningDelay',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`WideningDelay`](#wideningdelay)  */
+export const getWideningDelay: Server.GetRequest<null,number>= getWideningDelay_internal;
+
+const setWideningDelay_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setWideningDelay',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`WideningDelay`](#wideningdelay)  */
+export const setWideningDelay: Server.SetRequest<number,null>= setWideningDelay_internal;
+
+const WideningDelay_internal: State.State<number> = {
+  name: 'plugins.eva.general.WideningDelay',
+  signal: signalWideningDelay,
+  getter: getWideningDelay,
+  setter: setWideningDelay,
+};
+/** Widening delay */
+export const WideningDelay: State.State<number> = WideningDelay_internal;
+
+/** Signal for state [`HistoryPartitioning`](#historypartitioning)  */
+export const signalHistoryPartitioning: Server.Signal = {
+  name: 'plugins.eva.general.signalHistoryPartitioning',
+};
+
+const getHistoryPartitioning_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getHistoryPartitioning',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`HistoryPartitioning`](#historypartitioning)  */
+export const getHistoryPartitioning: Server.GetRequest<null,number>= getHistoryPartitioning_internal;
+
+const setHistoryPartitioning_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setHistoryPartitioning',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`HistoryPartitioning`](#historypartitioning)  */
+export const setHistoryPartitioning: Server.SetRequest<number,null>= setHistoryPartitioning_internal;
+
+const HistoryPartitioning_internal: State.State<number> = {
+  name: 'plugins.eva.general.HistoryPartitioning',
+  signal: signalHistoryPartitioning,
+  getter: getHistoryPartitioning,
+  setter: setHistoryPartitioning,
+};
+/** History partitioning */
+export const HistoryPartitioning: State.State<number> = HistoryPartitioning_internal;
+
+/** Signal for state [`ArrayPrecisionLevel`](#arrayprecisionlevel)  */
+export const signalArrayPrecisionLevel: Server.Signal = {
+  name: 'plugins.eva.general.signalArrayPrecisionLevel',
+};
+
+const getArrayPrecisionLevel_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getArrayPrecisionLevel',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`ArrayPrecisionLevel`](#arrayprecisionlevel)  */
+export const getArrayPrecisionLevel: Server.GetRequest<null,number>= getArrayPrecisionLevel_internal;
+
+const setArrayPrecisionLevel_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setArrayPrecisionLevel',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`ArrayPrecisionLevel`](#arrayprecisionlevel)  */
+export const setArrayPrecisionLevel: Server.SetRequest<number,null>= setArrayPrecisionLevel_internal;
+
+const ArrayPrecisionLevel_internal: State.State<number> = {
+  name: 'plugins.eva.general.ArrayPrecisionLevel',
+  signal: signalArrayPrecisionLevel,
+  getter: getArrayPrecisionLevel,
+  setter: setArrayPrecisionLevel,
+};
+/** Array precision level */
+export const ArrayPrecisionLevel: State.State<number> = ArrayPrecisionLevel_internal;
+
+/** Signal for state [`LinearLevel`](#linearlevel)  */
+export const signalLinearLevel: Server.Signal = {
+  name: 'plugins.eva.general.signalLinearLevel',
+};
+
+const getLinearLevel_internal: Server.GetRequest<null,number> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getLinearLevel',
+  input: Json.jNull,
+  output: Json.jNumber,
+  fallback: 0,
+  signals: [],
+};
+/** Getter for state [`LinearLevel`](#linearlevel)  */
+export const getLinearLevel: Server.GetRequest<null,number>= getLinearLevel_internal;
+
+const setLinearLevel_internal: Server.SetRequest<number,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setLinearLevel',
+  input: Json.jNumber,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`LinearLevel`](#linearlevel)  */
+export const setLinearLevel: Server.SetRequest<number,null>= setLinearLevel_internal;
+
+const LinearLevel_internal: State.State<number> = {
+  name: 'plugins.eva.general.LinearLevel',
+  signal: signalLinearLevel,
+  getter: getLinearLevel,
+  setter: setLinearLevel,
+};
+/** Linear level */
+export const LinearLevel: State.State<number> = LinearLevel_internal;
+
+/** Signal for state [`EqualityCall`](#equalitycall)  */
+export const signalEqualityCall: Server.Signal = {
+  name: 'plugins.eva.general.signalEqualityCall',
+};
+
+const getEqualityCall_internal: Server.GetRequest<null,string> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getEqualityCall',
+  input: Json.jNull,
+  output: Json.jString,
+  fallback: '',
+  signals: [],
+};
+/** Getter for state [`EqualityCall`](#equalitycall)  */
+export const getEqualityCall: Server.GetRequest<null,string>= getEqualityCall_internal;
+
+const setEqualityCall_internal: Server.SetRequest<string,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setEqualityCall',
+  input: Json.jString,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`EqualityCall`](#equalitycall)  */
+export const setEqualityCall: Server.SetRequest<string,null>= setEqualityCall_internal;
+
+const EqualityCall_internal: State.State<string> = {
+  name: 'plugins.eva.general.EqualityCall',
+  signal: signalEqualityCall,
+  getter: getEqualityCall,
+  setter: setEqualityCall,
+};
+/** Equality call */
+export const EqualityCall: State.State<string> = EqualityCall_internal;
+
+/** Signal for state [`OctagonCall`](#octagoncall)  */
+export const signalOctagonCall: Server.Signal = {
+  name: 'plugins.eva.general.signalOctagonCall',
+};
+
+const getOctagonCall_internal: Server.GetRequest<null,boolean> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getOctagonCall',
+  input: Json.jNull,
+  output: Json.jBoolean,
+  fallback: false,
+  signals: [],
+};
+/** Getter for state [`OctagonCall`](#octagoncall)  */
+export const getOctagonCall: Server.GetRequest<null,boolean>= getOctagonCall_internal;
+
+const setOctagonCall_internal: Server.SetRequest<boolean,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setOctagonCall',
+  input: Json.jBoolean,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`OctagonCall`](#octagoncall)  */
+export const setOctagonCall: Server.SetRequest<boolean,null>= setOctagonCall_internal;
+
+const OctagonCall_internal: State.State<boolean> = {
+  name: 'plugins.eva.general.OctagonCall',
+  signal: signalOctagonCall,
+  getter: getOctagonCall,
+  setter: setOctagonCall,
+};
+/** Octagon call */
+export const OctagonCall: State.State<boolean> = OctagonCall_internal;
+
+/** Signal for state [`SplitReturn`](#splitreturn)  */
+export const signalSplitReturn: Server.Signal = {
+  name: 'plugins.eva.general.signalSplitReturn',
+};
+
+const getSplitReturn_internal: Server.GetRequest<null,string> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getSplitReturn',
+  input: Json.jNull,
+  output: Json.jString,
+  fallback: '',
+  signals: [],
+};
+/** Getter for state [`SplitReturn`](#splitreturn)  */
+export const getSplitReturn: Server.GetRequest<null,string>= getSplitReturn_internal;
+
+const setSplitReturn_internal: Server.SetRequest<string,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setSplitReturn',
+  input: Json.jString,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`SplitReturn`](#splitreturn)  */
+export const setSplitReturn: Server.SetRequest<string,null>= setSplitReturn_internal;
+
+const SplitReturn_internal: State.State<string> = {
+  name: 'plugins.eva.general.SplitReturn',
+  signal: signalSplitReturn,
+  getter: getSplitReturn,
+  setter: setSplitReturn,
+};
+/** Split return value */
+export const SplitReturn: State.State<string> = SplitReturn_internal;
+
+/** Signal for state [`AllocReturnsNull`](#allocreturnsnull)  */
+export const signalAllocReturnsNull: Server.Signal = {
+  name: 'plugins.eva.general.signalAllocReturnsNull',
+};
+
+const getAllocReturnsNull_internal: Server.GetRequest<null,boolean> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getAllocReturnsNull',
+  input: Json.jNull,
+  output: Json.jBoolean,
+  fallback: false,
+  signals: [],
+};
+/** Getter for state [`AllocReturnsNull`](#allocreturnsnull)  */
+export const getAllocReturnsNull: Server.GetRequest<null,boolean>= getAllocReturnsNull_internal;
+
+const setAllocReturnsNull_internal: Server.SetRequest<boolean,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setAllocReturnsNull',
+  input: Json.jBoolean,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`AllocReturnsNull`](#allocreturnsnull)  */
+export const setAllocReturnsNull: Server.SetRequest<boolean,null>= setAllocReturnsNull_internal;
+
+const AllocReturnsNull_internal: State.State<boolean> = {
+  name: 'plugins.eva.general.AllocReturnsNull',
+  signal: signalAllocReturnsNull,
+  getter: getAllocReturnsNull,
+  setter: setAllocReturnsNull,
+};
+/** AllocReturnsNull value */
+export const AllocReturnsNull: State.State<boolean> = AllocReturnsNull_internal;
+
+/** Signal for state [`WarnPointerComparison`](#warnpointercomparison)  */
+export const signalWarnPointerComparison: Server.Signal = {
+  name: 'plugins.eva.general.signalWarnPointerComparison',
+};
+
+const getWarnPointerComparison_internal: Server.GetRequest<null,string> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.getWarnPointerComparison',
+  input: Json.jNull,
+  output: Json.jString,
+  fallback: '',
+  signals: [],
+};
+/** Getter for state [`WarnPointerComparison`](#warnpointercomparison)  */
+export const getWarnPointerComparison: Server.GetRequest<null,string>= getWarnPointerComparison_internal;
+
+const setWarnPointerComparison_internal: Server.SetRequest<string,null> = {
+  kind: Server.RqKind.SET,
+  name: 'plugins.eva.general.setWarnPointerComparison',
+  input: Json.jString,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Setter for state [`WarnPointerComparison`](#warnpointercomparison)  */
+export const setWarnPointerComparison: Server.SetRequest<string,null>= setWarnPointerComparison_internal;
+
+const WarnPointerComparison_internal: State.State<string> = {
+  name: 'plugins.eva.general.WarnPointerComparison',
+  signal: signalWarnPointerComparison,
+  getter: getWarnPointerComparison,
+  setter: setWarnPointerComparison,
+};
+/** Warn pointer comparison value */
+export const WarnPointerComparison: State.State<string> = WarnPointerComparison_internal;
+
 /* ------------------------------------- */
diff --git a/ivette/src/frama-c/plugins/eva/components/Form.tsx b/ivette/src/frama-c/plugins/eva/components/Form.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..88bf5fe38b3a91133b573db6432737b354928f63
--- /dev/null
+++ b/ivette/src/frama-c/plugins/eva/components/Form.tsx
@@ -0,0 +1,289 @@
+/* ************************************************************************ */
+/*                                                                          */
+/*   This file is part of Frama-C.                                          */
+/*                                                                          */
+/*   Copyright (C) 2007-2024                                                */
+/*     CEA (Commissariat à l'énergie atomique et aux énergies               */
+/*          alternatives)                                                   */
+/*                                                                          */
+/*   you can redistribute it and/or modify it under the terms of the GNU    */
+/*   Lesser General Public License as published by the Free Software        */
+/*   Foundation, version 2.1.                                               */
+/*                                                                          */
+/*   It 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.  See the          */
+/*   GNU Lesser General Public License for more details.                    */
+/*                                                                          */
+/*   See the GNU Lesser General Public License version 2.1                  */
+/*   for more details (enclosed in the file licenses/LGPLv2.1).             */
+/*                                                                          */
+/* ************************************************************************ */
+
+// --------------------------------------------------------------------------
+// --- Sidebar Selector
+// --------------------------------------------------------------------------
+
+import React from 'react';
+import * as Forms from 'dome/layout/forms';
+import { classes } from 'dome/misc/utils';
+import * as Globals from 'frama-c/kernel/Globals';
+import * as States from 'frama-c/states';
+import * as Ast from 'frama-c/kernel/api/ast';
+import * as Eva from 'frama-c/plugins/eva/api/general';
+import * as EvaDef from 'frama-c/plugins/eva/EvaDefinitions';
+
+/* -------------------------------------------------------------------------- */
+/* --- Eva form section                                                   --- */
+/* -------------------------------------------------------------------------- */
+function Section(p: Forms.SectionProps): JSX.Element {
+  const settings = `ivette.eva.option.${p.label}`;
+  return (
+    <Forms.Section
+      label={p.label}
+      unfold
+      error={p.error}
+      settings={settings}
+    >
+      {p.children}
+    </Forms.Section>
+  );
+}
+
+/* -------------------------------------------------------------------------- */
+/* --- Button/Radio list                                                  --- */
+/* -------------------------------------------------------------------------- */
+function OptionsButton(props: EvaDef.OptionsButtonProps): JSX.Element {
+  const { name, label, fieldState } = props;
+  const state = Forms.useProperty(fieldState, name);
+  return <Forms.ButtonField label={label} state={state} />;
+}
+
+function ButtonFieldList(
+  props: EvaDef.ButtonFieldListProps
+): JSX.Element {
+  const { classeName, state, fieldProps } = props;
+  const { value } = state;
+
+  const htmlButtonList = Object.keys(value)
+    .map((p) => <OptionsButton
+      key={p}
+      name={p}
+      label={p}
+      fieldState={state}
+    />);
+  return (
+    <Forms.Field  {...fieldProps}>
+      <div className={classeName}></div>
+      {htmlButtonList}
+    </Forms.Field>
+  );
+}
+
+export function RadioFieldList(
+  props: EvaDef.RadioFieldListProps
+): JSX.Element {
+  const { classeName, state, values, fieldProps } = props;
+  const htmlRadioList = Object.entries(values)
+    .map(([k, v]) => <Forms.RadioField
+      key={k}
+      label={v}
+      value={k}
+      state={state}
+    />);
+  return (
+    <Forms.Field  {...fieldProps}>
+      <div className={classeName}></div>
+      {htmlRadioList}
+    </Forms.Field>
+  );
+}
+
+
+/** ***************************************************************************
+*
+******************************************************************************/
+interface EvaFormOptionsProps {
+  fields: EvaDef.EvaFormProps;
+}
+
+function getActions<A>(
+  state: Forms.FieldState<A>,
+  equal?: (a: A, b: A) => boolean,
+): JSX.Element | undefined {
+  if(!state) return undefined;
+  return (
+    <Forms.Actions>
+      <Forms.ResetButton
+        state={state}
+        title="Reset"
+        equal={equal}
+      />
+      <Forms.CommitButton
+        state={state}
+        title="Commit"
+        equal={equal}
+      />
+    </Forms.Actions>
+  );
+}
+
+export function EvaFormOptions(
+  props: EvaFormOptionsProps
+): JSX.Element {
+  const { fields } = props;
+
+  const showAllFields = Forms.useState(false);
+
+  const ker = States.useSyncArrayProxy(Ast.functions);
+  const eva = States.useSyncArrayProxy(Eva.functions);
+  const fctsList = React.useMemo(() =>
+    Globals.computeFcts(ker, eva)
+      .filter((fct) => !fct.extern && !fct.stdlib && !fct.builtin)
+      .sort((a, b) => a.name.localeCompare(b.name)),
+    [ker, eva]
+  );
+
+  function isNoAlwaysVisibleFieldsStable(): boolean {
+    let disable = false;
+    for (const [name, evaField] of Object.entries(fields)) {
+      if (EvaDef.fieldsAlwaysVisible.includes(name as EvaDef.fieldsName)) {
+        continue;
+      }
+      if (!Forms.isStable(evaField.state)) {
+        disable = true;
+        break;
+      }
+    }
+    return disable;
+  }
+
+  function getClasses<A>(
+    state: Forms.FieldState<A>,
+    name: EvaDef.fieldsName
+  ): string | undefined {
+    const isDepPrecision = EvaDef.fieldsPrecisionDependent.includes(name);
+    const notVisible =
+      !showAllFields.value &&
+      !EvaDef.fieldsAlwaysVisible.includes(name);
+    return classes(
+      !Forms.isStable(state) && "eva-field-modified",
+      isDepPrecision && "eva-precision-dep",
+      notVisible ? "hidden-field" : "visible-field"
+    );
+  }
+
+  function getSpinnerField(name: EvaDef.fieldsName): JSX.Element {
+    const field = fields[name];
+    const state = field.state;
+    return (
+    <Forms.SpinnerField
+      label={field.label}
+      step={field.step}
+      min={field.min as number}
+      max={field.max as number}
+      state={field.state as Forms.FieldState<number | undefined>}
+      className={getClasses(state, name)}
+      actions={getActions(state)}
+      />
+    );
+  }
+
+  function getRadioField(name: EvaDef.fieldsName): JSX.Element {
+    const field = fields[name];
+    const state = field.state;
+    return (
+      <RadioFieldList
+        fieldProps={{
+          label: field.label,
+          actions: getActions(state)
+        }}
+        classeName={getClasses(state, name)}
+        values={field.optionRadio as EvaDef.RadioList}
+        state={field.state}
+        />
+    );
+  }
+
+  function getBooleanField(name: EvaDef.fieldsName): JSX.Element {
+    const field = fields[name];
+    const state = field.state;
+    return (
+      <Forms.Field
+        label={field.label}
+        actions={getActions(state)}
+      >
+        <div className={getClasses(state, "libEntry")} />
+        <Forms.ButtonField
+          label={state.value ? "Enabled" : "disabled"}
+          state={state}
+        />
+      </Forms.Field>
+    );
+  }
+
+  const mainField =
+  <Forms.SelectField
+    label="Eva main"
+    state={fields["main"].state as Forms.FieldState<string | undefined>}
+    actions={getActions(fields["main"].state)}
+  >
+    {
+      fctsList.map((f) => <option
+          key={f.key} id={f.key} value={f.name}
+          className={getClasses(fields["main"].state, "main")}
+        >{f.name}</option>
+      )
+    }
+  </Forms.SelectField>;
+
+  const domainsField =
+  <ButtonFieldList
+    fieldProps={{
+      label: "Domains",
+      actions: getActions(fields["domains"].state, EvaDef.buttonListEquality)
+    }}
+    classeName={getClasses(fields["domains"].state, "domains")}
+    state={fields["domains"].state}
+    />;
+
+  return (
+    <Forms.SidebarForm className="eva-form">
+      <Forms.CheckboxField
+        label={"show all fields"}
+        title=
+          "disabled if it checked and if the fields to be hidden are not stable"
+        state={showAllFields}
+        disabled={isNoAlwaysVisibleFieldsStable()}
+      />
+
+      {getSpinnerField("precision")}
+      {mainField}
+      {getBooleanField("libEntry")}
+
+      <Section label="Abstract interpretation" >
+          {domainsField}
+          {getSpinnerField("iLevel")}
+          {getSpinnerField("WideningDelay")}
+          {getSpinnerField("ArrayPrecisionLevel")}
+          {getSpinnerField("LinearLevel")}
+          {getRadioField("EqualityCall")}
+          {getBooleanField("OctagonCall")}
+      </Section>
+
+      <Section label="State partitioning" >
+          {getSpinnerField("sLevel")}
+          {getSpinnerField("MinLoopUnroll")}
+          {getSpinnerField("AutoLoopUnroll")}
+          {getSpinnerField("HistoryPartitioning")}
+          {getRadioField("SplitReturn")}
+      </Section>
+
+      <Section label="Message" >
+        {getBooleanField("AllocReturnsNull")}
+        {getRadioField("WarnPointerComparison")}
+      </Section>
+
+    </Forms.SidebarForm>
+  );
+}
diff --git a/ivette/src/frama-c/plugins/eva/components/Tools.tsx b/ivette/src/frama-c/plugins/eva/components/Tools.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b40233e6dec283d25796be82e76188dd37d8bf46
--- /dev/null
+++ b/ivette/src/frama-c/plugins/eva/components/Tools.tsx
@@ -0,0 +1,114 @@
+/* ************************************************************************ */
+/*                                                                          */
+/*   This file is part of Frama-C.                                          */
+/*                                                                          */
+/*   Copyright (C) 2007-2024                                                */
+/*     CEA (Commissariat à l'énergie atomique et aux énergies               */
+/*          alternatives)                                                   */
+/*                                                                          */
+/*   you can redistribute it and/or modify it under the terms of the GNU    */
+/*   Lesser General Public License as published by the Free Software        */
+/*   Foundation, version 2.1.                                               */
+/*                                                                          */
+/*   It 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.  See the          */
+/*   GNU Lesser General Public License for more details.                    */
+/*                                                                          */
+/*   See the GNU Lesser General Public License version 2.1                  */
+/*   for more details (enclosed in the file licenses/LGPLv2.1).             */
+/*                                                                          */
+/* ************************************************************************ */
+
+import React from 'react';
+import { IconButton } from 'dome/controls/buttons';
+import { Hbox } from 'dome/layout/boxes';
+import { Icon } from 'dome/controls/icons';
+import * as Forms from 'dome/layout/forms';
+import * as Server from 'frama-c/server';
+import * as States from 'frama-c/states';
+import * as Eva from 'frama-c/plugins/eva/api/general';
+
+
+export interface EvaToolsProps {
+  remote: Forms.BufferController;
+  iconSize: number;
+}
+
+function EvaState(
+  state: Eva.computationStateType | undefined
+): JSX.Element {
+  let id, title;
+  switch(state) {
+    case "computed": id="CHECK"; title="Computed"; break;
+    case "aborted": id="CROSS"; title="Aborted"; break;
+    case "not_computed": id="CROSS"; title="Not computed"; break;
+    case "computing": id="SPINNER"; title="Computing"; break;
+    default: id="CROSS"; title="Status undefined"; break;
+  }
+  return <Icon
+    id={id}
+    title={title}
+    className={"eva-status-icon eva-"+state}
+    size={18}
+  />;
+}
+
+export default function EvaTools(
+  props: EvaToolsProps
+): JSX.Element {
+  const { remote, iconSize } = props;
+
+  const evaComputed = States.useSyncValue(Eva.computationState);
+  const countErrors = remote.getErrors();
+  remote.resetNotified();
+
+  const compute = (): void => { Server.send(Eva.compute, null); };
+  const abort = (): void => { Server.send(Eva.abort, null); };
+  const syncFromFC = (): void => { remote.reset(); };
+  const syncToFC = (): void => { remote.commit(); };
+
+  return (
+    <Hbox className='eva-tools'>
+      <Hbox className='eva-tools-actions'>
+        <IconButton
+          icon="MEDIA.PLAY"
+          title="Launch Eva analysis"
+          size={iconSize}
+          disabled={evaComputed !== "not_computed"}
+          onClick={compute}
+        />
+        <IconButton
+          icon="MEDIA.STOP"
+          title="Abort Eva analysis"
+          size={iconSize}
+          disabled={evaComputed !== "computing"}
+          onClick={abort}
+        />
+        <IconButton
+          icon="RELOAD"
+          title="Reset form"
+          size={iconSize}
+          disabled={!remote.hasReset()}
+          onClick={syncFromFC}
+          />
+        <IconButton
+          icon="PUSH"
+          title={"Commit changes"
+            +
+            (countErrors > 0 ?
+            " : "+String(countErrors)+" error(s) in the form" : ""
+            )
+          }
+          size={iconSize}
+          kind={countErrors > 0 ? "warning" : "default"}
+          disabled={!remote.hasCommit()}
+          onClick={syncToFC}
+        />
+      </Hbox>
+      <Hbox className='eva-tools-title'>
+        {EvaState(evaComputed)}
+      </Hbox>
+    </Hbox>
+  );
+}
diff --git a/ivette/src/frama-c/plugins/eva/index.tsx b/ivette/src/frama-c/plugins/eva/index.tsx
index 1aced6c446efa710f2a9ce3c002b7cc4a5aaf6cf..d277a0fe8d7446e85312ffb17e8d4534b23c8a03 100644
--- a/ivette/src/frama-c/plugins/eva/index.tsx
+++ b/ivette/src/frama-c/plugins/eva/index.tsx
@@ -29,6 +29,7 @@ import './valuetable';
 import './Summary';
 import './Coverage';
 import './DomainStates';
+import './EvaSidebar';
 import './style.css';
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/frama-c/plugins/eva/style.css b/ivette/src/frama-c/plugins/eva/style.css
index 2d6367d5845267d7a8f76eaca15084b32936e1e0..d76029885871fff8143f2d8ee72a0ef0b3235858 100644
--- a/ivette/src/frama-c/plugins/eva/style.css
+++ b/ivette/src/frama-c/plugins/eva/style.css
@@ -4,8 +4,10 @@
 
 :root {
   --eva-min-width: 90px;
+  --eva-shadow-warning: darkorange;
 }
 
+
 .eva-info {
   width: 100%;
   display: flex;
@@ -334,3 +336,165 @@ tr:first-of-type > .eva-table-callsite-box {
 }
 
 /* -------------------------------------------------------------------------- */
+/* --- Sidebar Eva                                                        --- */
+/* -------------------------------------------------------------------------- */
+@keyframes eva-spinner {
+  from {
+      transform: rotate(-90deg);
+  } to {
+      transform: rotate(270deg);
+  }
+}
+
+/* ------------------ */
+/* --- Tools Eva  --- */
+.eva-tools {
+  display: block;
+  position: sticky;
+  top: 0px;
+  z-index: 10;
+  background-color: var(--background-profound);
+  padding: 5px;
+  border: 5px outset;
+  border-color: rgb(from var(--border-discrete) r g b / .7);
+  margin: 10px;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+
+  .eva-tools-actions {
+    display: flex;
+    flex-wrap: wrap;
+  }
+
+  .dome-xIconButton {
+    padding: 2px 5px;
+  }
+  .dome-xIconButton:hover {
+    cursor: pointer;
+    color: var(--background-button-hover);
+  }
+  .eva-status-icon.eva-computing {
+    transform: rotate(90deg);
+    animation: eva-spinner .9s linear infinite;
+    fill: var(--eva-alarms-unknown);
+  }
+  .eva-status-icon.eva-computed { fill: var(--eva-alarms-true); }
+  .eva-status-icon.eva-aborted,
+  .eva-status-icon.eva-not_computed {
+    fill: var(--eva-alarms-false);
+  }
+}
+
+/* ------------------ */
+/* --- Form Eva   --- */
+.eva-form {
+  padding: 4px 12px;
+  display: flex;
+  flex-wrap: nowrap;
+  flex-direction: column;
+
+  >label.dome-xCheckbox{
+    display: flex;
+    flex-direction: row-reverse;
+    font-size: 1.08em;
+    padding: 5px;
+
+    &:hover {
+      color: var(--text-highlighted);
+      cursor:pointer;
+      input {
+        border: 1px solid var(--text-highlighted);
+      }
+    }
+
+    &:has(input:disabled),
+    &:hover:has(input:disabled) {
+      color: var(--disabled-text) !important;
+      cursor:default;
+    }
+
+    input {
+      margin-left: 10px;
+      padding-bottom: 0;
+      border: 1px solid var(--text-discrete);
+    }
+
+    input:checked { background-color: var(--positive-button-active) }
+  }
+
+  .dome-xForm-field-actions { min-width: 42px; }
+
+  .dome-xCheckbox { overflow: hidden; }
+
+  .dome-xForm-field {
+    padding: 1px;
+
+    >input[type=radio] { display: none; }
+    &:has(> input[type=radio]) {
+      min-width: 0px;
+      border-radius: 2em 2em;
+      margin: 2px 3px;
+      padding: 2px 10px;
+    }
+
+    &:has(> input[type=radio]:checked):hover {
+      border-color: var(--border);
+      cursor:default;
+    }
+  }
+
+  .dome-xButton,
+  .dome-xForm-field:has(> input[type=radio]) {
+    border: solid 1px;
+    border-color: var(--border);
+    color: var(--text-discrete);
+    background-color: transparent;
+    background-image: none;
+  }
+
+  .dome-xButton:hover,
+  .dome-xForm-field:has(> input[type=radio]):hover {
+    cursor: pointer;
+    border-color: var(--text-highlighted);
+    color: var(--text-highlighted);
+    background-color: transparent;
+    background-image: none ;
+  }
+
+  .dome-xButton-selected,
+  .dome-xForm-field:has(> input[type=radio]:checked) {
+    color: var(--text);
+    background-color: var(--checked-element);
+    background-image: none;
+  }
+
+  .dome-xButton-selected:hover {
+    border-color: var(--text-highlighted);
+    background-image: none ;
+    background-color: var(--checked-element);
+    opacity: 0.5;
+  }
+
+  .dome-xForm-field-block:has(> .dome-xForm-field .eva-field-modified) {
+    box-shadow: -4px 0px 4px var(--eva-shadow-warning);
+  }
+
+  .dome-xForm-field-block:has(.dome-xForm-field .hidden-field) {
+    display: none;
+  }
+
+  input[type=number] {
+    background-color: var(--background-interaction);
+    color: var(--text);
+    text-align: right;
+    width: 80px;
+    max-width: 100%;
+    margin-right: 0;
+    padding: 1px;
+    margin-right: 5px;
+    border: none;
+  }
+}
+
+/* -------------------------------------------------------------------------- */
diff --git a/src/plugins/eva/api/general_requests.ml b/src/plugins/eva/api/general_requests.ml
index c5cba410e23c386073a573169696b59005e06b61..536264d211f68f1f10dd9b14da1fedc0e25bc03d 100644
--- a/src/plugins/eva/api/general_requests.ml
+++ b/src/plugins/eva/api/general_requests.ml
@@ -22,6 +22,9 @@
 
 open Server
 open Cil_types
+module D = Server.Data
+module S = Server.States
+module Md = Markdown
 
 let package =
   Package.package
@@ -869,4 +872,189 @@ let () = Request.register ~package
     ~signals:[computation_signal]
     get_states
 
+let () = Request.register ~package
+    ~kind:`GET ~name:"getCurrentLoc"
+    ~descr:(Md.plain "Get current location")
+    ~input:(module Data.Junit)
+    ~output:(module Kernel_ast.Position)
+    ~signals:[]
+    (fun () -> fst (Current_loc.get ()))
+
+(* -------------------------------------------------------------------------- *)
+(* --- Eva Options                                                        --- *)
+(* -------------------------------------------------------------------------- *)
+let _ =
+  S.register_state ~package
+    ~name:"eva"
+    ~descr:(Md.plain "Eva enabled")
+    ~data:(module D.Jbool)
+    ~get:Parameters.ForceValues.get
+    ~set:Parameters.ForceValues.set
+    ~add_hook:Parameters.ForceValues.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"precision"
+    ~descr:(Md.plain "Precision value")
+    ~data:(module D.Jint)
+    ~get:Parameters.Precision.get
+    ~set:Parameters.Precision.set
+    ~add_hook:Parameters.Precision.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"slevel"
+    ~descr:(Md.plain "slevel value")
+    ~data:(module D.Jint)
+    ~get:Parameters.SemanticUnrollingLevel.get
+    ~set:Parameters.SemanticUnrollingLevel.set
+    ~add_hook:Parameters.SemanticUnrollingLevel.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"main"
+    ~descr:(Md.plain "main function")
+    ~data:(module D.Jstring)
+    ~get:Kernel.MainFunction.get
+    ~set:Kernel.MainFunction.set
+    ~add_hook:Kernel.MainFunction.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"libEntry"
+    ~descr:(Md.plain "slevel value")
+    ~data:(module D.Jbool)
+    ~get:Kernel.LibEntry.get
+    ~set:Kernel.LibEntry.set
+    ~add_hook:Kernel.LibEntry.add_hook_on_update ()
+
+let get_domains () =
+  let set = Parameters.Domains.get () in
+  Datatype.String.Set.elements set
+
+let set_domains list =
+  let option = "cvalue" in
+  let set = Datatype.String.Set.of_list list in
+  Parameters.Domains.set (Datatype.String.Set.add option set)
+
+let signal =
+  S.register_state ~package
+    ~name:"Domains"
+    ~descr:(Md.plain "domains value")
+    ~data:(module D.Jlist (D.Jstring))
+    ~get:get_domains
+    ~set:set_domains
+    ()
+
+let () =
+  Parameters.Domains.add_update_hook (fun _ _ -> Request.emit signal)
+
+let _ =
+  S.register_state ~package
+    ~name:"ilevel"
+    ~descr:(Md.plain "ilevel value")
+    ~data:(module D.Jint)
+    ~get:Parameters.ILevel.get
+    ~set:Parameters.ILevel.set
+    ~add_hook:Parameters.ILevel.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"MinLoopUnroll"
+    ~descr:(Md.plain "Min loop unroll value")
+    ~data:(module D.Jint)
+    ~get:Parameters.MinLoopUnroll.get
+    ~set:Parameters.MinLoopUnroll.set
+    ~add_hook:Parameters.MinLoopUnroll.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"AutoLoopUnroll"
+    ~descr:(Md.plain "Auto loop unroll value")
+    ~data:(module D.Jint)
+    ~get:Parameters.AutoLoopUnroll.get
+    ~set:Parameters.AutoLoopUnroll.set
+    ~add_hook:Parameters.AutoLoopUnroll.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"WideningDelay"
+    ~descr:(Md.plain "Widening delay")
+    ~data:(module D.Jint)
+    ~get:Parameters.WideningDelay.get
+    ~set:Parameters.WideningDelay.set
+    ~add_hook:Parameters.WideningDelay.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"HistoryPartitioning"
+    ~descr:(Md.plain "History partitioning")
+    ~data:(module D.Jint)
+    ~get:Parameters.HistoryPartitioning.get
+    ~set:Parameters.HistoryPartitioning.set
+    ~add_hook:Parameters.HistoryPartitioning.add_hook_on_update ()
+
+
+let _ =
+  S.register_state ~package
+    ~name:"ArrayPrecisionLevel"
+    ~descr:(Md.plain "Array precision level")
+    ~data:(module D.Jint)
+    ~get:Parameters.ArrayPrecisionLevel.get
+    ~set:Parameters.ArrayPrecisionLevel.set
+    ~add_hook:Parameters.ArrayPrecisionLevel.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"LinearLevel"
+    ~descr:(Md.plain "Linear level")
+    ~data:(module D.Jint)
+    ~get:Parameters.LinearLevel.get
+    ~set:Parameters.LinearLevel.set
+    ~add_hook:Parameters.LinearLevel.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"EqualityCall"
+    ~descr:(Md.plain "Equality call")
+    ~data:(module D.Jstring)
+    ~get:Parameters.EqualityCall.get
+    ~set:Parameters.EqualityCall.set
+    ~add_hook:Parameters.EqualityCall.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"OctagonCall"
+    ~descr:(Md.plain "Octagon call")
+    ~data:(module D.Jbool)
+    ~get:Parameters.OctagonCall.get
+    ~set:Parameters.OctagonCall.set
+    ~add_hook:Parameters.OctagonCall.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"SplitReturn"
+    ~descr:(Md.plain "Split return value")
+    ~data:(module D.Jstring)
+    ~get:Parameters.SplitReturn.get
+    ~set:Parameters.SplitReturn.set
+    ~add_hook:Parameters.SplitReturn.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"AllocReturnsNull"
+    ~descr:(Md.plain "AllocReturnsNull value")
+    ~data:(module D.Jbool)
+    ~get:Parameters.AllocReturnsNull.get
+    ~set:Parameters.AllocReturnsNull.set
+    ~add_hook:Parameters.AllocReturnsNull.add_hook_on_update ()
+
+let _ =
+  S.register_state ~package
+    ~name:"WarnPointerComparison"
+    ~descr:(Md.plain "Warn pointer comparison value")
+    ~data:(module D.Jstring)
+    ~get:Parameters.WarnPointerComparison.get
+    ~set:Parameters.WarnPointerComparison.set
+    ~add_hook:Parameters.WarnPointerComparison.add_hook_on_update ()
 (* -------------------------------------------------------------------------- *)
diff --git a/src/plugins/eva/parameters.mli b/src/plugins/eva/parameters.mli
index 26f6d68592e322fd5f9d67c3dd244ef7974abb63..abc4d534b12a5aab1ed20b7a300fcf0a5b0d8ca3 100644
--- a/src/plugins/eva/parameters.mli
+++ b/src/plugins/eva/parameters.mli
@@ -86,6 +86,8 @@ module SplitLimit : Parameter_sig.Int
 module InterproceduralSplits : Parameter_sig.Bool
 module InterproceduralHistory : Parameter_sig.Bool
 
+module ILevel: Parameter_sig.Int
+
 module ArrayPrecisionLevel: Parameter_sig.Int
 
 module AllocatedContextValid: Parameter_sig.Bool
@@ -116,6 +118,8 @@ module BuiltinsOverrides:
                      and type value = string
 module BuiltinsAuto: Parameter_sig.Bool
 module BuiltinsList: Parameter_sig.Bool
+
+module SplitReturn: Parameter_sig.String
 module SplitReturnFunction:
   Parameter_sig.Map with type key = Cil_types.kernel_function
                      and type value = Split_strategy.t