diff --git a/spec/base.spec.ts b/spec/base.spec.ts
index af744b307477e9f9d4333274c8310a7ce6b51cdb..46dae6792d90d956dd37df304d443a03a603217d 100644
--- a/spec/base.spec.ts
+++ b/spec/base.spec.ts
@@ -9,7 +9,9 @@ describe("Class Nub: ", () => {
             expect(nub.Calc("C").vCalc).toBeCloseTo(3, precDigits);
         });
         it("should return a result.vCalc equal to 1", () => {
-            expect(nub.Calc("A").vCalc).toBeCloseTo(1, precDigits);
+            const r = nub.Calc("A");
+            const v = r.vCalc;
+            expect(v).toBeCloseTo(1, precDigits);
         });
         it("should return a result.vCalc equal to 2", () => {
             expect(nub.Calc("B").vCalc).toBeCloseTo(2, precDigits);
diff --git a/spec/cond_distri.spec.ts b/spec/cond_distri.spec.ts
index a5412cbccc102253e09c55e0f2c1b1ade33b762a..d8272b2c46d1d727f8ee2c5a28471e46d555f318 100644
--- a/spec/cond_distri.spec.ts
+++ b/spec/cond_distri.spec.ts
@@ -55,7 +55,8 @@ describe("Class ConduiteDistrib: ", () => {
 
             const nub = new ConduiteDistrib(prms);
 
-            checkResult(nub.Calc("D", 0), 2.12847);
+            const r = nub.Calc("D", 0);
+            checkResult(r, 2.12847);
         });
     });
 
diff --git a/spec/iterator/named_iterable_value.spec.ts b/spec/iterator/named_iterable_value.spec.ts
index 1a673a7bea0efd5699602367601b6b3a1bbf0f56..0b7a1f60d2de20c1293a5a1f3a15a9c2f4d7cc7b 100644
--- a/spec/iterator/named_iterable_value.spec.ts
+++ b/spec/iterator/named_iterable_value.spec.ts
@@ -1,4 +1,4 @@
-import { ExtraResults, ParamDefinition, ParamDomainValue, Result, ResultElement } from "../../src/index";
+import { ParamDefinition, ParamDomainValue, Result, ResultElement } from "../../src/index";
 
 /**
  * IMPORTANT !
@@ -31,7 +31,7 @@ function testResultValues(vals: number[]): Result {
     }
 
     let n = 0;
-    for (const v of r.valuesIterator) {
+    for (const v of r.getCalculatedValues()) {
         expect(v).toEqual(vals[n++]);
     }
 
@@ -40,7 +40,7 @@ function testResultValues(vals: number[]): Result {
     return r;
 }
 
-function testExtraResultsValues(vals: number[]): ExtraResults {
+/* function testExtraResultsValues(vals: number[]): ExtraResults {
     const ers: ExtraResults = new ExtraResults("aa");
 
     for (const v of vals) {
@@ -55,14 +55,14 @@ function testExtraResultsValues(vals: number[]): ExtraResults {
     expect(n).toEqual(vals.length);
 
     return ers;
-}
+} */
 
 describe("INamedIterableValues  : ", () => {
     describe("ParamDefinition  : ", () => {
         it("test 1", () => {
             const name = "aa";
             const p: ParamDefinition = new ParamDefinition(null, name, ParamDomainValue.ANY);
-            expect(p.name).toEqual(name);
+            expect(p.symbol).toEqual(name);
         });
 
         it("test 2", () => {
@@ -88,52 +88,26 @@ describe("INamedIterableValues  : ", () => {
         it("test 1", () => {
             const name = "aa";
             const r: Result = new Result(0);
-            r.name = name;
-            expect(r.name).toEqual(name);
+            r.symbol = name;
+            expect(r.symbol).toEqual(name);
         });
 
         it("test 2", () => {
             const vals: number[] = [];
             const r = testResultValues(vals);
-            expect(r.hasMultipleValues).toBeFalsy();
+            expect(r.hasMultipleValues()).toBeFalsy();
         });
 
         it("test 3", () => {
             const vals: number[] = [0];
             const r = testResultValues(vals);
-            expect(r.hasMultipleValues).toBeFalsy();
+            expect(r.hasMultipleValues()).toBeFalsy();
         });
 
         it("test 3", () => {
             const vals: number[] = [0, 1];
             const r = testResultValues(vals);
-            expect(r.hasMultipleValues).toBeTruthy();
-        });
-    });
-
-    describe("ExtraResults  : ", () => {
-        it("test 1", () => {
-            const name = "aa";
-            const ers: ExtraResults = new ExtraResults(name);
-            expect(ers.name).toEqual(name);
-        });
-
-        it("test 2", () => {
-            const vals: number[] = [];
-            const ers = testExtraResultsValues(vals);
-            expect(ers.hasMultipleValues).toBeFalsy();
-        });
-
-        it("test 3", () => {
-            const vals: number[] = [0];
-            const ers = testExtraResultsValues(vals);
-            expect(ers.hasMultipleValues).toBeFalsy();
-        });
-
-        it("test 4", () => {
-            const vals: number[] = [0, 1];
-            const ers = testExtraResultsValues(vals);
-            expect(ers.hasMultipleValues).toBeTruthy();
+            expect(r.hasMultipleValues()).toBeTruthy();
         });
     });
 });
diff --git a/spec/macrorugo/macrorugo.spec.ts b/spec/macrorugo/macrorugo.spec.ts
index 5de7ffcd84a8ee6f6160549d888f002616b2198c..1201f6b7ac08b8c4a7e84a5674d2242ce6375875 100644
--- a/spec/macrorugo/macrorugo.spec.ts
+++ b/spec/macrorugo/macrorugo.spec.ts
@@ -166,7 +166,8 @@ function testMacroRugo(sInstance: string, varTest: string, valRef: number) {
             const p = nub.getParameter(varTest);
             p.v = undefined;
             p.valueMode = ParamValueMode.CALCUL;
-            checkResult(nub.Calc(varTest, 0.1), valRef);
+            const r = nub.Calc(varTest, 0.1);
+            checkResult(r, valRef);
         });
 }
 
@@ -187,7 +188,7 @@ function testMacroRugoConfig(sInstance: string, Q0: number, fVal0: number, mrExt
         for (const sExtraRes in mrExtraRes) {
             if (mrExtraRes.hasOwnProperty(sExtraRes)) {
                 it(`${sExtraRes} should be ${mrExtraRes[sExtraRes]}`, () => {
-                    expect(MacroRugoFactory(sInstance).Calc("Q").extraResults[sExtraRes])
+                    expect(MacroRugoFactory(sInstance).Calc("Q").values[sExtraRes])
                     .toBeCloseTo(mrExtraRes[sExtraRes], 5);
                 });
             }
diff --git a/spec/pab/cloison_aval.spec.ts b/spec/pab/cloison_aval.spec.ts
index f3e187b8c0049d12441366961fa30d02a7a820a0..48fc8572781193e0ea267f11a650e7409e440d86 100644
--- a/spec/pab/cloison_aval.spec.ts
+++ b/spec/pab/cloison_aval.spec.ts
@@ -25,21 +25,22 @@ describe("class CloisonAval", () => {
             s = ca.structures[0] as StructureVanLevVillemonte;
         });
         it("Calc(Z1) should return 75.077 and extraResults.ZDV should be 73.95", () => {
-            expect(ca.CalcSerie().vCalc).toBeCloseTo(75.077, 3);
-            expect(ca.CalcSerie().extraResults.ZDV).toBeCloseTo(73.95, 2);
+            const r = ca.CalcSerie();
+            expect(r.vCalc).toBeCloseTo(75.077, 3);
+            expect(r.values.ZDV).toBeCloseTo(73.95, 2);
         });
         it("ZDV min bound Calc(Z1) should return 75.059 and extraResults.ZDV should be 73.9", () => {
             s.prms.maxZDV.singleValue = 73.90;
             const r = ca.CalcSerie();
             expect(r.vCalc).toBeCloseTo(75.059, 3);
-            expect(r.extraResults.ZDV).toBeCloseTo(73.9, 2);
+            expect(r.values.ZDV).toBeCloseTo(73.9, 2);
             expect(r.log.messages[0].code).toBe(MessageCode.WARNING_VANLEV_ZDV_SUP_MAX);
         });
         it("ZDV max bound Calc(Z1) should return 75.096 and extraResults.ZDV should be 74", () => {
             s.prms.minZDV.singleValue = 74;
             const r = ca.CalcSerie();
             expect(r.vCalc).toBeCloseTo(75.096, 3);
-            expect(r.extraResults.ZDV).toBeCloseTo(74, 2);
+            expect(r.values.ZDV).toBeCloseTo(74, 2);
             expect(r.log.messages[0].code).toBe(MessageCode.WARNING_VANLEV_ZDV_INF_MIN);
         });
     });
@@ -58,20 +59,20 @@ describe("class CloisonAval", () => {
         });
         it("Calc(Z1) should return 75.077 and extraResults.ZDV should be 73.431", () => {
             expect(ca.CalcSerie().vCalc).toBeCloseTo(75.077, 3);
-            expect(ca.CalcSerie().extraResults.ZDV).toBeCloseTo(73.431, 2);
+            expect(ca.CalcSerie().values.ZDV).toBeCloseTo(73.431, 2);
         });
         it("ZDV min bound Calc(Z1) should return 75.071 and extraResults.ZDV should be 73.4", () => {
             s.prms.maxZDV.singleValue = 73.40;
             const r = ca.CalcSerie();
             expect(r.vCalc).toBeCloseTo(75.071, 3);
-            expect(r.extraResults.ZDV).toBeCloseTo(73.4, 2);
+            expect(r.values.ZDV).toBeCloseTo(73.4, 2);
             expect(r.log.messages[0].code).toBe(MessageCode.WARNING_VANLEV_ZDV_SUP_MAX);
         });
         it("ZDV max bound Calc(Z1) should return 75.092 and extraResults.ZDV should be 73.5", () => {
             s.prms.minZDV.singleValue = 73.5;
             const r = ca.CalcSerie();
             expect(r.vCalc).toBeCloseTo(75.092, 3);
-            expect(r.extraResults.ZDV).toBeCloseTo(73.5, 2);
+            expect(r.values.ZDV).toBeCloseTo(73.5, 2);
             expect(r.log.messages[0].code).toBe(MessageCode.WARNING_VANLEV_ZDV_INF_MIN);
         });
     });
diff --git a/spec/pab/cloisons.spec.ts b/spec/pab/cloisons.spec.ts
index 94ff1554db9e87c2ff60a068c81b0e79706d45a4..65a0340d15e25f4e9c09689baadaef625a484c79 100755
--- a/spec/pab/cloisons.spec.ts
+++ b/spec/pab/cloisons.spec.ts
@@ -44,7 +44,7 @@ describe("Class Cloisons: ", () => {
             expect(c.CalcSerie().vCalc).toBeCloseTo(0.407, 3);
         });
         it("extraResults.PV should return 199.7", () => {
-            expect(c.CalcSerie().extraResults.PV).toBeCloseTo(199.7, 1);
+            expect(c.CalcSerie().values.PV).toBeCloseTo(199.7, 1);
         });
         it("ZRMB should be 100.5", () => {
             c.CalcSerie();
@@ -86,9 +86,9 @@ describe("Class Cloisons: ", () => {
             modelCloisons.calculatedParam = modelCloisons.prms.Q;
             const res = modelCloisons.CalcSerie();
             expect(res.vCalc).toBeCloseTo(0.773, 2);
-            expect(res.extraResults.PV).toBeCloseTo(150.1, 1);
-            expect(res.extraResults.ZRMB).toBeCloseTo(76.54, 2);
-            expect(res.extraResults["ouvrage[0].ZDV"]).toBeCloseTo(76.67, 2);
+            expect(res.values.PV).toBeCloseTo(150.1, 1);
+            expect(res.values.ZRMB).toBeCloseTo(76.54, 2);
+            expect(modelCloisons.structures[0].result.values.ZDV).toBeCloseTo(76.67, 2);
         });
     });
 
diff --git a/spec/pab/pab.spec.ts b/spec/pab/pab.spec.ts
index 515af522e657e8d46201862166527ff89f60f681..5d30b5a5573d6bdf2f45dc613d54109f3a1b8fcc 100644
--- a/spec/pab/pab.spec.ts
+++ b/spec/pab/pab.spec.ts
@@ -118,27 +118,27 @@ function checkPabResults(p: Pab, vCalc: number) {
     ];
     // Cote de l'eau dernier bassin à l'amont de la cloison aval
     expect(p.downWall.result.vCalc).toBeCloseTo(75.077, 2);
-    expect(p.downWall.result.extraResults.DH).toBeCloseTo(0.217, 2);
-    expect(p.downWall.result.extraResults.ZRAM).toBeCloseTo(73.435, 2);
-    expect(p.downWall.result.extraResults.Q).toBeCloseTo(0.773, 2);
-    expect(p.downWall.result.extraResults.x).toBeCloseTo(3.1 * 14, 2);
+    expect(p.downWall.result.values.DH).toBeCloseTo(0.217, 2);
+    expect(p.downWall.result.values.ZRAM).toBeCloseTo(73.435, 2);
+    expect(p.downWall.result.values.Q).toBeCloseTo(0.773, 2);
+    expect(p.downWall.result.values.x).toBeCloseTo(3.1 * 14, 2);
     for (let i = 0; i < 14; i++) {
         // Cote de l'eau à l'amont de la cloison amont du bassin
         expect(p.children[i].result.vCalc).toBeCloseTo(tRef[i][0], 2);
         // Puissance volumique dissipée
-        expect(p.children[i].result.extraResults.PV).toBeCloseTo(tRef[i][1], 0);
+        expect(p.children[i].result.values.PV).toBeCloseTo(tRef[i][1], 0);
         // Tirant d'eau moyen
-        expect(p.children[i].result.extraResults.YMOY).toBeCloseTo(tRef[i][2], 2);
+        expect(p.children[i].result.values.YMOY).toBeCloseTo(tRef[i][2], 2);
         // Chute
-        expect(p.children[i].result.extraResults.DH).toBeCloseTo(tRef[i][3], 2);
+        expect(p.children[i].result.values.DH).toBeCloseTo(tRef[i][3], 2);
         // Débits
-        expect(p.children[i].result.extraResults.Q).toBeCloseTo(0.773, 2);
-        expect(p.children[i].result.extraResults.QA).toBeCloseTo(0, 2);
+        expect(p.children[i].result.values.Q).toBeCloseTo(0.773, 2);
+        expect(p.children[i].result.values.QA).toBeCloseTo(0, 2);
         // Cote radier amont
-        expect(p.children[i].result.extraResults.ZRAM).toBeCloseTo(73.665 + (13 - i) * 0.23, 2);
+        expect(p.children[i].result.values.ZRAM).toBeCloseTo(73.665 + (13 - i) * 0.23, 2);
         // Cote radier mi-bassin
-        expect(p.children[i].result.extraResults.ZRMB).toBeCloseTo(73.550 + (13 - i) * 0.23, 2);
-        expect(p.children[i].result.extraResults.x).toBeCloseTo(3.1 * i, 2);
+        expect(p.children[i].result.values.ZRMB).toBeCloseTo(73.550 + (13 - i) * 0.23, 2);
+        expect(p.children[i].result.values.x).toBeCloseTo(3.1 * i, 2);
     }
 }
 
@@ -208,7 +208,7 @@ describe("Class Pab: ", () => {
             pab.calculatedParam = pab.prms.Q;
             pab.prms.Z1.singleValue = 76.60;
             pab.CalcSerie();
-            expect(pab.result.hasLog).toBe(true);
+            expect(pab.result.hasLog()).toBe(true);
             expect(pab.result.resultElement.log.messages[0].code)
                 .toBe(MessageCode.ERROR_PAB_Z1_LOWER_THAN_UPSTREAM_WALL); // @TODO or other error message ?
         });
@@ -219,8 +219,8 @@ describe("Class Pab: ", () => {
             pab.calculatedParam = pab.prms.Q;
             pab.prms.Z1.setValues(73, 85, 6);
             pab.CalcSerie();
-            expect(pab.result.nbResultElements).toBe(3);
-            expect(pab.result.hasLog).toBe(true);
+            expect(pab.result.resultElements.length).toBe(3);
+            expect(pab.result.hasLog()).toBe(true);
             expect(pab.result.resultElements[0].log.messages[0].code).toBe(MessageCode.ERROR_PAB_Z1_LOWER_THAN_Z2);
         });
 
@@ -229,8 +229,8 @@ describe("Class Pab: ", () => {
             pab.prms.Z1.setValues(73, 85, 6);
             pab.CalcSerie();
             // for ex. Cloisons n°1
-            expect(pab.children[0].result.nbResultElements).toBe(3);
-            expect(Object.keys(pab.children[0].result.resultElements[1].extraResults).length).toBe(12);
+            expect(pab.children[0].result.resultElements.length).toBe(3);
+            expect(Object.keys(pab.children[0].result.resultElements[1].extraResults).length).toBe(8);
         });
     });
 
diff --git a/spec/pab/pab_jalhyd131.spec.ts b/spec/pab/pab_jalhyd131.spec.ts
index 13d66b9359d9f29d361f1457ba1d6d406e482715..5e4e069c4bef2a7934557d8bd6e4bfb462ec4cbd 100644
--- a/spec/pab/pab_jalhyd131.spec.ts
+++ b/spec/pab/pab_jalhyd131.spec.ts
@@ -1221,7 +1221,7 @@ describe("Class Pab", () => {
     describe("Jalhyd #131", () => {
         it("CalcSerie() should return a consistent result", () => {
             const r = getPabJalhyd131().CalcSerie();
-            expect(BoolIdentity(!r.ok, r.hasErrorMessages)).toBe(true);
+            expect(BoolIdentity(!r.ok, r.hasErrorMessages())).toBe(true);
         });
     });
 });
diff --git a/spec/pab/pab_nombre.spec.ts b/spec/pab/pab_nombre.spec.ts
index 9136553725fb39bdb301f17c33c949d9d40a942b..db83da47c8a675bd2b4f07e89adc68158f95cc5f 100644
--- a/spec/pab/pab_nombre.spec.ts
+++ b/spec/pab/pab_nombre.spec.ts
@@ -36,7 +36,7 @@ describe("Class PabNombre: ", () => {
 
         nub.Calc("N", 0);
         expect(nub.result.vCalc).toBe(9);
-        expect(nub.result.getExtraResult("DHR")).toBeCloseTo(0.3);
+        expect(nub.result.getValue("DHR")).toBeCloseTo(0.3);
     });
 
     it ("DHR should be 0", () => {
@@ -50,7 +50,7 @@ describe("Class PabNombre: ", () => {
 
         nub.Calc("N", 0);
         expect(nub.result.vCalc).toBe(15);
-        expect(nub.result.getExtraResult("DHR")).toBe(0);
+        expect(nub.result.getValue("DHR")).toBe(0);
     });
 
     it ("non-integer number of basins should lead to log error entry", () => {
diff --git a/spec/regime_uniforme/regime_uniforme_puissance.spec.ts b/spec/regime_uniforme/regime_uniforme_puissance.spec.ts
index a69baf9ee7597c37dc1a595d7bd8d3717e3d7e2a..a813a80448528ee3032c427464ea58329e7c3030 100644
--- a/spec/regime_uniforme/regime_uniforme_puissance.spec.ts
+++ b/spec/regime_uniforme/regime_uniforme_puissance.spec.ts
@@ -129,7 +129,7 @@ describe("Class RegimeUniforme / section puissance :", () => {
 
             const res: Result = ru.Calc("k", 0);
             expect(res.vCalc).toBeUndefined();
-            expect(res.code).toBe(MessageCode.ERROR_DICHO_INIT_DOMAIN);
+            expect(res.log.messages[0].code).toBe(MessageCode.ERROR_DICHO_INIT_DOMAIN);
         });
 
         it("k should be 0.635", () => {
@@ -196,7 +196,7 @@ describe("Class RegimeUniforme / section puissance :", () => {
 
             const res: Result = ru.Calc("Ks", 5000000);
             expect(res.vCalc).toBeUndefined();
-            expect(res.code).toBe(MessageCode.ERROR_DICHO_TARGET_TOO_LOW);
+            expect(res.log.messages[0].code).toBe(MessageCode.ERROR_DICHO_TARGET_TOO_LOW);
         });
 
         it("Ks should be undefined", () => {
@@ -215,7 +215,7 @@ describe("Class RegimeUniforme / section puissance :", () => {
 
             const res: Result = ru.Calc("Ks", 1e-8);
             expect(res.vCalc).toBeUndefined();
-            expect(res.code).toBe(MessageCode.ERROR_DICHO_TARGET_TOO_HIGH);
+            expect(res.log.messages[0].code).toBe(MessageCode.ERROR_DICHO_TARGET_TOO_HIGH);
         });
 
         it("If should be 0.001", () => {
diff --git a/spec/remous/remous_rect_euler_pentefaible.spec.ts b/spec/remous/remous_rect_euler_pentefaible.spec.ts
index 6faefd3eeefd9b285541c8a62707571d9fa96046..a8545b7c5507df1bf3f19955faacbfa8eec96f9f 100644
--- a/spec/remous/remous_rect_euler_pentefaible.spec.ts
+++ b/spec/remous/remous_rect_euler_pentefaible.spec.ts
@@ -13,7 +13,7 @@ import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
 import { Result } from "../../src/util/result";
 import { precDist } from "../test_config";
-import { compareExtraResult, compareLog } from "../test_func";
+import { compareExtraResult, compareLog, extraResultLength } from "../test_func";
 
 describe("Class Remous / section rectangulaire :", () => {
     describe("méthode Euler explicite :", () => {
@@ -50,15 +50,15 @@ describe("Class Remous / section rectangulaire :", () => {
                 75: 0.9962500000000004, 80: 0.9970000000000003, 85: 0.9977500000000002,
                 90: 0.9985000000000002, 95: 0.9992500000000001, 100: 1
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             expect(
-                res.extraResultLength("tor") === 0
+                extraResultLength(res, "tor") === 0
             ).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             // const x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -113,15 +113,15 @@ describe("Class Remous / section rectangulaire :", () => {
                 75: 0.7362499999999997, 80: 0.7299999999999998, 85: 0.7232499999999998,
                 90: 0.7159999999999999, 95: 0.7082499999999999, 100: 0.7
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             expect(
-                res.extraResultLength("tor") === 0
+                extraResultLength(res, "tor") === 0
             ).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             // const x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
diff --git a/spec/remous/remous_rect_euler_penteforte.spec.ts b/spec/remous/remous_rect_euler_penteforte.spec.ts
index c3ee3da16e9597566b295ea4686054de44a52e1b..307ad084fc07ad833e062bc66d51f71289fcea47 100644
--- a/spec/remous/remous_rect_euler_penteforte.spec.ts
+++ b/spec/remous/remous_rect_euler_penteforte.spec.ts
@@ -4,7 +4,7 @@ import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rect
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
 import { precDist } from "../test_config";
-import { compareExtraResult, compareLog, equalEpsilon } from "../test_func";
+import { compareExtraResult, compareLog, equalEpsilon, extraResultLength } from "../test_func";
 
 /*
    Certaines valeurs de ligne d'eau torrentielle étaient auparavant remplacées par une valeur fluviale
@@ -70,15 +70,15 @@ describe("Class Remous / section rectangulaire :", () => {
                 95: 5.750000000000001,
                 100: 6
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {};
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // const x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -131,7 +131,7 @@ describe("Class Remous / section rectangulaire :", () => {
             // données de validation : version Typescript (Oct 2017) méthode des trapèzes
 
             const f = {};
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {
@@ -157,11 +157,11 @@ describe("Class Remous / section rectangulaire :", () => {
                 95: 0.2527499999999999,
                 100: 0.253
             }; // dernière valeur modifiée pour la raison en tête de fichier
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // const x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -320,7 +320,7 @@ describe("Class Remous / section rectangulaire :", () => {
                 0.5: 0.7275000000000007,
                 0.25: 0.7132500000000007
             }; // première valeur modifiée pour la raison en tête de fichier
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {
@@ -341,12 +341,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 3.5: 0.18550000000000003,
                 3.75: 0.9072500000000001
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, 4.5, 4.75, 5, 5.25, 5.5];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -398,7 +398,7 @@ describe("Class Remous / section rectangulaire :", () => {
 
             // données de validation : version Typescript (Oct 2017) méthode trapèzes
 
-            expect(res.extraResultLength("flu") === 0).toBeTruthy(
+            expect(extraResultLength(res, "flu") === 0).toBeTruthy(
                 "la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             const t = {
@@ -411,12 +411,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 24: 0.2492500000000001, 25: 0.2502500000000001, 26: 0.25050000000000006, 27: 0.25075000000000003,
                 28: 0.251, 29: 0.25125, 30: 0.25149999999999995
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.01);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.01);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.01);
 
             // const x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
             //     19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -463,7 +463,7 @@ describe("Class Remous / section rectangulaire :", () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            expect(res.extraResultLength("flu") === 0)
+            expect(extraResultLength(res, "flu") === 0)
                 .toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             const t = {
@@ -569,12 +569,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 9.900: 0.269,
                 10.000: 0.269
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.700, 0.800, 0.900, 1.000, 1.100, 1.200, 1.300, 1.400, 1.500, 1.600, 1.700, 1.800, 1.900, 2.000, 2.100, 2.200, 2.300, 2.400, 2.500, 2.600, 2.700, 2.800, 2.900, 3.000, 3.100, 3.200, 3.300, 3.400, 3.500, 3.600, 3.700, 3.800, 3.900, 4.000, 4.100, 4.200, 4.300, 4.400, 4.500, 4.600, 4.700, 4.800, 4.900, 5.000, 5.100, 5.200, 5.300, 5.400, 5.500, 5.600, 5.700, 5.800, 5.900, 6.000, 6.100, 6.200, 6.300, 6.400, 6.500, 6.600, 6.700, 6.800, 6.900, 7.000, 7.100, 7.200, 7.300, 7.400, 7.500, 7.600, 7.700, 7.800, 7.900, 8.000, 8.100, 8.200, 8.300, 8.400, 8.500, 8.600, 8.700, 8.800, 8.900, 9.000, 9.100, 9.200, 9.300, 9.400, 9.500, 9.600, 9.700, 9.800, 9.900, 10.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
diff --git a/spec/remous/remous_rect_rk4_pentefaible.spec.ts b/spec/remous/remous_rect_rk4_pentefaible.spec.ts
index 09f07a6526b748ba5b32082777e6d30216a97fe3..a0e9120f2b3837c6c8f7c4378ecd2b2ec17d0bc0 100644
--- a/spec/remous/remous_rect_rk4_pentefaible.spec.ts
+++ b/spec/remous/remous_rect_rk4_pentefaible.spec.ts
@@ -4,7 +4,7 @@ import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rect
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
 import { precDist } from "../test_config";
-import { compareExtraResult, compareLog, equalEpsilon } from "../test_func";
+import { compareExtraResult, compareLog, equalEpsilon, extraResultLength } from "../test_func";
 
 /*
   Le code de modification des lignes fluviale et torrentielle a été modifié, on enlève un point de plus
@@ -45,16 +45,16 @@ describe("Class Remous / section rectangulaire :", () => {
                 40.000: 0.89, 35.000: 0.891, 30.000: 0.892, 25.000: 0.893, 20.000: 0.894, 15.000: 0.895,
                 10.000: 0.896, 5.000: 0.897, 0.000: 0.898
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {};
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000,
             //     55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -134,17 +134,17 @@ describe("Class Remous / section rectangulaire :", () => {
                 10.000: 0.755,
                 5.000: 0.76
             }; // dernière valeur supprimée pour la raison en tête de fichier
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             // let t = { 0.000: 0.15, 5.000: 0.76 };
             const t = { 0.000: 0.15 }; // dernière valeur supprimée pour la raison en tête de fichier
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -223,16 +223,16 @@ describe("Class Remous / section rectangulaire :", () => {
                 0.250: 0.509,
                 0.000: 0.01
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = { 0.000: 0.01, 0.250: 0.017, 0.500: 0.022, 0.750: 0.028, 1.000: 0.502 };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 0.250, 0.500, 0.750, 1.000, 1.250, 1.500, 1.750, 2.000, 2.250, 2.500, 2.750, 3.000, 3.250, 3.500, 3.750, 4.000, 4.250, 4.500, 4.750, 5.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -306,15 +306,15 @@ describe("Class Remous / section rectangulaire :", () => {
                 5.000: 0.989,
                 0.000: 0.988
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
-            expect(res.extraResultLength("tor") === 0)
+            expect(extraResultLength(res, "tor") === 0)
                 .toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -383,15 +383,15 @@ describe("Class Remous / section rectangulaire :", () => {
                 5.000: 0.802,
                 0.000: 0.806
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
-            expect(res.extraResultLength("tor") === 0)
+            expect(extraResultLength(res, "tor") === 0)
                 .toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
diff --git a/spec/remous/remous_rect_rk4_penteforte.spec.ts b/spec/remous/remous_rect_rk4_penteforte.spec.ts
index 13b515cc31c77eb41f3be29c40398912021f7e20..d568aa99d29482e079b1eeafce42f9d44ebc44dd 100644
--- a/spec/remous/remous_rect_rk4_penteforte.spec.ts
+++ b/spec/remous/remous_rect_rk4_penteforte.spec.ts
@@ -4,7 +4,7 @@ import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rect
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
 import { precDist } from "../test_config";
-import { compareExtraResult, compareLog } from "../test_func";
+import { compareExtraResult, compareLog, extraResultLength } from "../test_func";
 
 /*
    cas 1 :
@@ -72,16 +72,16 @@ describe("Class Remous / section rectangulaire :", () => {
                 5.000: 1.237,
                 0.000: 0.977
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.01);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.01);
             compareExtraResult("Yfluvial", res, "flu", f, 0.01);
 
             const t = {};
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -134,7 +134,7 @@ describe("Class Remous / section rectangulaire :", () => {
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
             const f = {};
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             // tslint:disable-next-line:max-line-length
@@ -162,12 +162,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 95.000: 0.253,
                 100.000: 0.253
             }; // dernière valeur remplacée pour la raison 1 en tête de fichier
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -225,7 +225,7 @@ describe("Class Remous / section rectangulaire :", () => {
 
             // let f = { 100.000: 1, 95.000: 0.728, 90.000: 0.521 };
             const f = { 100.000: 1, 95.000: 0.728 }; // dernière valeur supprimée pour la raison 2 en tête de fichier
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             // tslint:disable-next-line:max-line-length
@@ -251,12 +251,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 85.000: 0.253,
                 90.000: 0.25
             }; // dernière valeur remplacée pour la raison 1 en tête de fichier
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -339,7 +339,7 @@ describe("Class Remous / section rectangulaire :", () => {
                 0.250: 0.713,
                 0.000: 0.699
             }; // dernière valeur remplacée pour la raison 1 en tête de fichier
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {
@@ -360,12 +360,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 3.500: 0.186,
                 3.750: 0.907
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 0.250, 0.500, 0.750, 1.000, 1.250, 1.500, 1.750, 2.000, 2.250, 2.500, 2.750, 3.000, 3.250, 3.500, 3.750, 4.000, 4.250, 4.500, 4.750, 5.000, 5.250, 5.500];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -417,7 +417,7 @@ describe("Class Remous / section rectangulaire :", () => {
 
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
-            expect(res.extraResultLength("flu") === 0)
+            expect(extraResultLength(res, "flu") === 0)
                 .toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             const t = {
@@ -443,12 +443,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 95.000: 0.253,
                 100.000: 0.253
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.01);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.01);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.01);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -495,7 +495,7 @@ describe("Class Remous / section rectangulaire :", () => {
 
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
-            expect(res.extraResultLength("flu") === 0)
+            expect(extraResultLength(res, "flu") === 0)
                 .toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             const t = {
@@ -601,12 +601,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 9.900: 0.26,
                 10.000: 0.26
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.01);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.01);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.01);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.700, 0.800, 0.900, 1.000, 1.100, 1.200, 1.300, 1.400, 1.500, 1.600, 1.700, 1.800, 1.900, 2.000, 2.100, 2.200, 2.300, 2.400, 2.500, 2.600, 2.700, 2.800, 2.900, 3.000, 3.100, 3.200, 3.300, 3.400, 3.500, 3.600, 3.700, 3.800, 3.900, 4.000, 4.100, 4.200, 4.300, 4.400, 4.500, 4.600, 4.700, 4.800, 4.900, 5.000, 5.100, 5.200, 5.300, 5.400, 5.500, 5.600, 5.700, 5.800, 5.900, 6.000, 6.100, 6.200, 6.300, 6.400, 6.500, 6.600, 6.700, 6.800, 6.900, 7.000, 7.100, 7.200, 7.300, 7.400, 7.500, 7.600, 7.700, 7.800, 7.900, 8.000, 8.100, 8.200, 8.300, 8.400, 8.500, 8.600, 8.700, 8.800, 8.900, 9.000, 9.100, 9.200, 9.300, 9.400, 9.500, 9.600, 9.700, 9.800, 9.900, 10.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
diff --git a/spec/remous/remous_rect_trapezes_pentefaible.spec.ts b/spec/remous/remous_rect_trapezes_pentefaible.spec.ts
index 720020a3297227c7dfb5fe68120827f32f84c5bf..0c430d0dc749462076f4336be97c88dc27ddc648 100644
--- a/spec/remous/remous_rect_trapezes_pentefaible.spec.ts
+++ b/spec/remous/remous_rect_trapezes_pentefaible.spec.ts
@@ -12,7 +12,7 @@ import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rect
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
 import { precDist } from "../test_config";
-import { compareExtraResult, compareLog, equalEpsilon } from "../test_func";
+import { compareExtraResult, compareLog, equalEpsilon, extraResultLength } from "../test_func";
 
 /*
   Le code de modification des lignes fluviale et torrentielle a été modifié, on enlève un point de plus
@@ -70,16 +70,16 @@ describe("Class Remous / section rectangulaire :", () => {
                 5.000: 0.75,
                 0.000: 0.755
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {};
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -159,17 +159,17 @@ describe("Class Remous / section rectangulaire :", () => {
                 10.000: 0.744,
                 5.000: 0.75
             };  // dernière valeur supprimée pour la raison en tête de fichier
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             // let t = { 0.000: 0.15, 5.000: 0.75 };
             const t = { 0.000: 0.15 }; // dernière valeur supprimée pour la raison en tête de fichier
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -264,16 +264,16 @@ describe("Class Remous / section rectangulaire :", () => {
                 0.250: 0.508,
                 0.000: 0.01
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = { 0.000: 0.01, 0.250: 0.022, 0.500: 0.027, 0.750: 0.033, 1.000: 0.501 };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 0.250, 0.500, 0.750, 1.000, 1.250, 1.500, 1.750, 2.000, 2.250, 2.500, 2.750, 3.000, 3.250, 3.500, 3.750, 4.000, 4.250, 4.500, 4.750, 5.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -428,7 +428,7 @@ describe("Class Remous / section rectangulaire :", () => {
                 0.0500: 0.51,
                 0.0000: 0.01
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {
@@ -452,12 +452,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 0.8500: 0.03,
                 0.9000: 0.502
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.0000, 0.0500, 0.1000, 0.1500, 0.2000, 0.2500, 0.3000, 0.3500, 0.4000, 0.4500, 0.5000, 0.5500, 0.6000, 0.6500, 0.7000, 0.7500, 0.8000, 0.8500, 0.9000, 0.9500, 1.0000, 1.0500, 1.1000, 1.1500, 1.2000, 1.2500, 1.3000, 1.3500, 1.4000, 1.4500, 1.5000, 1.5500, 1.6000, 1.6500, 1.7000, 1.7500, 1.8000, 1.8500, 1.9000, 1.9500, 2.0000, 2.0500, 2.1000, 2.1500, 2.2000, 2.2500, 2.3000, 2.3500, 2.4000, 2.4500, 2.5000, 2.5500, 2.6000, 2.6500, 2.7000, 2.7500, 2.8000, 2.8500, 2.9000, 2.9500, 3.0000, 3.0500, 3.1000, 3.1500, 3.2000, 3.2500, 3.3000, 3.3500, 3.4000, 3.4500, 3.5000, 3.5500, 3.6000, 3.6500, 3.7000, 3.7500, 3.8000, 3.8500, 3.9000, 3.9500, 4.0000, 4.0500, 4.1000, 4.1500, 4.2000, 4.2500, 4.3000, 4.3500, 4.4000, 4.4500, 4.5000, 4.5500, 4.6000, 4.6500, 4.7000, 4.7500, 4.8000, 4.8500, 4.9000, 4.9500, 5.0000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -532,15 +532,15 @@ describe("Class Remous / section rectangulaire :", () => {
             5.000: 0.988,
             0.000: 0.988
         };
-        // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+        // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
         compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
-        expect(res.extraResultLength("tor") === 0)
+        expect(extraResultLength(res, "tor") === 0)
             .toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
         // tslint:disable-next-line:max-line-length
         // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-        // compareArray("abscisses", res.getExtraResult("trX"), x);
+        // compareArray("abscisses", res.getValue("trX"), x);
 
         const expLog = new cLog();
         let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -609,15 +609,15 @@ describe("Class Remous / section rectangulaire :", () => {
             5.000: 0.803,
             0.000: 0.806
         };
-        // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+        // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
         compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
-        expect(res.extraResultLength("tor") === 0)
+        expect(extraResultLength(res, "tor") === 0)
             .toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
         // tslint:disable-next-line:max-line-length
         // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-        // compareArray("abscisses", res.getExtraResult("trX"), x);
+        // compareArray("abscisses", res.getValue("trX"), x);
 
         const expLog = new cLog();
         let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -664,18 +664,18 @@ describe("Class Remous / section rectangulaire :", () => {
 
         // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-        expect(res.extraResultLength("flu") === 0)
+        expect(extraResultLength(res, "flu") === 0)
             .toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
         const t = { 0.000: 0.15, 5.000: 0.239, 10.000: 0.34 };
-        // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.008);
+        // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.008);
         compareExtraResult("Ytorrentiel", res, "tor", t, 0.008);
 
         // const x = [0.000, 5.000, 10.000];
-        // compareArray("abscisses", res.getExtraResult("trX"), x);
+        // compareArray("abscisses", res.getValue("trX"), x);
 
         const extraHS = { 0.000: 1.6, 5.000: 0.808, 10.000: 0.618 };
-        // compareObject("extra (Hs)", res.getExtraResult("Hs"), extraHS, 0.001);
+        // compareObject("extra (Hs)", res.getValue("Hs"), extraHS, 0.001);
         compareExtraResult("extra (Hs)", res, "Hs", extraHS, 0.001);
 
         const expLog = new cLog();
diff --git a/spec/remous/remous_rect_trapezes_penteforte.spec.ts b/spec/remous/remous_rect_trapezes_penteforte.spec.ts
index 9da0a4806fb193d1bca1141f040ee4ce22a33d89..8e0f07be4075d15c3962e3be1d265a6439282df2 100644
--- a/spec/remous/remous_rect_trapezes_penteforte.spec.ts
+++ b/spec/remous/remous_rect_trapezes_penteforte.spec.ts
@@ -4,7 +4,7 @@ import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rect
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
 import { precDist } from "../test_config";
-import { compareExtraResult, compareLog, equalEpsilon } from "../test_func";
+import { compareExtraResult, compareLog, equalEpsilon, extraResultLength } from "../test_func";
 
 /*
    cas 1 :
@@ -72,16 +72,16 @@ describe("Class Remous / section rectangulaire :", () => {
                 5.000: 1.237,
                 0.000: 0.977
             };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {};
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -134,7 +134,7 @@ describe("Class Remous / section rectangulaire :", () => {
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
             const f = {};
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             // tslint:disable-next-line:max-line-length
@@ -164,12 +164,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 95.000: 0.253,
                 100.000: 0.253
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -226,7 +226,7 @@ describe("Class Remous / section rectangulaire :", () => {
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
             const f = { 100.000: 1, 95.000: 0.729 };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             // tslint:disable-next-line:max-line-length
@@ -252,12 +252,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 85.000: 0.253,
                 90.000: 0.253
             }; // dernière valeur supprimée pour la raison 2 en tête de fichier
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -340,7 +340,7 @@ describe("Class Remous / section rectangulaire :", () => {
                 0.250: 0.712,
                 0.000: 0.699
             };  // dernière valeur modifiée pour la raison 1 en tête de fichier
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.03);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.03);
             compareExtraResult("Yfluvial", res, "flu", f, 0.03);
 
             const t = {
@@ -361,12 +361,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 3.500: 0.184,
                 3.750: 0.906
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.03);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.03);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.03);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 0.250, 0.500, 0.750, 1.000, 1.250, 1.500, 1.750, 2.000, 2.250, 2.500, 2.750, 3.000, 3.250, 3.500, 3.750, 4.000, 4.250, 4.500, 4.750, 5.000, 5.250, 5.500];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -418,7 +418,7 @@ describe("Class Remous / section rectangulaire :", () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            expect(res.extraResultLength("flu") === 0).toBeTruthy(
+            expect(extraResultLength(res, "flu") === 0).toBeTruthy(
                 "la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             const t = {
@@ -427,12 +427,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253,
                 90.000: 0.253, 95.000: 0.253, 100.000: 0.253
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.01);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.01);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.01);
 
             // const x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000,
             //     55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
@@ -479,7 +479,7 @@ describe("Class Remous / section rectangulaire :", () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            expect(res.extraResultLength("flu") === 0)
+            expect(extraResultLength(res, "flu") === 0)
                 .toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             const t = {
@@ -585,12 +585,12 @@ describe("Class Remous / section rectangulaire :", () => {
                 9.900: 0.269,
                 10.000: 0.269
             };
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.01);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.01);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.01);
 
             // tslint:disable-next-line:max-line-length
             // const x = [0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.700, 0.800, 0.900, 1.000, 1.100, 1.200, 1.300, 1.400, 1.500, 1.600, 1.700, 1.800, 1.900, 2.000, 2.100, 2.200, 2.300, 2.400, 2.500, 2.600, 2.700, 2.800, 2.900, 3.000, 3.100, 3.200, 3.300, 3.400, 3.500, 3.600, 3.700, 3.800, 3.900, 4.000, 4.100, 4.200, 4.300, 4.400, 4.500, 4.600, 4.700, 4.800, 4.900, 5.000, 5.100, 5.200, 5.300, 5.400, 5.500, 5.600, 5.700, 5.800, 5.900, 6.000, 6.100, 6.200, 6.300, 6.400, 6.500, 6.600, 6.700, 6.800, 6.900, 7.000, 7.100, 7.200, 7.300, 7.400, 7.500, 7.600, 7.700, 7.800, 7.900, 8.000, 8.100, 8.200, 8.300, 8.400, 8.500, 8.600, 8.700, 8.800, 8.900, 9.000, 9.100, 9.200, 9.300, 9.400, 9.500, 9.600, 9.700, 9.800, 9.900, 10.000];
-            // compareArray("abscisses", res.getExtraResult("trX"), x);
+            // compareArray("abscisses", res.getValue("trX"), x);
 
             const expLog = new cLog();
             let m = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
diff --git a/spec/remous/remous_trapez.spec.ts b/spec/remous/remous_trapez.spec.ts
index c29440826ce31cf5bff24d0ca2abbd45edfbccb3..412fc70908b0aa136a10a846adcc9b57ca2c97e9 100644
--- a/spec/remous/remous_trapez.spec.ts
+++ b/spec/remous/remous_trapez.spec.ts
@@ -74,7 +74,7 @@ describe("Class Remous / section trapèze :", () => {
             const res = rem.calculRemous(undefined);
 
             const f = { 9: 0.278, 10: 0.4 };
-            // compareObject("Yfluvial", res.getExtraResult("flu"), f, 0.002);
+            // compareObject("Yfluvial", res.getValue("flu"), f, 0.002);
             compareExtraResult("Yfluvial", res, "flu", f, 0.002);
 
             // tslint:disable-next-line:max-line-length
@@ -92,11 +92,11 @@ describe("Class Remous / section trapèze :", () => {
                 9.000: 0.27817406380059,
                 10.000: 0.293
             };  // dernière valeur modifiée pour la raison en tête de fichier
-            // compareObject("Ytorrentiel", res.getExtraResult("tor"), t, 0.002);
+            // compareObject("Ytorrentiel", res.getValue("tor"), t, 0.002);
             compareExtraResult("Ytorrentiel", res, "tor", t, 0.002);
 
             // const x = [0.000, 1.000, 2.000, 3.000, 4.000, 5.000, 6.000, 7.000, 8.000, 9.000, 10.000];
-            // compareArray("abcisses", res.getExtraResult("trX"), x);
+            // compareArray("abcisses", res.getValue("trX"), x);
         });
 
         // it('pente forte, ressaut dans le bief sur plusieurs points', () => {
@@ -188,7 +188,7 @@ describe("Class Remous / section trapèze :", () => {
                 95.000: 0.603,
                 100.000: 0.572
             };
-            // compareObject("Hs", res.getExtraResult("Hs"), hs, 0.002);
+            // compareObject("Hs", res.getValue("Hs"), hs, 0.002);
             compareExtraResult("Hs", res, "Hs", hs, 0.002);
         });
 
@@ -277,7 +277,7 @@ describe("Class Remous / section trapèze :", () => {
                 7.900: 1.017,
                 8.000: 1.022
             };
-            // compareObject("Hs", res.getExtraResult("Hs"), hs, 0.009);
+            // compareObject("Hs", res.getValue("Hs"), hs, 0.009);
             compareExtraResult("Hs", res, "Hs", hs, 0.009);
         });
     });
diff --git a/spec/remous/test-remous-fenetre.ts b/spec/remous/test-remous-fenetre.ts
index f97afc47fe3c92b651cdcb6482b7c6580e0a141a..6287fa66deb21f7329016b555998686a0eae4160 100644
--- a/spec/remous/test-remous-fenetre.ts
+++ b/spec/remous/test-remous-fenetre.ts
@@ -199,20 +199,20 @@
 //     // const ligneFluviale: { [key: number]: number; } = remous.calculFluvial();
 //     const rLigneFluviale: ResultElement = remous.calculFluvial();
 //     expect(rLigneFluviale.ok).toBeTruthy("erreur de calcul de la ligne fluviale");
-//     const ligneFluviale: { [key: number]: number; } = rLigneFluviale.getExtraResult("trY");
+//     const ligneFluviale: { [key: number]: number; } = rLigneFluviale.getValue("trY");
 
 //     // ligne torrentielle totale, utilisée pour les conditions initiales
 //     // const ligneTorrentielle: { [key: number]: number; } = remous.calculTorrentiel();
 //     const rLigneTorrentielle: ResultElement = remous.calculTorrentiel();
 //     expect(rLigneTorrentielle.ok).toBeTruthy("erreur de calcul de la ligne torrentielle");
-//     const ligneTorrentielle: { [key: number]: number; } = rLigneTorrentielle.getExtraResult("trY");
+//     const ligneTorrentielle: { [key: number]: number; } = rLigneTorrentielle.getValue("trY");
 
 //     console.log(remous.log.toString());
 //     // let ms = r["remous"].log.messages;
 
-//     const trX = res.getExtraResult("trX");
-//     const flu = res.getExtraResult("flu");
-//     const tor = res.getExtraResult("tor");
+//     const trX = res.getValue("trX");
+//     const flu = res.getValue("flu");
+//     const tor = res.getValue("tor");
 
 //     //  saveCSV(res);
 
@@ -285,9 +285,9 @@
 //         const r2 = computeFenetreRect(yAmont, yAval, +xBief2 - +xBief1, i1 === ni);
 //         const resFenetre: Result = r2.res;
 //         expect(resFenetre.ok).toBeTruthy("erreur de calcul de la fenêtre");
-//         let trX_fenetre = resFenetre.getExtraResult("trX");
-//         let flu_fenetre = resFenetre.getExtraResult("flu");
-//         let tor_fenetre = resFenetre.getExtraResult("tor");
+//         let trX_fenetre = resFenetre.getValue("trX");
+//         let flu_fenetre = resFenetre.getValue("flu");
+//         let tor_fenetre = resFenetre.getValue("tor");
 
 //         // validation du tableau d'abscisses
 
diff --git a/spec/section_param/section_param.spec.ts b/spec/section_param/section_param.spec.ts
index 04517e86da77d416cfd2d0f452f5ef812b1e71b2..dbbda8ace066c1554e2a6afee06f3b90d8c7b187 100644
--- a/spec/section_param/section_param.spec.ts
+++ b/spec/section_param/section_param.spec.ts
@@ -38,7 +38,7 @@ function testVarier(nub: SectionParametree, p: ParamDefinition) {
 
         // tslint:disable-next-line:prefer-for-of
         for (let i = 0; i < nub.result.resultElements.length; i++) {
-            expect(Object.keys(nub.result.resultElements[i].extraResults).length).toBe(17);
+            expect(Object.keys(nub.result.resultElements[i].values).length).toBe(17);
         }
     });
 }
@@ -49,7 +49,7 @@ describe("Section paramétrée rectangulaire, paramètres fixés : ", () => {
         const nub = createSection(precDist);
         nub.CalcSerie();
         expect(nub.result).toBeDefined();
-        expect(Object.keys(nub.result.resultElement.extraResults).length).toBe(17);
+        expect(Object.keys(nub.result.resultElement.values).length).toBe(17);
     });
 });
 
diff --git a/spec/structure/dever.spec.ts b/spec/structure/dever.spec.ts
index f2bdecaff4ad6365f17cb9040872ebaa17be3c98..bf01d278b0830271d33b7ce1405b2cecb1654f2d 100644
--- a/spec/structure/dever.spec.ts
+++ b/spec/structure/dever.spec.ts
@@ -28,16 +28,16 @@ describe("Class Dever: ", () => {
             expect(dever.Calc("Q").vCalc).toBeCloseTo(5.407, 3);
         });
         it("extraResults.V should return 1.352", () => {
-            expect(dever.Calc("Q").extraResults.V).toBeCloseTo(1.352, 3);
+            expect(dever.Calc("Q").values.V).toBeCloseTo(1.352, 3);
         });
         it("extraResults.Ec should return 0.093", () => {
-            expect(dever.Calc("Q").extraResults.Ec).toBeCloseTo(0.093, 3);
+            expect(dever.Calc("Q").values.Ec).toBeCloseTo(0.093, 3);
         });
         it("extraResults.Cv should return 1.116", () => {
-            expect(dever.Calc("Q").extraResults.Cv).toBeCloseTo(1.116, 3);
+            expect(dever.Calc("Q").values.Cv).toBeCloseTo(1.116, 3);
         });
         it("extraResults.CvQT should return 6.036", () => {
-            expect(dever.Calc("Q").extraResults.CvQT).toBeCloseTo(6.036, 3);
+            expect(dever.Calc("Q").values.CvQT).toBeCloseTo(6.036, 3);
         });
     });
 });
diff --git a/spec/structure/functions.ts b/spec/structure/functions.ts
index 7b4823210158e4acdc11f8c0cf897ee0e468d9a0..f0874df85a17fde20854a6ebc74663dd0b372c67 100644
--- a/spec/structure/functions.ts
+++ b/spec/structure/functions.ts
@@ -52,12 +52,12 @@ export function itCalcQ(
         });
         if (mode !== undefined) {
             it("Q(Z1=" + Z1 + ",W=" + W + ") Mode should be " + mode, () => {
-                expect(res.extraResults.ENUM_StructureFlowMode).toBe(mode);
+                expect(res.values.ENUM_StructureFlowMode).toBe(mode);
             });
         }
         if (regime !== undefined) {
             it("Q(Z1=" + Z1 + ",W=" + W + ") Regime should be " + regime, () => {
-                expect(res.extraResults.ENUM_StructureFlowRegime).toBe(regime);
+                expect(res.values.ENUM_StructureFlowRegime).toBe(regime);
             });
         }
     });
@@ -103,7 +103,7 @@ function testStructureLoopPrm(
                     // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé
                     it(`should return an error`, () => {
                         expect(
-                            st.CalcSerie().code
+                            st.CalcSerie().log.messages[0].code
                         ).toBe(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE);
                     });
                 } else {
@@ -138,10 +138,9 @@ export function testParallelStructures(o: { ps: ParallelStructure, ld: number[]
                 o.ps.prms.Q.singleValue = o.ps.CalcSerie().vCalc;
             });
             // Tests sur les résultats complémentaires
-            it(`Calc(Q).extraResults[${i}.Q] should return o.ps.structures[${i}].Calc("Q").vCalc`, () => {
-                expect(
-                    o.ps.Calc("Q").extraResults[`ouvrage[${i}].Q`]
-                ).toBe(
+            it(`Calc(Q).values[${i}.Q] should return o.ps.structures[${i}].Calc("Q").vCalc`, () => {
+                o.ps.Calc("Q");
+                expect(o.ps.structures[i].result.resultElement.values.Q).toBe(
                     o.ps.structures[i].Calc("Q").vCalc
                 );
             });
@@ -173,7 +172,7 @@ export function testParallelStructures(o: { ps: ParallelStructure, ld: number[]
                             // Les lois GateCEM88D et CUNGE80 ne permettent pas le calcul de ZDV
                             it(`should return an error`, () => {
                                 expect(
-                                    o.ps.CalcSerie().code
+                                    o.ps.CalcSerie().log.messages[0].code
                                 ).toBe(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE);
                             });
                         } else if (
diff --git a/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts
index 21dd11ed00c3060e8c230083d7ca08cbcaf72920..f484951a00359e2aee24151b129eaa37ad5868f1 100644
--- a/spec/structure/parallel_structure.spec.ts
+++ b/spec/structure/parallel_structure.spec.ts
@@ -61,23 +61,23 @@ function itParallelStructure(structIndex: number, sVarCalc: string, rVcalc: numb
     if (Q !== undefined) {
         const pstructLocal = createEnv();
         for (let i = 0; i < pstructLocal.structures.length; i++) {
-            it(`Calc(${JSON.stringify(sVarCalc)}) ExtraResult[ouvrage[${i}].Q] should be ${Q}`, () => {
+            it(`Calc(${JSON.stringify(sVarCalc)}) ouvrage[${i}].Q should be ${Q}`, () => {
                 const VC2: any = getVarCalc(pstruct, structIndex, sVarCalc);
-                expect(
-                    pstruct.Calc(VC2).resultElement.extraResults[`ouvrage[${i}].Q`]
-                ).toBeCloseTo(Q, Math.max(0, precDigits - 1));
+                pstruct.Calc(VC2);
+                const val = pstruct.structures[i].result.resultElement.values.Q;
+                expect(val).toBeCloseTo(Q, Math.max(0, precDigits - 1));
             });
             it(`Calc(${JSON.stringify(sVarCalc)}) ExtraResult[ouvrage[${i}].Q_Mode] should be 0`, () => {
                 const VC3 = getVarCalc(pstruct, structIndex, sVarCalc);
-                expect(
-                    pstruct.Calc(VC3).resultElement.extraResults[`ouvrage[${i}].Q_ENUM_StructureFlowMode`]
-                ).toEqual(0);
+                pstruct.Calc(VC3);
+                const val = pstruct.structures[i].result.resultElement.values.ENUM_StructureFlowMode;
+                expect(val).toEqual(0);
             });
             it(`Calc(${JSON.stringify(sVarCalc)}) ExtraResult[ouvrage[${i}].Q_Regime] should be 0`, () => {
                 const VC4 = getVarCalc(pstruct, structIndex, sVarCalc);
-                expect(
-                    pstruct.Calc(VC4).resultElement.extraResults[`ouvrage[${i}].Q_ENUM_StructureFlowRegime`]
-                ).toEqual(0);
+                pstruct.Calc(VC4);
+                const val = pstruct.structures[i].result.resultElement.values.ENUM_StructureFlowRegime;
+                expect(val).toEqual(0);
             });
         }
     }
@@ -91,7 +91,7 @@ describe("Class ParallelStructure: ", () => {
         it("should return 1 result", () => {
             const p1 = createEnv();
             const res: Result = p1.Calc("Q");
-            expect(p1.Calc("Q").nbResultElements).toEqual(1);
+            expect(p1.Calc("Q").resultElements.length).toEqual(1);
         });
         itParallelStructure(null, "Q", 30, 15);
         itParallelStructure(null, "Z1", 30, 15);
@@ -104,7 +104,7 @@ describe("Class ParallelStructure: ", () => {
                 uid: pstruct.structures[1].uid,
                 symbol: "ZDV"
             });
-            expect(res.code).toBe(MessageCode.ERROR_STRUCTURE_Q_TROP_ELEVE);
+            expect(res.log.messages[0].code).toBe(MessageCode.ERROR_STRUCTURE_Q_TROP_ELEVE);
         });
 
         /*
diff --git a/spec/structure/structure.spec.ts b/spec/structure/structure.spec.ts
index e37eb84550943d0d2f394fe81a5f1f204bdce132..1c435756cb7c55adbf257e34c934032a2a209b99 100644
--- a/spec/structure/structure.spec.ts
+++ b/spec/structure/structure.spec.ts
@@ -61,15 +61,16 @@ describe("Class Structure: ", () => {
         });
         it("W=0 => Q=0", () => {
             structTest.prms.W.v = 0;
-            checkResult(structTest.Calc("Q"), 0);
-            expect(structTest.Calc("Q").extraResults).toEqual(flagsNull);
+            const r = structTest.Calc("Q");
+            checkResult(r, 0);
+            expect(r.extraResults).toEqual(flagsNull);
             structTest.prms.W.v = Infinity;
         });
         it("Q=0 => Z1=Z2", () => {
             structTest.prms.Q.singleValue = 0;
             structTest.calculatedParam = structTest.prms.Q;
             checkResult(structTest.CalcSerie(), structTest.prms.h2.v);
-            // expect(structTest.Calc("Z1").extraResults).toEqual(flagsNull);
+            // expect(structTest.Calc("Z1").values).toEqual(flagsNull);
             structTest.prms.Q.singleValue = 1;
         });
         it("Q=0 => W=0", () => {
diff --git a/spec/structure/structure_cem88v.spec.ts b/spec/structure/structure_cem88v.spec.ts
index f9a5d82f2d5a85a903150cfa36d68aa4bd79305c..8ee80ca59266d8edc16575ce7f92e30414aa28ff 100644
--- a/spec/structure/structure_cem88v.spec.ts
+++ b/spec/structure/structure_cem88v.spec.ts
@@ -63,7 +63,7 @@ describe("Class StructureGateCem88v: ", () => {
             s.prms.Q.singleValue = 9;
             s.calculatedParam = s.prms.W;
             const res: Result = s.CalcSerie();
-            expect(res.code).toBe(MessageCode.ERROR_DICHO_TARGET_TOO_HIGH);
+            expect(res.log.messages[0].code).toBe(MessageCode.ERROR_DICHO_TARGET_TOO_HIGH);
         });
     });
 });
diff --git a/spec/test_func.ts b/spec/test_func.ts
index e074ee3f0bbbf7e3b700edf404a5d0e037068de3..0c321f7861a8103a7233d5b99eb09ca811b16b45 100644
--- a/spec/test_func.ts
+++ b/spec/test_func.ts
@@ -192,7 +192,7 @@ export function compareLog(logTest: cLog, logValid: cLog) {
 }
 
 export function checkResult(result: Result, valRef: number, prec?: number) {
-    expect(result.ok).toBeTruthy((!result.ok) ? "Result: ERROR code=" + MessageCode[result.code] : "");
+    expect(result.ok).toBeTruthy((!result.ok) ? "Result: ERROR code=" + MessageCode[result.log.messages[0].code] : "");
     if (result.ok) {
         /*
          * on demande une précision de vérification inférieure à la précision de calcul
@@ -220,10 +220,10 @@ export function checkResultConsistency(nub: Nub, r?: Result) {
             expect(isFiniteNumber(r.vCalc))
                 .toBe(true, `vCalc = ${r.vCalc} isn't a finite number`);
         }
-        if (r.resultElement.hasExtraResults) {
-            for (const key in r.resultElement.extraResults) {
-                if (r.resultElement.extraResults.hasOwnProperty(key)) {
-                    const er = r.resultElement.extraResults[key];
+        if (Object.keys(r.resultElement.values).length > 0) {
+            for (const key in r.resultElement.values) {
+                if (r.resultElement.values.hasOwnProperty(key)) {
+                    const er = r.resultElement.values[key];
                     expect(isFiniteNumber(er))
                         .toBe(
                             true,
@@ -233,7 +233,7 @@ export function checkResultConsistency(nub: Nub, r?: Result) {
             }
         }
     } else {
-        expect(r.hasErrorMessages).toBe(true, "Result KO and no error message");
+        expect(r.hasErrorMessages()).toBe(true, "Result KO and no error message");
     }
 }
 
@@ -255,7 +255,7 @@ export function compareExtraResult(
     const nre = res.resultElements.length;
     let n1 = 0;
     for (let i = 0; i < nre; i++) {
-        if (res.resultElements[i].getExtraResult(key) !== undefined) {
+        if (res.resultElements[i].getValue(key) !== undefined) {
             n1++;
         }
     }
@@ -266,7 +266,7 @@ export function compareExtraResult(
     if (!b) { return; }
 
     for (let i = 0; i < n1; i++) {
-        const v1: number = res.resultElements[i].getExtraResult(key);
+        const v1: number = res.resultElements[i].getValue(key);
         const v2: number = objValid[+Object.keys(objValid)[i]];
         b = equalEpsilon(v1, v2, epsilon);
         expect(b).toBeTruthy(s + " : " + i + "ieme valeur incorrecte " + v1 + ", devrait etre " + v2);
@@ -296,3 +296,13 @@ export function SetJasmineCurrentSpec() {
 export function isFiniteNumber(x: any) {
     return isNumeric(x) && isFinite(x);
 }
+
+export function extraResultLength(res: Result, name: string): number {
+    let nb = 0;
+    for (const re of res.resultElements) {
+        if (re.getValue(name) !== undefined) {
+            nb ++;
+        }
+    }
+    return nb;
+}
diff --git a/spec/util/result_element.spec.ts b/spec/util/result_element.spec.ts
deleted file mode 100644
index 305623c906d0b38b74247f6fff6919d6d776a551..0000000000000000000000000000000000000000
--- a/spec/util/result_element.spec.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * IMPORTANT !
- * Décommenter temporairement la ligne suivante (import { } from "./mock_jasmine")
- * Pour exécuter ce code dans le débugger.
- * Faire de même avec le fichier test_func.ts
- */
-// import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
-
-import { ResultElement } from "../../src/util/resultelement";
-
-describe("Class Result: ", () => {
-    describe("Method AddResulToExtra", () => {
-        const resEle: ResultElement = new ResultElement(1);
-        const resEleToAdd: ResultElement = new ResultElement(2);
-
-        const resEleRef: ResultElement = new ResultElement(1);
-        resEleRef.extraResults = { R: 2 };
-
-        it("Result should be integrated in extraResult", () => {
-            resEle.AddResultElementToExtra(resEleToAdd, "R");
-            expect(resEle).toEqual(resEleRef);
-        });
-    });
-});
diff --git a/src/compute-node.ts b/src/compute-node.ts
index 346ce6e51ca8a337c624dc5a8560c7f1ee5366c2..a7b0795f2f122ff2da6d284f49caea41920d8006 100644
--- a/src/compute-node.ts
+++ b/src/compute-node.ts
@@ -45,10 +45,10 @@ export abstract class ComputeNode extends JalhydObject implements IDebug {
     protected _prms: ParamsEquation;
 
     /**
-     * { symbol => ParamFamily } map for ExtraResults; defines a priori which
-     * future extra result can be linked to other Nub's parameters
+     * { symbol => ParamFamily } map for results; defines a priori which
+     * future result can be linked to other Nub's parameters
      */
-    protected _extraResultsFamilies: any;
+    protected _resultsFamilies: any;
 
     protected _calcType: CalculatorType;
 
@@ -65,7 +65,7 @@ export abstract class ComputeNode extends JalhydObject implements IDebug {
 
         this._prms.Pr.calculability = ParamCalculability.FREE; // so that it can be set through Pr.v
         this.setParametersCalculability();
-        this.setExtraResultsFamilies();
+        this.setResultsFamilies();
     }
 
     public get prms(): ParamsEquation {
@@ -116,12 +116,12 @@ export abstract class ComputeNode extends JalhydObject implements IDebug {
     /**
      * Define ParamFamily (@see ParamDefinition) for extra results
      */
-    protected setExtraResultsFamilies() {
-        this._extraResultsFamilies = {};
+    protected setResultsFamilies() {
+        this._resultsFamilies = {};
     }
 
-    public get extraResultsFamilies()  {
-        return this._extraResultsFamilies;
+    public get resultsFamilies()  {
+        return this._resultsFamilies;
     }
 
     protected abstract setParametersCalculability(): void;
diff --git a/src/jalhyd_object.ts b/src/jalhyd_object.ts
index 732ea42d05b7e7ba5561c10c09c34e6ee2e5a845..3db1b406110b7b011443068aba2814df7412a059 100644
--- a/src/jalhyd_object.ts
+++ b/src/jalhyd_object.ts
@@ -5,7 +5,7 @@ export interface IJalhydObject {
 }
 
 export interface INamedObject extends IJalhydObject {
-    readonly name: string;
+    readonly symbol: string;
 }
 
 export interface IObjectWithFamily extends IJalhydObject {
diff --git a/src/linked-value.ts b/src/linked-value.ts
index e1d6a0a3499a807513c4849925529fb0b089fd7b..a9c7bb633e6880cd4f98a030c337cd9e36d91ee3 100644
--- a/src/linked-value.ts
+++ b/src/linked-value.ts
@@ -11,7 +11,7 @@ export class LinkedValue {
     /** target Nub */
     private _nub: Nub;
 
-    /** target value : ParamDefinition (possibly in CALC mode) | undefined (ExtraResults) */
+    /** target value : ParamDefinition (possibly in CALC mode) | undefined (extra result) */
     private _element: INamedIterableValues;
 
     /** parameter / result symbol (ex: "Q") */
@@ -105,7 +105,7 @@ export class LinkedValue {
     /**
      * Returs the ParamValues for the linked Parameter if any, or a
      * fake ParamValues object if the targetted element is a Result
-     * or ExtraResults.
+     * or extra result.
      * If target is a result and triggerChainComputation is true,
      * triggers a chain computation to obtain the result
      */
@@ -159,10 +159,10 @@ export class LinkedValue {
                     this._paramValues = new ParamValues();
                     // populate
                     if (this.nub.resultHasMultipleValues()) {
-                        const multipleExtraRes = this.nub.result.getExtraResults(this.symbol);
+                        const multipleExtraRes = this.getExtraResults(this.symbol);
                         this._paramValues.setValues(multipleExtraRes);
                     } else {
-                        const singleExtraRes = this.nub.result.getExtraResult(this.symbol);
+                        const singleExtraRes = this.nub.result.getValue(this.symbol);
                         this._paramValues.setValues(singleExtraRes);
                     }
                 }
@@ -221,4 +221,15 @@ export class LinkedValue {
     public invalidateParamValues() {
         this._paramValues = undefined;
     }
+
+    private getExtraResults(symbol: string): number[] {
+        const res: number[] = [];
+        for (const re of this.nub.result.resultElements) {
+            const er = re.getValue(symbol);
+            if (er !== undefined) {
+                res.push(er);
+            }
+        }
+        return res;
+    }
 }
diff --git a/src/macrorugo/macrorugo.ts b/src/macrorugo/macrorugo.ts
index 2a652cc40dd99d399a4a806e1b47a6560496e177..2f1bb744be7f26d1ce36ebd779c7489a7ac91133 100644
--- a/src/macrorugo/macrorugo.ts
+++ b/src/macrorugo/macrorugo.ts
@@ -68,33 +68,33 @@ export class MacroRugo extends Nub {
         const r: Result = super.Calc(sVarCalc, rInit);
         // Ajout des résultats complémentaires
         // Cote de fond aval
-        r.extraResults.ZF2 = this.prms.ZF1.v - this.prms.If.v * this.prms.L.v;
+        r.resultElement.values.ZF2 = this.prms.ZF1.v - this.prms.If.v * this.prms.L.v;
         // Vitesse débitante
-        r.extraResults.Vdeb = this.prms.Q.V / this.prms.B.v / this.prms.Y.v;
+        r.resultElement.values.Vdeb = this.prms.Q.V / this.prms.B.v / this.prms.Y.v;
         // Froude
-        const vg: number = r.extraResults.Vdeb / (1 - Math.sqrt(MacroRugo.fracAxAy * this.prms.C.v));
-        r.extraResults.Fr = vg / Math.sqrt(MacroRugo.g * this.prms.Y.v);
+        const vg: number = r.resultElement.values.Vdeb / (1 - Math.sqrt(MacroRugo.fracAxAy * this.prms.C.v));
+        r.resultElement.values.Fr = vg / Math.sqrt(MacroRugo.g * this.prms.Y.v);
         // Vitesse maximale
         const cc = 0.4 * this.prms.Cd0.v + 0.7;
-        r.extraResults.Vmax = vg * Math.min(
-            cc / (1 - Math.pow(r.extraResults.Fr, 2) / 4),
-            Math.pow(r.extraResults.Fr, -2 / 3)
+        r.resultElement.values.Vmax = vg * Math.min(
+            cc / (1 - Math.pow(r.resultElement.values.Fr, 2) / 4),
+            Math.pow(r.resultElement.values.Fr, -2 / 3)
         );
         // Puissance dissipée
-        r.extraResults.PV = 1000 * MacroRugo.g * this.prms.Q.V / this.prms.B.v * this.prms.If.v;
+        r.resultElement.values.PV = 1000 * MacroRugo.g * this.prms.Q.V / this.prms.B.v * this.prms.If.v;
         // Type d'écoulement
         if (this.prms.Y.v / this.prms.PBH.v < 1) {
-            r.extraResults.ENUM_MacroRugoFlowType = MacroRugoFlowType.EMERGENT;
+            r.resultElement.values.ENUM_MacroRugoFlowType = MacroRugoFlowType.EMERGENT;
         } else if (this.prms.Y.v / this.prms.PBH.v < MacroRugo.limitSubmerg) {
-            r.extraResults.ENUM_MacroRugoFlowType = MacroRugoFlowType.QUASI_EMERGENT;
+            r.resultElement.values.ENUM_MacroRugoFlowType = MacroRugoFlowType.QUASI_EMERGENT;
         } else {
-            r.extraResults.ENUM_MacroRugoFlowType = MacroRugoFlowType.SUBMERGED;
+            r.resultElement.values.ENUM_MacroRugoFlowType = MacroRugoFlowType.SUBMERGED;
         }
         // Vitesse et débit du guide technique
         let cQ: [number, number, number, number];
         let cV: [number, number, number];
         let hdk: number;
-        if (r.extraResults.ENUM_MacroRugoFlowType === MacroRugoFlowType.SUBMERGED) {
+        if (r.resultElement.values.ENUM_MacroRugoFlowType === MacroRugoFlowType.SUBMERGED) {
             cQ = [0.955, 2.282, 0.466, -0.23];
             hdk = this.prms.PBH.v;
         } else {
@@ -107,11 +107,11 @@ export class MacroRugo extends Nub {
                 cV = [4.54, 0.32, 0.56];
             }
         }
-        r.extraResults.Q_GuideTech = cQ[0] * Math.pow(this.prms.Y.v / hdk, cQ[1]) *
+        r.resultElement.values.Q_GuideTech = cQ[0] * Math.pow(this.prms.Y.v / hdk, cQ[1]) *
             Math.pow(this.prms.If.v, cQ[2]) * Math.pow(this.prms.C.v, cQ[3]) *
             Math.sqrt(MacroRugo.g * hdk) * hdk * this.prms.B.v;
-        if (r.extraResults.ENUM_MacroRugoFlowType !== MacroRugoFlowType.SUBMERGED) {
-            r.extraResults.V_GuideTech = cV[0] * Math.pow(this.prms.Y.v / this.prms.PBD.v, cV[1]) *
+        if (r.resultElement.values.ENUM_MacroRugoFlowType !== MacroRugoFlowType.SUBMERGED) {
+            r.resultElement.values.V_GuideTech = cV[0] * Math.pow(this.prms.Y.v / this.prms.PBD.v, cV[1]) *
                 Math.pow(this.prms.If.v, cV[2]) * Math.sqrt(MacroRugo.g * this.prms.PBD.v);
         }
 
@@ -151,8 +151,8 @@ export class MacroRugo extends Nub {
         this.prms.Cd0.calculability = ParamCalculability.FREE;
     }
 
-    protected setExtraResultsFamilies() {
-        this._extraResultsFamilies = {
+    protected setResultsFamilies() {
+        this._resultsFamilies = {
             ZF2: ParamFamily.ELEVATIONS,
             Q_GuideTech: ParamFamily.FLOWS
         };
diff --git a/src/nub.ts b/src/nub.ts
index 3b258d994cbaaf41276a5560da497f064360e0ea..e4809e58135d1c0b994b75d0e09dc9420369bfd4 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -3,7 +3,7 @@ import { Dichotomie } from "./dichotomie";
 import { acSection, IParamDefinitionIterator, Pab, ParamDefinition, ParamsEquation,
          ParamsEquationArrayIterator, Session, Structure } from "./index";
 import { LinkedValue } from "./linked-value";
-import { ParamCalculability } from "./param/param-definition";
+import { ParamCalculability, ParamFamily } from "./param/param-definition";
 import { ParamValueMode } from "./param/param-value-mode";
 import { ParamValues } from "./param/param-values";
 import { Props } from "./props";
@@ -27,7 +27,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
      * (used by CalcSerie with varying parameters)
      */
     protected set currentResult(r: Result) {
-        // if for ex. Calc() is called outside of CalcSerie(), _result might not be initialized
+        // this.setCurrentResult(r);
         if (! this._result) {
             this.initNewResultElement();
         }
@@ -316,22 +316,23 @@ export abstract class Nub extends ComputeNode implements IObservable {
         }
         if (computedVar.isAnalytical()) {
             this.currentResult = this.Equation(sVarCalc);
-            this._result.name = sVarCalc;
+            this._result.symbol = sVarCalc;
             return this._result;
         }
 
         const resSolve: Result = this.Solve(sVarCalc, rInit);
         if (!resSolve.ok) {
             this.currentResult = resSolve;
-            this._result.name = sVarCalc;
+            this._result.symbol = sVarCalc;
             return this._result;
         }
         const sAnalyticalPrm: string = this.getFirstAnalyticalParameter().symbol;
         computedVar.v = resSolve.vCalc;
         const res: Result = this.Equation(sAnalyticalPrm);
         res.vCalc = resSolve.vCalc;
+
         this.currentResult = res;
-        this._result.name = sVarCalc;
+        this._result.symbol = sVarCalc;
 
         this.notifyResultUpdated();
 
@@ -457,7 +458,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
 
         if (computedSymbol !== undefined) {
             const realSymbol = (typeof computedSymbol === "string") ? computedSymbol : computedSymbol.symbol;
-            this._result.name = realSymbol;
+            this._result.symbol = realSymbol;
         }
 
         this.notifyResultUpdated();
@@ -546,13 +547,13 @@ export abstract class Nub extends ComputeNode implements IObservable {
             }
 
             // 2. extra results
-            if (this._extraResultsFamilies) {
+            if (this._resultsFamilies) {
                 // if I don't depend on your result, you may depend on mine !
                 if (! this.dependsOnNubResult(src.parentNub)) {
-                    const erk = Object.keys(this._extraResultsFamilies);
+                    const erk = Object.keys(this._resultsFamilies);
                     // browse extra results
                     for (const erSymbol of erk) {
-                        const erFamily = this._extraResultsFamilies[erSymbol];
+                        const erFamily = this._resultsFamilies[erSymbol];
                         // if family is identical
                         if (erFamily === src.family) {
                             res.push(new LinkedValue(this, undefined, erSymbol));
@@ -1210,6 +1211,29 @@ export abstract class Nub extends ComputeNode implements IObservable {
         this._observable.notifyObservers(data, sender);
     }
 
+    /**
+     * Retrieves the ParamFamily associated to the given symbol, whether it is a
+     * parameter or a result
+     */
+    public getFamily(symbol: string): ParamFamily {
+        // is it a parameter ?
+        let p;
+        try { // SectionNub.getParameter() (for ex.) throws exceptions
+            p = this.getParameter(symbol);
+        } catch (e) {
+            // silent fail
+        }
+        if (p) {
+            return p.family;
+        }
+        // is it a result ?
+        if (symbol in this.resultsFamilies) {
+            return this.resultsFamilies[symbol];
+        }
+        // give up
+        return undefined;
+    }
+
     protected findCalculatedParameter(sDonnee: any): any {
         let computedSymbol: any;
         if (sDonnee) {
diff --git a/src/pab/cloison_aval.ts b/src/pab/cloison_aval.ts
index 3851a974612371e68ec1a01782a134a57011db77..f533640c535afcdb65daa29a92133113b75932f0 100644
--- a/src/pab/cloison_aval.ts
+++ b/src/pab/cloison_aval.ts
@@ -56,8 +56,6 @@ export class CloisonAval extends ParallelStructure {
             this.prms.Z1.v = this.prms.Z2.v + s.getParameter("DH").v;
             this.currentResult = this.CalcStructPrm(this.indexVanneLevante, "ZDV");
             if (this.result.ok) {
-                // Suppression des extraResults : ils sont complétés plus bas pour chaque ouvrage
-                this.result.resultElement.extraResults = {};
                 s.prms.ZDV.v = this.result.vCalc;
             }
             // Check if calculated ZDV is between minZDV and maxZDV
@@ -77,12 +75,14 @@ export class CloisonAval extends ParallelStructure {
                 // Recalcul du débit total pour récupérer les résultats des ouvrages dans les résultats complémentaires
                 const resQtot: Result = this.CalcQ();
                 for (const extraResKey in resQtot.extraResults) {
-                    if (resQtot.extraResults.hasOwnProperty(extraResKey)) {
-                        this.result.resultElement.addExtraResult(extraResKey, resQtot.extraResults[extraResKey]);
+                    if (resQtot.resultElement.values.hasOwnProperty(extraResKey)) {
+                        this.result.resultElement.addExtraResult(
+                            extraResKey, resQtot.resultElement.values[extraResKey]
+                        );
                     }
                 }
                 if (this.hasVanneLevante()) {
-                    this.result.extraResults.ZDV = this.structures[this.indexVanneLevante].prms.ZDV.v;
+                    this.result.resultElement.values.ZDV = this.structures[this.indexVanneLevante].prms.ZDV.v;
                     if (m !== undefined) {
                         this.result.resultElement.addMessage(m);
                     }
diff --git a/src/pab/cloisons.ts b/src/pab/cloisons.ts
index 3149b1bda4ad34f22d220baf5fd0f1984c0b4155..32ec000c0493af0204739ce93a44c4c5fafd7353 100644
--- a/src/pab/cloisons.ts
+++ b/src/pab/cloisons.ts
@@ -66,16 +66,16 @@ export class Cloisons extends ParallelStructure {
         const prms = this.getParamValuesAfterCalc(sVarCalc, r);
         const ro: number = 1000;     // masse volumique de l'eau en kg/m3
         const g: number = 9.81;     // accélération de la gravité terrestre en m/s2.
-        r.extraResults.PV = ro * g * this.prms.Q.v * (prms.Z1 - prms.Z2) / (prms.LB * prms.BB * prms.PB);
+        r.resultElement.values.PV = ro * g * this.prms.Q.v * (prms.Z1 - prms.Z2) / (prms.LB * prms.BB * prms.PB);
 
         // Ajout de la cote de radier de bassin
-        r.extraResults.ZRMB = this.prms.ZRMB.v;
-        r.extraResults.ZRAM = this.prms.ZRAM.v;
+        r.resultElement.values.ZRMB = this.prms.ZRMB.v;
+        r.resultElement.values.ZRAM = this.prms.ZRAM.v;
 
         // Ajout de ZDV pour les seuils
-        for (let i = 0; i < this.structures.length; i++) {
-            if (this.structures[i].prms.h1.visible) {
-                r.resultElement.addExtraResult(`ouvrage[${i}].ZDV`, this.prms.Z1.v - this.structures[i].prms.h1.v);
+        for (const s of this.structures) {
+            if (s.prms.h1.visible) {
+                s.result.resultElement.addExtraResult("ZDV", this.prms.Z1.v - s.prms.h1.v);
             }
         }
 
diff --git a/src/pab/pab.ts b/src/pab/pab.ts
index 3206a8042d63702ca61eb1570efeaa0dac70c00f..29bba650feb506fcec243cd2001902728449a8fd 100644
--- a/src/pab/pab.ts
+++ b/src/pab/pab.ts
@@ -126,7 +126,7 @@ export class Pab extends Nub {
                 r.resultElement.addMessage(new Message(MessageCode.ERROR_PAB_Z1_LOWER_THAN_UPSTREAM_WALL));
             }
         }
-        if (r.hasErrorMessages) {
+        if (r.hasErrorMessages()) {
             this.currentResult = r;
             return this.result;
         }
@@ -164,11 +164,11 @@ export class Pab extends Nub {
         if (!this.downWall.result.ok) {
             return new Result(new Message(MessageCode.ERROR_PAB_CALC_Z1_CLOISON));
         }
-        this.downWall.result.extraResults.ZRAM =
+        this.downWall.result.resultElement.values.ZRAM =
             this.children[this.children.length - 1].prms.ZRMB.v
             - this.children[this.children.length - 1].prms.DH.v / 2;
-        this.downWall.result.extraResults.Q = this.downWall.prms.Q.v;
-        this.downWall.result.extraResults.x = l;
+        this.downWall.result.resultElement.values.Q = this.downWall.prms.Q.v;
+        this.downWall.result.resultElement.values.x = l;
         this.debug("Downstream wall");
         this.dbgWall(this.downWall);
 
@@ -184,11 +184,11 @@ export class Pab extends Nub {
                 return new Result(new Message(MessageCode.ERROR_PAB_CALC_Z1_CLOISON));
             }
             // Add extraresults: mean depth in pool and discharge
-            cl.result.extraResults.YMOY = cl.prms.PB.v;
-            cl.result.extraResults.Q = cl.prms.Q.v;
-            cl.result.extraResults.QA = cl.prms.QA.v;
+            cl.result.resultElement.values.YMOY = cl.prms.PB.v;
+            cl.result.resultElement.values.Q = cl.prms.Q.v;
+            cl.result.resultElement.values.QA = cl.prms.QA.v;
             l -= cl.prms.LB.v;
-            cl.result.extraResults.x = l;
+            cl.result.resultElement.values.x = l;
 
             this.debug("Bassin n°" + i);
             this.dbgWall(cl);
@@ -353,7 +353,7 @@ export class Pab extends Nub {
         cl.Calc("Z1", Z + 0.1);
 
         // Fall on this wall
-        cl.result.extraResults.DH = cl.result.vCalc - cl.prms.Z2.v;
+        cl.result.resultElement.values.DH = cl.result.vCalc - cl.prms.Z2.v;
 
         // Return Update elevation for next pool
         return cl.result.vCalc;
diff --git a/src/pab/pab_nombre.ts b/src/pab/pab_nombre.ts
index d84190631b36c95fc7771ea874f13d466749bbc2..fbad5cd396ad6c9c7c5e9ca66f248cfe1204ce93 100644
--- a/src/pab/pab_nombre.ts
+++ b/src/pab/pab_nombre.ts
@@ -89,7 +89,7 @@ export class PabNombre extends Nub {
         }
 
         const r = new Result(v, this);
-        r.extraResults.DHR = DHR;
+        r.resultElement.values.DHR = DHR;
 
         return r;
     }
diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts
index c09dfa827640289936061cff5844ee0228b46d3c..fd7362becbbeeb72e68560a5726c596a8fd8710b 100644
--- a/src/param/param-definition.ts
+++ b/src/param/param-definition.ts
@@ -376,7 +376,7 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
                 defined = (this.valueList && this.valueList.length > 0 && this.valueList[0] !== undefined);
                 break;
             case ParamValueMode.CALCUL:
-                if (this.parentNub && this.parentNub.result && this.parentNub.result.nbResultElements > 0) {
+                if (this.parentNub && this.parentNub.result && this.parentNub.result.resultElements.length > 0) {
                     const res = this.parentNub.result;
                     defined = (res.vCalc !== undefined);
                 }
@@ -695,7 +695,7 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
             // - start here to avoid extra results being presented as
             // parameters by the iterator internally used by nub.getParameter()
             // - extra results with no family are not linkable
-            if (Object.keys(nub.extraResultsFamilies).includes(symbol)) {
+            if (Object.keys(nub.resultsFamilies).includes(symbol)) {
                 this._referencedValue = new LinkedValue(nub, undefined, symbol);
             } else {
                 // 2. is it a parameter (possibly in CALC mode) ?
@@ -966,12 +966,6 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
         return linked;
     }
 
-    // interface INamedIterableValues
-
-    get name(): string {
-        return this._symbol;
-    }
-
     // interface IterableValues
 
     /**
diff --git a/src/remous/remous.ts b/src/remous/remous.ts
index c4e6c61e1bad962f2a7a7e29a4ee1f69844daec0..7203ecb286ea65a3813ae77ebd4bc1f96de9bfc9 100644
--- a/src/remous/remous.ts
+++ b/src/remous/remous.ts
@@ -8,11 +8,17 @@ import { ParamValues } from "../param/param-values";
 import { ParamsEquation } from "../param/params-equation";
 import { SectionNub } from "../section/section_nub";
 import { acSection } from "../section/section_type";
+import { cLog } from "../util/log";
 import { Message, MessageCode } from "../util/message";
 import { Result } from "../util/result";
 import { ResultElement } from "../util/resultelement";
 import { MethodeResolution } from "./methode-resolution";
 
+export interface ITrYResult {
+    trY: { [key: number]: number; };
+    log: cLog;
+}
+
 /**
  * paramètres pour les courbes de remous
  */
@@ -206,25 +212,17 @@ export class CourbeRemous extends SectionNub {
         xValues.setValues(0, this.prms.Long.v, this.prms.Dx.v);
         xValues.valueMode = ParamValueMode.MINMAX;
 
-        // let crbFlu: { [key: number]: number; } = this.calculFluvial();
-        const rCourbeFlu: ResultElement = this.calculFluvial(xValues);
-        // if (!rCourbeFlu.ok) {
+        const rCourbeFlu: ITrYResult = this.calculFluvial(xValues);
         res.addLog(rCourbeFlu.log);
-        // 	return res;
-        // }
 
-        // let crbTor: { [key: number]: number; } = this.calculTorrentiel();
-        const rCourbeTor: ResultElement = this.calculTorrentiel(xValues);
-        // if (!rCourbeTor.ok) {
+        const rCourbeTor: ITrYResult = this.calculTorrentiel(xValues);
         res.addLog(rCourbeTor.log);
-        // 	return res;
-        // }
 
-        let crbFlu = rCourbeFlu.getExtraResult("trY");
+        let crbFlu = rCourbeFlu.trY;
         if (crbFlu === undefined) {
             crbFlu = {};
         }
-        let crbTor = rCourbeTor.getExtraResult("trY");
+        let crbTor = rCourbeTor.trY;
         if (crbTor === undefined) {
             crbTor = {};
         }
@@ -469,7 +467,7 @@ export class CourbeRemous extends SectionNub {
             } else {
                 ligneDeau = Math.max(crbFlu[x], crbTor[x]);
             }
-            const re = new ResultElement(ligneDeau);
+            const re = new ResultElement({ Y: ligneDeau });
 
             if (crbFlu[x]) {
                 re.addExtraResult("flu", crbFlu[x]);
@@ -512,7 +510,7 @@ export class CourbeRemous extends SectionNub {
     public Equation(sVarCalc: string): Result {
         if (sVarCalc === "Hs") {
             const rHS: number = this.CalcHS();
-            return new Result(rHS);
+            return new Result(rHS, this);
         }
 
         throw new Error("CourbeRemous.Equation() : parameter " + sVarCalc + " not allowed");
@@ -583,13 +581,17 @@ export class CourbeRemous extends SectionNub {
     /**
      * calcul de la ligne fluviale depuis l'aval (si possible)
      */
-    private calculFluvial(xValues: ParamValues): ResultElement {
+    private calculFluvial(xValues: ParamValues): ITrYResult {
+        let res: ITrYResult = {
+            log: new cLog(),
+            trY: {}
+        };
+
         if (!this.Sn.HautCritique.ok) {
-            return new ResultElement(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE));
+            res.log.add(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE));
+            return res;
         }
 
-        let res: ResultElement;
-
         // Calcul depuis l'aval
         if (this.Sn.HautCritique.vCalc <= this.prms.Yaval.v) {
             // this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_FLUVIAL));
@@ -600,15 +602,15 @@ export class CourbeRemous extends SectionNub {
             this.Dx = this.prms.Dx.v;
             xValues.initValuesIterator(true);
             res = this.calcul(this.prms.Yaval.v, xValues);
-            res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_FLUVIAL));
+            res.log.insert(new Message(MessageCode.INFO_REMOUS_CALCUL_FLUVIAL));
         } else {
             this.debug(
                 "Condition limite aval (" + this.prms.Yaval.v +
                 ") < Hauteur critique (" + this.Sn.HautCritique +
                 ") : pas de calcul possible depuis l'aval");
             // this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL));
-            res = new ResultElement();
-            res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL));
+            res.log = new cLog();
+            res.log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL));
         }
 
         return res;
@@ -617,13 +619,17 @@ export class CourbeRemous extends SectionNub {
     /**
      * calcul de la ligne torrentielle depuis l'amont (si possible)
      */
-    private calculTorrentiel(xValues: ParamValues): ResultElement {
+    private calculTorrentiel(xValues: ParamValues): ITrYResult {
+        let res: ITrYResult = {
+            log: new cLog(),
+            trY: {}
+        };
+
         if (!this.Sn.HautCritique.ok) {
-            return new ResultElement(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE));
+            res.log.add(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE));
+            return res;
         }
 
-        let res: ResultElement;
-
         // Calcul depuis l'amont
         if (this.Sn.HautCritique.vCalc >= this.prms.Yamont.v) {
             // this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_TORRENTIEL));
@@ -635,15 +641,15 @@ export class CourbeRemous extends SectionNub {
             this.Dx = -this.prms.Dx.v;
             xValues.initValuesIterator(false);
             res = this.calcul(this.prms.Yamont.v, xValues);
-            res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_TORRENTIEL));
+            res.log.insert(new Message(MessageCode.INFO_REMOUS_CALCUL_TORRENTIEL));
         } else {
             // this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT));
             this.debug(
                 "Condition limite amont (" + this.prms.Yamont.v +
                 ") > Hauteur critique (" + this.Sn.HautCritique +
                 ") : pas de calcul possible depuis l'amont");
-            res = new ResultElement();
-            res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT));
+            res.log = new cLog();
+            res.log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT));
         }
 
         return res;
@@ -857,12 +863,14 @@ export class CourbeRemous extends SectionNub {
      * Calcul d'une courbe de remous en fluvial ou torrentiel
      * @param YCL Condition limite amont (torrentiel) ou aval (fluvial)
      */
-    private calcul(YCL: number, varParam: ParamValues): ResultElement {
-        const trY: { [key: number]: number; } = {};
-        const res = new ResultElement();
+    private calcul(YCL: number, varParam: ParamValues): ITrYResult {
+        const res: ITrYResult = {
+            log: new cLog(),
+            trY: {}
+        };
 
         let lastY = YCL;
-        trY[round(varParam.next().value, this.section.prms.iPrec)] = lastY;
+        res.trY[round(varParam.next().value, this.section.prms.iPrec)] = lastY;
 
         // Boucle de calcul de la courbe de remous
         while (varParam.hasNext) {
@@ -889,23 +897,21 @@ export class CourbeRemous extends SectionNub {
                     const m: Message = new Message(MessageCode.ERROR_REMOUS_PENTE_FORTE);
                     m.extraVar.x = x;
                     // this._log.add(m);
-                    res.addMessage(m);
+                    res.log.add(m);
                 }
 
-                trY[round(x, this.section.prms.iPrec)] = rY.vCalc;
+                res.trY[round(x, this.section.prms.iPrec)] = rY.vCalc;
             } else {
                 const m = new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE);
                 m.extraVar.x = x;
                 // this._log.add(m);
-                res.addMessage(m);
+                res.log.add(m);
                 this.debug("Arrêt du calcul : Hauteur critique atteinte à l'abscisse " + x + " m");
                 break;
             }
             lastY = rY.vCalc;
         }
 
-        // return trY;
-        res.addExtraResult("trY", trY);
         return res;
     }
 
diff --git a/src/section/section_parametree.ts b/src/section/section_parametree.ts
index 7b5d2a5a7a4b74564ba3c895e272d81fab215d96..0ef7ed543d53e85e2a757f37eb79e0350190a767 100644
--- a/src/section/section_parametree.ts
+++ b/src/section/section_parametree.ts
@@ -188,8 +188,8 @@ export class SectionParametree extends SectionNub {
     // tslint:disable-next-line:no-empty
     protected adjustChildParameters(): void {}
 
-    protected setExtraResultsFamilies() {
-        this._extraResultsFamilies = {
+    protected setResultsFamilies() {
+        this._resultsFamilies = {
             B: ParamFamily.WIDTHS,
             Yc: ParamFamily.HEIGHTS,
             Yn: ParamFamily.HEIGHTS,
diff --git a/src/session.ts b/src/session.ts
index f1a2070a5bfd75144c698b47dbc1d6eabd17a551..745bc6c54e7e9a1808d361baa1df2c1be5eb1570 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -207,7 +207,7 @@ export class Session {
     }
 
     /**
-     * Creates a Nub from a JSON representation and adds it tot he current session; returns
+     * Creates a Nub from a JSON representation and adds it to the current session; returns
      * a pointer to the Nub and its JSON metadata
      * @param serialised JSON representation of a single Nub
      * @param register if false, new Nub will just be returned and won't be registered into the session
diff --git a/src/structure/dever.ts b/src/structure/dever.ts
index 819803143b3434dd1fcee6e0a3e152e8c2f72f45..a1bbd61a496881a094233ad00b23b08e17dd796c 100644
--- a/src/structure/dever.ts
+++ b/src/structure/dever.ts
@@ -42,17 +42,17 @@ export class Dever extends ParallelStructure {
         }
         // Vitesse dans le cours d'eau amont
         if (this.prms.Z1.v > this.prms.ZR.v) {
-            r.extraResults.V = QT / (this.prms.BR.v * Math.max(0, this.prms.Z1.v - this.prms.ZR.v));
+            r.resultElement.values.V = QT / (this.prms.BR.v * Math.max(0, this.prms.Z1.v - this.prms.ZR.v));
             // Energie cinétique dans le cours d'eau amont
-            r.extraResults.Ec = r.extraResults.V * r.extraResults.V / (2 * 9.81);
+            r.resultElement.values.Ec = r.resultElement.values.V * r.resultElement.values.V / (2 * 9.81);
             // Calcul du rapport des aires sur les seuils et de l'aire du cours d'eau amont
             const rA: number = this.calcA() / (this.prms.BR.v * Math.max(0, this.prms.Z1.v - this.prms.ZR.v));
             // Calcul de Cv
-            r.extraResults.Cv = this.calcCv(rA);
+            r.resultElement.values.Cv = this.calcCv(rA);
             // Calcul de CV.QT
-            r.extraResults.CvQT = r.extraResults.Cv * QT;
+            r.resultElement.values.CvQT = r.resultElement.values.Cv * QT;
         } else {
-            r.resultElement.addMessage(new Message(MessageCode.ERROR_DEVER_ZR_SUP_Z1));
+            r.resultElement.addMessage(new Message(MessageCode.WARNING_DEVER_ZR_SUP_Z1));
         }
         return r;
     }
@@ -76,8 +76,8 @@ export class Dever extends ParallelStructure {
         this.prms.Z2.visible = false;
     }
 
-    protected setExtraResultsFamilies() {
-        this._extraResultsFamilies = {
+    protected setResultsFamilies() {
+        this._resultsFamilies = {
             CvQT: ParamFamily.FLOWS
         };
     }
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
index bac6ffb80e450e4e44b5ad54c74a41a7c4444d40..107b5b571a63ba2f13b20e3f6f2117c9460d176a 100644
--- a/src/structure/parallel_structure.ts
+++ b/src/structure/parallel_structure.ts
@@ -91,7 +91,8 @@ export class ParallelStructure extends Nub {
         for (let i = 0; i < this._children.length; i++) {
             if (i !== iExcept) {
                 const res: Result = this._children[i].Calc("Q");
-                calcRes.resultElement.AddResultElementToExtra(res.resultElement, `ouvrage[${i}].Q`);
+                // @TODO vérifier que ça marche sans la ligne ci-dessous
+                // calcRes.resultElement.AddResultElementToExtra(res.resultElement, `ouvrage[${i}].Q`);
                 qTot += res.vCalc;
             }
         }
@@ -129,8 +130,6 @@ export class ParallelStructure extends Nub {
                 const structureIndex = this.getIndexForChild(sVarCalc.uid);
                 this.currentResult = this.CalcStructPrm(structureIndex, sVarCalc.symbol, rInit);
                 if (this.result.ok) {
-                    // Suppression des extraResults : ils sont complétés plus bas pour chaque ouvrage
-                    this.result.resultElement.extraResults = {};
                     this._children[structureIndex].getParameter(sVarCalc.symbol).v = this.result.resultElement.vCalc;
                 }
         }
@@ -138,8 +137,10 @@ export class ParallelStructure extends Nub {
             // Recalcul du débit total pour récupérer les résultats des ouvrages dans les résultats complémentaires
             const resQtot: Result = this.CalcQ();
             for (const extraResKey in resQtot.extraResults) {
-                if (resQtot.extraResults.hasOwnProperty(extraResKey)) {
-                    this.result.resultElement.addExtraResult(extraResKey, resQtot.extraResults[extraResKey]);
+                if (resQtot.resultElement.values.hasOwnProperty(extraResKey)) {
+                    this.result.resultElement.addExtraResult(
+                        extraResKey, resQtot.extraResults.resultElement.values[extraResKey]
+                    );
                 }
             }
         }
diff --git a/src/structure/structure_kivi.ts b/src/structure/structure_kivi.ts
index 01dc093c1926de24657971e6576aeef2099f1b27..a00937d3c9c6bfa12056be4b133ef803cff04266 100644
--- a/src/structure/structure_kivi.ts
+++ b/src/structure/structure_kivi.ts
@@ -46,7 +46,7 @@ export class StructureKivi extends Structure {
 
         let Q = cd * this.prms.L.v * Structure.R2G * Math.pow(this.prms.h1.v, 1.5);
 
-        if (res.extraResults.ENUM_StructureFlowRegime === StructureFlowRegime.SUBMERGED) {
+        if (res.resultElement.values.ENUM_StructureFlowRegime === StructureFlowRegime.SUBMERGED) {
             Q = Villemonte(this.prms.h1.v, this.prms.h2.v, 1.5) * Q;
         }
 
diff --git a/src/structure/structure_weir_villemonte.ts b/src/structure/structure_weir_villemonte.ts
index cd06a7290e4a20df679f3d9753a30c6bee501d36..a2399dc5032f915de5423f727bdf4770e38eb26d 100644
--- a/src/structure/structure_weir_villemonte.ts
+++ b/src/structure/structure_weir_villemonte.ts
@@ -17,7 +17,7 @@ export class StructureWeirVillemonte extends StructureWeirFree {
      */
     public CalcQ(): Result {
         const r: Result = super.CalcQ();
-        if (r.ok && r.extraResults.ENUM_StructureFlowRegime !== StructureFlowRegime.FREE) {
+        if (r.ok && r.resultElement.values.ENUM_StructureFlowRegime !== StructureFlowRegime.FREE) {
             r.vCalc = Villemonte(this.prms.h1.v, this.prms.h2.v, 1.5) * r.vCalc;
         }
         return r;
diff --git a/src/util/message.ts b/src/util/message.ts
index a08100a50335de7884e0039d7ab55a8d14a9b6e3..5593a09130aa062489e601db6eb2850b1379d8ed 100644
--- a/src/util/message.ts
+++ b/src/util/message.ts
@@ -136,7 +136,7 @@ export enum MessageCode {
     /**
      * Dever : La cote du lit de la rivière ne peut pas être supérieure à la cote de l'eau
      */
-    ERROR_DEVER_ZR_SUP_Z1,
+    WARNING_DEVER_ZR_SUP_Z1,
 
     /**
      * internationalisation : langue non prise en charge
diff --git a/src/util/result.ts b/src/util/result.ts
index fafdab0bbf03e148ad4205cd9cd60444eb2612c0..83db9cbb484bf2af1c87ae0f28d10195720efe36 100644
--- a/src/util/result.ts
+++ b/src/util/result.ts
@@ -1,232 +1,120 @@
 import { JalhydObject } from "../jalhyd_object";
 import { Nub } from "../nub";
-import { ParamFamily } from "../param/param-definition";
-import {
-    INamedIterableValues,
-    INumberIterator,
-    NumberArrayIterator,
-    NumberArrayReverseIterator
-} from "../param/param-value-iterator";
 import { cLog } from "./log";
-import { Message, MessageCode, MessageSeverity } from "./message";
+import { Message, MessageSeverity } from "./message";
 import { ResultElement } from "./resultelement";
 
 /**
- * Résultat global d'un calcul
- * Peut comporter un ou plusieurs ResultElement.
+ * Result of a calculation.
+ * May contain several ResultElement, if one or more parameters were varying.
  */
-// tslint:disable-next-line:max-classes-per-file
-export class Result extends JalhydObject implements INamedIterableValues {
+export class Result extends JalhydObject {
 
-    /** nom de la variable/paramètre calculé (= symbol) */
-    public name: string;
-
-    /** "parameters" family, for linked parameters */
-    public family: ParamFamily;
+    /** calculated parameter (main result) symbol */
+    private _symbol: string;
 
     /** Nub that produced this result */
     private _sourceNub: Nub;
 
-    /**
-     * Messages (erreurs, infos, ...)
-     */
+    /** global messages, related to the whole module */
     private _globalLog: cLog;
 
+    /** one result element for each iteration (when parameters are varying) */
     private _resultElements: ResultElement[];
 
     /**
-     * itérateur sur les valeurs des ResultElements
+     * @param v value of calculated parameter, or result element, or (usually error) Message
+     * @param sourceNub Nub that generated this result
+     * @param extraValues map of result values by symbol, to add to the first result element
      */
-    private _iterator: INumberIterator;
-
-    constructor(v?: number | Message | ResultElement, sourceNub?: Nub, extraResults?: any) {
+    constructor(v?: number | Message | ResultElement, sourceNub?: Nub, extraValues?: { [key: string]: number }) {
         super();
         this._globalLog = new cLog();
         this._resultElements = [];
-        if (typeof (v) === "number" || v instanceof Message) {
-            this._resultElements.push(new ResultElement(v));
-        } else if (v instanceof ResultElement) {
-            this._resultElements.push(v);
-        }
         this._sourceNub = sourceNub;
-        if (extraResults !== undefined) { // for setter
-            this.resultElement.extraResults = extraResults;
-        }
-    }
-
-    /**
-     * retourne le journal de la calculette
-     */
-    public get globalLog() {
-        return this._globalLog;
-    }
-
-    /**
-     * @return true si il y a au moins un message dans le log global
-     */
-    public get hasGlobalLog(): boolean {
-        return this.globalLog.messages.length > 0;
-    }
-
-    /**
-     * @return true si il y a au moins un message dans le log global ou dans les ResultElement
-     */
-    public get hasLog(): boolean {
-        if (this.hasGlobalLog) {
-            return true;
-        } else {
-            // Test des journaux des résultats
-            for (const r of this._resultElements) {
-                if (r.hasLog) {
-                    return true;
-                }
+        // try to store main result symbol
+        if (this._sourceNub) {
+            if (this._sourceNub.calculatedParam) {
+                this.symbol = this._sourceNub.calculatedParam.symbol;
             }
         }
-        return false;
-    }
-
-    /**
-     * Retourne le ResultElement le plus récent
-     */
-    get resultElement(): ResultElement {
-        if (this._resultElements.length === 0) {
-            throw new Error("appel à la méthode de Result.result() invalide, il n'y a pas au moins un 'ResultElement'");
+        // detect first argument
+        if (typeof (v) === "number") {
+            this.addResultElement(new ResultElement());
+            this.resultElement.vCalc = v;
+        } else if (v instanceof Message) {
+            this.addResultElement(new ResultElement(v));
+        } else if (v instanceof ResultElement) {
+            this.resultElement = v;
         }
-        return this._resultElements[ this._resultElements.length - 1 ];
-    }
-
-    /**
-     * Affecte le ResultElement le plus récent
-     */
-    set resultElement(r: ResultElement) {
-        if (this._resultElements.length === 0) {
-            throw new Error("appel à la méthode de Result.result() invalide, il n'y a pas au moins un 'ResultElement'");
+        if (extraValues !== undefined) { // for setter
+            this.resultElement.mergeValues(extraValues);
         }
-        this._resultElements[ this._resultElements.length - 1 ] = r;
     }
 
-    get resultElements(): ResultElement[] {
-        return this._resultElements;
+    public get symbol(): string {
+        return this._symbol;
     }
 
-    /**
-     * @return true si il existe au moins 1 ResultElement dans le tableau
-     */
-    get hasResultElements(): boolean {
-        return this._resultElements.length > 0;
+    public set symbol(s: string) {
+        this._symbol = s;
+        // hack to update "vCalc"
+        if (this.resultElement) {
+            this.resultElement.updateVCalcSymbol(s);
+        }
     }
 
     public get sourceNub(): Nub {
         return this._sourceNub;
     }
 
-    /**
-     * @return le résultat de calcul du ResultElement le plus récent
-     */
-    get vCalc(): number {
-        return this.resultElement.vCalc;
-    }
-
-    set vCalc(r: number) {
-        this.resultElement.vCalc = r;
-    }
-
-    /**
-     * retourne le journal du ResultElement le plus récent
-     */
-    public get log() {
-        // return this._globalLog;
-        return this.resultElement.log;
+    public get globalLog() {
+        return this._globalLog;
     }
 
-    /**
-     * retourne le code du ResultElement le plus récent
-     */
-    public get code(): MessageCode {
-        return this.resultElement.code;
+    public get resultElements(): ResultElement[] {
+        return this._resultElements;
     }
 
     /**
-     * retourne les résultats complémentaires du ResultElement le plus récent
+     * @return the most recent result element
      */
-    get extraResults() {
-        return this.resultElement.extraResults;
-    }
-
-    public count() {
-        return this._resultElements.length;
+    public get resultElement(): ResultElement {
+        /* if (this._resultElements.length === 0) {
+            throw new Error("Result.resultElement() : there are no result elements");
+        } */
+        return this._resultElements[ this._resultElements.length - 1 ];
     }
 
     /**
-     * Extract one ResultElement as a Result
-     * @param i index of the ResultElement
+     * sets the most recent result element
      */
-    public extractResult(i: number): Result {
-        if (i < 0 || i >= this._resultElements.length) {
-            throw new Error("Result.extractResult index outside [0;" + (this._resultElements.length - 1) + "]");
+    public set resultElement(r: ResultElement) {
+        if (this._resultElements.length === 0) {
+            this._resultElements.push(r);
+        } else {
+            this._resultElements[ this._resultElements.length - 1 ] = r;
         }
-        return new Result(this._resultElements[i], this._sourceNub);
+        r.parent = this;
     }
 
-    /**
-     * Renvoie le nombre de résultats dans le tableau de résultats
-     */
-    public get nbResultElements(): number {
-        return this._resultElements.length;
-    }
-
-    /**
-     * Ajoute un ResultElement au tableau
-     * @param r ResultElement à ajouter
-     */
     public addResultElement(r: ResultElement) {
         this._resultElements.push(r);
+        r.parent = this;
     }
 
     /**
-     * Insert result r at index i
-     * @param r Result to insert
-     * @param i Index position
+     * @return true if there is at least 1 result element
      */
-    public insertResultElement(r: ResultElement, i: number) {
-        this._resultElements.splice(i, 0, r);
+    public hasResultElements(): boolean {
+        return this._resultElements.length > 0;
     }
 
     /**
-     * @param name nom du résultat complémentaire
-     * @returns le nombre la taille d'un résultat complémentaire
+     * @return true if there are at least 2 result elements
      */
-    public extraResultLength(name: string): number {
-        const r = this.getExtraResult(name);
-        if (r === undefined) {
-            return 0;
-        }
-        return Object.keys(r).length;
-    }
-
-    // WTF
-    public getExtraResult(name: string): any {
-        const res = [];
-        for (const r of this._resultElements) {
-            const er = r.getExtraResult(name);
-            if (er !== undefined) {
-                res.push(er);
-            }
-        }
-
-        switch (res.length) {
-            case 0:
-                return undefined;
-
-            case 1:
-                return res[0];
-
-            default:
-                throw new Error(
-                    "Result.getExtraResult() : il existe plusieurs ResultElement avec" +
-                    " un extraResult dont le nom est '" + name + "'",
-                );
-        }
+    public hasMultipleValues(): boolean {
+        return this.resultElements.length > 1;
     }
 
     /**
@@ -240,61 +128,63 @@ export class Result extends JalhydObject implements INamedIterableValues {
     }
 
     /**
-     * Returns the list of extra results values for the given symbol;
-     * if no parameter is variated, the list will contain only 1 value
+     * @returns proxy to .resultElement.ok (false if there is no result element)
      */
-    public getExtraResults(symbol: string): number[] {
-        const extraRes: number[] = [];
-        const ier = this.getIterableExtraResults(symbol);
-        ier.initValuesIterator(false);
-        for (const er of ier) {
-            extraRes.push(er);
-        }
-        return extraRes;
+    public get ok(): boolean {
+        return this._resultElements.length > 0 && this.resultElement.ok;
     }
 
-    /**
-     * ajoute un message au journal
-     */
+    // -------------- log related methods
+
+    /** adds a message to the global log */
     public addMessage(m: Message) {
         this._globalLog.add(m);
     }
 
-    /**
-     * ajoute tous les messages d'un journal au journal
-     */
+    /** merges the given log with the global log */
     public addLog(l: cLog) {
         this._globalLog.addLog(l);
     }
 
     /**
-     * insert un message en début de liste
+     * @return true if global log has at least one message, whatever its level
      */
-    public insertMessage(m: Message) {
-        this._globalLog.insert(m);
+    public hasGlobalLog(): boolean {
+        return this.globalLog.messages.length > 0;
     }
 
     /**
-     * Teste si tous les résultats + complémentaires sont valides et journal sans erreur
-     * @returns true si le test est valide
+     * @return true if union of global log and result elements logs has at least one
+     *         message, whatever its level
      */
-    public get ok(): boolean {
-        return this._resultElements.length > 0 && this.resultElement.ok;
+    public hasLog(): boolean {
+        if (this.hasGlobalLog()) {
+            return true;
+        } else {
+            // result elements logs
+            for (const r of this._resultElements) {
+                if (r.hasLog()) {
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     /**
-     * @returns true si au moins un message de log comporte un code d'erreur (= au moins un calcul a raté)
+     * @returns true if at least one of the log messages (general log or result elements logs)
+     *          has an error-level message, i.e. true if at least one calculation has failed
      */
-    public get hasErrorMessages(): boolean {
-        // Test du journal global
+    public hasErrorMessages(): boolean {
+        // global log
         for (const m of this._globalLog.messages) {
             if (m.getSeverity() === MessageSeverity.ERROR) {
                 return true;
             }
         }
-        // Test des journaux des résultats
+        // result elements logs
         for (const r of this._resultElements) {
-            if (r.hasErrorMessages) {
+            if (r.hasErrorMessages()) {
                 return true;
             }
         }
@@ -302,154 +192,54 @@ export class Result extends JalhydObject implements INamedIterableValues {
     }
 
     /**
-     * @returns true si chaque ResultElement contient une erreur (= aucun calcul n'a réussi)
+     * @returns true if every result element log contains an error (i.e. no calculation has succeeded);
+     *          does not inspect global log
      */
     public get hasOnlyErrors(): boolean {
-        // Test des journaux des résultats
         for (const r of this._resultElements) {
-            if (! r.hasErrorMessages) {
+            if (! r.hasErrorMessages()) {
                 return false;
             }
         }
         return true;
     }
 
-    //  interface INamedIterableValues
-
-    public get valuesIterator(): INumberIterator {
-        const tmp: number[] = [];
-        for (const re of this._resultElements) {
-            tmp.push(re.vCalc);
-        }
-        return tmp[Symbol.iterator]() as INumberIterator;
-    }
-
-    public get hasMultipleValues(): boolean {
-        return this._resultElements.length > 1;
-    }
-
-    //  interface INamedIterableValues pour les résultats complémentaires
-
-    public getIterableExtraResults(name: string): INamedIterableValues {
-        const res = new ExtraResults(name);
-        let found = false;
-
-        for (const r of this._resultElements) {
-            const er = r.getExtraResult(name);
-            if (er !== undefined) {
-                found = true;
-                res.addValue(er);
-            }
-        }
-        if (found) {
-            return res;
-        }
-        return undefined;
-    }
-
-    public initValuesIterator(reverse: boolean = false): INumberIterator {
-        const vals: number[] = [];
-        for (const r of this._resultElements) {
-            vals.push(r.vCalc);
-        }
-
-        if (reverse) {
-            this._iterator = new NumberArrayReverseIterator(vals);
-        } else {
-            this._iterator = new NumberArrayIterator(vals);
-        }
-
-        return this._iterator;
-    }
-
-    public get hasNext(): boolean {
-        return this._iterator.hasNext;
-    }
-
-    public next(): IteratorResult<number> {
-        return this._iterator.next();
-    }
-
-    public get currentValue(): number {
-        if (this._iterator === undefined) {
-            return this.vCalc;
-        }
-        return this._iterator.currentValue;
-    }
-
-    public [Symbol.iterator](): IterableIterator<number> {
-        return this;
-    }
-}
-
-/**
- * série de valeurs de résultat complémentaire
- */
-// tslint:disable-next-line:max-classes-per-file
-export class ExtraResults extends JalhydObject implements INamedIterableValues {
-
-    public family: ParamFamily;
-
-    private _name: string;
-
-    private _values: number[];
+    // -------------- shortcuts to most recent result element
 
     /**
-     * itérateur courant
+     * @return value of the calculated parameter, for the most recent result element
      */
-    private _iterator: INumberIterator;
-
-    constructor(n: string) {
-        super();
-        this._name = n;
-        this._values = [];
-    }
-
-    public count() {
-        return this._values.length;
-    }
-
-    public addValue(v: number) {
-        this._values.push(v);
-    }
-
-    // interface INamedIterableValues
-
-    public get valuesIterator(): INumberIterator {
-        return this._values[Symbol.iterator]() as INumberIterator;
-    }
-
-    public get hasMultipleValues(): boolean {
-        return this._values.length > 1;
-    }
-
-    public get name(): string {
-        return this._name;
+    get vCalc(): number {
+        return this.resultElement.vCalc;
     }
 
-    public initValuesIterator(reverse: boolean = false): INumberIterator {
-        if (reverse) {
-            this._iterator = new NumberArrayReverseIterator(this._values);
-        } else {
-            this._iterator = new NumberArrayIterator(this._values);
-        }
-
-        return this._iterator;
+    /**
+     * sets the value of the calculated parameter, for the most recent result element
+     */
+    set vCalc(r: number) {
+        this.resultElement.vCalc = r;
     }
 
-    public get hasNext(): boolean {
-        return this._iterator.hasNext;
+    /**
+     * @returns log from the most recent result element
+     * @TODO ambiguous / counter-intuitive : should be renamed
+     */
+    public get log() {
+        return this.resultElement.log;
     }
 
-    public next(): IteratorResult<number> {
-        return this._iterator.next();
+    // set of all results, from most recent result element
+    public get values() {
+        return this.resultElement.values;
     }
 
-    public get currentValue(): number {
-        return this._iterator.currentValue;
+    // set of all results except vCalc, from most recent result element
+    public get extraResults() {
+        return this.resultElement.extraResults;
     }
 
-    public [Symbol.iterator](): IterableIterator<number> {
-        return this;
+    // value of a result given its symbol, from most recent result element
+    public getValue(name: string): number {
+        return this.resultElement.getValue(name);
     }
 }
diff --git a/src/util/resultelement.ts b/src/util/resultelement.ts
index 556b2da5e95cc4094ff452df494200c0256b0cbb..9ae17e0dd22b54a5cd321936afed0157b23b9382 100644
--- a/src/util/resultelement.ts
+++ b/src/util/resultelement.ts
@@ -1,155 +1,191 @@
 import { cLog } from "./log";
 import { Message, MessageCode, MessageSeverity } from "./message";
+import { Result } from "./result";
 
 /**
- * Résultat de calcul comprenant la valeur du résultat et des calculs annexes (flag, calculs intermédiaires...)
- * Représente une valeur unique
+ * Calculation result for one iteration.
+ * May include value of the Nub's calculated parameter (if any), and/or other
+ * values (previously known as extraResults)
  */
 export class ResultElement {
 
-    /**
-     * Messages (erreurs, infos, ...)
-     * public for easy setting by Nub
-     */
+    /** local messages, related to this calculation iteration */
     public log: cLog;
 
+    /** pointer to parent result */
+    public parent: Result;
+
     /**
-     * Valeur calculée
+     * result values by symbol; generally contains at least the symbol of the calculated
+     * parameter and its associated calculated value (aka. vCalc)
      */
-    private _vCalc: number;
+    private _values: { [key: string]: number };
+
+    /** latest key assigned to vCalc (this key might change) */
+    private _vCalcSymbol: string;
 
     /**
-     * résultats complémentaires
+     * @param v value of calculated parameter, or key-values map, or (usually error) Message
      */
-    private _extraResults: { [key: string]: any };
-
-    constructor(v?: number | Message) {
+    constructor(v?: number | Message | { [key: string]: number }) {
         this.log = new cLog();
+        this._values = {};
+        this._vCalcSymbol = ""; // default retrocompatible pseudo-symbol for cases like  `new ResultElement(42);`
+        // detect first argument
         if (typeof v === "number") {
-            this._vCalc = v;
+            this.vCalc = v;
         } else if (v instanceof Message) {
             this.addMessage(v);
+        } else if (v !== undefined) {
+            // assuming key-value map
+            this._values = v;
         }
-        this._extraResults = {};
     }
 
-    get vCalc() { return this._vCalc; }
+    /**
+     * @returns value of the calculated parameter (main result); might be undefined,
+     *          for ex. with SectionParametree
+     */
+    get vCalc(): number {
+        return this._values[this._vCalcSymbol];
+    }
 
+    /**
+     * sets value of the calculated parameter (main result)
+     */
     set vCalc(r: number) {
-        this._vCalc = r;
+        if (this.parent && this.parent.symbol) {
+            this._vCalcSymbol = this.parent.symbol;
+        }
+        this._values[this._vCalcSymbol] = r;
     }
 
-    get code(): MessageCode {
-        if (this.messageCount !== 1) {
-            throw new Error("appel à Result.code invalide, il n'y pas exactement un message de log");
-        }
-        return this.log.messages[0].code;
+    public get vCalcSymbol(): string {
+        return this._vCalcSymbol;
     }
 
-    get extraVar() {
-        if (this.messageCount !== 1) {
-            throw new Error("appel à Result.extraVar invalide, il n'y pas exactement un message de log");
+    /**
+     * Hack to update the key of vCalc, when Result.symbol is updated
+     * after Equation() returned a ResultElement
+     */
+    public updateVCalcSymbol(s: string) {
+        if (! this.hasValues) {
+            throw new Error("updateVCalcSymbol() : values map is empty");
         }
-        return this.log.messages[0].extraVar;
+        const tmp = this.vCalc;
+        delete this._values[this._vCalcSymbol];
+        this._vCalcSymbol = s;
+        this.vCalc = tmp;
     }
 
-    public get hasExtraResults(): boolean {
-        return Object.keys(this._extraResults).length > 0;
+    /**
+     * Adds given values map to the local values map; in case of key conflict,
+     * precedence goes to the given value
+     */
+    public mergeValues(values: { [key: string]: number }) {
+        this._values = { ...this._values, ...values };
+    }
+
+    /**
+     * Returns an array of all the keys in the local values map,
+     * where vCalcSymbol is always in first position (used by
+     * GUI to iterate on displayable results)
+     */
+    public get keys(): string[] {
+        const keys = Object.keys(this._values);
+        //  make sure vCalc symbol is always first
+        if (this._vCalcSymbol) { // sometimes empty (ex: SectionParametree)
+            const index = keys.indexOf(this._vCalcSymbol);
+            if (index > -1) {
+                keys.splice(index, 1);
+            }
+            keys.unshift(this._vCalcSymbol);
+        }
+        return keys;
     }
 
-    private get messageCount(): number {
-        return this.log.messages.length;
+    /** Returns the whole key-value map */
+    public get values() {
+        return this._values;
     }
 
     /**
-     * Returns true if current log has at least one message
+     * @returns the result value associated to the given symbol, or undefined if the given
+     *          symbol was not found in the local values map
      */
-    public get hasLog() {
-        return this.messageCount > 0;
+    public getValue(symbol: string) {
+        return this._values[symbol];
     }
 
-    public get hasErrorMessages(): boolean {
-        for (const m of this.log.messages) {
-            if (m.code !== MessageCode.ERROR_OK && m.getSeverity() === MessageSeverity.ERROR) {
-                return true;
-            }
-        }
-        return false;
+    public get firstValue(): number {
+        return this._values[Object.keys(this._values)[0]];
     }
 
-    public get ok(): boolean {
-        return (this._vCalc !== undefined || this.hasExtraResults) && !this.hasErrorMessages;
+    public count(): number {
+        return Object.keys(this._values).length;
     }
 
     /**
-     * ajoute un message au journal
+     * @returns true if local values map is not empty, and local log has no error-level
+     *          message (log still might have non-error level messages)
      */
-    public addMessage(m: Message) {
-        this.log.add(m);
+    public get ok(): boolean {
+        return this.hasValues() && !this.hasErrorMessages();
     }
 
     /**
-     * insert un message en début de liste
+     * @returns true if local values map has at least one key-value pair
      */
-    public insertMessage(m: Message) {
-        this.log.insert(m);
+    public hasValues(): boolean {
+        return Object.keys(this._values).length > 0;
     }
 
     /**
-     * résultats complémentaires
+     * Adds a key-value pair to the values map
      */
+    public addExtraResult(name: string, value: any) {
+        this._values[name] = value;
+    }
 
-    get extraResults() {
-        return this._extraResults;
+    /**
+     * Returns a copy of the local key-values map, without vCalc (only "extra" results)
+     */
+    public get extraResults() {
+        const er = JSON.parse(JSON.stringify(this._values)); // clone
+        // remove vCalc
+        delete er[this._vCalcSymbol];
+        return er;
     }
 
-    set extraResults(d: { [key: string]: any }) {
-        this._extraResults = d;
+    public toString(): string {
+        if (this.vCalc !== undefined) {
+            return String(this.vCalc);
+        }
+        return JSON.stringify(this);
     }
 
-    public addExtraResult(name: string, value: any) {
-        this._extraResults[name] = value;
+    // -------------- log related methods
+
+    /** adds a message to the global log */
+    public addMessage(m: Message) {
+        this.log.add(m);
     }
 
-    /**
-     * Add a ResultElement object into extraResult.
-     * The added ResultElement contains the Value of the ResultElement and the extraResults
-     * which are added using varCalc as prefix (i.e. [varCalc]_[key])
-     * Log messages are also copied to ResultElement
-     * @param resultElementToAdd Result object to add
-     * @param varCalc Name of the variable calculated used as key in extraResult
-     */
-    public AddResultElementToExtra(resultElementToAdd: ResultElement, varCalc: string) {
-        // Add ResultElement into extraResult
-        this.extraResults[varCalc] = resultElementToAdd.vCalc;
-        // Add extraResults
-        for (const extraResKey in resultElementToAdd.extraResults) {
-            if (resultElementToAdd.extraResults.hasOwnProperty(extraResKey)) {
-                const newExtraKey: string = varCalc + "_" + extraResKey;
-                this.extraResults[newExtraKey] = resultElementToAdd.extraResults[extraResKey];
-            }
-        }
-        // Add Logs
-        this.log.addLog(resultElementToAdd.log);
+    /** @returns true if current log has at least one message */
+    public hasLog() {
+        return this.log.messages.length > 0;
     }
 
     /**
-     * @param name nom du résultat complémentaire à retourner
-     * @returns un résultat complémentaire par son nom
+     * @returns true if at least one of the log messages has an error level,
+     *          i.e. if calculation has failed
      */
-    public getExtraResult(name: string): any {
-        for (const n in this._extraResults) {
-            if (n === name) {
-                return this._extraResults[n];
+    public hasErrorMessages(): boolean {
+        for (const m of this.log.messages) {
+            if (m.code !== MessageCode.ERROR_OK && m.getSeverity() === MessageSeverity.ERROR) {
+                return true;
             }
         }
-        return undefined;
-    }
-
-    public toString(): string {
-        if (this._vCalc !== undefined) {
-            return String(this._vCalc);
-        }
-        return JSON.stringify(this);
+        return false;
     }
 }