You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2023/03/10 06:28:41 UTC

[myfaces] branch main updated: https://issues.apache.org/jira/browse/MYFACES-4584: Improvements in the Ajax Codebase (#547)

This is an automated email from the ASF dual-hosted git repository.

werpu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/main by this push:
     new 00cf33a65 https://issues.apache.org/jira/browse/MYFACES-4584: Improvements in the Ajax Codebase (#547)
00cf33a65 is described below

commit 00cf33a65fdc99647126175b16ca3dd7e38f008a
Author: Werner Punz <we...@apache.org>
AuthorDate: Fri Mar 10 07:28:36 2023 +0100

    https://issues.apache.org/jira/browse/MYFACES-4584: Improvements in the Ajax Codebase (#547)
    
    * https://issues.apache.org/jira/browse/MYFACES-4584: improvements:
    Elimination of Streams in favor of Arrays
    Configs now have a flatter structure
    Additional Tests
    Simplification of the XHR Queue
    Simplification of XhrRequest
    onLoad.spec was not executed due to a wrong name pattern!
---
 api/src/client/package-lock.json                   |  82 +-
 api/src/client/package.json                        |   6 +-
 api/src/client/tsconfig-myfaces.json               |   1 -
 api/src/client/typescript/faces/impl/AjaxImpl.ts   | 108 +--
 api/src/client/typescript/faces/impl/core/Const.ts |   7 +-
 .../typescript/faces/impl/util/AsyncRunnable.ts    |  87 +-
 .../typescript/faces/impl/util/ExtDomQuery.ts      |  16 +-
 .../client/typescript/faces/impl/util/FileUtils.ts |  48 +-
 .../faces/impl/util/HiddenInputBuilder.ts          |  10 +-
 api/src/client/typescript/faces/impl/util/Lang.ts  |  66 +-
 .../faces/impl/util/XhrQueueController.ts          | 112 +++
 .../typescript/faces/impl/xhrCore/EventData.ts     |   6 +-
 .../faces/impl/xhrCore/ResponseProcessor.ts        |  26 +-
 .../typescript/faces/impl/xhrCore/XhrFormData.ts   |  52 +-
 .../typescript/faces/impl/xhrCore/XhrRequest.ts    | 123 ++-
 .../client/typescript/faces/myfaces/OamSubmit.ts   |  12 +-
 .../_ext/monadish/DomQueryTest.spec.ts             | 219 ++++-
 .../frameworkBase/_ext/monadish/MonadTest.spec.ts  |   8 +-
 .../frameworkBase/_ext/monadish/StreamTest.spec.ts | 231 ------
 .../frameworkBase/_ext/monadish/fixtures/blank.css |  15 +
 .../frameworkBase/_ext/monadish/fixtures/test.js   |  15 +
 .../frameworkBase/_ext/monadish/fixtures/test2.js  |  15 +
 .../_ext/monadish/markups/tobago-with-header.ts    | 921 +++++++++++++++++++++
 .../_ext/monadish/markups/tobago-without-header.ts | 108 +++
 .../frameworkBase/_ext/shared/StandardInits.ts     |   5 +-
 .../fixtures/jakarta.faces.resource/faces.js.jsf   |  15 +
 .../typescript/faces/test/impl/ImplTest.spec.ts    |  30 +-
 .../typescript/faces/test/myfaces/OnLoad.spec.ts   |  52 ++
 .../faces/test/queue/AsynchronousProbe.ts          |  10 +-
 .../faces/test/queue/AsynchronousQueueTest.spec.ts |   7 +-
 .../faces/test/xhrCore/ClientWindow.spec.ts        |   2 +
 .../faces/test/xhrCore/EventTests.spec.ts          |  50 +-
 .../faces/test/xhrCore/FileUploadTest.spec.ts      |  10 +-
 .../test/xhrCore/NamespacesRequestTest.spec.ts     |  37 +-
 .../faces/test/xhrCore/OamSubmitTest.spec.ts       |  11 +-
 .../faces/test/xhrCore/RequestParamsTest.spec.ts   |   6 +-
 .../faces/test/xhrCore/RequestTest.spec.ts         |  97 ++-
 .../faces/test/xhrCore/RequestTest_23.spec.ts      |   7 +-
 .../faces/test/xhrCore/ResponseTest.spec.ts        |  56 +-
 .../test/xhrCore/TobagoFileUploadTest.spec.ts      |  10 +-
 .../typescript/faces/test/xhrCore/WebsocketTest.ts |  13 +-
 .../faces/test/xhrCore/XhrFormDataTest.spec.ts     |  11 +-
 api/src/client/typescript/mona_dish/AssocArray.ts  | 291 +++++++
 api/src/client/typescript/mona_dish/Config.ts      | 263 ++++++
 api/src/client/typescript/mona_dish/DomQuery.ts    | 246 +++---
 api/src/client/typescript/mona_dish/Es2019Array.ts | 135 +++
 .../client/typescript/mona_dish/ExtendedArray.ts   |  66 --
 api/src/client/typescript/mona_dish/Lang.ts        |  19 +-
 api/src/client/typescript/mona_dish/Messaging.ts   |  11 +-
 api/src/client/typescript/mona_dish/Monad.ts       | 431 +---------
 api/src/client/typescript/mona_dish/PromiseShim.ts |   1 -
 .../typescript/mona_dish/SourcesCollectors.ts      | 198 ++---
 api/src/client/typescript/mona_dish/Stream.ts      | 159 +++-
 api/src/client/typescript/mona_dish/index.ts       |  12 +-
 api/src/client/typescript/mona_dish/index_core.ts  |  25 +-
 55 files changed, 3181 insertions(+), 1399 deletions(-)

diff --git a/api/src/client/package-lock.json b/api/src/client/package-lock.json
index ddc8cfa5d..3adcfc058 100644
--- a/api/src/client/package-lock.json
+++ b/api/src/client/package-lock.json
@@ -22,19 +22,19 @@
         "html-webpack-plugin": "^5.5.0",
         "jsdom": "^21.1.0",
         "jsdom-global": "^3.0.2",
-        "jsf.js_next_gen": "4.0.1-beta.2",
+        "jsf.js_next_gen": "4.0.1-beta.5",
         "mocha": "^10.2.0",
         "npm-check-updates": "^16.7.10",
         "nyc": "^15.1.0",
         "replace-in-file": "^6.3.5",
         "rxjs": "^7.8.0",
         "sinon": "^15.0.1",
-        "terser-webpack-plugin": "^5.3.6",
+        "terser-webpack-plugin": "^5.3.7",
         "ts-loader": "^9.4.2",
         "ts-node": "^10.9.1",
         "typedoc": "^0.23.26",
         "typescript": "^4.9.5",
-        "webpack": "^5.75.0",
+        "webpack": "^5.76.0",
         "webpack-cli": "^5.0.1",
         "webpack-dev-server": "^4.11.1"
       }
@@ -4998,12 +4998,12 @@
       }
     },
     "node_modules/jsf.js_next_gen": {
-      "version": "4.0.1-beta.2",
-      "resolved": "https://registry.npmjs.org/jsf.js_next_gen/-/jsf.js_next_gen-4.0.1-beta.2.tgz",
-      "integrity": "sha512-CZ/H+6ZVuJudhkAZsx4U1FiqkpMp23UkN+x/Io9Y36G9E0LIMojAgTBTBUqg+EYlOy1lTVP12GzWtRXGJAthQA==",
+      "version": "4.0.1-beta.5",
+      "resolved": "https://registry.npmjs.org/jsf.js_next_gen/-/jsf.js_next_gen-4.0.1-beta.5.tgz",
+      "integrity": "sha512-+wezsuZ8H9396asy2x82jbwvIvXWL1glk1RjVGlCi2+1HSyllHAWFp/ZKcAYYkIVl7wT8O7Izv/ABYY+lTxfFQ==",
       "dev": true,
       "dependencies": {
-        "mona-dish": "0.26.0"
+        "mona-dish": "0.28.3"
       }
     },
     "node_modules/json-buffer": {
@@ -5886,9 +5886,9 @@
       }
     },
     "node_modules/mona-dish": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/mona-dish/-/mona-dish-0.26.0.tgz",
-      "integrity": "sha512-fvbQOv9x97iw3TFjGZD8Tx4i7Joy7gJYlQuo9INMflSWmBZKdK3232wOkQZD9siE1jMFCPhPNwKGR5u9wbO/kw==",
+      "version": "0.28.3",
+      "resolved": "https://registry.npmjs.org/mona-dish/-/mona-dish-0.28.3.tgz",
+      "integrity": "sha512-VqB+3R4wisQJ0SNjVzXVHsGeqpACS8lbC9EoeOuVhD/F3pWIx3/4iZtQmPKZw6n+5m9js0MWyKZLZFIFE6j+8g==",
       "dev": true
     },
     "node_modules/ms": {
@@ -8480,9 +8480,9 @@
       }
     },
     "node_modules/terser": {
-      "version": "5.16.3",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz",
-      "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==",
+      "version": "5.16.5",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.5.tgz",
+      "integrity": "sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==",
       "dev": true,
       "dependencies": {
         "@jridgewell/source-map": "^0.3.2",
@@ -8498,16 +8498,16 @@
       }
     },
     "node_modules/terser-webpack-plugin": {
-      "version": "5.3.6",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
-      "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
+      "version": "5.3.7",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
+      "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/trace-mapping": "^0.3.14",
+        "@jridgewell/trace-mapping": "^0.3.17",
         "jest-worker": "^27.4.5",
         "schema-utils": "^3.1.1",
-        "serialize-javascript": "^6.0.0",
-        "terser": "^5.14.1"
+        "serialize-javascript": "^6.0.1",
+        "terser": "^5.16.5"
       },
       "engines": {
         "node": ">= 10.13.0"
@@ -9217,9 +9217,9 @@
       }
     },
     "node_modules/webpack": {
-      "version": "5.75.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
-      "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
+      "version": "5.76.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz",
+      "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==",
       "dev": true,
       "dependencies": {
         "@types/eslint-scope": "^3.7.3",
@@ -13761,12 +13761,12 @@
       "dev": true
     },
     "jsf.js_next_gen": {
-      "version": "4.0.1-beta.2",
-      "resolved": "https://registry.npmjs.org/jsf.js_next_gen/-/jsf.js_next_gen-4.0.1-beta.2.tgz",
-      "integrity": "sha512-CZ/H+6ZVuJudhkAZsx4U1FiqkpMp23UkN+x/Io9Y36G9E0LIMojAgTBTBUqg+EYlOy1lTVP12GzWtRXGJAthQA==",
+      "version": "4.0.1-beta.5",
+      "resolved": "https://registry.npmjs.org/jsf.js_next_gen/-/jsf.js_next_gen-4.0.1-beta.5.tgz",
+      "integrity": "sha512-+wezsuZ8H9396asy2x82jbwvIvXWL1glk1RjVGlCi2+1HSyllHAWFp/ZKcAYYkIVl7wT8O7Izv/ABYY+lTxfFQ==",
       "dev": true,
       "requires": {
-        "mona-dish": "0.26.0"
+        "mona-dish": "0.28.3"
       }
     },
     "json-buffer": {
@@ -14455,9 +14455,9 @@
       }
     },
     "mona-dish": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/mona-dish/-/mona-dish-0.26.0.tgz",
-      "integrity": "sha512-fvbQOv9x97iw3TFjGZD8Tx4i7Joy7gJYlQuo9INMflSWmBZKdK3232wOkQZD9siE1jMFCPhPNwKGR5u9wbO/kw==",
+      "version": "0.28.3",
+      "resolved": "https://registry.npmjs.org/mona-dish/-/mona-dish-0.28.3.tgz",
+      "integrity": "sha512-VqB+3R4wisQJ0SNjVzXVHsGeqpACS8lbC9EoeOuVhD/F3pWIx3/4iZtQmPKZw6n+5m9js0MWyKZLZFIFE6j+8g==",
       "dev": true
     },
     "ms": {
@@ -16450,9 +16450,9 @@
       }
     },
     "terser": {
-      "version": "5.16.3",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz",
-      "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==",
+      "version": "5.16.5",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.5.tgz",
+      "integrity": "sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==",
       "dev": true,
       "requires": {
         "@jridgewell/source-map": "^0.3.2",
@@ -16470,16 +16470,16 @@
       }
     },
     "terser-webpack-plugin": {
-      "version": "5.3.6",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
-      "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
+      "version": "5.3.7",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
+      "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
       "dev": true,
       "requires": {
-        "@jridgewell/trace-mapping": "^0.3.14",
+        "@jridgewell/trace-mapping": "^0.3.17",
         "jest-worker": "^27.4.5",
         "schema-utils": "^3.1.1",
-        "serialize-javascript": "^6.0.0",
-        "terser": "^5.14.1"
+        "serialize-javascript": "^6.0.1",
+        "terser": "^5.16.5"
       },
       "dependencies": {
         "ajv": {
@@ -16986,9 +16986,9 @@
       "dev": true
     },
     "webpack": {
-      "version": "5.75.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
-      "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
+      "version": "5.76.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz",
+      "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==",
       "dev": true,
       "requires": {
         "@types/eslint-scope": "^3.7.3",
diff --git a/api/src/client/package.json b/api/src/client/package.json
index 218d54624..940f23440 100644
--- a/api/src/client/package.json
+++ b/api/src/client/package.json
@@ -24,19 +24,19 @@
     "html-webpack-plugin": "^5.5.0",
     "jsdom": "^21.1.0",
     "jsdom-global": "^3.0.2",
-    "jsf.js_next_gen": "4.0.1-beta.2",
+    "jsf.js_next_gen": "4.0.1-beta.5",
     "mocha": "^10.2.0",
     "npm-check-updates": "^16.7.10",
     "nyc": "^15.1.0",
     "replace-in-file": "^6.3.5",
     "rxjs": "^7.8.0",
     "sinon": "^15.0.1",
-    "terser-webpack-plugin": "^5.3.6",
+    "terser-webpack-plugin": "^5.3.7",
     "ts-loader": "^9.4.2",
     "ts-node": "^10.9.1",
     "typedoc": "^0.23.26",
     "typescript": "^4.9.5",
-    "webpack": "^5.75.0",
+    "webpack": "^5.76.0",
     "webpack-cli": "^5.0.1",
     "webpack-dev-server": "^4.11.1"
   }
diff --git a/api/src/client/tsconfig-myfaces.json b/api/src/client/tsconfig-myfaces.json
index 80d5f4b45..d4054aa63 100644
--- a/api/src/client/tsconfig-myfaces.json
+++ b/api/src/client/tsconfig-myfaces.json
@@ -46,7 +46,6 @@
     }
   },
   "exclude": [
-    "./typescript/mona_dish/ExtendedArray.ts",
     "./typescript/mona_dish/index.ts",
     "./typescript/mona_dish/Messaging.ts"
   ]
diff --git a/api/src/client/typescript/faces/impl/AjaxImpl.ts b/api/src/client/typescript/faces/impl/AjaxImpl.ts
index 959533e4b..5981c3361 100644
--- a/api/src/client/typescript/faces/impl/AjaxImpl.ts
+++ b/api/src/client/typescript/faces/impl/AjaxImpl.ts
@@ -17,8 +17,7 @@
 import {IListener} from "./util/IListener";
 import {Response} from "./xhrCore/Response";
 import {XhrRequest} from "./xhrCore/XhrRequest";
-import {AsynchronousQueue} from "./util/AsyncQueue";
-import {AssocArrayCollector, Config, DQ, DQ$, Lang, LazyStream, Optional, Stream} from "mona-dish";
+import {Config, DQ, DQ$, Lang, Optional} from "mona-dish";
 import {Assertions} from "./util/Assertions";
 import {ExtConfig, ExtDomQuery} from "./util/ExtDomQuery";
 import {ErrorData} from "./xhrCore/ErrorData";
@@ -41,7 +40,7 @@ import {
     P_CLIENT_WINDOW,
     P_EVT,
     P_EXECUTE,
-    P_PARTIAL_SOURCE,
+    P_AJAX_SOURCE,
     P_RENDER,
     P_RESET_VALUES,
     P_WINDOW_ID,
@@ -52,9 +51,10 @@ import {
     VIEW_ID,
     $faces,
     EMPTY_STR,
-    CTX_PARAM_MF_INTERNAL,
     NAMED_VIEWROOT,
     NAMING_CONTAINER_ID,
+    CTX_PARAM_PPS,
+    MYFACES_OPTION_PPS,
     $nsp
 } from "./core/Const";
 import {
@@ -64,7 +64,7 @@ import {
     resolveTimeout, resolveViewId, resolveViewRootId, resoveNamingContainerMapper
 } from "./xhrCore/RequestDataResolver";
 import {encodeFormData} from "./util/FileUtils";
-
+import {XhrQueueController} from "./util/XhrQueueController";
 
 /*
  * allowed project stages
@@ -93,6 +93,8 @@ enum BlockFilter {
     params = "params"
 }
 
+
+
 /**
  * Core Implementation
  * to distinct between api and impl
@@ -112,17 +114,7 @@ export module Implementation {
  it provides following
 
  a) Monad like structures for querying because this keeps the code denser and adds abstractions
- that always was the strong point of jquery and it still is better in this regard than what ecmascript provides
-
- b) Streams and lazy streams like java has, a pull stream construct, ecmascript does not have anything like it.
- (it has array filters and maps, but ES2015 does not support flatMap)
- Another option would have been rxjs but that would have introduced a code dependency and probably more code. We might
- move to RXJS if the need arises, however. But for now I would rather stick with my small self grown library which works
- quite well and where I can patch quickly (I have used it in several industrial projects, so it works well
- and is heavily fortified by unit tests (140 testcases as time of writing this))
- The long term plan is to eliminate the Stream usage as soon as we can move up to ES2019 (adding the missing
- functions as shims, is a no go, because we are a library, and absolutey do not Shim anything which can leak
- into the global namespace!)
+ that always was the strong point of jQuery, and it still is better in this regard than what ecmascript provides
 
  c) A neutral json like configuration which allows assignments of arbitrary values with reduce code which then can be
  transformed into different data representations
@@ -159,12 +151,14 @@ export module Implementation {
     import getMessage = ExtLang.getMessage;
     import getGlobalConfig = ExtLang.getGlobalConfig;
     import assert = Assertions.assert;
+    import ofAssoc = ExtLang.ofAssoc;
+    import collectAssoc = ExtLang.collectAssoc;
 
     let projectStage: string = null;
     let separator: string = null;
     let eventQueue = [];
     let errorQueue = [];
-    export let requestQueue: AsynchronousQueue<XhrRequest> = null;
+    export let requestQueue: XhrQueueController<XhrRequest> = null;
     /*error reporting threshold*/
     let threshold = "ERROR";
 
@@ -194,7 +188,7 @@ export module Implementation {
     /**
      * @return the project stage also emitted by the server:
      * it cannot be cached and must be delivered over the server
-     * The value for it comes from the request parameter of the faces.js script called "stage".
+     * The value for it comes from the requestInternal parameter of the faces.js script called "stage".
      */
     export function getProjectStage(): string | null {
         return resolveGlobalConfig()?.projectStage ??
@@ -220,17 +214,21 @@ export module Implementation {
      * @param event
      * @param funcs
      */
-    export function chain(source: HTMLElement | string, event: Event | null, ...funcs: EvalFuncs): boolean {
-        // we can use our lazy stream each functionality to run our chain here..
+    export function chain(source: any, event: Event, ...funcs: EvalFuncs): boolean {
+        // we can use our lazy stream each functionality to run our chain here.
         // by passing a boolean as return value into the onElem call
         // we can stop early at the first false, just like the spec requests
 
-        return LazyStream.of(...funcs)
-            .map(func => resolveAndExecute(source, event, func))
-            // we use the return false == stop as an early stop, onElem stops at the first false
-            .onElem((opResult: boolean) => opResult)
-            //last ensures we run until the first false is returned
-            .last().value;
+        let ret;
+        funcs.every(func => {
+            let returnVal = resolveAndExecute(source, event, func);
+            if(returnVal !== false) {
+                ret = returnVal;
+            }
+            return returnVal !== false;
+        });
+        return ret;
+
     }
 
     /**
@@ -280,7 +278,7 @@ export module Implementation {
 
         requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;
 
-        // old non spec behavior will be removed after it is clear whether the removal breaks any code
+        // old non - spec behavior will be removed after it is clear whether the removal breaks any code
         requestCtx.assign(CTX_PARAM_REQ_PASS_THR).value = extractLegacyParams(options.value);
 
         // spec conform behavior, all passthrough params must be under "passthrough
@@ -312,14 +310,14 @@ export module Implementation {
         requestCtx.assign(ON_ERROR).value = options.value?.onerror;
 
         /**
-         * lets drag the myfaces config params also in
+         * Fetch the myfaces config params
          */
         requestCtx.assign(MYFACES).value = options.value?.myfaces;
 
         /**
          * binding contract the jakarta.faces.source must be set
          */
-        requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_PARTIAL_SOURCE).value = elementId;
+        requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_AJAX_SOURCE).value = elementId;
 
         /**
          * jakarta.faces.partial.ajax must be set to true
@@ -346,6 +344,9 @@ export module Implementation {
         // won't hurt but for the sake of compatibility we are going to add it
         requestCtx.assign(CTX_PARAM_REQ_PASS_THR, formId).value = formId;
         internalCtx.assign(CTX_PARAM_SRC_CTL_ID).value = elementId;
+        // reintroduction of PPS as per myfaces 2.3 (myfaces.pps = true, only the executes are submitted)
+        internalCtx.assign(CTX_PARAM_PPS).value = extractMyFacesParams(options.value)?.[MYFACES_OPTION_PPS] ?? false;
+
 
         assignClientWindowId(form, requestCtx);
         assignExecute(options, requestCtx, form, elementId);
@@ -426,7 +427,7 @@ export module Implementation {
             }
         } finally {
             if (clearRequestQueue) {
-                requestQueue.cleanup();
+                requestQueue.clear();
             }
         }
     }
@@ -522,16 +523,16 @@ export module Implementation {
          * or non-existent. If they exist all of them must be the same
          */
 
-        let formWindowId: Optional<string> = inputs.stream.map(getValue).reduce(differenceCheck, INIT);
+        let formWindowId: string = inputs.asArray.map(getValue).reduce(differenceCheck, INIT);
 
 
         //if the resulting window id is set on altered then we have an unresolvable problem
-        assert(ALTERED != formWindowId.value, "Multiple different windowIds found in document");
+        assert(ALTERED != formWindowId, "Multiple different windowIds found in document");
 
         /*
          * return the window id or null
          */
-        return formWindowId.value != INIT ? formWindowId.value : (fetchWindowIdFromURL() || fetchWindowIdFromJSFJS());
+        return formWindowId != INIT ? formWindowId : (fetchWindowIdFromURL() || fetchWindowIdFromJSFJS());
     }
 
     /**
@@ -560,7 +561,7 @@ export module Implementation {
         let formElements = element.deepElements.encodeFormElement()
 
         // encode them! (file inputs are handled differently and are not part of the viewstate)
-        return encodeFormData(formElements, resoveNamingContainerMapper(dummyContext));
+        return encodeFormData(new ExtConfig(formElements), resoveNamingContainerMapper(dummyContext));
     }
 
     /**
@@ -575,8 +576,8 @@ export module Implementation {
          * adds a new request to our queue for further processing
          */
         addRequestToQueue: function (elem: DQ, form: DQ, reqCtx: ExtConfig, respPassThr: Config, delay = 0, timeout = 0) {
-            requestQueue = requestQueue ?? new AsynchronousQueue<XhrRequest>();
-            requestQueue.enqueue(new XhrRequest(elem, form, reqCtx, respPassThr, [], timeout), delay);
+            requestQueue = requestQueue ?? new XhrQueueController<XhrRequest>();
+            requestQueue.enqueue(new XhrRequest(reqCtx, respPassThr, timeout), delay);
         }
     };
 
@@ -685,7 +686,7 @@ export module Implementation {
          * can deal with them either prefixed ir not
          * also resolves the absolute id case (it was assumed the server does this, but
          * apparently the RI does not, so we have to follow the RI behavior here)
-         * @param componentIdToTransform the componentId which needs post processing
+         * @param componentIdToTransform the componentId which needs post-processing
          */
         const remapNamingContainer = componentIdToTransform => {
             // pattern :<anything> must be prepended by viewRoot if there is one,
@@ -699,7 +700,7 @@ export module Implementation {
             const hasLeadingSep = componentIdToTransform.indexOf(SEP) === 0;
             const isAbsolutSearchExpr = hasLeadingSep || (rootNamingContainerId.length
                 && componentIdToTransform.indexOf(rootNamingContainerPrefix) == 0);
-            let finalIdentifier = "";
+            let finalIdentifier: string;
             if (isAbsolutSearchExpr) {
                 //we cut off the leading sep if there is one
                 componentIdToTransform = hasLeadingSep ? componentIdToTransform.substring(1) : componentIdToTransform;
@@ -718,14 +719,14 @@ export module Implementation {
                     [rootNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR) :
                     [nearestNamingContainerPrefix,  componentIdToTransform].join(EMPTY_STR);
             }
-            // We need to double check because we have scenarios where we have a naming container
+            // We need to double-check because we have scenarios where we have a naming container
             // and no prepend (aka tobago testcase "must handle ':' in IDs properly", scenario 3,
             // in this case we return the component id, and be happy
             // we can roll a dom check here
             return (!!document.getElementById(finalIdentifier)) ? finalIdentifier : componentIdToTransform;
         };
 
-        // in this case we do not use lazy stream because it wont bring any code reduction
+        // in this case we do not use lazy stream because it won´t bring any code reduction
         // or speedup
         for (let cnt = 0; cnt < iterValues.length; cnt++) {
             //avoid doubles
@@ -767,24 +768,37 @@ export module Implementation {
      * the values required for params-through are processed in the ajax request
      *
      * Note this is a bug carried over from the old implementation
-     * the spec conform behavior is to use params for passthrough values
+     * the spec conform behavior is to use params for pass - through values
      * this will be removed soon, after it is cleared up whether removing
      * it breaks any legacy code
      *
      * @param {Context} mappedOpts the options to be filtered
-     * @deprecated
      */
-    function extractLegacyParams(mappedOpts: Options): Context {
+    function extractLegacyParams(mappedOpts: Options): {[key: string]: any} {
+        //we now can use the full code reduction given by our stream api
+        //to filter
+        return ofAssoc(mappedOpts)
+            .filter((item => !(item[0] in BlockFilter)))
+            .reduce(collectAssoc, {});
+    }
+
+    /**
+     * extracts the myfaces config parameters which provide extra functionality
+     * on top of JSF
+     * @param mappedOpts
+     * @private
+     */
+    function extractMyFacesParams(mappedOpts: Options): {[key: string]: any} {
         //we now can use the full code reduction given by our stream api
         //to filter
-        return Stream.ofAssoc(mappedOpts)
-            .filter(item => !(item[0] in BlockFilter))
-            .collect(new AssocArrayCollector());
+        return ofAssoc(mappedOpts)
+            .filter((item => (item[0] == "myfaces")))
+            .reduce(collectAssoc, {})?.[MYFACES];
     }
 
     function remapArrayToAssocArr(arrayedParams: [[string, any]] | {[key: string]: any}): {[key: string]: any} {
         if(Array.isArray(arrayedParams)) {
-            return Stream.of(... arrayedParams).collect(new AssocArrayCollector());
+            return arrayedParams.reduce(collectAssoc, {} as any);
         }
         return arrayedParams;
     }
diff --git a/api/src/client/typescript/faces/impl/core/Const.ts b/api/src/client/typescript/faces/impl/core/Const.ts
index 484328edf..f0e4eedea 100644
--- a/api/src/client/typescript/faces/impl/core/Const.ts
+++ b/api/src/client/typescript/faces/impl/core/Const.ts
@@ -21,8 +21,8 @@
 export const XML_ATTR_NAMED_VIEWROOT = "namedViewRoot";
 export const NAMED_VIEWROOT = "namedViewRoot";
 
-export const P_PARTIAL_SOURCE = "jakarta.faces.source";
-export const NAMING_CONTAINER_ID = "myfaces.partialId";
+export const P_AJAX_SOURCE = "jakarta.faces.source";
+export const NAMING_CONTAINER_ID = "myfaces.NamingContainerId";
 
 export const VIEW_ID = "myfaces.viewId";
 export const P_VIEWSTATE = "jakarta.faces.ViewState";
@@ -108,6 +108,7 @@ export const CTX_PARAM_MF_INTERNAL = "myfaces.internal";
 export const CTX_PARAM_SRC_FRM_ID = "myfaces.source.formId";
 export const CTX_PARAM_SRC_CTL_ID = "myfaces.source.controlId";
 export const CTX_PARAM_REQ_PASS_THR = "myfaces.request.passThrough";
+export const CTX_PARAM_PPS = "myfaces.request.pps";
 
 export const CONTENT_TYPE = "Content-Type";
 export const HEAD_FACES_REQ = "Faces-Request";
@@ -141,6 +142,8 @@ export const PHASE_PROCESS_RESPONSE = "processResponse";
 
 export const ERR_NO_PARTIAL_RESPONSE = "Partial response not set";
 
+export const MYFACES_OPTION_PPS = "pps";
+
 export const ATTR_URL = "url";
 export const ATTR_NAME = "name";
 export const ATTR_VALUE = "value";
diff --git a/api/src/client/typescript/faces/impl/util/AsyncRunnable.ts b/api/src/client/typescript/faces/impl/util/AsyncRunnable.ts
index 49c5030ac..77097bd3e 100644
--- a/api/src/client/typescript/faces/impl/util/AsyncRunnable.ts
+++ b/api/src/client/typescript/faces/impl/util/AsyncRunnable.ts
@@ -26,7 +26,7 @@
  * from the implementation side it is mostly registering callbacks
  * and calling them at the appropriate time.
  */
-export interface AsyncRunnable<T> {
+export interface IAsyncRunnable<T> {
     /**
      * starts the runnable
      */
@@ -45,9 +45,9 @@ export interface AsyncRunnable<T> {
      * and then triggers all the registered then functions
      * when it is complete
      *
-     * @param func
+     * @param func the then functor
      */
-    then(func: (data: any) => any): AsyncRunnable<T>;
+    then(func: (data: any) => any): IAsyncRunnable<T>;
 
     /**
      * callback for catch functionality
@@ -59,7 +59,7 @@ export interface AsyncRunnable<T> {
      *
      * @param func
      */
-    catch(func: (data: any) => any): AsyncRunnable<T>;
+    catch(func: (data: any) => any): IAsyncRunnable<T>;
 
 
     /**
@@ -68,5 +68,80 @@ export interface AsyncRunnable<T> {
      * and once the finally time for the promise has
      * come the finally functions must be performed
      */
-    finally(func: () => void): AsyncRunnable<T>;
-}
\ No newline at end of file
+    finally(func: () => void): IAsyncRunnable<T>;
+}
+
+
+/**
+ * pretty much the same as cancellable Promise, but given
+ * we do not have that on browser level yet this is sort
+ * of a non - intrusive Shim!
+ */
+export abstract class AsyncRunnable<T> implements IAsyncRunnable<T>{
+    /**
+     * helper support so that we do not have to drag in Promise shims
+     */
+    private catchFunctions: Array<Function> = [];
+    private thenFunctions: Array<Function> = [];
+
+    /**
+     * cancel the run of the runnable (which then depending on the implementation
+     * either triggers indirectly resolve or reject)
+     */
+    abstract cancel(): void;
+
+    /**
+     * extended functionality start to trigger the runnable
+     */
+    abstract start(): void;
+
+    /**
+     * resolve handler function which calls the then chain
+     * and after that finally
+     * @param data
+     */
+    resolve(data: any) {
+        this.thenFunctions.reduce((inputVal: any, thenFunc: any) => {
+            return thenFunc(inputVal);
+        }, data)
+    }
+
+    /**
+     * reject handler function which triggers the catch chain
+     * @param data
+     */
+    reject(data: any) {
+        this.catchFunctions.reduce((inputVal: any, catchFunc: any) => {
+            return catchFunc(inputVal);
+        }, data);
+    }
+
+    /**
+     * register a catch functor
+     * @param func the functor for the catch monad
+     */
+    catch(func: (data: any) => any): IAsyncRunnable<T> {
+        this.catchFunctions.push(func);
+        return this;
+    }
+
+    /**
+     * registers a finally functor
+     * @param func the functor for the finally handling chanin
+     */
+    finally(func: () => void): IAsyncRunnable<T> {
+        // no ie11 support we probably are going to revert to shims for that one
+        this.catchFunctions.push(func);
+        this.thenFunctions.push(func);
+        return this;
+    }
+
+    /**
+     * @param func then functor similar to promise
+     */
+    then(func: (data: any) => any): IAsyncRunnable<T> {
+        this.thenFunctions.push(func);
+        return this;
+    }
+}
+
diff --git a/api/src/client/typescript/faces/impl/util/ExtDomQuery.ts b/api/src/client/typescript/faces/impl/util/ExtDomQuery.ts
index 465d5b3a4..e28da5a9f 100644
--- a/api/src/client/typescript/faces/impl/util/ExtDomQuery.ts
+++ b/api/src/client/typescript/faces/impl/util/ExtDomQuery.ts
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import {Config, IValueHolder, Optional, DomQuery, DQ, Stream, ArrayCollector} from "mona-dish";
+import {Config, IValueHolder, Optional, DomQuery, DQ, Es2019Array} from "mona-dish";
 import {$nsp, P_WINDOW_ID} from "../core/Const";
 
 
@@ -120,12 +120,10 @@ export class ExtDomQuery extends DQ {
         }
         // fallback if the currentScript method fails, we just search the jsf tags for nonce, this is
         // the last possibility
-        let nonceScript = DQ
-            .querySelectorAll("script[src], link[src]")
-            .lazyStream
+        let nonceScript = Optional.fromNullable(DQ
+            .querySelectorAll("script[src], link[src]").asArray
             .filter((item) => this.extractNonce(item)  && item.attr(ATTR_SRC) != null)
-            .filter(item => IS_FACES_SOURCE(item.attr(ATTR_SRC).value))
-            .first();
+            .filter(item => IS_FACES_SOURCE(item.attr(ATTR_SRC).value))?.[0]);
 
         if (nonceScript.isPresent()) {
             return this.extractNonce(nonceScript.value);
@@ -144,13 +142,13 @@ export class ExtDomQuery extends DQ {
      */
     searchJsfJsFor(regExp: RegExp): Optional<string> {
         //perfect application for lazy stream
-        return DQ.querySelectorAll("script[src], link[src]").lazyStream
+        return Optional.fromNullable(DQ.querySelectorAll("script[src], link[src]").asArray
             .filter(item => IS_FACES_SOURCE(item.attr(ATTR_SRC).value))
             .map(item => item.attr(ATTR_SRC).value.match(regExp))
             .filter(item => item != null && item.length > 1)
             .map((result: string[]) => {
                 return decodeURIComponent(result[1]);
-            }).first();
+            })?.[0]);
     }
 
     globalEval(code: string, nonce ?: string): DQ {
@@ -332,6 +330,6 @@ export class ExtConfig extends  Config {
         if(!this.$nspEnabled) {
             return accessPath;
         }
-        return Stream.of(...accessPath).map(key => $nsp(key)).collect(new ArrayCollector());
+        return new Es2019Array(...accessPath).map(key => $nsp(key));
     }
 }
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/impl/util/FileUtils.ts b/api/src/client/typescript/faces/impl/util/FileUtils.ts
index 176b0d142..4415e8493 100644
--- a/api/src/client/typescript/faces/impl/util/FileUtils.ts
+++ b/api/src/client/typescript/faces/impl/util/FileUtils.ts
@@ -1,4 +1,4 @@
-import {ArrayCollector, Config, DomQuery, DQ, LazyStream, Stream} from "mona-dish";
+import {Config, DomQuery, DQ, Es2019Array} from "mona-dish";
 import {ExtDomQuery} from "./ExtDomQuery";
 import {$faces, EMPTY_STR} from "../core/Const";
 
@@ -22,27 +22,24 @@ export function encodeFormData(formData: Config,
     }
     const assocValues = formData.value;
 
-    const expandValueArrAndRename = key => Stream.of(...assocValues[key]).map(val => paramsMapper(key, val));
+    const expandValueArrAndRename = key => assocValues[key].map(val => paramsMapper(key, val));
     const isPropertyKey = key => assocValues.hasOwnProperty(key);
     const isNotFile = ([, value]) => !(value instanceof ExtDomQuery.global().File);
     const mapIntoUrlParam = keyVal => `${encodeURIComponent(keyVal[0])}=${encodeURIComponent(keyVal[1])}`;
 
-    const entries = LazyStream.of(...Object.keys(assocValues))
+    return new Es2019Array(...Object.keys(assocValues))
         .filter(isPropertyKey)
         .flatMap(expandValueArrAndRename)
-        //we cannot encode file elements that is handled by multipart requests anyway
         .filter(isNotFile)
         .map(mapIntoUrlParam)
-        .collect(new ArrayCollector());
-
-    return entries.join("&")
+        .join("&");
 }
 
 /**
  * splits and decodes encoded values into strings containing of key=value
  * @param encoded encoded string
  */
-export function decodeEncodedValues(encoded: string): Stream<string[]> {
+export function decodeEncodedValues(encoded: string): string[][] {
     const filterBlanks = item => !!(item || '').replace(/\s+/g, '');
     const splitKeyValuePair = line => {
         let index = line.indexOf("=");
@@ -53,9 +50,7 @@ export function decodeEncodedValues(encoded: string): Stream<string[]> {
     };
 
     let requestParamEntries = decodeURIComponent(encoded).split(/&/gi);
-    return Stream.of(...requestParamEntries)
-        .filter(filterBlanks)
-        .map(splitKeyValuePair)
+    return requestParamEntries.filter(filterBlanks).map(splitKeyValuePair);
 }
 
 
@@ -63,19 +58,28 @@ export function decodeEncodedValues(encoded: string): Stream<string[]> {
  * gets all the input files and their corresponding file objects
  * @param dataSource
  */
-export function resolveFiles(dataSource: DQ): Stream<[string, File]> {
+export function resolveFiles(dataSource: DQ): [string, File][] {
+
+    const expandFilesArr = ([key, files]) => {
+        return [...files].map(file => [key, file]);
+    }
+    const remapFileInput = fileInput => {
+        return [fileInput.name.value || fileInput.id.value, fileInput.filesFromElem(0)];
+    }
 
-    const expandFilesArr = ([key, files]) => Stream.of(...files).map(file => [key, file]);
-    const remapFileInput = fileInput => [fileInput.name.value || fileInput.id.value, fileInput.filesFromElem(0)];
-    return dataSource
+    const files = dataSource
         .querySelectorAllDeep("input[type='file']")
-        .stream
+        .asArray;
+
+    const ret = files
         .map(remapFileInput)
         .flatMap(expandFilesArr);
+
+    return ret as any;
 }
 
 
-export function fixEmmptyParameters(keyVal: any[]): [string, any] {
+export function fixEmptyParameters(keyVal: any[]): [string, any] {
     return (keyVal.length < 3 ? [keyVal?.[0] ?? [], keyVal?.[1] ?? []] : keyVal) as [string, any];
 }
 
@@ -83,7 +87,7 @@ export function fixEmmptyParameters(keyVal: any[]): [string, any] {
  * returns the decoded viewState from parentItem
  * @param parentItem
  */
-function resolveViewState(parentItem: DomQuery): Stream<string[] | [string, File]> {
+function resolveViewState(parentItem: DomQuery): string[][] | [string, File][] {
     const viewStateStr = $faces().getViewState(parentItem.getAsElem(0).value);
 
     // we now need to decode it and then merge it into the target buf
@@ -94,11 +98,11 @@ function resolveViewState(parentItem: DomQuery): Stream<string[] | [string, File
 
 /**
  * gets all the inputs under the form parentItem
- * as stream
+ * as array
  * @param parentItem
  */
-export function getFormInputsAsStream(parentItem: DomQuery): Stream<string[] | [string, File]> {
-    const standardInputs = resolveViewState(parentItem);
+export function getFormInputsAsArr(parentItem: DomQuery): string[][] | [string, File][] {
+    const standardInputs: any = resolveViewState(parentItem);
     const fileInputs = resolveFiles(parentItem);
-    return  standardInputs.concat(fileInputs as any)
+    return standardInputs.concat(fileInputs)
 }
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/impl/util/HiddenInputBuilder.ts b/api/src/client/typescript/faces/impl/util/HiddenInputBuilder.ts
index 82ee20794..d2a50a484 100644
--- a/api/src/client/typescript/faces/impl/util/HiddenInputBuilder.ts
+++ b/api/src/client/typescript/faces/impl/util/HiddenInputBuilder.ts
@@ -58,13 +58,17 @@ export class HiddenInputBuilder {
         const SEP = $faces().separatorchar;
 
         let existingStates = DQ$(`[name*='${$nsp(this.name)}']`);
-        let cnt = existingStates.stream.map(state => {
+        let cnt = existingStates.asArray.map(state => {
             let ident: string = state.id.orElse("-1").value;
             ident = ident.substring(ident.lastIndexOf(SEP)+1);
             return parseInt(ident);
         })
-            .filter(item => !isNaN(item))
-            .reduce((item1, item2) => Math.max(item1, item2), -1).value;
+            .filter(item => {
+                return !isNaN(item);
+            })
+            .reduce((item1, item2) => {
+                return Math.max(item1, item2);
+            }, -1);
         //the maximum  new ident is the current max + 1
         cnt++;
 
diff --git a/api/src/client/typescript/faces/impl/util/Lang.ts b/api/src/client/typescript/faces/impl/util/Lang.ts
index 8b1b931d6..b5038127d 100644
--- a/api/src/client/typescript/faces/impl/util/Lang.ts
+++ b/api/src/client/typescript/faces/impl/util/Lang.ts
@@ -15,10 +15,11 @@
  *
  */
 
-import {Lang as LangBase, Config, Optional, DomQuery, DQ, Stream} from "mona-dish";
+import {Lang as LangBase, Config, Optional, DomQuery, DQ} from "mona-dish";
 import {Messages} from "../i18n/Messages";
 import {EMPTY_STR, HTML_TAG_FORM} from "../core/Const";
 import {getEventTarget} from "../xhrCore/RequestDataResolver";
+import {Es2019Array} from "mona-dish";
 
 
 export module ExtLang {
@@ -85,10 +86,10 @@ export module ExtLang {
         installedLocale = installedLocale ?? new Messages();
 
         let msg = installedLocale[key] ?? defaultMessage ?? key;
-
-        Stream.of(...templateParams).each((param, cnt) => {
+        templateParams.forEach((param, cnt) => {
             msg = msg.replace(new RegExp(["\\{", cnt, "\\}"].join(EMPTY_STR), "g"), param);
-        });
+        })
+
 
         return msg;
     }
@@ -202,6 +203,61 @@ export module ExtLang {
             defaultValue;
     }
 
+    /**
+     * expands an associative array into an array of key value tuples
+     * @param value
+     */
+    export function ofAssoc(value: {[key: string]: any}) {
+        return new Es2019Array(...Object.keys(value))
+            .map(key => [key, value[key]]);
+    }
+
+    export function collectAssoc(target: any, item: any) {
+        target[item[0]] = item[1];
+        return target;
+    }
+
+    /**
+     * The active timeout for the "debounce".
+     * Since we only use it in the XhrController
+     * we can use a local module variable here
+     */
+    let activeTimeouts = {};
+
+
+
+
+    /**
+     * a simple debounce function
+     * which waits until a timeout is reached and
+     * if something comes in in between debounces
+     *
+     * @param runnable a runnable which should go under debounce control
+     * @param timeout a timeout for the debounce window
+     */
+    export function debounce(key, runnable, timeout) {
+        function clearActiveTimeout() {
+            clearTimeout(activeTimeouts[key]);
+            delete activeTimeouts[key];
+        }
+
+        if (!!(activeTimeouts?.[key])) {
+            clearActiveTimeout();
+        }
+        if (timeout > 0) {
+            activeTimeouts[key] = setTimeout(() => {
+                try {
+                    runnable();
+                } finally {
+                    clearActiveTimeout();
+                }
+            }, timeout);
+        } else {
+            runnable();
+        }
+    }
+
+
     /**
      * assert that the form exists and throw an exception in the case it does not
      *
@@ -212,4 +268,6 @@ export module ExtLang {
             throw makeException(new Error(), null, null, "Impl", "getForm", getMessage("ERR_FORM"));
         }
     }
+
+
 }
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/impl/util/XhrQueueController.ts b/api/src/client/typescript/faces/impl/util/XhrQueueController.ts
new file mode 100644
index 000000000..76af89da0
--- /dev/null
+++ b/api/src/client/typescript/faces/impl/util/XhrQueueController.ts
@@ -0,0 +1,112 @@
+import {IAsyncRunnable} from "./AsyncRunnable";
+import {ExtLang} from "./Lang";
+import debounce = ExtLang.debounce;
+
+/**
+ * A simple XHR queue controller
+ * following the async op -> next pattern
+ * Faces enforces for the XHR handling
+ */
+export class XhrQueueController<T extends IAsyncRunnable<any>> {
+    queue = [];
+    taskRunning = false;
+
+    constructor() {
+    }
+
+    /**
+     * executes or enqueues an element
+     * @param runnable the runnable (request) to be enqueued
+     * @param timeOut timeout if > 0 which defers the execution
+     * until the debounce window for the timeout is closed.
+     */
+    enqueue(runnable: T, timeOut: number = 0) {
+        debounce("xhrQueue", () => {
+            const requestHandler = this.enrichRunnable(runnable);
+            if (!this.taskRunning) {
+                this.signalTaskRunning();
+                requestHandler.start();
+            } else {
+                this.queue.push(requestHandler);
+            }
+        }, timeOut);
+    }
+
+    /**
+     * trigger the next element in the queue
+     * to be started!
+     */
+    next() {
+        this.updateTaskRunning();
+        const next = this.queue.shift();
+        next?.start();
+    }
+
+    /**
+     * clears and resets the queue
+     */
+    clear() {
+        this.queue.length = 0;
+        this.updateTaskRunning();
+    }
+
+    /**
+     * true if queue is empty
+     */
+    get isEmpty(): boolean {
+        return !this.queue.length;
+    }
+
+    /**
+     * Enriches the incoming async asyncRunnable
+     * with the error and next handling
+     * (aka: asyncRunnable is done -> next
+     *                   error -> clear queue
+     * @param asyncRunnable the async runnable which needs enrichment
+     * @private
+     */
+    private enrichRunnable(asyncRunnable: T) {
+        /**
+         * we can use the Promise pattern asyncrunnable uses
+         * to trigger queue control callbacks of next element
+         * and clear the queue (theoretically this
+         * would work with any promise)
+         */
+        try {
+            return asyncRunnable
+                .then(() => this.next())
+                .catch((e) => this.handleError(e));
+        } catch (e) {
+            this.handleError(e);
+        }
+    }
+
+
+    /**
+     * alerts the queue that a task is running
+     *
+     * @private
+     */
+    private signalTaskRunning() {
+        this.taskRunning = true;
+    }
+
+    /**
+     * updates the task running status according to the current queue
+     * @private
+     */
+    private updateTaskRunning() {
+        this.taskRunning = !this.isEmpty;
+    }
+
+    /**
+     * standard error handling
+     * we clear the queue and then bomb out
+     * @param e
+     * @private
+     */
+    private handleError(e) {
+        this.clear();
+        throw e;
+    }
+}
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/impl/xhrCore/EventData.ts b/api/src/client/typescript/faces/impl/xhrCore/EventData.ts
index fab410a31..a04f0ebb6 100644
--- a/api/src/client/typescript/faces/impl/xhrCore/EventData.ts
+++ b/api/src/client/typescript/faces/impl/xhrCore/EventData.ts
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 import {Config, DQ} from "mona-dish";
-import {BEGIN, CTX_PARAM_REQ_PASS_THR, EVENT, P_PARTIAL_SOURCE, SOURCE} from "../core/Const";
+import {BEGIN, CTX_PARAM_REQ_PASS_THR, EVENT, P_AJAX_SOURCE, SOURCE} from "../core/Const";
 
 export class EventData implements IEventData{
     type: string;
@@ -32,8 +32,8 @@ export class EventData implements IEventData{
         eventData.status = name;
 
         let sourceId: string = context.getIf(SOURCE)
-            .orElseLazy(() => context.getIf(P_PARTIAL_SOURCE).value)
-            .orElseLazy(() => context.getIf(CTX_PARAM_REQ_PASS_THR, P_PARTIAL_SOURCE).value)
+            .orElseLazy(() => context.getIf(P_AJAX_SOURCE).value)
+            .orElseLazy(() => context.getIf(CTX_PARAM_REQ_PASS_THR, P_AJAX_SOURCE).value)
             .value;
         if (sourceId) {
             eventData.source = DQ.byId(sourceId, true).first().value.value;
diff --git a/api/src/client/typescript/faces/impl/xhrCore/ResponseProcessor.ts b/api/src/client/typescript/faces/impl/xhrCore/ResponseProcessor.ts
index 3be0f837a..a27def1ed 100644
--- a/api/src/client/typescript/faces/impl/xhrCore/ResponseProcessor.ts
+++ b/api/src/client/typescript/faces/impl/xhrCore/ResponseProcessor.ts
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-import {Config, DomQuery, DomQueryCollector, DQ, DQ$, Lang, LazyStream, Stream, XMLQuery} from "mona-dish";
+import {Config, DomQuery, DQ, DQ$, Lang, XMLQuery} from "mona-dish";
 import {Implementation} from "../AjaxImpl";
 import {Assertions} from "../util/Assertions";
 import {IResponseProcessor} from "./IResponseProcessor";
@@ -46,7 +46,7 @@ import {
     ON_EVENT,
     P_CLIENT_WINDOW,
     P_EXECUTE,
-    P_PARTIAL_SOURCE,
+    P_AJAX_SOURCE,
     P_RENDER,
     P_RENDER_OVERRIDE,
     P_VIEWSTATE,
@@ -65,6 +65,8 @@ import {
 import {ExtConfig, ExtDomQuery} from "../util/ExtDomQuery";
 import {HiddenInputBuilder} from "../util/HiddenInputBuilder";
 import trim = Lang.trim;
+import {ExtLang} from "../util/Lang";
+import ofAssoc = ExtLang.ofAssoc;
 
 
 /**
@@ -113,8 +115,8 @@ export class ResponseProcessor implements IResponseProcessor {
         const nodesToAdd = (shadowHead.tagName.value === "HEAD") ? shadowHead.childNodes : shadowHead;
         // this is stored for "post" processing
         // after the rest of the "physical build up", head before body
-        const scriptElements = nodesToAdd.stream
-            .filter(item => scriptTags.indexOf(item.tagName.orElse("").value) != -1).collect(new DomQueryCollector());
+        const scriptElements = new DomQuery(...nodesToAdd.asArray
+            .filter(item => scriptTags.indexOf(item.tagName.orElse("").value) != -1));
 
         this.addToHeadDeferred(scriptElements);
     }
@@ -174,7 +176,7 @@ export class ResponseProcessor implements IResponseProcessor {
          */
 
         const mergedErrorData = new ExtConfig({});
-        mergedErrorData.assign(SOURCE).value = this.externalContext.getIf(P_PARTIAL_SOURCE).get(0).value;
+        mergedErrorData.assign(SOURCE).value = this.externalContext.getIf(P_AJAX_SOURCE).get(0).value;
         mergedErrorData.assign(ERROR_NAME).value = node.querySelectorAll(ERROR_NAME).textContent(EMPTY_STR);
         mergedErrorData.assign(ERROR_MESSAGE).value = node.querySelectorAll(ERROR_MESSAGE).cDATAAsString;
 
@@ -346,15 +348,15 @@ export class ResponseProcessor implements IResponseProcessor {
      * as last lifecycle step, before going into the next request.
      */
     fixViewStates() {
-        Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_VST).orElse({}).value)
-            .each(([, value]) => {
+        ofAssoc(this.internalContext.getIf(APPLIED_VST).orElse({}).value)
+            .forEach(([, value]) => {
                 const namingContainerId = this.internalContext.getIf(NAMING_CONTAINER_ID);
                 const namedViewRoot = !!this.internalContext.getIf(NAMED_VIEWROOT).value
                 const affectedForms = this.getContainerForms(namingContainerId)
                     .filter(affectedForm => this.isInExecuteOrRender(affectedForm));
 
                 this.appendViewStateToForms(affectedForms, namedViewRoot, value.value, namingContainerId.orElse("").value);
-            });
+            })
     }
 
 
@@ -364,8 +366,8 @@ export class ResponseProcessor implements IResponseProcessor {
      * is done.
      */
     fixClientWindow() {
-        Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_CLIENT_WINDOW).orElse({}).value)
-            .each(([, value]) => {
+        ofAssoc(this.internalContext.getIf(APPLIED_CLIENT_WINDOW).orElse({}).value)
+            .forEach(([, value]) => {
                 const namingContainerId = this.internalContext.getIf(NAMING_CONTAINER_ID);
                 const namedViewRoot = !!this.internalContext.getIf(NAMED_VIEWROOT).value;
                 const affectedForms = this.getContainerForms(namingContainerId)
@@ -522,7 +524,7 @@ export class ResponseProcessor implements IResponseProcessor {
             .orElseLazy(() => this.externalContext.getIf($nsp(P_RENDER)).value)
             .orElse(IDENT_NONE).value.split(/\s+/gi);
         const executeAndRenders = executes.concat(...renders);
-        return LazyStream.of(...executeAndRenders).filter(nameOrId => {
+        return [...executeAndRenders].filter(nameOrId => {
             if ([IDENT_ALL, IDENT_NONE].indexOf(nameOrId) != -1) {
                 return true;
             }
@@ -532,7 +534,7 @@ export class ResponseProcessor implements IResponseProcessor {
             return affectedForm.matchesSelector(NAME_OR_ID) ||
                 affectedForm.querySelectorAll(NAME_OR_ID).isPresent() ||
                 affectedForm.firstParent(NAME_OR_ID).isPresent();
-        }).first().isPresent();
+        }).length > 0;
     }
 
     /**
diff --git a/api/src/client/typescript/faces/impl/xhrCore/XhrFormData.ts b/api/src/client/typescript/faces/impl/xhrCore/XhrFormData.ts
index 83937708a..dff98415e 100644
--- a/api/src/client/typescript/faces/impl/xhrCore/XhrFormData.ts
+++ b/api/src/client/typescript/faces/impl/xhrCore/XhrFormData.ts
@@ -13,19 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import {Config, DQ, FormDataCollector, Stream} from "mona-dish";
+import {Config, DQ} from "mona-dish";
 import {$nsp, EMPTY_STR, IDENT_NONE, P_VIEWSTATE} from "../core/Const";
 
 import {
     encodeFormData,
-    fixEmmptyParameters, getFormInputsAsStream
+    fixEmptyParameters, getFormInputsAsArr
 } from "../util/FileUtils";
+import {ExtLang} from "../util/Lang";
+import ofAssoc = ExtLang.ofAssoc;
+import {Es2019Array} from "mona-dish";
 
 
 type ParamsMapper<V, K> = (key: V, item: K) => [V, K];
 const defaultParamsMapper: ParamsMapper<string, any> = (key, item) => [key, item];
 
-
 /**
  * A unified form data class
  * which builds upon our configuration.
@@ -76,13 +78,17 @@ export class XhrFormData extends Config {
      */
     toFormData(): FormData {
         /*
-         * expands key: [item1, item2]
-         * to: [{key: key,  value: item1}, {key: key, value: item2}]
-         */
-        let expandAssocArray = ([key, item]) =>
-            Stream.of(...(item as Array<any>)).map(value => {
-                return {key, value};
-            });
+           * expands key: [item1, item2]
+           * to: [{key: key,  value: item1}, {key: key, value: item2}]
+           */
+        let expandValueArrays = ([key, item]) => {
+            if (Array.isArray(item)) {
+                return new Es2019Array(...item).map(value => {
+                    return {key, value}
+                })
+            }
+            return [{key, value: item}]
+        }
 
         /*
          * remaps the incoming {key, value} tuples
@@ -96,10 +102,13 @@ export class XhrFormData extends Config {
         /*
          * collects everything into a FormData object
          */
-        return  Stream.ofAssoc(this.value)
-            .flatMap(expandAssocArray)
+        return ofAssoc(this.value)
+            .flatMap(expandValueArrays)
             .map(remapForNamingContainer)
-            .collect(new FormDataCollector() as any);
+            .reduce((formData: FormData, {key, value}: any) => {
+                formData.append(key, value);
+                return formData;
+            }, new FormData()) as FormData;
     }
 
     /**
@@ -113,6 +122,7 @@ export class XhrFormData extends Config {
 
     /**
      * generic post init code, for now, this performs some post assign data post-processing
+     * @param rootElement the root element which knows the request type (usually a form)
      * @param executes the executable dom nodes which need to be processed into the form data, which we can send
      * in our ajax request
      */
@@ -139,20 +149,24 @@ export class XhrFormData extends Config {
 
     /**
      * determines fields to submit
-     * @param {Object} targetBuf - the target form buffer receiving the data
      * @param {Node} parentItem - form element item is nested in
      * @param {Array} partialIds - ids fo PPS
      */
-    private encodeSubmittableFields(parentItem: DQ, partialIds ?: string[]) {
+    private encodeSubmittableFields(parentItem: DQ, partialIds: string[] = []) {
 
-        const formInputs = getFormInputsAsStream(parentItem);
         const mergeIntoThis = ([key, value]) => this.append(key).value = value;
         const namingContainerRemap = ([key, value]) => this.paramsMapper(key as string, value);
 
-        formInputs
-            .map(fixEmmptyParameters)
+        const remappedPartialIds = partialIds.map(partialId => this.remapKeyForNamingContainer(partialId));
+        const partialIdsFilter = ([key, value]) => (!remappedPartialIds.length || key.indexOf("@") == 0) ? true :
+            remappedPartialIds.indexOf(key) != -1;
+
+        let inputs = getFormInputsAsArr(parentItem);
+        inputs
+            .map(fixEmptyParameters)
             .map(namingContainerRemap)
-            .each(mergeIntoThis);
+            .filter(partialIdsFilter)
+            .forEach(mergeIntoThis);
     }
 
     private remapKeyForNamingContainer(key: string): string {
diff --git a/api/src/client/typescript/faces/impl/xhrCore/XhrRequest.ts b/api/src/client/typescript/faces/impl/xhrCore/XhrRequest.ts
index 642fa61e4..b23417ac1 100644
--- a/api/src/client/typescript/faces/impl/xhrCore/XhrRequest.ts
+++ b/api/src/client/typescript/faces/impl/xhrCore/XhrRequest.ts
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-import {AsyncRunnable} from "../util/AsyncRunnable";
-import {Config, DQ, DQ$, Stream} from "mona-dish";
+import {AsyncRunnable, IAsyncRunnable} from "../util/AsyncRunnable";
+import {Config, DQ} from "mona-dish";
 import {Implementation} from "../AjaxImpl";
 
 import {XhrFormData} from "./XhrFormData";
@@ -41,7 +41,7 @@ import {
     STATE_EVT_TIMEOUT,
     STD_ACCEPT,
     URL_ENCODED,
-    VAL_AJAX, IDENT_NONE
+    VAL_AJAX, IDENT_NONE, CTX_PARAM_SRC_FRM_ID, CTX_PARAM_SRC_CTL_ID, CTX_PARAM_PPS
 } from "../core/Const";
 import {
     resolveFinalUrl,
@@ -54,6 +54,10 @@ import {ExtConfig} from "../util/ExtDomQuery";
 /**
  * Faces XHR Request Wrapper
  * as AsyncRunnable for our Asynchronous queue
+ * This means from the outside the
+ * xhr request is similar to a Promise in a way
+ * that you can add then and catch and finally callbacks.
+ *
  *
  * The idea is that we basically just enqueue
  * a single ajax request into our queue
@@ -62,60 +66,43 @@ import {ExtConfig} from "../util/ExtDomQuery";
  *
  */
 
-export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
+export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
 
     private responseContext: Config;
 
     private stopProgress = false;
 
-    /**
-     * helper support so that we do not have to drag in Promise shims
-     */
-    private catchFunctions: Array<Function> = [];
-    private thenFunctions: Array<Function> = [];
 
+    private xhrObject = new XMLHttpRequest();
     /**
      * Required Parameters
      *
-     * @param source the issuing element
-     * @param sourceForm the form which is related to the issuing element
      * @param requestContext the request context with all pass through values
-     *
-     * Optional Parameters
-     *
      * @param internalContext internal context with internal info which is passed through, not used by the user
-     * @param partialIdsArray an optional restricting partial ids array for encoding
+     * Optional Parameters
      * @param timeout optional xhr timeout
      * @param ajaxType optional request type, default "POST"
      * @param contentType optional content type, default "application/x-www-form-urlencoded"
-     * @param xhrObject optional xhr object which must fulfill the XMLHTTPRequest api, default XMLHttpRequest
      */
     constructor(
-        private source: DQ,
-        private sourceForm: DQ,
         private requestContext: ExtConfig,
         private internalContext: Config,
-        private partialIdsArray = [],
         private timeout = NO_TIMEOUT,
         private ajaxType = REQ_TYPE_POST,
-        private contentType = URL_ENCODED,
-        private xhrObject = new XMLHttpRequest()
+        private contentType = URL_ENCODED
     ) {
-
+        super();
         // we omit promises here because we have to deal with cancel functionality,
         // and promises to not provide that (yet) instead we have our async queue
         // which uses an api internally, which is very close to promises
-        this.registerXhrCallbacks((data: any) => {
-            this.resolve(data)
-        }, (data: any) => {
-            this.reject(data)
-        });
+        this.registerXhrCallbacks((data: any) => this.resolve(data), (data: any) => this.reject(data));
     }
 
-    start(): AsyncRunnable<XMLHttpRequest> {
+    start(): IAsyncRunnable<XMLHttpRequest> {
 
         let ignoreErr = failSaveExecute;
         let xhrObject = this.xhrObject;
+        let sourceForm = DQ.byId(this.internalContext.getIf(CTX_PARAM_SRC_FRM_ID).value)
 
         let executesArr = () => {
             return this.requestContext.getIf(CTX_PARAM_REQ_PASS_THR, P_EXECUTE).get(IDENT_NONE).value.split(/\s+/gi);
@@ -130,15 +117,20 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
             // whatever the formData object delivers
             // the partialIdsArray arr is almost deprecated legacy code where we allowed to send a separate list of partial
             // ids for reduced load and server processing, this will be removed soon, we can handle the same via execute
-            // anyway TODO reimplement the partial ids array, we still do not have it in jsf the way we need it
-            let formData: XhrFormData = new XhrFormData(this.sourceForm, resoveNamingContainerMapper(this.internalContext), executesArr(), this.partialIdsArray);
+            const executes = executesArr();
+            const partialIdsArray = this.internalContext.getIf(CTX_PARAM_PPS).value === true ? executes : [];
+            const formData: XhrFormData = new XhrFormData(
+                sourceForm,
+                resoveNamingContainerMapper(this.internalContext),
+                executes, partialIdsArray
+            );
 
             this.contentType = formData.isMultipartRequest ? "undefined" : this.contentType;
 
             // next step the pass through parameters are merged in for post params
             this.requestContext.$nspEnabled = false;
-            let requestContext = this.requestContext;
-            let requestPassThroughParams = requestContext.getIf(CTX_PARAM_REQ_PASS_THR) as ExtConfig;
+            const requestContext = this.requestContext;
+            const requestPassThroughParams = requestContext.getIf(CTX_PARAM_REQ_PASS_THR) as ExtConfig;
 
             // we are turning off here the jsf, faces remapping because we are now dealing with
             // pass-through parameters
@@ -149,6 +141,9 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
             try {
                 formData.shallowMerge(requestPassThroughParams, true, true);
             } finally {
+                // unfortunately as long as we support
+                // both namespaces we have to keep manual control
+                // on the key renaming before doing ops like deep copy
                 this.requestContext.$nspEnabled = true;
                 requestPassThroughParams.$nspEnabled = true;
             }
@@ -156,15 +151,15 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
             this.responseContext = requestPassThroughParams.deepCopy;
 
             // we have to shift the internal passthroughs around to build up our response context
-            let responseContext = this.responseContext;
+            const responseContext = this.responseContext;
 
             responseContext.assign(CTX_PARAM_MF_INTERNAL).value = this.internalContext.value;
 
-            // per spec the onevent and onerror handlers must be passed through to the response
+            // per spec the onEvent and onError handlers must be passed through to the response
             responseContext.assign(ON_EVENT).value = requestContext.getIf(ON_EVENT).value;
             responseContext.assign(ON_ERROR).value = requestContext.getIf(ON_ERROR).value;
 
-            xhrObject.open(this.ajaxType, resolveFinalUrl(this.sourceForm, formData, this.ajaxType), true);
+            xhrObject.open(this.ajaxType, resolveFinalUrl(sourceForm, formData, this.ajaxType), true);
 
             // adding timeout
             this.timeout ? xhrObject.timeout = this.timeout : null;
@@ -194,40 +189,15 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
 
     cancel() {
         try {
+            // this causes onError to be called where the error
+            // handling takes over
             this.xhrObject.abort();
         } catch (e) {
             this.handleError(e);
         }
     }
 
-    resolve(data: any) {
-        Stream.of(...this.thenFunctions).reduce((inputVal: any, thenFunc: any) => {
-            return thenFunc(inputVal);
-        }, data);
-    }
 
-    reject(data: any) {
-        Stream.of(...this.catchFunctions).reduce((inputVal: any, catchFunc: any) => {
-            return catchFunc(inputVal);
-        }, data);
-    }
-
-    catch(func: (data: any) => any): AsyncRunnable<XMLHttpRequest> {
-        this.catchFunctions.push(func);
-        return this;
-    }
-
-    finally(func: () => void): AsyncRunnable<XMLHttpRequest> {
-        // no ie11 support we probably are going to revert to shims for that one
-        this.catchFunctions.push(func);
-        this.thenFunctions.push(func);
-        return this;
-    }
-
-    then(func: (data: any) => any): AsyncRunnable<XMLHttpRequest> {
-        this.thenFunctions.push(func);
-        return this;
-    }
 
     /**
      * attaches the internal event and processing
@@ -237,7 +207,7 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
      * @param reject
      */
     private registerXhrCallbacks(resolve: Consumer<any>, reject: Consumer<any>) {
-        let xhrObject = this.xhrObject;
+        const xhrObject = this.xhrObject;
 
         xhrObject.onabort = () => {
             this.onAbort(reject);
@@ -253,13 +223,17 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
         };
         xhrObject.onerror = (errorData: any) => {
 
-            // some browsers trigger an error when cancelling a request internally
+            // some browsers trigger an error when cancelling a request internally, or when
+            // cancel is called from outside
             // in this case we simply ignore the request and clear up the queue, because
             // it is not safe anymore to proceed with the current queue
             // This bypasses a Safari issue where it keeps requests hanging after page unload
             // and then triggers a cancel error on then instead of just stopping
             // and clearing the code
             if(this.isCancelledResponse(this.xhrObject)) {
+                /*
+                 * this triggers the catch chain and after that finally
+                 */
                 reject();
                 this.stopProgress = true;
                 return;
@@ -307,14 +281,12 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
 
     private handleMalFormedXML(resolve: Function) {
         this.stopProgress = true;
-        let errorData = {
+        const errorData = {
             type: ERROR,
             status: MALFORMEDXML,
             responseCode: 200,
             responseText: this.xhrObject?.responseText,
-            // we remap the element just in case it gets replaced
-            // it will be unremapped
-            source:  this.source.id.value
+            source:  this.internalContext.getIf(CTX_PARAM_SRC_CTL_ID).value
         };
         try {
             this.handleError(errorData, true);
@@ -331,16 +303,22 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
         if (this.stopProgress) {
             return;
         }
+        /**
+         * now call the then chain
+         */
         resolve(data);
     }
 
     private onError(errorData: any,  reject: Consumer<any>) {
         this.handleError(errorData);
+        /*
+         * this triggers the catch chain and after that finally
+         */
         reject();
     }
 
     private sendRequest(formData: XhrFormData) {
-        let isPost = this.ajaxType != REQ_TYPE_GET;
+        const isPost = this.ajaxType != REQ_TYPE_GET;
         if (formData.isMultipartRequest) {
             // in case of a multipart request we send in a formData object as body
             this.xhrObject.send((isPost) ? formData.toFormData() : null);
@@ -354,7 +332,7 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
      * other helpers
      */
     private sendEvent(evtType: string) {
-        let eventData = EventData.createFromRequest(this.xhrObject, this.requestContext, evtType);
+        const eventData = EventData.createFromRequest(this.xhrObject, this.requestContext, evtType);
         try {
             // User code error, we might cover
             // this in onError, but also we cannot swallow it.
@@ -366,14 +344,15 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
         } catch (e) {
             e.source = e?.source ?? this.requestContext.getIf(SOURCE).value;
             this.handleError(e);
+
             throw e;
         }
     }
 
     private handleError(exception, responseFormatError: boolean = false) {
-        let errorData = (responseFormatError) ? ErrorData.fromHttpConnection(exception.source, exception.type, exception.status, exception.responseText, exception.responseCode, exception.status) : ErrorData.fromClient(exception);
+        const errorData = (responseFormatError) ? ErrorData.fromHttpConnection(exception.source, exception.type, exception.status, exception.responseText, exception.responseCode, exception.status) : ErrorData.fromClient(exception);
+        const eventHandler = resolveHandlerFunc(this.requestContext, this.responseContext, ON_ERROR);
 
-        let eventHandler = resolveHandlerFunc(this.requestContext, this.responseContext, ON_ERROR);
         Implementation.sendError(errorData, eventHandler);
     }
 }
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/myfaces/OamSubmit.ts b/api/src/client/typescript/faces/myfaces/OamSubmit.ts
index bed3b7d57..c094cc358 100644
--- a/api/src/client/typescript/faces/myfaces/OamSubmit.ts
+++ b/api/src/client/typescript/faces/myfaces/OamSubmit.ts
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-import {DQ, Stream} from "mona-dish";
+import {DQ} from "mona-dish";
+import {ExtLang} from "../impl/util/Lang";
 
 /**
  * legacy code to enable various aspects
@@ -28,6 +29,7 @@ import {DQ, Stream} from "mona-dish";
  * we might move the code over in the future, but for now a straight 1:1 port suffices
  */
 export module oam {
+    import ofAssoc = ExtLang.ofAssoc;
     /**
      * sets a hidden input field
      * @param formName the formName
@@ -86,8 +88,8 @@ export module oam {
         if (window?.myfaces?.core?.config?.autoScroll && (window as any)?.getScrolling) {
             myfaces.oam.setHiddenInput(formName, 'autoScroll', (window as any)?.getScrolling());
         }
-        let paramsStream: Stream<[string, any]> = Array.isArray(params) ? Stream.of(...params) : Stream.ofAssoc(params);
-        paramsStream.each(([key, data]) => myfaces.oam.setHiddenInput(formName, key, data));
+        let paramsStream: Array<[string, any]> = Array.isArray(params) ? [...params] : ofAssoc(params);
+        paramsStream.forEach(([key, data]) => myfaces.oam.setHiddenInput(formName, key, data));
 
         //we call the namespaced function, to allow decoration, via a direct call we would
         myfaces.oam.setHiddenInput(formName, `${formName}:_idcl`, linkId ?? '');
@@ -102,8 +104,6 @@ export module oam {
                 (form.getAsElem(0).value as HTMLFormElement).setAttribute("target", target);
             }
 
-
-
             const result = formElement?.onsubmit?.(null);
 
             try {
@@ -120,7 +120,7 @@ export module oam {
                 }
 
                 // noinspection JSUnusedLocalSymbols
-                paramsStream.each(([key, data]) => {
+                paramsStream.forEach(([key, data]) => {
                     myfaces.oam.clearHiddenInput(formName, key);
                 });
                 myfaces.oam.clearHiddenInput(formName, `${formName}:_idcl`);
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts
index f21317d33..4b7b0874b 100644
--- a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts
@@ -16,20 +16,21 @@
 
 import {expect} from 'chai';
 import {describe, it} from 'mocha';
-import {ArrayCollector, DomQuery, DomQueryCollector, Lang, LazyStream} from "mona-dish";
-import trim = Lang.trim;
 import {from} from "rxjs";
-
+import {ArrayCollector, Config, DomQuery, DomQueryCollector, Lang, LazyStream, Stream} from "mona-dish/dist/js/umd";
+import {tobagoSheetWithHeader} from "./markups/tobago-with-header";
+import {tobagoSheetWithoutHeader} from "./markups/tobago-without-header";
 
 const jsdom = require("jsdom");
 const {JSDOM} = jsdom;
+import trim = Lang.trim;
+
 (global as any).window = {}
 let dom = null;
 describe('DOMQuery tests', function () {
 
     beforeEach(function () {
 
-        // language=HTML
         dom = new JSDOM(`
             <!DOCTYPE html>
         <html lang="en">
@@ -86,14 +87,14 @@ describe('DOMQuery tests', function () {
         let probe1 = new DomQuery(window.document.body);
         let probe2 = DomQuery.querySelectorAll("div");
 
-        let o1 = from(probe1.stream);
-        let o2 = from(probe2.stream);
+        let o1 = from(Stream.ofDataSource(probe1));
+        let o2 = from(Stream.ofDataSource(probe2));
 
         let cnt1 = 0;
         let isDQuery = false;
         let cnt2 = 0;
 
-        o1.subscribe(() => {
+        o1.subscribe((item: any) => {
             cnt1++;
         });
 
@@ -112,14 +113,14 @@ describe('DOMQuery tests', function () {
         let probe1 = new DomQuery(window.document.body);
         let probe2 = DomQuery.querySelectorAll("div");
 
-        let o1 = from(probe1.stream);
-        let o2 = from(probe2.stream);
+        let o1 = from(Stream.ofDataSource(probe1));
+        let o2 = from(Stream.ofDataSource(probe2));
 
         let cnt1 = 0;
         let isDQuery = false;
         let cnt2 = 0;
 
-        o1.subscribe(() => {
+        o1.subscribe((item: any) => {
             cnt1++;
         });
 
@@ -183,7 +184,7 @@ describe('DOMQuery tests', function () {
     it('domquery ops test2 eachNode', function () {
         let probe2 = DomQuery.querySelectorAll("div");
         let noIter = 0;
-        probe2.each((item, cnt) => {
+        probe2 = probe2.each((item, cnt) => {
             expect(item instanceof DomQuery).to.be.true;
             expect(noIter == cnt).to.be.true;
             noIter++;
@@ -298,28 +299,61 @@ describe('DOMQuery tests', function () {
         expect(DomQuery.querySelectorAll("#insertedAfter2").isPresent()).to.be.true;
     });
 
+    it('do not create new <html> tag on <header', function () {
+
+        const fromMarkupWithHeader = DomQuery.fromMarkup(tobagoSheetWithHeader);
+        const fromMarkupWithoutHeader = DomQuery.fromMarkup(tobagoSheetWithoutHeader);
+
+        expect(fromMarkupWithHeader.tagName.value === "HTML").to.be.false;
+        expect(fromMarkupWithoutHeader.tagName.value === "HTML").to.be.false;
+    });
+
+
+    it('do not falsely assume standard tag', function () {
+
+        const fromMarkup1 = DomQuery.fromMarkup(`
+        <head-mine>booga</head-mine>
+        `);
+
+        const fromMarkup2 = DomQuery.fromMarkup(`
+        <body_mine>booga</body_mine>
+        
+        `);
+        expect(fromMarkup1.tagName.value === "HTML").to.be.false;
+        expect(fromMarkup1.tagName.value === "HTML").to.be.false;
+        expect(fromMarkup1.tagName.value === "HEAD").to.be.false;
+        expect(fromMarkup2.tagName.value === "BODY").to.be.false;
+    });
+
+
     it('it must stream', function () {
         let probe1 = new DomQuery(document).querySelectorAll("div");
-        let coll: Array<any> = probe1.stream.collect(new ArrayCollector());
+        let coll: Array<any> = Stream.ofDomQuery(probe1).collect(new ArrayCollector());
         expect(coll.length == 4).to.be.true;
 
-        coll = probe1.lazyStream.collect(new ArrayCollector());
+        coll = LazyStream.ofDomQuery(probe1).collect(new ArrayCollector());
         expect(coll.length == 4).to.be.true;
 
     });
 
-    it('it must stream to a domquery', function () {
+    it('it must stream - DQ API (dynamically added)', function () {
         let probe1 = new DomQuery(document).querySelectorAll("div");
-        let coll: DomQuery = probe1.stream.collect(new DomQueryCollector());
+        let coll: Array<any> = probe1.asArray;
         expect(coll.length == 4).to.be.true;
+    });
 
-        coll = probe1.lazyStream.collect(new DomQueryCollector());
+    it('it must stream to a domquery', function () {
+        let probe1 = new DomQuery(document).querySelectorAll("div");
+        let coll: DomQuery = Stream.ofDataSource(probe1).collect(new DomQueryCollector());
+        expect(coll.length == 4).to.be.true;
+        probe1.reset();
+        coll = LazyStream.ofStreamDataSource(probe1).collect(new DomQueryCollector());
         expect(coll.length == 4).to.be.true;
     });
 
     it('it must have parents', function () {
         let probe1 = new DomQuery(document).querySelectorAll("div");
-        let coll: Array<any> = probe1.firstParent("body").stream.collect(new ArrayCollector());
+        let coll: Array<any> = Stream.ofDataSource(probe1.parentsWhileMatch("body")).collect(new ArrayCollector());
         expect(coll.length == 1).to.be.true;
 
     });
@@ -342,22 +376,90 @@ describe('DOMQuery tests', function () {
         expect(innerHtml.indexOf("id_x_1_1") > innerHtml.indexOf("id_x_0_1")).to.be.true;
     })
 
+
+    it("must have a working replace", function () {
+        let probe1 = new DomQuery(document).byId("id_1");
+        probe1.replace(DomQuery.fromMarkup(` <div id="id_x_0"></div><div id="id_x_1"></div>`));
+
+
+        expect(DomQuery.querySelectorAll("div").length).to.eq(5);
+
+        let innerHtml = DomQuery.querySelectorAll("body").innerHTML;
+
+        expect(innerHtml.indexOf("id_x_0") > 0).to.be.true;
+        expect(innerHtml.indexOf("id_x_0") < innerHtml.indexOf("id_2")).to.be.true;
+        expect(innerHtml.indexOf("id_x_0") < innerHtml.indexOf("id_3")).to.be.true;
+
+        expect(innerHtml.indexOf("id_x_0") < innerHtml.indexOf("id_x_1")).to.be.true;
+
+        expect(innerHtml.indexOf("id_x_1") > 0).to.be.true;
+        expect(innerHtml.indexOf("id_x_1") < innerHtml.indexOf("id_2")).to.be.true;
+        expect(innerHtml.indexOf("id_x_1") < innerHtml.indexOf("id_3")).to.be.true;
+
+        expect(innerHtml.indexOf("id_1") == -1).to.be.true;
+    })
+
+    it("must have a working replace - 2", function () {
+        let probe1 = new DomQuery(document).byId("id_2");
+        probe1.replace(DomQuery.fromMarkup(` <div id="id_x_0"></div><div id="id_x_1"></div>`));
+
+
+        expect(DomQuery.querySelectorAll("div").length).to.eq(5);
+
+        let innerHtml = DomQuery.querySelectorAll("body").innerHTML;
+        expect(innerHtml.indexOf("id_x_0") > innerHtml.indexOf("id_1")).to.be.true;
+
+        expect(innerHtml.indexOf("id_x_0") > 0).to.be.true;
+        expect(innerHtml.indexOf("id_x_0") > innerHtml.indexOf("id_0")).to.be.true;
+        expect(innerHtml.indexOf("id_x_0") < innerHtml.indexOf("id_3")).to.be.true;
+
+        expect(innerHtml.indexOf("id_x_1") > 0).to.be.true;
+        expect(innerHtml.indexOf("id_x_1") > innerHtml.indexOf("id_0")).to.be.true;
+        expect(innerHtml.indexOf("id_x_1") < innerHtml.indexOf("id_3")).to.be.true;
+
+        expect(innerHtml.indexOf("id_2") == -1).to.be.true;
+    })
+
+    it("must have a working replace - 3", function () {
+        let probe1 = new DomQuery(document).byId("id_4");
+        probe1.replace(DomQuery.fromMarkup(` <div id="id_x_0"></div><div id="id_x_1"></div>`));
+
+
+        expect(DomQuery.querySelectorAll("div").length).to.eq(5);
+
+        let innerHtml = DomQuery.querySelectorAll("body").innerHTML;
+
+        expect(innerHtml.indexOf("id_x_0") > 0).to.be.true;
+        expect(innerHtml.indexOf("id_x_0") > innerHtml.indexOf("id_1")).to.be.true;
+        expect(innerHtml.indexOf("id_x_0") > innerHtml.indexOf("id_2")).to.be.true;
+        expect(innerHtml.indexOf("id_x_0") > innerHtml.indexOf("id_3")).to.be.true;
+
+        expect(innerHtml.indexOf("id_x_0") < innerHtml.indexOf("id_x_1")).to.be.true;
+
+        expect(innerHtml.indexOf("id_x_1") > 0).to.be.true;
+        expect(innerHtml.indexOf("id_x_1") > innerHtml.indexOf("id_1")).to.be.true;
+        expect(innerHtml.indexOf("id_x_1") > innerHtml.indexOf("id_2")).to.be.true;
+        expect(innerHtml.indexOf("id_x_1") > innerHtml.indexOf("id_3")).to.be.true;
+
+        expect(innerHtml.indexOf("id_4") == -1).to.be.true;
+    })
+
     it("must have a working input handling", function () {
         DomQuery.querySelectorAll("body").innerHTML = `<form id="blarg">
     <div id="embed1">
-        <input type="text" id="id_1" name="id_1" value="id_1_val">
-        <input type="text" id="id_2" name="id_2" value="id_2_val" disabled="disabled">
-        <textarea id="id_3" name="id_3">textareaVal</textarea>
+        <input type="text" id="id_1" name="id_1" value="id_1_val"></input>
+        <input type="text" id="id_2" name="id_2" value="id_2_val" disabled="disabled"> </input>
+        <textarea type="text" id="id_3" name="id_3">textareaVal</textarea>
 
         <fieldset>
-            <input type="radio" id="mc" name="cc_1" value="Mastercard" checked="checked">
+            <input type="radio" id="mc" name="cc_1" value="Mastercard" checked="checked"></input>
             <label for="mc"> Mastercard</label>
-            <input type="radio" id="vi" name="cc_1" value="Visa">
+            <input type="radio" id="vi" name="cc_1" value="Visa"></input>
             <label for="vi"> Visa</label>
-            <input type="radio" id="ae" name="cc_1" value="AmericanExpress">
+            <input type="radio" id="ae" name="cc_1" value="AmericanExpress"></input>
             <label for="ae"> American Express</label>
         </fieldset>
-        <select id="val_5" name="val_5" size="5">
+        <select id="val_5" name="val_5" name="top5" size="5">
             <option>barg</option>
             <option>jjj</option>
             <option selected>akaka</option>
@@ -375,22 +477,22 @@ describe('DOMQuery tests', function () {
         let length2 = DomQuery.byId("embed1").elements.length;
         expect(length2 == 8).to.be.true;
 
-        let count = DomQuery.byId("embed1").elements
-            .stream.map(item => item.disabled ? 1 : 0)
+        let count = Stream.ofDataSource(DomQuery.byId("embed1").elements)
+            .map<number>(item => item.disabled ? 1 : 0)
             .reduce((val1, val2) => val1 + val2, 0);
         expect(count.value).to.eq(1);
 
-        DomQuery.byId("embed1").elements
-            .stream.filter(item => item.disabled)
+        Stream.ofDataSource(DomQuery.byId("embed1").elements)
+            .filter(item => item.disabled)
             .each(item => item.disabled = false);
 
-        count = DomQuery.byId("embed1").elements
-            .stream.map(item => item.disabled ? 1 : 0)
+        count = Stream.ofDataSource(DomQuery.byId("embed1").elements)
+            .map<number>(item => item.disabled ? 1 : 0)
             .reduce((val1, val2) => val1 + val2, 0);
         expect(count.value).to.eq(0);
 
-        count = DomQuery.byId("embed1").elements
-            .stream.map(item => item.attr("checked").isPresent() ? 1 : 0)
+        count = Stream.ofDataSource(DomQuery.byId("embed1").elements)
+            .map<number>(item => item.attr("checked").isPresent() ? 1 : 0)
             .reduce((val1, val2) => val1 + val2, 0);
         expect(count.value).to.eq(1);
 
@@ -403,7 +505,7 @@ describe('DOMQuery tests', function () {
         DomQuery.byId("id_3").inputValue.value = "hello world";
         expect(DomQuery.byId("id_3").inputValue.value).to.eq("hello world");
 
-        let cfg = DomQuery.querySelectorAll("form").elements.encodeFormElement();
+        let cfg = new Config(DomQuery.querySelectorAll("form").elements.encodeFormElement());
         expect(cfg.getIf("id_1").value[0]).to.eq("booga");
         expect(cfg.getIf("id_2").value[0]).to.eq("id_2_val");
         expect(cfg.getIf("id_3").value[0]).to.eq("hello world");
@@ -451,17 +553,22 @@ describe('DOMQuery tests', function () {
             //-->   
             </script>
         
-            <style>
+            <style type="text/css">
                 #first {
                     border: 1px solid black;
                 }
             </style>
+            
+            <link rel="stylesheet" href="./fixtures/blank.css"></link>
         `;
         let content = DomQuery.byTagName("body").runScripts().runCss();
         expect(content.byId("first").innerHTML).to.eq("hello world");
         expect(content.byId("second").innerHTML).to.eq("hello world");
         expect(content.byId("third").innerHTML).to.eq("hello world");
         expect(content.byId("fourth").innerHTML).to.eq("hello world");
+
+        expect(DomQuery.byTagName("head")
+            .querySelectorAll("link[rel='stylesheet'][href='./fixtures/blank.css']").length).to.eq(1);
         done();
 
     });
@@ -482,7 +589,7 @@ describe('DOMQuery tests', function () {
 
     it("it must handle events properly", function () {
         let clicked = 0;
-        let listener = () => {
+        let listener = (evt: any) => {
             clicked++;
         };
         let eventReceiver = DomQuery.byId("id_1");
@@ -498,7 +605,7 @@ describe('DOMQuery tests', function () {
 
     });
 
-    it("it must handle innerText properly", function () {
+    it("it must handle innerText properly", function (done) {
 
         //jsdom bug
         Object.defineProperty(Object.prototype, 'innerText', {
@@ -510,6 +617,7 @@ describe('DOMQuery tests', function () {
         let probe = DomQuery.byId("id_1");
         probe.innerHTML = "<div>hello</div><div>world</div>";
         expect(probe.innerText()).to.eq("helloworld");
+        done();
     });
     it("it must handle textContent properly", function () {
         let probe = DomQuery.byId("id_1");
@@ -519,7 +627,7 @@ describe('DOMQuery tests', function () {
 
     it("it must handle iterations properly", function () {
         let probe = DomQuery.byTagName("div");
-        let resArr = probe.lazyStream.collect(new ArrayCollector());
+        let resArr = LazyStream.ofStreamDataSource(probe).collect(new ArrayCollector());
         expect(resArr.length).to.eq(4);
 
         probe.reset();
@@ -558,6 +666,21 @@ describe('DOMQuery tests', function () {
     })
 
 
+    it("parent must break shadow barriers", function () {
+        let probe = DomQuery.fromMarkup("<div id='shadowItem'>hello</div>'");
+        try {
+            //probably not testable atm, mocha does not have shadow dom support
+            //we might be able to shim it in one way or the other
+            let element = DomQuery.byId("id_1").attachShadow();
+            element.append(probe);
+            expect(probe.firstParent("#id_1").length > 0).to.eq(true);
+        } catch (e) {
+            //not supported we still need to get an error here
+            expect(e.message.indexOf("not supported") != -1).to.be.true;
+        }
+    })
+
+
     it('it must have a working wait for dom with mut observer and must detect condition after change', async function () {
         let probe = DomQuery.byId('id_1');
         probe.innerHTML = 'true';
@@ -629,11 +752,14 @@ describe('DOMQuery tests', function () {
 
     it('must by recycleable', function () {
         let probe = DomQuery.querySelectorAll("div");
+        let probe2 = DomQuery.querySelectorAll("body");
 
         let res1 = probe.filter(item => item.matchesSelector("div"));
         expect(res1.length).to.eq(4);
         let res2 = probe.filter(item => item.matchesSelector("div"));
         expect(res2.length).to.eq(4);
+
+
     })
 
     it('delete must work', function () {
@@ -651,9 +777,22 @@ describe('DOMQuery tests', function () {
         let probe2 = DomQuery.querySelectorAll("div");
         let probeCnt = 0;
         let probe2Cnt = 0;
-        from(probe).subscribe(() => probeCnt++);
-        from(probe2.stream).subscribe(() => probe2Cnt++);
+        from(probe).subscribe(el => probeCnt++);
+        from(Stream.ofDataSource(probe2)).subscribe(el => probe2Cnt++);
         expect(probeCnt).to.be.above(0);
         expect(probeCnt).to.eq(probe2Cnt);
-    })
+    });
+
+    it('must handle closest properly', function() {
+        let probe = DomQuery.byId("id_1");
+        probe.innerHTML = "<div id='inner_elem'>hello world<div id='inner_elem2'></div></div>";
+
+        let probe2 = DomQuery.byId("inner_elem");
+        expect(probe2.closest("div#id_1").id.value).to.eq("id_1");
+        expect(probe2.parent().closest("div").id.value).to.eq("id_1");
+        probe2 = DomQuery.byId("inner_elem2");
+        expect(probe2.closest("div").id.value).to.eq("inner_elem2");
+        expect(probe2.closest("div#id_1").id.value).to.eq("id_1");
+        expect(probe2.parent().parent().closest("div").id.value).to.eq("id_1");
+    });
 });
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/MonadTest.spec.ts b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/MonadTest.spec.ts
index df5dbe334..42026158e 100644
--- a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/MonadTest.spec.ts
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/MonadTest.spec.ts
@@ -125,7 +125,7 @@ describe('Config tests', () => {
     });
 
     it('array config2', () => {
-        let config = setup();
+        let config = new Config([]);
         config.assign("[5]", "world[3]", "from").value = "me";
         expect(config.getIf("[5]", "world[3]", "from").value).to.be.eq("me");
         expect(config.value[5].world[3].from).to.be.eq("me");
@@ -133,7 +133,7 @@ describe('Config tests', () => {
     });
 
     it('array config3', () => {
-        let config = setup();
+        let config = new Config([]);
         config.assign("[5]", "[3]", "from").value = "me";
         expect(config.getIf("[5]", "[3]", "from").value).to.be.eq("me");
         expect(config.value[5][3].from).to.be.eq("me");
@@ -141,7 +141,7 @@ describe('Config tests', () => {
     });
 
     it('array config4', () => {
-        let config = setup();
+        let config = new Config([]);
         config.assign("[5]", "[3]", "[2]").value = "me";
         expect(config.getIf("[5]", "[3]", "[2]").value).to.be.eq("me");
         expect(config.value[5][3][2]).to.be.eq("me");
@@ -149,7 +149,7 @@ describe('Config tests', () => {
     });
 
     it('array config5', () => {
-        let config = setup();
+        let config = new Config([]);
         config.assign("[5]", "world[3]", "from[2]").value = "me";
         expect(config.getIf("[5]", "world[3]", "from[2]").value).to.be.eq("me");
         expect(config.value[5].world[3].from[2]).to.be.eq("me");
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/StreamTest.spec.ts b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/StreamTest.spec.ts
deleted file mode 100644
index fa2724738..000000000
--- a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/StreamTest.spec.ts
+++ /dev/null
@@ -1,231 +0,0 @@
-/*! Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {describe} from "mocha";
-import {expect} from "chai";
-import {ArrayCollector, LazyStream, Stream} from "mona-dish";
-
-describe('early stream tests', () => {
-
-    beforeEach(function () {
-        this.probe = [1, 2, 3, 4, 5];
-    });
-
-    it("must iterate normal", function () {
-        let stream = Stream.of<number>(...this.probe);
-        let sum = 0;
-        stream.each((data) => {
-            sum = sum + data;
-        });
-        expect(sum).to.eq(15);
-
-        let stream2 = LazyStream.of<number>(...this.probe);
-        sum = 0;
-        stream2.each((data: number) => {
-            sum = sum + data;
-        });
-        expect(sum).to.eq(15);
-    });
-
-    it("must iterate filtered", function () {
-        let stream = Stream.of<number>(...this.probe);
-        let sum = 0;
-        stream.filter((data) => data != 5).each((data) => {
-            sum = sum + data;
-        });
-        expect(sum).to.eq(10);
-
-        let stream2 = LazyStream.of<number>(...this.probe);
-        sum = 0;
-        stream2.filter((data) => data != 5).each((data: number) => {
-            sum = sum + data;
-        });
-        expect(sum).to.eq(10);
-    });
-
-    it("must onElem", function () {
-        let stream = Stream.of<number>(...this.probe);
-        let sum = 0;
-        let sum2: number = stream.filter((data) => data != 5).onElem((data) => {
-            sum = sum + data;
-        }).reduce<number>((el1, el2) => el1 + el2).value;
-        expect(sum).to.eq(10);
-        expect(sum2).to.eq(10);
-
-        let stream2 = LazyStream.of<number>(...this.probe);
-        sum = 0;
-        sum2 = stream2.filter((data) => data != 5).onElem((data: number) => {
-            sum = sum + data;
-        }).reduce((el1: number, el2: number) => el1 + el2).value;
-        expect(sum).to.eq(10);
-        expect(sum2).to.eq(10);
-    })
-
-    it("must have a correct first last", function () {
-        let first = Stream.of<number>(...this.probe).filter((data) => data != 5).onElem(() => {
-        }).first().value;
-        let last = Stream.of<number>(...this.probe).filter((data) => data != 5).onElem(() => {
-        }).last().value;
-        expect(first).to.eq(1);
-        expect(last).to.eq(4);
-
-    });
-
-    it("must have a correct first last lazy", function () {
-        let first = LazyStream.of<number>(...this.probe).filter((data) => data != 5).onElem((data) => {
-            data;
-        }).first().value;
-        let last = Stream.of<number>(...this.probe).filter((data) => data != 5).onElem((data) => {
-            data;
-        }).last().value;
-        expect(first).to.eq(1);
-        expect(last).to.eq(4);
-
-    });
-
-    it("must have a correct limits", function () {
-        let cnt = 0;
-        let last = Stream.of<number>(...this.probe).filter((data) => data != 5).limits(2).onElem(() => {
-            cnt++;
-        }).last().value;
-
-        expect(last).to.eq(2);
-        expect(cnt).to.eq(2);
-
-    });
-
-    it("must initialize correctly from assoc array", function () {
-        let probe = {
-            key1: "val1",
-            key2: 2,
-            key3: "val3"
-        }
-
-        let arr1: Array<string | number> = [];
-        let arr2: Array<string | number> = [];
-
-        Stream.ofAssoc(probe).each(item => {
-            expect(item.length).to.eq(2);
-            arr1.push(item[0]);
-            arr2.push(item[1]);
-        });
-
-        expect(arr1.join(",")).to.eq("key1,key2,key3");
-        expect(arr2.join(",")).to.eq("val1,2,val3");
-
-    });
-
-    it("must have a correct lazy limits", function () {
-        let last = LazyStream.of<number>(...this.probe).filter((data) => data != 5).limits(2).onElem((data) => {
-            data;
-        }).last().value;
-
-        expect(last).to.eq(2);
-
-    })
-
-    it("must correctly lazily flatmap", function () {
-
-        let resultingArr = LazyStream.of<number>(...this.probe).flatMap((data) => LazyStream.of(...[data, 2])).value;
-
-        expect(resultingArr.length == 10).to.be.true;
-        expect(resultingArr.join(",")).to.eq("1,2,2,2,3,2,4,2,5,2");
-    });
-
-    it("must correctly lazily flatmap with arrays", function () {
-
-        let resultingArr = LazyStream.of<number>(...this.probe).flatMap((data) => [data, 2]).value;
-
-        expect(resultingArr.length == 10).to.be.true;
-        expect(resultingArr.join(",")).to.eq("1,2,2,2,3,2,4,2,5,2");
-    });
-
-    it("must correctly early flatmap", function () {
-
-        let resultingArr = Stream.of<number>(...this.probe).flatMap((data) => Stream.of(...[data, 2])).value;
-
-        expect(resultingArr.length == 10).to.be.true;
-        expect(resultingArr.join(",")).to.eq("1,2,2,2,3,2,4,2,5,2");
-    });
-
-    it("must correctly early flatmap with arrays", function () {
-
-        let resultingArr = Stream.of<number>(...this.probe).flatMap((data) => [data, 2]).value;
-
-        expect(resultingArr.length == 10).to.be.true;
-        expect(resultingArr.join(",")).to.eq("1,2,2,2,3,2,4,2,5,2");
-    });
-
-    it("must correctly flatmap intermixed", function () {
-
-        let resultingArr = LazyStream.of<number>(...this.probe).flatMap((data) => Stream.of(...[data, 2])).value;
-
-        expect(resultingArr.length == 10).to.be.true;
-        expect(resultingArr.join(",")).to.eq("1,2,2,2,3,2,4,2,5,2");
-    });
-
-    it("must correctly flatmap intermixed2", function () {
-
-        let resultingArr = Stream.of<number>(...this.probe).flatMap((data) => LazyStream.of(...[data, 2])).value;
-
-        expect(resultingArr.length == 10).to.be.true;
-        expect(resultingArr.join(",")).to.eq("1,2,2,2,3,2,4,2,5,2");
-    });
-
-    it("must correctly pass anyMatch allMatch noneMatch", function () {
-        let anyMatch = LazyStream.of<number>(...this.probe).anyMatch((item) => item == 3);
-        let allMatch = LazyStream.of<number>(...this.probe).allMatch((item) => item < 6);
-        let noneMatch = LazyStream.of<number>(...this.probe).noneMatch((item) => item > 5);
-
-        expect(anyMatch).to.be.true;
-        expect(allMatch).to.be.true;
-        expect(noneMatch).to.be.true;
-    })
-
-    it("must correctly pass anyMatch allMatch noneMatch early", function () {
-        let anyMatch = Stream.of<number>(...this.probe).anyMatch((item) => item == 3);
-        let allMatch = Stream.of<number>(...this.probe).allMatch((item) => item < 6);
-        let noneMatch = Stream.of<number>(...this.probe).noneMatch((item) => item > 5);
-
-        expect(anyMatch).to.be.true;
-        expect(allMatch).to.be.true;
-        expect(noneMatch).to.be.true;
-    })
-
-    it("must sort correctly", function () {
-
-        let probe: Array<number> = [1, 5, 3, 2, 4];
-
-        let res = Stream.of<number>(...probe)
-            .sort((el1: number, el2: number) => el1 - el2)
-            .collect(new ArrayCollector());
-
-        expect(res.join(",")).to.eq("1,2,3,4,5");
-
-    })
-
-    it("must sort correctly lazy", function () {
-
-        let probe: Array<number> = [1, 5, 3, 2, 4];
-
-        let res = LazyStream.of<number>(...probe)
-            .sort((el1: number, el2: number) => el1 - el2)
-            .collect(new ArrayCollector());
-
-        expect(res.join(",")).to.eq("1,2,3,4,5");
-
-    })
-});
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/blank.css b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/blank.css
new file mode 100644
index 000000000..1eb4b5b0c
--- /dev/null
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/blank.css
@@ -0,0 +1,15 @@
+/*! Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test.js b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test.js
index 24b4a21f0..b78d5194b 100644
--- a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test.js
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test.js
@@ -1 +1,16 @@
+/*! Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 document.getElementById('id_1').innerHTML = "hello world";
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test2.js b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test2.js
index 24b4a21f0..b78d5194b 100644
--- a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test2.js
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/fixtures/test2.js
@@ -1 +1,16 @@
+/*! Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 document.getElementById('id_1').innerHTML = "hello world";
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/markups/tobago-with-header.ts b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/markups/tobago-with-header.ts
new file mode 100644
index 000000000..d5961acbe
--- /dev/null
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/markups/tobago-with-header.ts
@@ -0,0 +1,921 @@
+export const tobagoSheetWithHeader = `<tobago-sheet id="page:mainForm:s1" data-tobago-selection-mode="multi" data-tobago-first="0" rows="0" row-count="88" data-tobago-layout="{&quot;columns&quot;:[1.0]}">
+                   <style nonce="" id="page:mainForm:s1:j_id_2n">#page\\:mainForm\\:s1{max-height:486px;}
+                   </style>
+                   <input id="page:mainForm:s1::widths" name="page:mainForm:s1::widths" type="hidden" value="[]">
+                   <input id="page:mainForm:s1::rendered" name="page:mainForm:s1::rendered" type="hidden" value="[true]">
+                   <input id="page:mainForm:s1::scrollPosition" name="page:mainForm:s1::scrollPosition" type="hidden" value="[0,0]">
+                   <input id="page:mainForm:s1::selected" name="page:mainForm:s1::selected" type="hidden" value="[]">
+                   <header>
+                    <table cellspacing="0" cellpadding="0" summary="" class="table table-sm tobago-tableLayout-fixed">
+                     <colgroup>
+                      <col width="385">
+                      <col>
+                      <col width="15">
+                     </colgroup>
+                     <thead>
+                      <tr>
+                       <th>
+                        <span><tobago-out id="page:mainForm:s1:_col0"><span class="form-control-plaintext">Name</span></tobago-out></span>
+                        <span class="tobago-resize" data-tobago-column-index="0">&nbsp;&nbsp;</span>
+                       </th>
+                       <th>
+                        <span></span>
+                       </th>
+                       <th>
+                        <span></span>
+                       </th>
+                      </tr>
+                     </thead>
+                    </table>
+                   </header>
+                   <div class="tobago-body">
+                    <table cellspacing="0" cellpadding="0" summary="" class="table table-sm tobago-tableLayout-fixed">
+                     <colgroup>
+                      <col width="385">
+                      <col>
+                     </colgroup>
+                     <tbody>
+                      <tr row-index="0" id="page:mainForm:s1:0:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:0:t_name"><span class="form-control-plaintext">Sun</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:0:sample0" execute="page:mainForm:s1:0:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="1" id="page:mainForm:s1:1:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:1:t_name"><span class="form-control-plaintext">Mercury</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:1:sample0" execute="page:mainForm:s1:1:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="2" id="page:mainForm:s1:2:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:2:t_name"><span class="form-control-plaintext">Venus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:2:sample0" execute="page:mainForm:s1:2:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="3" id="page:mainForm:s1:3:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:3:t_name"><span class="form-control-plaintext">Earth</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:3:sample0" execute="page:mainForm:s1:3:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="4" id="page:mainForm:s1:4:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:4:t_name"><span class="form-control-plaintext">Mars</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:4:sample0" execute="page:mainForm:s1:4:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="5" id="page:mainForm:s1:5:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:5:t_name"><span class="form-control-plaintext">Jupiter</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:5:sample0" execute="page:mainForm:s1:5:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="6" id="page:mainForm:s1:6:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:6:t_name"><span class="form-control-plaintext">Saturn</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:6:sample0" execute="page:mainForm:s1:6:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="7" id="page:mainForm:s1:7:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:7:t_name"><span class="form-control-plaintext">Uranus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:7:sample0" execute="page:mainForm:s1:7:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="8" id="page:mainForm:s1:8:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:8:t_name"><span class="form-control-plaintext">Neptune</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:8:sample0" execute="page:mainForm:s1:8:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="9" id="page:mainForm:s1:9:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:9:t_name"><span class="form-control-plaintext">Pluto</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:9:sample0" execute="page:mainForm:s1:9:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="10" id="page:mainForm:s1:10:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:10:t_name"><span class="form-control-plaintext">Moon</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:10:sample0" execute="page:mainForm:s1:10:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="11" id="page:mainForm:s1:11:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:11:t_name"><span class="form-control-plaintext">Phobos</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:11:sample0" execute="page:mainForm:s1:11:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="12" id="page:mainForm:s1:12:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:12:t_name"><span class="form-control-plaintext">Deimos</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:12:sample0" execute="page:mainForm:s1:12:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="13" id="page:mainForm:s1:13:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:13:t_name"><span class="form-control-plaintext">Metis</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:13:sample0" execute="page:mainForm:s1:13:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="14" id="page:mainForm:s1:14:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:14:t_name"><span class="form-control-plaintext">Adrastea</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:14:sample0" execute="page:mainForm:s1:14:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="15" id="page:mainForm:s1:15:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:15:t_name"><span class="form-control-plaintext">Amalthea</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:15:sample0" execute="page:mainForm:s1:15:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="16" id="page:mainForm:s1:16:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:16:t_name"><span class="form-control-plaintext">Thebe</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:16:sample0" execute="page:mainForm:s1:16:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="17" id="page:mainForm:s1:17:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:17:t_name"><span class="form-control-plaintext">Io</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:17:sample0" execute="page:mainForm:s1:17:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="18" id="page:mainForm:s1:18:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:18:t_name"><span class="form-control-plaintext">Europa</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:18:sample0" execute="page:mainForm:s1:18:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="19" id="page:mainForm:s1:19:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:19:t_name"><span class="form-control-plaintext">Ganymede</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:19:sample0" execute="page:mainForm:s1:19:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="20" id="page:mainForm:s1:20:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:20:t_name"><span class="form-control-plaintext">Callisto</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:20:sample0" execute="page:mainForm:s1:20:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="21" id="page:mainForm:s1:21:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:21:t_name"><span class="form-control-plaintext">Themisto</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:21:sample0" execute="page:mainForm:s1:21:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="22" id="page:mainForm:s1:22:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:22:t_name"><span class="form-control-plaintext">Leda</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:22:sample0" execute="page:mainForm:s1:22:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="23" id="page:mainForm:s1:23:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:23:t_name"><span class="form-control-plaintext">Himalia</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:23:sample0" execute="page:mainForm:s1:23:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="24" id="page:mainForm:s1:24:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:24:t_name"><span class="form-control-plaintext">Lysithea</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:24:sample0" execute="page:mainForm:s1:24:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="25" id="page:mainForm:s1:25:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:25:t_name"><span class="form-control-plaintext">Elara</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:25:sample0" execute="page:mainForm:s1:25:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="26" id="page:mainForm:s1:26:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:26:t_name"><span class="form-control-plaintext">Ananke</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:26:sample0" execute="page:mainForm:s1:26:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="27" id="page:mainForm:s1:27:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:27:t_name"><span class="form-control-plaintext">Carme</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:27:sample0" execute="page:mainForm:s1:27:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="28" id="page:mainForm:s1:28:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:28:t_name"><span class="form-control-plaintext">Pasiphae</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:28:sample0" execute="page:mainForm:s1:28:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="29" id="page:mainForm:s1:29:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:29:t_name"><span class="form-control-plaintext">Sinope</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:29:sample0" execute="page:mainForm:s1:29:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="30" id="page:mainForm:s1:30:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:30:t_name"><span class="form-control-plaintext">Iocaste</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:30:sample0" execute="page:mainForm:s1:30:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="31" id="page:mainForm:s1:31:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:31:t_name"><span class="form-control-plaintext">Harpalyke</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:31:sample0" execute="page:mainForm:s1:31:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="32" id="page:mainForm:s1:32:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:32:t_name"><span class="form-control-plaintext">Praxidike</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:32:sample0" execute="page:mainForm:s1:32:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="33" id="page:mainForm:s1:33:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:33:t_name"><span class="form-control-plaintext">Taygete</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:33:sample0" execute="page:mainForm:s1:33:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="34" id="page:mainForm:s1:34:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:34:t_name"><span class="form-control-plaintext">Chaldene</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:34:sample0" execute="page:mainForm:s1:34:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="35" id="page:mainForm:s1:35:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:35:t_name"><span class="form-control-plaintext">Kalyke</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:35:sample0" execute="page:mainForm:s1:35:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="36" id="page:mainForm:s1:36:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:36:t_name"><span class="form-control-plaintext">Callirrhoe</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:36:sample0" execute="page:mainForm:s1:36:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="37" id="page:mainForm:s1:37:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:37:t_name"><span class="form-control-plaintext">Megaclite</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:37:sample0" execute="page:mainForm:s1:37:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="38" id="page:mainForm:s1:38:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:38:t_name"><span class="form-control-plaintext">Isonoe</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:38:sample0" execute="page:mainForm:s1:38:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="39" id="page:mainForm:s1:39:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:39:t_name"><span class="form-control-plaintext">Erinome</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:39:sample0" execute="page:mainForm:s1:39:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="40" id="page:mainForm:s1:40:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:40:t_name"><span class="form-control-plaintext">Pan</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:40:sample0" execute="page:mainForm:s1:40:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="41" id="page:mainForm:s1:41:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:41:t_name"><span class="form-control-plaintext">Atlas</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:41:sample0" execute="page:mainForm:s1:41:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="42" id="page:mainForm:s1:42:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:42:t_name"><span class="form-control-plaintext">Prometheus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:42:sample0" execute="page:mainForm:s1:42:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="43" id="page:mainForm:s1:43:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:43:t_name"><span class="form-control-plaintext">Pandora</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:43:sample0" execute="page:mainForm:s1:43:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="44" id="page:mainForm:s1:44:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:44:t_name"><span class="form-control-plaintext">Epimetheus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:44:sample0" execute="page:mainForm:s1:44:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="45" id="page:mainForm:s1:45:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:45:t_name"><span class="form-control-plaintext">Janus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:45:sample0" execute="page:mainForm:s1:45:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="46" id="page:mainForm:s1:46:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:46:t_name"><span class="form-control-plaintext">Mimas</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:46:sample0" execute="page:mainForm:s1:46:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="47" id="page:mainForm:s1:47:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:47:t_name"><span class="form-control-plaintext">Enceladus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:47:sample0" execute="page:mainForm:s1:47:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="48" id="page:mainForm:s1:48:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:48:t_name"><span class="form-control-plaintext">Tethys</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:48:sample0" execute="page:mainForm:s1:48:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="49" id="page:mainForm:s1:49:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:49:t_name"><span class="form-control-plaintext">Telesto</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:49:sample0" execute="page:mainForm:s1:49:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="50" id="page:mainForm:s1:50:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:50:t_name"><span class="form-control-plaintext">Calypso</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:50:sample0" execute="page:mainForm:s1:50:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="51" id="page:mainForm:s1:51:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:51:t_name"><span class="form-control-plaintext">Dione</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:51:sample0" execute="page:mainForm:s1:51:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="52" id="page:mainForm:s1:52:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:52:t_name"><span class="form-control-plaintext">Helene</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:52:sample0" execute="page:mainForm:s1:52:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="53" id="page:mainForm:s1:53:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:53:t_name"><span class="form-control-plaintext">Rhea</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:53:sample0" execute="page:mainForm:s1:53:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="54" id="page:mainForm:s1:54:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:54:t_name"><span class="form-control-plaintext">Titan</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:54:sample0" execute="page:mainForm:s1:54:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="55" id="page:mainForm:s1:55:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:55:t_name"><span class="form-control-plaintext">Hyperion</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:55:sample0" execute="page:mainForm:s1:55:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="56" id="page:mainForm:s1:56:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:56:t_name"><span class="form-control-plaintext">Iapetus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:56:sample0" execute="page:mainForm:s1:56:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="57" id="page:mainForm:s1:57:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:57:t_name"><span class="form-control-plaintext">Phoebe</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:57:sample0" execute="page:mainForm:s1:57:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="58" id="page:mainForm:s1:58:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:58:t_name"><span class="form-control-plaintext">Cordelia</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:58:sample0" execute="page:mainForm:s1:58:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="59" id="page:mainForm:s1:59:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:59:t_name"><span class="form-control-plaintext">Ophelia</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:59:sample0" execute="page:mainForm:s1:59:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="60" id="page:mainForm:s1:60:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:60:t_name"><span class="form-control-plaintext">Bianca</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:60:sample0" execute="page:mainForm:s1:60:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="61" id="page:mainForm:s1:61:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:61:t_name"><span class="form-control-plaintext">Cressida</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:61:sample0" execute="page:mainForm:s1:61:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="62" id="page:mainForm:s1:62:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:62:t_name"><span class="form-control-plaintext">Desdemona</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:62:sample0" execute="page:mainForm:s1:62:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="63" id="page:mainForm:s1:63:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:63:t_name"><span class="form-control-plaintext">Juliet</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:63:sample0" execute="page:mainForm:s1:63:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="64" id="page:mainForm:s1:64:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:64:t_name"><span class="form-control-plaintext">Portia</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:64:sample0" execute="page:mainForm:s1:64:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="65" id="page:mainForm:s1:65:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:65:t_name"><span class="form-control-plaintext">Rosalind</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:65:sample0" execute="page:mainForm:s1:65:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="66" id="page:mainForm:s1:66:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:66:t_name"><span class="form-control-plaintext">Belinda</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:66:sample0" execute="page:mainForm:s1:66:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="67" id="page:mainForm:s1:67:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:67:t_name"><span class="form-control-plaintext">1986U10</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:67:sample0" execute="page:mainForm:s1:67:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="68" id="page:mainForm:s1:68:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:68:t_name"><span class="form-control-plaintext">Puck</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:68:sample0" execute="page:mainForm:s1:68:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="69" id="page:mainForm:s1:69:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:69:t_name"><span class="form-control-plaintext">Miranda</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:69:sample0" execute="page:mainForm:s1:69:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="70" id="page:mainForm:s1:70:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:70:t_name"><span class="form-control-plaintext">Ariel</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:70:sample0" execute="page:mainForm:s1:70:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="71" id="page:mainForm:s1:71:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:71:t_name"><span class="form-control-plaintext">Umbriel</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:71:sample0" execute="page:mainForm:s1:71:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="72" id="page:mainForm:s1:72:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:72:t_name"><span class="form-control-plaintext">Titania</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:72:sample0" execute="page:mainForm:s1:72:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="73" id="page:mainForm:s1:73:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:73:t_name"><span class="form-control-plaintext">Oberon</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:73:sample0" execute="page:mainForm:s1:73:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="74" id="page:mainForm:s1:74:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:74:t_name"><span class="form-control-plaintext">Caliban</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:74:sample0" execute="page:mainForm:s1:74:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="75" id="page:mainForm:s1:75:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:75:t_name"><span class="form-control-plaintext">Stephano</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:75:sample0" execute="page:mainForm:s1:75:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="76" id="page:mainForm:s1:76:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:76:t_name"><span class="form-control-plaintext">Sycorax</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:76:sample0" execute="page:mainForm:s1:76:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="77" id="page:mainForm:s1:77:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:77:t_name"><span class="form-control-plaintext">Prospero</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:77:sample0" execute="page:mainForm:s1:77:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="78" id="page:mainForm:s1:78:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:78:t_name"><span class="form-control-plaintext">Setebos</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:78:sample0" execute="page:mainForm:s1:78:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="79" id="page:mainForm:s1:79:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:79:t_name"><span class="form-control-plaintext">Naiad</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:79:sample0" execute="page:mainForm:s1:79:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="80" id="page:mainForm:s1:80:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:80:t_name"><span class="form-control-plaintext">Thalassa</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:80:sample0" execute="page:mainForm:s1:80:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="81" id="page:mainForm:s1:81:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:81:t_name"><span class="form-control-plaintext">Despina</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:81:sample0" execute="page:mainForm:s1:81:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="82" id="page:mainForm:s1:82:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:82:t_name"><span class="form-control-plaintext">Galatea</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:82:sample0" execute="page:mainForm:s1:82:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="83" id="page:mainForm:s1:83:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:83:t_name"><span class="form-control-plaintext">Larissa</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:83:sample0" execute="page:mainForm:s1:83:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="84" id="page:mainForm:s1:84:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:84:t_name"><span class="form-control-plaintext">Proteus</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:84:sample0" execute="page:mainForm:s1:84:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="85" id="page:mainForm:s1:85:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:85:t_name"><span class="form-control-plaintext">Triton</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:85:sample0" execute="page:mainForm:s1:85:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="86" id="page:mainForm:s1:86:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:86:t_name"><span class="form-control-plaintext">Nereid</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:86:sample0" execute="page:mainForm:s1:86:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                      <tr row-index="87" id="page:mainForm:s1:87:sample0">
+                       <td>
+                        <tobago-out id="page:mainForm:s1:87:t_name"><span class="form-control-plaintext">Charon</span></tobago-out>
+                       </td>
+                       <td>
+                        <div>
+                        </div>
+                        <tobago-behavior event="click" client-id="page:mainForm:s1:87:sample0" execute="page:mainForm:s1:87:sample0"></tobago-behavior>
+                       </td>
+                      </tr>
+                     </tbody>
+                    </table>
+                   </div>
+                  </tobago-sheet>`
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/markups/tobago-without-header.ts b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/markups/tobago-without-header.ts
new file mode 100644
index 000000000..61950c2bd
--- /dev/null
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/monadish/markups/tobago-without-header.ts
@@ -0,0 +1,108 @@
+export const tobagoSheetWithoutHeader = `<tobago-sheet id="page:mainForm:s1" data-tobago-selection-mode="multi" data-tobago-first="0" rows="0" row-count="88" data-tobago-layout="{&quot;columns&quot;:[1.0]}">
+  <style nonce="" id="page:mainForm:s1:j_id_2n">#page\\:mainForm\\:s1{max-height:486px;}
+  </style>
+  <input id="page:mainForm:s1::widths" name="page:mainForm:s1::widths" type="hidden" value="[]">
+  <input id="page:mainForm:s1::rendered" name="page:mainForm:s1::rendered" type="hidden" value="[true]">
+  <input id="page:mainForm:s1::scrollPosition" name="page:mainForm:s1::scrollPosition" type="hidden" value="[0,0]">
+  <input id="page:mainForm:s1::selected" name="page:mainForm:s1::selected" type="hidden" value="[]">
+  <div class="tobago-body">
+    <table cellspacing="0" cellpadding="0" summary="" class="table table-sm tobago-tableLayout-fixed">
+      <colgroup>
+        <col>
+        <col>
+      </colgroup>
+      <tbody>
+      <tr row-index="0" id="page:mainForm:s1:0:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:0:t_name"><span class="form-control-plaintext">Sun</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:0:sample0" execute="page:mainForm:s1:0:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="1" id="page:mainForm:s1:1:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:1:t_name"><span class="form-control-plaintext">Mercury</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:1:sample0" execute="page:mainForm:s1:1:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="2" id="page:mainForm:s1:2:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:2:t_name"><span class="form-control-plaintext">Venus</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:2:sample0" execute="page:mainForm:s1:2:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="3" id="page:mainForm:s1:3:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:3:t_name"><span class="form-control-plaintext">Earth</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:3:sample0" execute="page:mainForm:s1:3:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="4" id="page:mainForm:s1:4:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:4:t_name"><span class="form-control-plaintext">Mars</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:4:sample0" execute="page:mainForm:s1:4:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="5" id="page:mainForm:s1:5:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:5:t_name"><span class="form-control-plaintext">Jupiter</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:5:sample0" execute="page:mainForm:s1:5:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="6" id="page:mainForm:s1:6:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:6:t_name"><span class="form-control-plaintext">Saturn</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:6:sample0" execute="page:mainForm:s1:6:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="7" id="page:mainForm:s1:7:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:7:t_name"><span class="form-control-plaintext">Uranus</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:7:sample0" execute="page:mainForm:s1:7:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      <tr row-index="8" id="page:mainForm:s1:8:sample0">
+        <td>
+          <tobago-out id="page:mainForm:s1:8:t_name"><span class="form-control-plaintext">Neptune</span></tobago-out>
+        </td>
+        <td>
+          <div>
+          </div>
+          <tobago-behavior event="click" client-id="page:mainForm:s1:8:sample0" execute="page:mainForm:s1:8:sample0"></tobago-behavior>
+        </td>
+      </tr>
+      </tbody>
+    </table>
+  </div>
+</tobago-sheet>`;
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/shared/StandardInits.ts b/api/src/client/typescript/faces/test/frameworkBase/_ext/shared/StandardInits.ts
index dd668771b..d726e06f8 100644
--- a/api/src/client/typescript/faces/test/frameworkBase/_ext/shared/StandardInits.ts
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/shared/StandardInits.ts
@@ -83,6 +83,7 @@ export module StandardInits {
 <body>
 <form id="blarg">
     <input type="text" id="input_1" name="input_1" value="input_1_val"></input>
+    <input type="text" id="input_2_text" name="input_2_text" value="input_2_text_val"></input>
     <input type="hidden" id="jakarta.faces.ViewState" name="jakarta.faces.ViewState" value="blubbblubblubb"></input>
     <input type="button" id="input_2" name="input_2" value="input_1_val"></input>
 </form>
@@ -222,7 +223,7 @@ export module StandardInits {
     <meta charset="UTF-8">
     <title>Title</title>
     <script type="text/javascript"
-            src="/wfmportal/${IS_40 ? 'jakarta' : 'javax'}.faces.resource/${IS_40 ? 'faces': 'jsf'}.js.jsf?ln=jakarta.faces&separator=${separatorChar}"></script>
+            src="./fixtures/${IS_40 ? 'jakarta' : 'javax'}.faces.resource/${IS_40 ? 'faces': 'jsf'}.js.jsf?ln=jakarta.faces&separator=${separatorChar}"></script>
 </head>
 <body>
 <form id="blarg">
@@ -513,7 +514,7 @@ export module StandardInits {
         //let dom2 = new JSDOM(template)
         //return initMyFacesFromDom(dom2);
         let clean = null;
-        //we use jsdom global to fullfill our requirements
+        //we use jsdom global to fulfill our requirements
         //we need to import dynamically and use awaits
         if (withJsf) {
 
diff --git a/api/src/client/typescript/faces/test/frameworkBase/_ext/shared/fixtures/jakarta.faces.resource/faces.js.jsf b/api/src/client/typescript/faces/test/frameworkBase/_ext/shared/fixtures/jakarta.faces.resource/faces.js.jsf
new file mode 100644
index 000000000..86fc3d32a
--- /dev/null
+++ b/api/src/client/typescript/faces/test/frameworkBase/_ext/shared/fixtures/jakarta.faces.resource/faces.js.jsf
@@ -0,0 +1,15 @@
+/*! Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to you under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/test/impl/ImplTest.spec.ts b/api/src/client/typescript/faces/test/impl/ImplTest.spec.ts
index 3dc77449d..46ec0e544 100644
--- a/api/src/client/typescript/faces/test/impl/ImplTest.spec.ts
+++ b/api/src/client/typescript/faces/test/impl/ImplTest.spec.ts
@@ -15,13 +15,14 @@
  */
 
 import {Config, DomQuery} from "mona-dish";
-import {describe, it} from 'mocha';
+import {afterEach, describe, it} from 'mocha';
 import {expect} from 'chai';
 import * as sinon from 'sinon';
 
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
 import {CTX_PARAM_REQ_PASS_THR, P_EXECUTE, P_RENDER} from "../../impl/core/Const";
 import defaultMyFaces = StandardInits.defaultMyFaces;
+import {_Es2019Array} from "mona-dish";
 
 
 sinon.reset();
@@ -37,11 +38,26 @@ declare var Implementation: any;
  */
 
 describe('faces.ajax.request test suite', () => {
-
+    let oldFlatMap = null;
     beforeEach(async () => {
-        return await defaultMyFaces();
+        //we test ES2019 with it and whether we have missed
+        //a map somewhere
+        return await defaultMyFaces().then( () => {
+            if(Array.prototype.map) {
+                oldFlatMap =Array.prototype["flatMap"];
+                window["Es2019Array"] = _Es2019Array;
+                delete Array.prototype["flatMap"];
+            }
+        });
     });
 
+    afterEach(() => {
+        if(oldFlatMap) {
+            Array.prototype["flatMap"] = oldFlatMap;
+            oldFlatMap = null;
+        }
+    })
+
     it("faces.ajax.request can be called", () => {
         //we stub the addRequestToQueue, to enable the request check only
         //without any xhr and response, both will be tested separately for
@@ -50,12 +66,15 @@ describe('faces.ajax.request test suite', () => {
         //now the faces.ajax.request should trigger but should not go into
         //the asynchronous event loop.
         //lets check it out
+        let flatMap = Array.prototype.flatMap;
 
         try {
             DomQuery.byId("input_2").addEventListener("click", (event: Event) => {
-                faces.ajax.request(null, event, {render: '@all', execute: '@form'})
+
+                faces.ajax.request(null, event, {render: '@all', execute: '@form'});
             }).click();
 
+
             expect(addRequestToQueue.called).to.be.true;
             expect(addRequestToQueue.callCount).to.eq(1);
             const context = (<Config>addRequestToQueue.args[0][2]);
@@ -103,7 +122,7 @@ describe('faces.ajax.request test suite', () => {
             called["func5"] = true;
             return false;
         };
-
+        delete Array.prototype["flatMap"];
         faces.util.chain(this, called, func1, func2, func3, func4, func5);
 
         expect(called["func1"]).to.be.true;
@@ -118,7 +137,6 @@ describe('faces.ajax.request test suite', () => {
         expect(called["func2"]).to.be.true;
         expect(!!called["func4"]).to.be.true;
         expect(!!called["func5"]).to.be.false;
-
     });
 
 
diff --git a/api/src/client/typescript/faces/test/myfaces/OnLoad.spec.ts b/api/src/client/typescript/faces/test/myfaces/OnLoad.spec.ts
new file mode 100644
index 000000000..f82e469b7
--- /dev/null
+++ b/api/src/client/typescript/faces/test/myfaces/OnLoad.spec.ts
@@ -0,0 +1,52 @@
+/*! Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {describe, it} from "mocha";
+
+import {expect} from "chai";
+import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
+import defaultMyFaces = StandardInits.defaultMyFaces;
+
+
+
+declare var myfaces: any;
+
+/**
+ * Adds test s for the newly introduced onload handling
+ */
+describe('Tests on the xhr core when it starts to call the request', function () {
+
+    beforeEach(async () => {
+        return
+    });
+
+    it("must be present", async function()  {
+        await defaultMyFaces();
+        expect(myfaces?.onDomReady).to.exist;
+        return true;
+    });
+
+    it("must be called on onDocumentReady", async function(done) {
+        let called: boolean = false;
+        const onDomCalled = () => {
+            expect(true).to.true;
+            done();
+        }
+        myfaces?.onDomReady(onDomCalled);
+        await defaultMyFaces();
+    });
+
+});
diff --git a/api/src/client/typescript/faces/test/queue/AsynchronousProbe.ts b/api/src/client/typescript/faces/test/queue/AsynchronousProbe.ts
index 2ea93717e..25b77a554 100644
--- a/api/src/client/typescript/faces/test/queue/AsynchronousProbe.ts
+++ b/api/src/client/typescript/faces/test/queue/AsynchronousProbe.ts
@@ -18,10 +18,10 @@
  * we need a probe to test our asynchronous behavior
  * the asynchronous behavior needs to be in an asynchronous runnable
  */
-import {AsyncRunnable} from "../../impl/util/AsyncRunnable";
+import {IAsyncRunnable} from "../../impl/util/AsyncRunnable";
 import {IValueHolder} from "mona-dish";
 
-export class ProbeClass implements AsyncRunnable<Promise<any>>, IValueHolder<Promise<any>> {
+export class ProbeClass implements IAsyncRunnable<Promise<any>>, IValueHolder<Promise<any>> {
 
     value: Promise<any>;
     fCatch: (data: any) => any;
@@ -44,7 +44,7 @@ export class ProbeClass implements AsyncRunnable<Promise<any>>, IValueHolder<Pro
         });
     }
 
-    catch(func: (data: any) => any): AsyncRunnable<boolean> {
+    catch(func: (data: any) => any): IAsyncRunnable<boolean> {
         let catchFunc = (data: any) => {
             this.catchPerformed = true;
             return func(data);
@@ -57,7 +57,7 @@ export class ProbeClass implements AsyncRunnable<Promise<any>>, IValueHolder<Pro
         return this;
     }
 
-    finally(func: () => void): AsyncRunnable<boolean> {
+    finally(func: () => void): IAsyncRunnable<boolean> {
         let finallyFunc = () => {
             this.finallyPerformed = true;
             func();
@@ -88,7 +88,7 @@ export class ProbeClass implements AsyncRunnable<Promise<any>>, IValueHolder<Pro
         //TODO do something with it
     }
 
-    then(func: (data: any) => any): AsyncRunnable<boolean> {
+    then(func: (data: any) => any): IAsyncRunnable<boolean> {
 
         let thenFunc = (data: any) => {
             this.thenPerformed = true;
diff --git a/api/src/client/typescript/faces/test/queue/AsynchronousQueueTest.spec.ts b/api/src/client/typescript/faces/test/queue/AsynchronousQueueTest.spec.ts
index 611c5fe04..7773adeaa 100644
--- a/api/src/client/typescript/faces/test/queue/AsynchronousQueueTest.spec.ts
+++ b/api/src/client/typescript/faces/test/queue/AsynchronousQueueTest.spec.ts
@@ -18,10 +18,11 @@ import {describe, it} from 'mocha';
 import {expect} from 'chai';
 import * as sinon from 'sinon';
 import {ProbeClass} from "./AsynchronousProbe";
-import {AsynchronousQueue} from "../../impl/util/AsyncQueue";
+
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
 import {Implementation} from "../../impl/AjaxImpl";
 import defaultMyFaces = StandardInits.defaultMyFaces;
+import {XhrQueueController} from "../../impl/util/XhrQueueController";
 
 describe('Asynchronous Queue tests', () => {
 
@@ -60,7 +61,7 @@ describe('Asynchronous Queue tests', () => {
 
         const probe1 = new ProbeClass(setTimeout);
 
-        const queue = new AsynchronousQueue();
+        const queue = new XhrQueueController();
         probe1.then(() => {
             expect(probe1.thenPerformed, "called").to.be.true;
             done();
@@ -69,7 +70,7 @@ describe('Asynchronous Queue tests', () => {
     });
 
     it('multiple  entries', (done) => {
-        const queue = new AsynchronousQueue();
+        const queue = new XhrQueueController();
         const probe1 = new ProbeClass(setTimeout);
         const probe2 = new ProbeClass(setTimeout);
         const probe3 = new ProbeClass(setTimeout);
diff --git a/api/src/client/typescript/faces/test/xhrCore/ClientWindow.spec.ts b/api/src/client/typescript/faces/test/xhrCore/ClientWindow.spec.ts
index 5f25bb1e6..277b695b0 100644
--- a/api/src/client/typescript/faces/test/xhrCore/ClientWindow.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/ClientWindow.spec.ts
@@ -4,6 +4,8 @@ import {Implementation} from "../../impl/AjaxImpl";
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
 import {expect} from "chai";
 
+const jsdom = require("jsdom");
+const {JSDOM} = jsdom;
 
 describe('adds a getClientWindowTests', function () {
 
diff --git a/api/src/client/typescript/faces/test/xhrCore/EventTests.spec.ts b/api/src/client/typescript/faces/test/xhrCore/EventTests.spec.ts
index bb9e8b09b..cf8c2536f 100644
--- a/api/src/client/typescript/faces/test/xhrCore/EventTests.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/EventTests.spec.ts
@@ -87,28 +87,34 @@ describe('tests the addOnEvent and addOnError handling', function () {
     });
 
     it("must have onError called in case of error", function () {
-        let onErrorCalled1 = 0;
-        let onErrorCalled2 = 0;
-
-        let errorTitle = '';
-        let errorMessage = '';
-        faces.ajax.addOnError((data: any) => {
-            errorTitle = data.errorName;
-            errorMessage = data.errorMessage;
-            onErrorCalled1++
-        });
-        faces.ajax.addOnError(() => {
-            onErrorCalled2++;
-        });
-
-        //cmd_error_component
-        DQ.byId("cmd_error_component").click();
-        this.respond(XmlResponses.ERROR_2);
-
-        expect(onErrorCalled1).to.eq(1);
-        expect(onErrorCalled2).to.eq(1);
-        expect(errorTitle).to.eq('Erro21');
-        expect(errorMessage).to.eq('serverError: Error2 Text');
+        const oldErr = console.error;
+        console.error = () => {}
+        try {
+            let onErrorCalled1 = 0;
+            let onErrorCalled2 = 0;
+
+            let errorTitle = '';
+            let errorMessage = '';
+            faces.ajax.addOnError((data: any) => {
+                errorTitle = data.errorName;
+                errorMessage = data.errorMessage;
+                onErrorCalled1++
+            });
+            faces.ajax.addOnError(() => {
+                onErrorCalled2++;
+            });
+
+            //cmd_error_component
+            DQ.byId("cmd_error_component").click();
+            this.respond(XmlResponses.ERROR_2);
+
+            expect(onErrorCalled1).to.eq(1);
+            expect(onErrorCalled2).to.eq(1);
+            expect(errorTitle).to.eq('Erro21');
+            expect(errorMessage).to.eq('serverError: Error2 Text');
+        } finally {
+            console.error = oldErr;
+        }
     });
 
     it("must have an id set if there is an emitting element", function () {
diff --git a/api/src/client/typescript/faces/test/xhrCore/FileUploadTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/FileUploadTest.spec.ts
index 0ae8096e0..d67c137a0 100644
--- a/api/src/client/typescript/faces/test/xhrCore/FileUploadTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/FileUploadTest.spec.ts
@@ -17,7 +17,7 @@ import {describe, it} from "mocha";
 import * as sinon from "sinon";
 import {expect} from "chai";
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
-import {DomQuery, DQ} from "mona-dish";
+import {_Es2019Array, DomQuery, DQ} from "mona-dish";
 import defaultFileForm = StandardInits.defaultFileForm;
 import {Implementation} from "../../impl/AjaxImpl";
 
@@ -27,6 +27,7 @@ declare var faces: any;
  * specialized tests testing the xhr core behavior when it hits the xmlHttpRequest object
  */
 describe('Tests on the xhr core when it starts to call the request', function () {
+    let oldFlatMap = null;
     beforeEach(async function () {
 
         let waitForResult = defaultFileForm();
@@ -47,6 +48,9 @@ describe('Tests on the xhr core when it starts to call the request', function ()
             };
             (<any>global).XMLHttpRequest = this.xhr;
             window.XMLHttpRequest = this.xhr;
+            oldFlatMap =Array.prototype["flatMap"];
+            window["Es2019Array"] = _Es2019Array;
+            delete Array.prototype["flatMap"];
 
             this.closeIt = () => {
                 (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
@@ -59,6 +63,10 @@ describe('Tests on the xhr core when it starts to call the request', function ()
     });
     afterEach(function () {
         this.closeIt();
+        if(oldFlatMap) {
+            Array.prototype["flatMap"] = oldFlatMap;
+            oldFlatMap = null;
+        }
     });
 
     it('must have sent a form multipart request', function (done) {
diff --git a/api/src/client/typescript/faces/test/xhrCore/NamespacesRequestTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/NamespacesRequestTest.spec.ts
index 94ad76469..6f7aa3283 100644
--- a/api/src/client/typescript/faces/test/xhrCore/NamespacesRequestTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/NamespacesRequestTest.spec.ts
@@ -18,22 +18,19 @@ import {describe, it} from "mocha";
 import * as sinon from "sinon";
 import {expect} from "chai";
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
-import {DomQuery, DQ$, Stream} from "mona-dish";
+import {_Es2019Array, DQ$} from "mona-dish";
 import {
-    $nsp,
-    COMPLETE,
     P_AJAX,
     P_EXECUTE,
-    P_PARTIAL_SOURCE,
+    P_AJAX_SOURCE,
     P_RENDER,
     P_VIEWSTATE,
-    P_WINDOW_ID,
-    SUCCESS
+    P_WINDOW_ID
 } from "../../impl/core/Const";
-import defaultMyFaces = StandardInits.defaultMyFaces;
-import STD_XML = StandardInits.STD_XML;
 import defaultMyFacesNamespaces = StandardInits.defaultMyFacesNamespaces;
 import {escape} from "querystring";
+import {ExtLang} from "../../impl/util/Lang";
+import ofAssoc = ExtLang.ofAssoc;
 
 declare var faces: any;
 declare var Implementation: any;
@@ -50,6 +47,7 @@ let issueStdReq = function (element) {
 };
 
 describe('Namespacing tests', function () {
+    let oldFlatMap = null;
     beforeEach(async function () {
 
         let waitForResult = defaultMyFacesNamespaces();
@@ -65,6 +63,9 @@ describe('Namespacing tests', function () {
             window.XMLHttpRequest = this.xhr;
 
             this.jsfAjaxResponse = sinon.spy((<any>global).faces.ajax, "response");
+            oldFlatMap =Array.prototype["flatMap"];
+            window["Es2019Array"] = _Es2019Array;
+            delete Array.prototype["flatMap"];
 
             this.closeIt = () => {
                 (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
@@ -77,6 +78,10 @@ describe('Namespacing tests', function () {
 
     afterEach(function () {
         this.closeIt();
+        if(oldFlatMap) {
+            Array.prototype["flatMap"] = oldFlatMap;
+            oldFlatMap = null;
+        }
     });
 
     it('must send the element identifiers properly encoded', function () {
@@ -107,7 +112,7 @@ describe('Namespacing tests', function () {
             expect(!!resultsMap["execute"]).to.be.false;
             expect(P_WINDOW_ID in resultsMap).to.be.false;
             expect(P_VIEWSTATE in resultsMap).to.be.true;
-            expect(resultsMap[P_PARTIAL_SOURCE]).to.eq(escape("jd_0:input_2"));
+            expect(resultsMap[P_AJAX_SOURCE]).to.eq(escape("jd_0:input_2"));
             expect(resultsMap[P_AJAX]).to.eq("true");
             expect(resultsMap[P_RENDER]).to.eq(escape("jd_0:blarg jd_0:input_2"));
             expect(resultsMap[P_EXECUTE]).to.eq(escape("jd_0:input_1 jd_0:input_2"));
@@ -143,7 +148,7 @@ describe('Namespacing tests', function () {
             expect(!!resultsMap["execute"]).to.be.false;
             expect(P_WINDOW_ID in resultsMap).to.be.false;
             expect(P_VIEWSTATE in resultsMap).to.be.true;
-            expect(resultsMap[P_PARTIAL_SOURCE]).to.eq(escape("jd_0:input_2"));
+            expect(resultsMap[P_AJAX_SOURCE]).to.eq(escape("jd_0:input_2"));
             expect(resultsMap[P_AJAX]).to.eq("true");
             expect(resultsMap[P_RENDER]).to.eq(escape("jd_0:blarg jd_0:input_2"));
             expect(resultsMap[P_EXECUTE]).to.eq(escape("jd_0:input_1 jd_0:input_2"));
@@ -182,16 +187,16 @@ describe('Namespacing tests', function () {
             expect(!!resultsMap["render"]).to.be.false;
             expect(!!resultsMap["execute"]).to.be.false;
 
-            let hasWindowdId = Stream.ofAssoc(resultsMap).filter(data => data[0].indexOf(P_WINDOW_ID) != -1).first().isPresent();
-            let hasViewState = Stream.ofAssoc(resultsMap).filter(data => data[0].indexOf(P_VIEWSTATE) != -1).first().isPresent();
+            let hasWindowdId = ofAssoc(resultsMap).filter(data => data[0].indexOf(P_WINDOW_ID) != -1)?.[0];
+            let hasViewState = ofAssoc(resultsMap).filter(data => data[0].indexOf(P_VIEWSTATE) != -1)?.[0];
 
-            expect(hasWindowdId).to.be.false;
-            expect(hasViewState).to.be.true;
+            expect(!!hasWindowdId).to.be.false;
+            expect(!!hasViewState).to.be.true;
 
-            let viewState = Stream.ofAssoc(resultsMap).filter(data => data[0].indexOf(P_VIEWSTATE) != -1).map(item => item[1]).first().value;
+            let viewState = ofAssoc(resultsMap).filter(data => data[0].indexOf(P_VIEWSTATE) != -1).map(item => item[1])?.[0];
 
             expect(viewState).to.eq("booga");
-            expect(resultsMap[NAMING_CONTAINER_PREF + P_PARTIAL_SOURCE]).to.eq("jd_0:input_2");
+            expect(resultsMap[NAMING_CONTAINER_PREF + P_AJAX_SOURCE]).to.eq("jd_0:input_2");
             expect(resultsMap[NAMING_CONTAINER_PREF + P_AJAX]).to.eq("true");
             expect(resultsMap[NAMING_CONTAINER_PREF + P_RENDER]).to.eq("jd_0:blarg jd_0:input_2");
             expect(resultsMap[NAMING_CONTAINER_PREF + P_EXECUTE]).to.eq("jd_0:input_1 jd_0:input_2");
diff --git a/api/src/client/typescript/faces/test/xhrCore/OamSubmitTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/OamSubmitTest.spec.ts
index e00a5f1c4..7024076f5 100644
--- a/api/src/client/typescript/faces/test/xhrCore/OamSubmitTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/OamSubmitTest.spec.ts
@@ -19,11 +19,11 @@ import * as sinon from "sinon";
 import {Implementation} from "../../impl/AjaxImpl";
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
 import defaultMyFaces = StandardInits.defaultMyFaces;
-import {DQ, DQ$} from "mona-dish";
+import {_Es2019Array, DQ, DQ$} from "mona-dish";
 import {expect} from "chai";
 
 describe('Tests for the MyFaces specifig oam submit', function () {
-
+    let oldFlatMap = null;
     beforeEach(async function () {
 
         let waitForResult = defaultMyFaces();
@@ -39,6 +39,9 @@ describe('Tests for the MyFaces specifig oam submit', function () {
             window.XMLHttpRequest = this.xhr;
 
             this.jsfAjaxResponse = sinon.spy((<any>global).faces.ajax, "response");
+            oldFlatMap =Array.prototype["flatMap"];
+            window["Es2019Array"] = _Es2019Array;
+            delete Array.prototype["flatMap"];
 
             this.closeIt = () => {
                 (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
@@ -51,6 +54,10 @@ describe('Tests for the MyFaces specifig oam submit', function () {
 
     afterEach(function () {
         this.closeIt();
+        if(oldFlatMap) {
+            Array.prototype["flatMap"] = oldFlatMap;
+            oldFlatMap = null;
+        }
     });
 
     it(("must handle oam submit correctly, tuples"), (done) => {
diff --git a/api/src/client/typescript/faces/test/xhrCore/RequestParamsTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/RequestParamsTest.spec.ts
index 9ef6d0de9..a58e35503 100644
--- a/api/src/client/typescript/faces/test/xhrCore/RequestParamsTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/RequestParamsTest.spec.ts
@@ -18,7 +18,7 @@ import {Implementation} from "../../impl/AjaxImpl";
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
 
 import protocolPage = StandardInits.protocolPage;
-import {Config, DQ, Stream} from "mona-dish";
+import {Config, DQ} from "mona-dish";
 import {expect} from "chai";
 import HTML_PREFIX_EMBEDDED_BODY = StandardInits.HTML_PREFIX_EMBEDDED_BODY;
 import {it} from "mocha";
@@ -31,7 +31,7 @@ import {ExtConfig} from "../../impl/util/ExtDomQuery";
  * @param keyValueEntries a list of key value entries divided by =
  * @param paramsMapper a key value remapper
  */
-function mergeKeyValueEntries(target: Config, keyValueEntries: Stream<string[]>, paramsMapper = (key, value) => [key, value]) {
+function mergeKeyValueEntries(target: Config, keyValueEntries: string[][], paramsMapper = (key, value) => [key, value]) {
 
     function fixKeyWithoutVal(keyVal: string[]) {
         return keyVal.length < 3 ? [keyVal?.[0] ?? [], keyVal?.[1] ?? []] : keyVal;
@@ -42,7 +42,7 @@ function mergeKeyValueEntries(target: Config, keyValueEntries: Stream<string[]>,
         //special case of having keys without values
         .map(keyVal => fixKeyWithoutVal(keyVal))
         .map(keyVal => paramsMapper(keyVal[0] as string, keyVal[1]))
-        .each(keyVal => {
+        .forEach(keyVal => {
             let value = keyVal?.splice(1)?.join("") ?? "";
             if(toMerge.getIfPresent(keyVal[0]).isPresent()) {
                 toMerge.append(keyVal[0] as string).value = value;
diff --git a/api/src/client/typescript/faces/test/xhrCore/RequestTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/RequestTest.spec.ts
index 9d14a0ff5..1420eb883 100644
--- a/api/src/client/typescript/faces/test/xhrCore/RequestTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/RequestTest.spec.ts
@@ -18,12 +18,12 @@ import {describe, it} from "mocha";
 import * as sinon from "sinon";
 import {expect} from "chai";
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
-import {DomQuery} from "mona-dish";
+import {_Es2019Array, DomQuery} from "mona-dish";
 import {
     COMPLETE, EMPTY_STR,
     P_AJAX,
     P_EXECUTE,
-    P_PARTIAL_SOURCE,
+    P_AJAX_SOURCE,
     P_RENDER,
     P_VIEWSTATE,
     P_WINDOW_ID,
@@ -45,11 +45,34 @@ let issueStdReq = function (element) {
         }
     });
 };
+
+
+let issueStdPPSReq = function (element) {
+    faces.ajax.request(element, null, {
+        execute: "input_1",
+        render: "@form",
+        /*
+        * myfaces is the extension placeholder, atm only pps is used
+        * which was the most useful extension in our legacy codebase
+        */
+        myfaces: {
+            pps: true
+        },
+        /*
+         * params is the spec conform way to pass additional request paramerters
+         */
+        params: {
+            pass1: "pass1",
+            pass2: "pass2"
+        }
+    });
+};
+
 /**
  * specialized tests testing the xhr core behavior when it hits the xmlHttpRequest object
  */
 describe('Tests on the xhr core when it starts to call the request', function () {
-
+    let oldFlatMap = null;
     beforeEach(async function () {
 
         let waitForResult = defaultMyFaces();
@@ -65,6 +88,9 @@ describe('Tests on the xhr core when it starts to call the request', function ()
             window.XMLHttpRequest = this.xhr;
 
             this.jsfAjaxResponse = sinon.spy((<any>global).faces.ajax, "response");
+            oldFlatMap =Array.prototype["flatMap"];
+            window["Es2019Array"] = _Es2019Array;
+            delete Array.prototype["flatMap"];
 
             this.closeIt = () => {
                 (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
@@ -77,6 +103,10 @@ describe('Tests on the xhr core when it starts to call the request', function ()
 
     afterEach(function () {
         this.closeIt();
+        if(oldFlatMap) {
+            Array.prototype["flatMap"] = oldFlatMap;
+            oldFlatMap = null;
+        }
     });
 
     it('must have the standard parameters all in', function (done) {
@@ -119,13 +149,16 @@ describe('Tests on the xhr core when it starts to call the request', function ()
                 resultsMap[keyVal[0]] = keyVal[1];
             }
 
+            // normal request, all issuing form must be encoded!
+            expect(!!(resultsMap?.["input_2_text"] ?? false)).to.eq(true);
+            expect(!!(resultsMap?.["input_1"] ?? false)).to.eq(true);
             expect(resultsMap["pass1"]).to.eq("pass1");
             expect(resultsMap["pass2"]).to.eq("pass2");
             expect(!!resultsMap["render"]).to.be.false;
             expect(!!resultsMap["execute"]).to.be.false;
             expect(P_WINDOW_ID in resultsMap).to.be.false;
             expect(P_VIEWSTATE in resultsMap).to.be.true;
-            expect(resultsMap[P_PARTIAL_SOURCE]).to.eq("input_2");
+            expect(resultsMap[P_AJAX_SOURCE]).to.eq("input_2");
             expect(resultsMap[P_AJAX]).to.eq("true");
             expect(resultsMap[P_RENDER]).to.eq("blarg");
             expect(resultsMap[P_EXECUTE]).to.eq("input_1%20input_2");
@@ -292,7 +325,7 @@ describe('Tests after core when it hits response', function () {
                         expect(!!lastArg.onError).to.be.false;
                         expect(lastArg.pass1 == "pass1").to.be.true;
                         expect(lastArg.pass2 == "pass2").to.be.true;
-                        expect(!!lastArg[P_PARTIAL_SOURCE]).to.be.true;
+                        expect(!!lastArg[P_AJAX_SOURCE]).to.be.true;
                         expect(!!lastArg[P_AJAX]).to.be.true;
                         expect(!!lastArg[P_EXECUTE]).to.be.true;
                         expect(!!lastArg[P_RENDER]).to.be.true;
@@ -354,7 +387,7 @@ describe('Tests after core when it hits response', function () {
                         expect(!!lastArg.onError).to.be.false;
                         expect(lastArg.pass1 == "pass1").to.be.true;
                         expect(lastArg.pass2 == "pass2").to.be.true;
-                        expect(!!lastArg[P_PARTIAL_SOURCE]).to.be.true;
+                        expect(!!lastArg[P_AJAX_SOURCE]).to.be.true;
                         expect(!!lastArg[P_AJAX]).to.be.true;
                         expect(!!lastArg[P_EXECUTE]).to.be.true;
                         expect(!!lastArg[P_RENDER]).to.be.true;
@@ -417,7 +450,7 @@ describe('Tests after core when it hits response', function () {
                         expect(!!lastArg.onError).to.be.false;
                         expect(lastArg.pass1 == "pass1").to.be.true;
                         expect(lastArg.pass2 == "pass2").to.be.true;
-                        expect(!!lastArg[P_PARTIAL_SOURCE]).to.be.true;
+                        expect(!!lastArg[P_AJAX_SOURCE]).to.be.true;
                         expect(!!lastArg[P_AJAX]).to.be.true;
                         expect(!!lastArg[P_EXECUTE]).to.be.true;
                         expect(!!lastArg[P_RENDER]).to.be.true;
@@ -451,9 +484,10 @@ describe('Tests after core when it hits response', function () {
 
         let send = sinon.spy(XMLHttpRequest.prototype, "send");
         let xhrReq = null;
-
+        const oldErr = console.error;
         try {
             let errorCnt = 0;
+
             let element = DomQuery.byId("input_2").getAsElem(0).value;
             faces.ajax.request(element, null, {
                 execute: "input_1",
@@ -474,6 +508,8 @@ describe('Tests after core when it hits response', function () {
                 },
                 onevent: (evt: any) => {
                     if (evt.status == COMPLETE) {
+                        console.error = () => {
+                        };
                         throw Error("This error is wanted, ignore the log");
                     }
                 }
@@ -484,9 +520,13 @@ describe('Tests after core when it hits response', function () {
             xhrReq.respond(200, {'Content-Type': 'text/xml'}, STD_XML);
 
         } catch (e) {
+            if (e.message.indexOf("This error is wanted") != -1) {
+                return;
+            }
             console.error(e);
 
         } finally {
+            console.error = oldErr;
             send.restore();
         }
 
@@ -557,6 +597,47 @@ describe('Tests after core when it hits response', function () {
         done("Expecting a client error to be thrown")
     });
 
+    it("must have a proper working myfaces.pps = true, partial page submit", function (done) {
+        /**
+         * derived from the passthrough test
+         */
+        let send = sinon.spy(XMLHttpRequest.prototype, "send");
+        try {
+            //we only issue input 1
+            let element = DomQuery.byId("input_1").getAsElem(0).value;
+            issueStdPPSReq(element);
+
+            expect(send.called).to.be.true;
+            let argsVal: any = send.args[0][0];
+            let arsArr = argsVal.split("&");
+            let resultsMap = {};
+            for (let val of arsArr) {
+                let keyVal = val.split("=");
+                resultsMap[keyVal[0]] = keyVal[1];
+            }
+
+            expect(resultsMap?.["input_2_text"] ?? false).to.eq(false);
+            expect(!!(resultsMap?.["input_1"] ?? false)).to.eq(true);
+            expect(resultsMap["pass1"]).to.eq("pass1");
+            expect(resultsMap["pass2"]).to.eq("pass2");
+            expect(!!resultsMap["render"]).to.be.false;
+            expect(!!resultsMap["execute"]).to.be.false;
+            expect(P_WINDOW_ID in resultsMap).to.be.false;
+            expect(P_VIEWSTATE in resultsMap).to.be.true;
+            expect(resultsMap[P_AJAX_SOURCE]).to.eq("input_1");
+            expect(resultsMap[P_AJAX]).to.eq("true");
+            expect(resultsMap[P_RENDER]).to.eq("blarg");
+            expect(resultsMap[P_EXECUTE]).to.eq("input_1");
+
+
+            // TODO the request map only has the params and input1_ and input_2 passed no matter now many other values
+            // we might have to add some input elements into the form which are filetered out
+        } finally {
+            send.restore();
+        }
+        done();
+    });
+
 
 });
 
diff --git a/api/src/client/typescript/faces/test/xhrCore/RequestTest_23.spec.ts b/api/src/client/typescript/faces/test/xhrCore/RequestTest_23.spec.ts
index a8fb83354..95da34b5e 100644
--- a/api/src/client/typescript/faces/test/xhrCore/RequestTest_23.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/RequestTest_23.spec.ts
@@ -324,7 +324,7 @@ describe('Tests after core when it hits response', function () {
 
         let send = sinon.spy(XMLHttpRequest.prototype, "send");
         let xhrReq = null;
-
+        let oldErr = console.error;
         try {
             let element = DomQuery.byId("input_2").getAsElem(0).value;
             jsf.ajax.request(element, null, {
@@ -344,6 +344,7 @@ describe('Tests after core when it hits response', function () {
                 },
                 onevent: (evt: any) => {
                     if (evt.status == COMPLETE) {
+                        console.error = () => {};
                         throw Error("This error is wanted, ignore the log");
                     }
                 }
@@ -354,9 +355,13 @@ describe('Tests after core when it hits response', function () {
             xhrReq.respond(200, {'Content-Type': 'text/xml'}, STD_XML);
 
         } catch (e) {
+            if(e.message.indexOf("This error is wanted") != -1) {
+                return;
+            }
             console.error(e);
 
         } finally {
+            console.error = oldErr;
             send.restore();
         }
 
diff --git a/api/src/client/typescript/faces/test/xhrCore/ResponseTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/ResponseTest.spec.ts
index 0103f1fd3..8a9c733df 100644
--- a/api/src/client/typescript/faces/test/xhrCore/ResponseTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/ResponseTest.spec.ts
@@ -21,7 +21,7 @@ import * as sinon from "sinon";
 
 import {XmlResponses} from "../frameworkBase/_ext/shared/XmlResponses";
 import {expect} from "chai";
-import {DomQuery, DQ, DQ$} from "mona-dish";
+import {_Es2019Array, DomQuery, DQ, DQ$} from "mona-dish";
 import protocolPage = StandardInits.protocolPage;
 
 
@@ -35,7 +35,7 @@ declare var Implementation: any;
  * we do not need to go through the entire ajax cycle for that.
  */
 describe('Tests of the various aspects of the response protocol functionality', function () {
-
+    let oldFlatMap = null;
     beforeEach(async function () {
         let waitForResult = protocolPage();
         return waitForResult.then((close) => {
@@ -55,6 +55,9 @@ describe('Tests of the various aspects of the response protocol functionality',
             };
             (<any>global).XMLHttpRequest = this.xhr;
             window.XMLHttpRequest = this.xhr;
+            oldFlatMap =Array.prototype["flatMap"];
+            window["Es2019Array"] = _Es2019Array;
+            delete Array.prototype["flatMap"];
 
             this.closeIt = () => {
                 (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
@@ -66,6 +69,10 @@ describe('Tests of the various aspects of the response protocol functionality',
 
     afterEach(function () {
         this.closeIt();
+        if(oldFlatMap) {
+            Array.prototype["flatMap"] = oldFlatMap;
+            oldFlatMap = null;
+        }
     });
 
     it("must have a simple field updated as well as the viewstate", function (done) {
@@ -517,7 +524,6 @@ describe('Tests of the various aspects of the response protocol functionality',
         </partial-response>`
 
         window.document.body.innerHTML = INNER_HTML_MULIT_VIEW;
-        global["debug4"] = true;
         faces.ajax.request(window.document.getElementById("viewroot_1:submit_1"), null, {
             "javax.faces.behavior.event": "change",
             execute: "submit_1",
@@ -675,7 +681,7 @@ describe('Tests of the various aspects of the response protocol functionality',
         });
 
         //TODO xhr stubbing, to check if the viewId is prepended in render!
-
+        global["state_1"] = true;
         this.respond(`<?xml version="1.0" encoding="UTF-8"?>
 <partial-response id="viewroot_1">
     <changes>
@@ -727,35 +733,37 @@ describe('Tests of the various aspects of the response protocol functionality',
     it('must handle a ViewExpired Error correctly, and only once in a listener', function (done) {
 
         document.body.innerHTML = TCK_790_NAV_MARKUP;
-
-        let errorCalled = 0;
-        faces.ajax.addOnError((error)=> {
-            expect(error.errorName).to.eq("jakarta.faces.application.ViewExpiredException");
-            expect(error.errorMessage).to.eq("serverError: View \"/testhmtl.xhtml\" could not be restored.");
-            expect(error.source.id).to.eq("form1x:button");
-            errorCalled++;
-        });
-
-        faces.ajax.request(window.document.getElementById("form1x:button"), null, {
-            "javax.faces.behavior.event": "click",
-            execute: "@form",
-            render: ":form1x:button"
-        });
-
-        this.respond(`<?xml version="1.0" encoding="UTF-8"?>
+        const oldErr = console.error;
+        console.error = () => {};
+        try {
+            let errorCalled = 0;
+            faces.ajax.addOnError((error) => {
+                expect(error.errorName).to.eq("jakarta.faces.application.ViewExpiredException");
+                expect(error.errorMessage).to.eq("serverError: View \"/testhmtl.xhtml\" could not be restored.");
+                expect(error.source.id).to.eq("form1x:button");
+                errorCalled++;
+            });
+
+            faces.ajax.request(window.document.getElementById("form1x:button"), null, {
+                "javax.faces.behavior.event": "click",
+                execute: "@form",
+                render: ":form1x:button"
+            });
+
+            this.respond(`<?xml version="1.0" encoding="UTF-8"?>
         <partial-response><error>
         <error-name>jakarta.faces.application.ViewExpiredException</error-name>
         <error-message><![CDATA[View "/testhmtl.xhtml" could not be restored.]]></error-message>
         </error>
         </partial-response>`)
 
-        expect(errorCalled).to.eq(1);
-
+            expect(errorCalled).to.eq(1);
+        } finally {
+            console.error = oldErr;
+        }
         done();
 
     });
 
 
-
-
 });
\ No newline at end of file
diff --git a/api/src/client/typescript/faces/test/xhrCore/TobagoFileUploadTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/TobagoFileUploadTest.spec.ts
index 0bc297ce7..722819702 100644
--- a/api/src/client/typescript/faces/test/xhrCore/TobagoFileUploadTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/TobagoFileUploadTest.spec.ts
@@ -17,7 +17,7 @@ import {describe, it} from "mocha";
 import * as sinon from "sinon";
 import {expect} from "chai";
 import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
-import {DomQuery} from "mona-dish";
+import {_Es2019Array, DomQuery} from "mona-dish";
 import {Implementation} from "../../impl/AjaxImpl";
 import defaultFileForm = StandardInits.tobagoFileForm;
 
@@ -27,6 +27,7 @@ declare var faces: any;
  * specialized tests testing the xhr core behavior when it hits the xmlHttpRequest object
  */
 describe('Tests on the xhr core when it starts to call the request', function () {
+  let oldFlatMap = null;
   beforeEach(async function () {
 
     let waitForResult = defaultFileForm();
@@ -47,11 +48,18 @@ describe('Tests on the xhr core when it starts to call the request', function ()
       };
       (<any>global).XMLHttpRequest = this.xhr;
       window.XMLHttpRequest = this.xhr;
+      oldFlatMap =Array.prototype["flatMap"];
+      window["Es2019Array"] = _Es2019Array;
+      delete Array.prototype["flatMap"];
 
       this.closeIt = () => {
         (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
         Implementation.reset();
         close();
+        if(oldFlatMap) {
+          Array.prototype["flatMap"] = oldFlatMap;
+          oldFlatMap = null;
+        }
       }
     });
 
diff --git a/api/src/client/typescript/faces/test/xhrCore/WebsocketTest.ts b/api/src/client/typescript/faces/test/xhrCore/WebsocketTest.ts
index 2bc70c8ff..ef420ff4e 100644
--- a/api/src/client/typescript/faces/test/xhrCore/WebsocketTest.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/WebsocketTest.ts
@@ -21,16 +21,16 @@ import {Implementation} from "../../impl/AjaxImpl";
 import {expect} from "chai";
 
 import defaultMyFaces = StandardInits.defaultMyFaces;
-import {Lang} from "mona-dish";
+import {_Es2019Array, Lang} from "mona-dish";
 import {FakeWebsocket} from "./FakeWebsocket";
 import assertType = Lang.assertType;
 
 declare var faces: any;
 
 describe('Tests the jsf websocket client side api on high level (generic test without any myfaces dependencies', function () {
-
+    let oldFlatMap = null;
     beforeEach(async function () {
-
+        let oldFlatMap = null;
         let waitForResult = defaultMyFaces();
 
         return waitForResult.then((close) => {
@@ -51,6 +51,9 @@ describe('Tests the jsf websocket client side api on high level (generic test wi
 
             this.pushImpl = (<any>global).PushImpl;
             this.initSpy = sinon.spy(this.pushImpl, "init");
+            oldFlatMap =Array.prototype["flatMap"];
+            window["Es2019Array"] = _Es2019Array;
+            delete Array.prototype["flatMap"];
 
             this.closeIt = () => {
                 (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
@@ -67,6 +70,10 @@ describe('Tests the jsf websocket client side api on high level (generic test wi
 
     afterEach(function () {
         this.closeIt();
+        if(oldFlatMap) {
+            Array.prototype["flatMap"] = oldFlatMap;
+            oldFlatMap = null;
+        }
     });
 
     it("must register a channel", function (done: Function) {
diff --git a/api/src/client/typescript/faces/test/xhrCore/XhrFormDataTest.spec.ts b/api/src/client/typescript/faces/test/xhrCore/XhrFormDataTest.spec.ts
index 491a1c487..7ae120ed7 100644
--- a/api/src/client/typescript/faces/test/xhrCore/XhrFormDataTest.spec.ts
+++ b/api/src/client/typescript/faces/test/xhrCore/XhrFormDataTest.spec.ts
@@ -15,7 +15,7 @@
  */
 
 import {describe, it} from 'mocha';
-import {DQ} from "mona-dish";
+import {_Es2019Array, DQ} from "mona-dish";
 import * as sinon from 'sinon';
 import {XhrFormData} from "../../impl/xhrCore/XhrFormData";
 import {expect} from "chai";
@@ -27,7 +27,7 @@ const jsdom = require("jsdom");
 const {JSDOM} = jsdom;
 
 describe('XhrFormData tests', function () {
-
+    let oldFlatMap = null;
     beforeEach(async function () {
 
         let waitForResult = defaultMyFaces();
@@ -43,12 +43,19 @@ describe('XhrFormData tests', function () {
             window.XMLHttpRequest = this.xhr;
 
             this.jsfAjaxResponse = sinon.spy((<any>global).faces.ajax, "response");
+            oldFlatMap =Array.prototype["flatMap"];
+            window["Es2019Array"] = _Es2019Array;
+            delete Array.prototype["flatMap"];
 
             this.closeIt = () => {
                 (<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
                 this.jsfAjaxResponse.restore();
                 Implementation.reset();
                 close();
+                if(oldFlatMap) {
+                    Array.prototype["flatMap"] = oldFlatMap;
+                    oldFlatMap = null;
+                }
             }
         });
     });
diff --git a/api/src/client/typescript/mona_dish/AssocArray.ts b/api/src/client/typescript/mona_dish/AssocArray.ts
new file mode 100644
index 000000000..5552724f1
--- /dev/null
+++ b/api/src/client/typescript/mona_dish/AssocArray.ts
@@ -0,0 +1,291 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * various helpers to deal with associative
+ * arrays. If someone feels uncomfortable using
+ * The config system, this is similar!
+ */
+import {IValueHolder} from "./Monad";
+import {Es2019Array} from "./Es2019Array";
+
+/**
+ * A nop as assign functionality (aka ignore assign)
+ */
+class IgnoreAssign implements IValueHolder<any>  {
+    constructor(private parent: any) {}
+
+    set value(value: any | Array<any>) {
+    }
+    get value(): any | Array<any> {
+        return this.parent;
+    }
+};
+
+/**
+ * uses the known pattern from config
+ * assign(target, key1, key2, key3).value = value;
+ * @param target
+ * @param keys
+ */
+export function assign<T>(target: {[key: string]: any}, ...accessPath: string[]): IValueHolder<T> {
+    if (accessPath.length < 1) {
+        return new IgnoreAssign(target);
+    }
+    const lastPathItem = buildPath(target, ...accessPath);
+    let assigner: IValueHolder<T> = new (class {
+        set value(value: T | Array<T>) {
+            lastPathItem.target[lastPathItem.key] = value;
+        }
+
+        get value(): T | Array<T> {
+            return lastPathItem.target[lastPathItem.key];
+        }
+    })();
+    return assigner;
+}
+
+
+export function append<T>(target: {[key: string]: any}, ...accessPath: string[]): IValueHolder<T> {
+    if (accessPath.length < 1) {
+        return new IgnoreAssign(target);
+    }
+    const lastPathItem = buildPath(target, ...accessPath);
+    let appender: IValueHolder<T> = new (class {
+        set value(value: T | Array<T>) {
+            if(!Array.isArray(value)) {
+                value = [value];
+            }
+            if(!lastPathItem.target[lastPathItem.key]) {
+                lastPathItem.target[lastPathItem.key] = value
+            } else {
+                if(!Array.isArray(lastPathItem.target[lastPathItem.key])) {
+                    lastPathItem.target[lastPathItem.key] = [lastPathItem.target[lastPathItem.key]];
+                }
+                lastPathItem.target[lastPathItem.key].push(...value);
+            }
+        }
+    })();
+    return appender;
+}
+
+/**
+ * uses the known pattern from config
+ * assign(target, key1, key2, key3).value = value;
+ * @param target
+ * @param keys
+ */
+export function assignIf<T>(condition: boolean, target: {[key: string]: any}, ...accessPath: string[]): IValueHolder<T> {
+    if ((!condition) || accessPath.length < 1) {
+        return new IgnoreAssign(target);
+    }
+    return assign(target, ...accessPath);
+}
+
+
+/**
+ * uses the known pattern from config
+ * assign(target, key1, key2, key3).value = value;
+ * @param target
+ * @param keys
+ */
+export function appendIf<T>(condition: boolean, target: {[key: string]: any}, ...accessPath: string[]): IValueHolder<T> {
+    if ((!condition) || accessPath.length < 1) {
+        return new IgnoreAssign(target);
+    }
+    return append(target, ...accessPath);
+}
+
+export function resolve<T>(target, ...accessPath: string[]): T | null {
+    let ret = null;
+    accessPath = flattenAccessPath(accessPath);
+    let currPtr = target;
+    for(let cnt = 0; cnt < accessPath.length; cnt++) {
+        let accessKeyIndex: number | string = accessPath[cnt];
+        accessKeyIndex = arrayIndex(accessKeyIndex) != -1 ? arrayIndex(accessKeyIndex) : accessKeyIndex;
+        currPtr = currPtr?.[accessKeyIndex];
+        if('undefined' == typeof currPtr) {
+            return null;
+        }
+        ret = currPtr;
+    }
+    return currPtr;
+}
+
+
+function keyVal(key: string): string {
+    let start = key.indexOf("[");
+
+    if (start >= 0) {
+        return key.substring(0, start);
+    } else {
+        return key;
+    }
+}
+
+function arrayIndex(key: string): number {
+    let start = key.indexOf("[");
+    let end = key.indexOf("]");
+    if (start >= 0 && end > 0 && start < end) {
+        return parseInt(key.substring(start + 1, end));
+    } else {
+        return -1;
+    }
+}
+
+function isArrayPos(currKey: string, arrPos: number): boolean {
+    return currKey === "" && arrPos >= 0;
+}
+
+function isNoArray(arrPos: number): boolean {
+    return arrPos == -1;
+}
+
+function alloc(arr: Array<any>, length: number, defaultVal = {}) {
+    let toAdd = [];
+    toAdd.length = length;
+    toAdd[length - 1] = defaultVal;
+    arr.push(...toAdd);
+}
+
+
+function flattenAccessPath(accessPath: string[]) {
+    return new Es2019Array(...accessPath).flatMap(path => path.split("["))
+        .map(path => path.indexOf("]") != -1 ? "[" + path : path)
+        .filter(path => path != "");
+}
+
+/**
+ * builds up a path, only done if no data is present!
+ * @param target
+ * @param accessPath
+ * @returns the last assignable entry
+ */
+export function buildPath(target, ...accessPath: string[]) {
+    accessPath = flattenAccessPath(accessPath);
+    //we now have a pattern of having the array accessors always in separate items
+    let parentPtr = target;
+    let parKeyArrPos = null;
+    let currKey = null;
+    let arrPos = -1;
+
+    for (let cnt = 0; cnt < accessPath.length; cnt++) {
+        currKey = keyVal(accessPath[cnt]);
+        arrPos = arrayIndex(accessPath[cnt]);
+        //it now is either key or arrPos
+        if (arrPos != -1) {
+            //case root(array)[5] -> root must be array and allocate 5 elements
+            //case root.item[5] root.item must be array and of 5 elements
+            if(!Array.isArray(parentPtr)) {
+                throw Error("Associative array referenced as index array in path reference");
+            }
+
+            //we need to look ahead for proper allocation
+            //not end reached
+            let nextArrPos = -1;
+            if(cnt < accessPath.length - 1) {
+                nextArrPos = arrayIndex(accessPath[cnt + 1])
+            }
+            let dataPresent = 'undefined' != typeof parentPtr?.[arrPos];
+            //no data present check here is needed, because alloc only reserves if not present
+            alloc(parentPtr, arrPos + 1, nextArrPos != -1 ?[]: {});
+            parKeyArrPos = arrPos;
+            //we now go to the reserved element
+            if(cnt == accessPath.length - 1) {
+                parentPtr[arrPos] = (dataPresent) ? parentPtr[arrPos] : null;
+            } else {
+                parentPtr = parentPtr[arrPos];
+            }
+        } else {
+            if(Array.isArray(parentPtr)) {
+                throw Error("Index array referenced as associative array in path reference");
+            }
+            //again look ahead whether the next value is an array or assoc array
+            let nextArrPos = -1;
+            if(cnt < accessPath.length - 1) {
+                nextArrPos = arrayIndex(accessPath[cnt + 1])
+            }
+            parKeyArrPos = currKey;
+            let dataPresent = 'undefined' != typeof parentPtr?.[currKey];
+            if(cnt == accessPath.length - 1) {
+                if(!dataPresent) {
+                    parentPtr[currKey] = null;
+                }
+            } else {
+                if(!dataPresent) {
+                    parentPtr[currKey] = nextArrPos == -1 ? {} : [];
+                }
+                parentPtr = parentPtr[currKey];
+            }
+        }
+    }
+
+    return {target: parentPtr, key: parKeyArrPos};
+
+}
+
+export function deepCopy(fromAssoc: {[key: string]: any}): {[key: string]: any} {
+    return JSON.parse(JSON.stringify(fromAssoc));
+}
+
+/**
+ * simple left to right merge
+ *
+ * @param assocArrays
+ */
+export function simpleShallowMerge(...assocArrays) {
+   return shallowMerge(true, false, ...assocArrays);
+}
+
+/**
+ * Shallow merge as in config
+ *
+ * @param overwrite
+ * @param withAppend
+ * @param assocArrays
+ */
+export function shallowMerge(overwrite = true, withAppend = false, ...assocArrays) {
+    let target: {[key: string]: any} = {};
+    new Es2019Array(...assocArrays).map(arr => {
+        return {arr, keys: Object.keys(arr)};
+    }).forEach(({arr, keys}) => {
+        keys.forEach(key => {
+            let toAssign = arr[key];
+            if(!Array.isArray(toAssign) && withAppend) {
+                toAssign = new Es2019Array(...[toAssign]);
+            }
+            if(overwrite || !target?.[key]) {
+                if(!withAppend) {
+                    target[key] = arr[key];
+                } else {
+                        if('undefined' == typeof target?.[key]) {
+                            target[key] = toAssign
+                        } else if(!Array.isArray(target[key])) {
+                            let oldVal = target[key];
+                            target[key] = new Es2019Array(...[]);
+                            target[key].push(oldVal);
+                            target[key].push(...toAssign);
+                        } else {
+                            target[key].push(...toAssign);
+                        }
+                }
+            }
+        })
+    });
+    return target;
+}
+
diff --git a/api/src/client/typescript/mona_dish/Config.ts b/api/src/client/typescript/mona_dish/Config.ts
new file mode 100644
index 000000000..0cb62ec8f
--- /dev/null
+++ b/api/src/client/typescript/mona_dish/Config.ts
@@ -0,0 +1,263 @@
+import {Es2019Array} from "./Es2019Array";
+import {IValueHolder, Optional, ValueEmbedder} from "./Monad";
+import {Lang} from "./Lang";
+import objAssign = Lang.objAssign;
+import {append, appendIf, assign, assignIf, resolve, shallowMerge} from "./AssocArray";
+
+/**
+ * specialized value embedder
+ * for our Configuration
+ */
+class ConfigEntry<T> extends ValueEmbedder<T> {
+
+    /*default value for absent*/
+    static absent = ConfigEntry.fromNullable(null);
+
+    /**
+     * arrayed value positions
+     */
+    arrPos: number;
+
+    constructor(rootElem: any, key: any, arrPos?: number) {
+        super(rootElem, key);
+
+        this.arrPos = arrPos ?? -1;
+    }
+
+    get value() {
+        if (this.key == "" && this.arrPos >= 0) {
+            return this._value[this.arrPos];
+        } else if (this.key && this.arrPos >= 0) {
+            return this._value[this.key][this.arrPos];
+        }
+        return this._value[this.key];
+    }
+
+    set value(val: T) {
+        if (this.key == "" && this.arrPos >= 0) {
+            this._value[this.arrPos] = val;
+            return;
+        } else if (this.key && this.arrPos >= 0) {
+            this._value[this.key][this.arrPos] = val;
+            return;
+        }
+        this._value[this.key] = val;
+    }
+}
+
+export const CONFIG_VALUE = "__END_POINT__";
+export const CONFIG_ANY = "__ANY_POINT__";
+export type ConfigDef = { [key: string]: any };
+
+/**
+ * Config, basically an optional wrapper for a json structure
+ * (not Side - effect free, since we can alter the internal config state
+ * without generating a new config), not sure if we should make it side - effect free
+ * since this would swallow a lot of performance and ram
+ */
+export class Config extends Optional<any> {
+    constructor(root: any, private configDef ?: ConfigDef) {
+        super(root);
+    }
+
+    /**
+     * shallow copy getter, copies only the first level, references the deeper nodes
+     * in a shared manner
+     */
+    get shallowCopy(): Config {
+        return this.shallowCopy$();
+    }
+
+    protected shallowCopy$(): Config {
+        let ret = new Config({});
+        ret.shallowMerge(this.value);
+        return ret;
+    }
+
+    /**
+     * deep copy, copies all config nodes
+     */
+    get deepCopy(): Config {
+        return this.deepCopy$();
+    }
+
+    protected deepCopy$(): Config {
+        return new Config(objAssign({}, this.value));
+    }
+
+    /**
+     * creates a config from an initial value or null
+     * @param value
+     */
+    static fromNullable<T>(value?: T | null): Config {
+        return new Config(value);
+    }
+
+    /**
+     * simple merge for the root configs
+     */
+    shallowMerge(other: Config, overwrite = true, withAppend = false) {
+        //shallow merge must be mutable so we have to remap
+        let newThis = shallowMerge(overwrite, withAppend, this.value, other.value);
+        if (Array.isArray(this._value)) {
+            this._value.length = 0;
+            this._value.push(...(newThis as any));
+        } else {
+            Object.getOwnPropertyNames(this._value).forEach(key => delete this._value[key]);
+            Object.getOwnPropertyNames(newThis).forEach(key => this._value[key] = newThis[key]);
+        }
+    }
+
+    /**
+     * assigns a single value as array, or appends it
+     * to an existing value mapping a single value to array
+     *
+     *
+     * usage myConfig.append("foobaz").value = "newValue"
+     *       myConfig.append("foobaz").value = "newValue2"
+     *
+     * resulting in myConfig.foobaz == ["newValue, newValue2"]
+     *
+     * @param {string[]} accessPath
+     */
+    append(...accessPath: string[]): IValueHolder<any> {
+        return append(this._value, ...accessPath);
+    }
+
+    /**
+     * appends to an existing entry (or extends into an array and appends)
+     * if the condition is met
+     * @param {boolean} condition
+     * @param {string[]} accessPath
+     */
+    appendIf(condition: boolean, ...accessPath: string[]): IValueHolder<any> {
+        return appendIf(condition, this._value, ...accessPath);
+    }
+
+    /**
+     * assigns a new value on the given access path
+     * @param accessPath
+     */
+    assign(...accessPath): IValueHolder<any> {
+        return assign(this.value, ...accessPath);
+    }
+
+
+    /**
+     * assign a value if the condition is set to true, otherwise skip it
+     *
+     * @param condition the condition, the access accessPath into the config
+     * @param accessPath
+     */
+    assignIf(condition: boolean, ...accessPath: Array<any>): IValueHolder<any> {
+        return assignIf(condition, this._value, ...accessPath);
+    }
+
+    /**
+     * get if the access path is present (get is reserved as getter with a default, on the current path)
+     * TODO will be renamed to something more meaningful and deprecated, the name is ambiguous
+     * @param accessPath the access path
+     */
+    getIf(...accessPath: Array<string>): Config {
+        this.assertAccessPath(...accessPath);
+        return this.getClass().fromNullable(resolve(this.value, ...accessPath));
+    }
+
+
+    /**
+     * gets the current node and if none is present returns a config with a default value
+     * @param defaultVal
+     */
+    get(defaultVal: any): Config {
+        return this.getClass().fromNullable(super.get(defaultVal).value);
+    }
+
+    //empties the current config entry
+    delete(key: string): Config {
+        if (key in this.value) {
+            delete this.value[key];
+        }
+        return this;
+    }
+
+    /**
+     * converts the entire config into a json object
+     */
+    toJson(): any {
+        return JSON.stringify(this.value);
+    }
+
+
+    protected getClass(): any {
+        return Config;
+    }
+
+    private setVal(val: any) {
+        this._value = val;
+    }
+
+
+    /**
+     * asserts the access path for a semi typed access
+     * @param accessPath
+     * @private
+     */
+    private assertAccessPath(...accessPath: Array<string>) {
+        accessPath = this.preprocessKeys(...accessPath);
+        if (!this.configDef) {
+            //untyped
+            return;
+        }
+
+        const ERR_ACCESS_PATH = "Access Path to config invalid";
+        let currAccessPos: any = Optional.fromNullable(Object.keys(this.configDef).map(key => {
+            let ret = {};
+            ret[key] = this.configDef[key];
+            return ret;
+        }));
+
+        for (let cnt = 0; cnt < accessPath.length; cnt++) {
+            let currKey = this.keyVal(accessPath[cnt]);
+            let arrPos: any = this.arrayIndex(accessPath[cnt]);
+
+            //key index
+            if (this.isArray(arrPos)) {
+                if (currKey != "") {
+                    currAccessPos = Array.isArray(currAccessPos.value) ?
+                        Optional.fromNullable(new Es2019Array(...currAccessPos.value)
+                            .find(item => {
+                                return !!(item?.[currKey] ?? false)
+                            })?.[currKey]?.[arrPos]) :
+                        Optional.fromNullable(currAccessPos.value?.[currKey]?.[arrPos] ?? null);
+
+                } else {
+                    currAccessPos = (Array.isArray(currAccessPos.value)) ?
+                        Optional.fromNullable(currAccessPos.value?.[arrPos]) : Optional.absent;
+                }
+                //we noe store either the current array or the filtered look ahead to go further
+            } else {
+                //we now have an array and go further with a singular key
+                currAccessPos = (Array.isArray(currAccessPos.value)) ? Optional.fromNullable(new Es2019Array(...currAccessPos.value)
+                        .find(item => {
+                            return !!(item?.[currKey] ?? false);
+                        })?.[currKey]) :
+                    Optional.fromNullable(currAccessPos.value?.[currKey] ?? null);
+            }
+            if (!currAccessPos.isPresent()) {
+                throw Error(ERR_ACCESS_PATH)
+            }
+            if (currAccessPos.value == CONFIG_ANY) {
+                return;
+            }
+        }
+    }
+
+    private isNoArray(arrPos: number) {
+        return arrPos == -1;
+    }
+
+    private isArray(arrPos: number) {
+        return !this.isNoArray(arrPos);
+    }
+
+}
\ No newline at end of file
diff --git a/api/src/client/typescript/mona_dish/DomQuery.ts b/api/src/client/typescript/mona_dish/DomQuery.ts
index 192c37201..e3a94f29d 100644
--- a/api/src/client/typescript/mona_dish/DomQuery.ts
+++ b/api/src/client/typescript/mona_dish/DomQuery.ts
@@ -15,23 +15,19 @@
  * limitations under the License.
  */
 
-import {Config, Optional, ValueEmbedder} from "./Monad";
+import {Optional, ValueEmbedder} from "./Monad";
 import {XMLQuery} from "./XmlQuery";
-import {IStream, LazyStream, Stream} from "./Stream";
-import {
-    ArrayCollector,
-    AssocArrayCollector,
-    ICollector,
-    IStreamDataSource,
-    ITERATION_STATUS
-} from "./SourcesCollectors";
+
+import {ICollector, IStreamDataSource, ITERATION_STATUS} from "./SourcesCollectors";
 import {Lang} from "./Lang";
+import {_global$} from "./Global";
+import {Es2019Array} from "./Es2019Array";
 import trim = Lang.trim;
 
 import isString = Lang.isString;
 import eqi = Lang.equalsIgnoreCase;
-import {_global$} from "./Global";
 import objToArray = Lang.objToArray;
+import {append, assign, simpleShallowMerge} from "./AssocArray";
 
 declare var ownerDocument: any;
 
@@ -307,11 +303,11 @@ interface IDomQuery {
     /**
      * an early stream representation for this DomQuery
      */
-    readonly stream: Stream<DomQuery>;
+    readonly stream: any;
     /**
      * lazy stream representation for this DomQuery
      */
-    readonly lazyStream: LazyStream<DomQuery>;
+    readonly lazyStream: any;
     /**
      * transform this node collection to an array
      */
@@ -332,7 +328,7 @@ interface IDomQuery {
     innerHtml: string;
 
     /**
-     * convenience for dq.id.value to make the code a little bit tighter
+     * convenience for dq.id.value to make the code a little tighter
      */
     nodeId: string;
 
@@ -660,7 +656,7 @@ interface IDomQuery {
 
     /**
      * all parents until the selector match stops
-     * @param tagName
+     * @param selector
      */
     parentsWhileMatch(selector: string): DomQuery;
 
@@ -749,7 +745,7 @@ interface IDomQuery {
      * @param toMerge optional config which can be merged in
      * @return a copy pf
      */
-    encodeFormElement(toMerge): Config;
+    encodeFormElement(toMerge): {[key: string]: any};
 
     /**
      * fetches the sub-nodes from ... to..
@@ -854,6 +850,14 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
         return _global$;
     }
 
+    get stream(): any {
+        throw Error("Not implemented, include Stream.ts for this to work")
+    }
+
+    get lazyStream(): any {
+        throw Error("Not implemented, include Stream.ts for this to work")
+    }
+
     /**
      * returns the id of the first element
      */
@@ -942,7 +946,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
     }
 
     get checked(): boolean {
-        return Stream.of(...this.values).allMatch(el => !!(<any>el).checked);
+        return new Es2019Array(...this.values).every(el => !!(<any>el).checked);
     }
 
     set checked(newChecked: boolean) {
@@ -1010,65 +1014,47 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
         return new DomQuery(...childNodeArr);
     }
 
-    /**
-     * binding into stream
-     */
-    get stream(): Stream<DomQuery> {
-        return new Stream<DomQuery>(...this.asArray);
-    }
 
-    /**
-     * fetches a lazy stream representation
-     * lazy should be applied if you have some filters etc.
-     * in between, this can reduce the number of post filter operations
-     * and ram usage
-     * significantly because the operations are done lazily and stop
-     * once they hit a dead end.
-     */
-    get lazyStream(): LazyStream<DomQuery> {
-        return LazyStream.of(...this.asArray);
-    }
-
-    get asArray(): Array<DomQuery> {
+    get asArray(): DomQuery[] {
         // filter not supported by IE11
-        return [].concat(LazyStream.of(...this.rootNode).filter(item => {
+        let items = new Es2019Array(...this.rootNode).filter(item => {
             return item != null
-        })
-            .map(item => {
-                return DomQuery.byId(item)
-            }).collect(new ArrayCollector()));
+        }).map(item => {
+            return DomQuery.byId(item)
+        });
+        return items as DomQuery[];
     }
 
     get offsetWidth(): number {
-        return LazyStream.of(...this.rootNode)
+        return new Es2019Array(...this.rootNode)
             .filter(item => item != null)
             .map(elem => (elem as HTMLElement).offsetWidth)
-            .reduce((accumulate, incoming) => accumulate + incoming, 0).value;
+            .reduce((accumulate, incoming) => accumulate + incoming, 0);
     }
 
     get offsetHeight(): number {
-        return LazyStream.of(...this.rootNode)
+        return new Es2019Array(...this.rootNode)
             .filter(item => item != null)
             .map(elem => (elem as HTMLElement).offsetHeight)
-            .reduce((accumulate, incoming) => accumulate + incoming, 0).value;
+            .reduce((accumulate, incoming) => accumulate + incoming, 0);
     }
 
     get offsetLeft(): number {
-        return LazyStream.of(...this.rootNode)
+        return new Es2019Array(...this.rootNode)
             .filter(item => item != null)
             .map(elem => (elem as HTMLElement).offsetLeft)
-            .reduce((accumulate, incoming) => accumulate + incoming, 0).value;
+            .reduce((accumulate, incoming) => accumulate + incoming, 0);
     }
 
     get offsetTop(): number {
-        return LazyStream.of(...this.rootNode)
+        return new Es2019Array(this.rootNode)
             .filter(item => item != null)
-            .map(elem => (elem as HTMLElement).offsetTop)
-            .reduce((accumulate, incoming) => accumulate + incoming, 0).value;
+            .map(elem => (elem as any).offsetTop)
+            .reduce((accumulate, incoming) => accumulate + incoming, 0);
     }
 
-    get asNodeArray(): Array<DomQuery> {
-        return [].concat(Stream.of(...this.rootNode).filter(item => item != null).collect(new ArrayCollector()));
+    get asNodeArray(): Array<Element> {
+        return new Es2019Array(...this.rootNode.filter(item => item != null));
     }
 
 
@@ -1138,10 +1124,10 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
         const doc = document.implementation.createHTMLDocument("");
         markup = trim(markup);
         let lowerMarkup = markup.toLowerCase();
-        if (lowerMarkup.search(/\<\!doctype[^\w\-]+/gi) != -1 ||
-            lowerMarkup.search(/\<html[^\w\-]+/gi) != -1 ||
-            lowerMarkup.search(/\<head[^\w\-]+/gi) != -1 ||
-            lowerMarkup.search(/\<body[^\w\-]+/gi) != -1) {
+        if (lowerMarkup.search(/<!doctype[^\w\-]+/gi) != -1 ||
+            lowerMarkup.search(/<html[^\w\-]+/gi) != -1 ||
+            lowerMarkup.search(/<head[^\w\-]+/gi) != -1 ||
+            lowerMarkup.search(/<body[^\w\-]+/gi) != -1) {
             doc.documentElement.innerHTML = markup;
             return new DomQuery(doc.documentElement);
         } else {
@@ -1283,11 +1269,10 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
     byId(id: string, includeRoot?: boolean): DomQuery {
         let res: Array<DomQuery> = [];
         if (includeRoot) {
-            res = res.concat(
-                LazyStream.of(...(this?.rootNode || []))
-                    .filter(item => id == item.id)
+            res = res.concat(...
+                new Es2019Array(...(this?.rootNode || []))
+                    .filter(((item) => id == item.id) as any)
                     .map(item => new DomQuery(item))
-                    .collect(new ArrayCollector())
             );
         }
 
@@ -1303,10 +1288,9 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
         let res: Array<DomQuery> = [];
         if (includeRoot) {
             res = res.concat(
-                LazyStream.of(...(this?.rootNode || []))
+                new Es2019Array(...(this?.rootNode || []))
                     .filter(item => id == item.id)
                     .map(item => new DomQuery(item))
-                    .collect(new ArrayCollector())
             );
         }
 
@@ -1327,10 +1311,9 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
     byTagName(tagName: string, includeRoot ?: boolean, deep ?: boolean): DomQuery {
         let res: Array<Element | DomQuery> = [];
         if (includeRoot) {
-            res = <any>LazyStream.of(...(this?.rootNode ?? []))
+            res = new Es2019Array(...(this?.rootNode ?? []))
                 .filter(element => element?.tagName == tagName)
-                .reduce<Array<Element | DomQuery>>((reduction: any, item: Element) => reduction.concat([item]), res)
-                .orElse(res).value;
+                .reduce((reduction: any, item: Element) => reduction.concat([item]), res);
         }
 
         (deep) ? res.push(this.querySelectorAllDeep(tagName)) : res.push(this.querySelectorAll(tagName));
@@ -1481,11 +1464,8 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
      * @param selector
      */
     matchesSelector(selector: string): boolean {
-        const ret = this.lazyStream
-            .map(item => this._mozMatchesSelector(item.getAsElem(0).value, selector))
-            .filter(match => match)
-            .first();
-        return ret.isPresent();
+        return this.asArray
+            .some(item => this._mozMatchesSelector(item.getAsElem(0).value, selector));
     }
 
     /**
@@ -1533,8 +1513,8 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
     }
 
     each(func: (item: DomQuery, cnt?: number) => any): DomQuery {
-        Stream.of(...this.rootNode)
-            .each((item, cnt) => {
+        new Es2019Array(...this.rootNode)
+            .forEach((item, cnt) => {
                 // we could use a filter, but for the best performance we don´t
                 if (item == null) {
                     return;
@@ -1775,7 +1755,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
         let ret = [];
         while(parent.isPresent()) {
             if(parent.matchesSelector(selector)) {
-               ret.push(parent);
+                ret.push(parent);
             }
             parent = parent.parent();
         }
@@ -1916,7 +1896,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
                 // scripts before we run the 'include' command
                 // this.globalEval(finalScripts.join("\n"));
                 let joinedScripts = [];
-                Stream.of(...scriptsToProcess).each(item => {
+                new Es2019Array(...scriptsToProcess).forEach(item => {
                     if (!item.nonce) {
                         joinedScripts.push(item.evalText)
                     } else {
@@ -2006,10 +1986,10 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
         try {
             let scriptElements = new DomQuery(this.filterSelector("script"), this.querySelectorAll("script"));
             // script execution order by relative pos in their dom tree
-            scriptElements.stream
-                .flatMap(item => Stream.of(...item.values))
+            scriptElements.asArray
+                .flatMap(item => [...item.values])
                 .sort((node1, node2) => node1.compareDocumentPosition(node2) - 3) // preceding 2, following == 4)
-                .each(item => execScript(item));
+                .forEach(item => execScript(item));
 
             evalCollectedScripts(finalScripts);
         } catch (e) {
@@ -2036,38 +2016,39 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
     runCss(): DomQuery {
 
         const execCss = (toReplace: HTMLElement) => {
-                const _toReplace = DomQuery.byId(toReplace);
-                const tagName = _toReplace.tagName.orElse("").value;
-                const head = DomQuery.byTagName("head");
+            const _toReplace = DomQuery.byId(toReplace);
+            const tagName = _toReplace.tagName.orElse("").value;
+            const head = DomQuery.byTagName("head");
 
-                if (tagName && eqi(tagName, "link") && eqi(toReplace.getAttribute("rel"), "stylesheet")) {
-                    const rel = toReplace.getAttribute("rel");
-                    //if possible we are now replacing the existing elements where we reference this stylesheet
-                    const matches = head.querySelectorAll(`link[rel='stylesheet'][href='${rel}']`);
+            if (tagName && eqi(tagName, "link") && eqi(toReplace.getAttribute("rel"), "stylesheet")) {
+                const rel = toReplace.getAttribute("rel");
+                //if possible we are now replacing the existing elements where we reference this stylesheet
+                const matches = head.querySelectorAll(`link[rel='stylesheet'][href='${rel}']`);
 
-                    if(matches.length) {
-                        matches.replace(_toReplace);
-                    } else {
-                        head.append(_toReplace);
-                    }
-                } else if (tagName && eqi(tagName, "style")) {
-                    let innerText = _toReplace.innerHTML.replace(/\s+/gi, "");
-                    let styles = head.querySelectorAll("style");
-                    styles = styles.stream.filter(style => {
-                        return style.innerHTML.replace(/\s+/gi, "") == innerText;
-                    }).collect(new DomQueryCollector())
-                    if(!styles.length) { //already present
-                        head.append(_toReplace);
-                    }
+                if(matches.length) {
+                    matches.replace(_toReplace);
+                } else {
+                    head.append(_toReplace);
                 }
-            };
+            } else if (tagName && eqi(tagName, "style")) {
+                let innerText = _toReplace.innerHTML.replace(/\s+/gi, "");
+                let styles = head.querySelectorAll("style");
+                let filteredStyles = styles.asArray.filter(style => {
+                    return style.innerHTML.replace(/\s+/gi, "") == innerText;
+                });
+                styles = new DomQuery(...filteredStyles);
+                if(!styles.length) { //already present
+                    head.append(_toReplace);
+                }
+            }
+        };
 
         const scriptElements: DomQuery = new DomQuery(this.filterSelector("link, style"), this.querySelectorAll("link, style"));
 
-        scriptElements.stream
-            .flatMap(item => Stream.of(...item.values))
+        scriptElements.asArray
+            .flatMap(item => [...item.values])
             .sort((node1, node2) => node1.compareDocumentPosition(node2) - 3)
-            .each(item => execCss(item));
+            .forEach(item => execCss(item as HTMLElement));
 
         return this;
     }
@@ -2095,10 +2076,12 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
      */
     fireEvent(eventName: string, options: {[key: string]: any} = {}) {
         // merge with last one having the highest priority
-        let finalOptions = Stream.ofAssoc({
+
+        let finalOptions: any = {
             bubbles: true, cancelable: true
-        }).concat(Stream.ofAssoc(options)).collect(new AssocArrayCollector());
-        
+        }
+        finalOptions = simpleShallowMerge(finalOptions, options);
+
         this.eachElem((node: Element) => {
             let doc;
             if (node.ownerDocument) {
@@ -2149,16 +2132,14 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
                 // IE-old school style, you can drop this if you don't need to support IE8 and lower
                 let event = doc.createEventObject();
                 event.synthetic = true; // allow detection of synthetic events
-                Stream.ofAssoc(finalOptions).each(([key, value]): void => {
-                    event[key] = value;
-                });
+                Object.keys(finalOptions).forEach(key => event[key] = finalOptions[key]);
                 (<any>node).fireEvent("on" + eventName, event);
             }
         })
     }
 
     textContent(joinString: string = ""): string {
-        return this.stream
+        return this.asArray
             .map((value: DomQuery) => {
                 let item = value.getAsElem(0).orElseLazy(() => {
                     return <any>{
@@ -2167,11 +2148,11 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
                 }).value;
                 return (<any>item).textContent || "";
             })
-            .reduce((text1, text2) => [text1,joinString,text2].join(""), "").value;
+            .reduce((text1, text2) => [text1,joinString,text2].join(""), "");
     }
 
     innerText(joinString: string = ""): string {
-        return this.stream
+        return this.asArray
             .map((value: DomQuery) => {
                 let item = value.getAsElem(0).orElseLazy(() => {
                     return <any>{
@@ -2180,8 +2161,9 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
                 }).value;
                 return (<any>item).innerText || "";
             })
-            .reduce((text1, text2) => [text1, text2].join(joinString), "").value;
-
+            .reduce((text1, text2) => {
+                return [text1, text2].join(joinString)
+            }, "");
     }
 
     /**
@@ -2193,7 +2175,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
      * @param toMerge optional config which can be merged in
      * @return a copy pf
      */
-    encodeFormElement(toMerge = new Config({})): Config {
+    encodeFormElement(toMerge = {}): {[key: string]: any} {
 
         // browser behavior no element name no encoding (normal submit fails in that case)
         // https:// issues.apache.org/jira/browse/MYFACES-2847
@@ -2202,7 +2184,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
         }
 
         // let´s keep it side-effects free
-        let target = toMerge.shallowCopy;
+        let target = simpleShallowMerge(toMerge);
 
         this.each((element: DomQuery) => {
             if (element.name.isAbsent()) {// no name, no encoding
@@ -2240,7 +2222,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
                             // let subBuf = [];
                             if (selectElem.options[u].selected) {
                                 let elementOption = selectElem.options[u];
-                                target.append(name).value = (elementOption.getAttribute("value") != null) ?
+                                append(target, name).value = (elementOption.getAttribute("value") != null) ?
                                     elementOption.value : elementOption.text;
                             }
                         }
@@ -2268,13 +2250,13 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
                     let filesArr: any = uploadedFiles ?? [];
                     if (filesArr?.length) { //files can be empty but set
                         // xhr level2, single multiple must be passes as they are
-                        target.assign(name).value = Array.from(filesArr);
+                        assign(target, name).value = Array.from(filesArr);
                     } else {
                         if(!!uploadedFiles) { //we skip empty file elements i
                             return;
                         }
                         //checkboxes etc.. need to be appended
-                        target.append(name).value = element.inputValue.value;
+                        append(target, name).value = element.inputValue.value;
                     }
                 }
 
@@ -2287,14 +2269,25 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
     get cDATAAsString(): string {
         let TYPE_CDATA_BLOCK = 4;
 
-        let res: any = this.lazyStream.flatMap(item => {
+        let res = this.asArray
+            .flatMap( item => {
+                return item.childNodes.asArray;
+            })
+            .filter(item => {
+                return item?.value?.value?.nodeType == TYPE_CDATA_BLOCK;
+            })
+            .reduce((reduced: Array<any>, item: DomQuery) => {
+                reduced.push((<any>item?.value?.value)?.data ?? "");
+                return reduced;
+            }, []);
+        /*let res: any = this.lazyStream.flatMap(item => {
             return item.childNodes.stream
         }).filter(item => {
             return item?.value?.value?.nodeType == TYPE_CDATA_BLOCK;
         }).reduce((reduced: Array<any>, item: DomQuery) => {
             reduced.push((<any>item?.value?.value)?.data ?? "");
             return reduced;
-        }, []).value;
+        }, []).value;*/
 
         // response may contain several blocks
         return res.join("");
@@ -2311,7 +2304,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
     // because we can stream from an array stream directly into the dom query
     _limits = -1;
 
-    limits(end: number): IStream<DomQuery> {
+    limits(end: number): DomQuery {
         this._limits = end;
         return <any>this;
     }
@@ -2456,7 +2449,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
      * Implementation of an iterator
      * to allow loops over dom query collections
      */
-    [Symbol.iterator](): Iterator<DomQuery, any, undefined> {
+    [Symbol.iterator](): Iterator<DomQuery> {
         return {
             next: () => {
                 let done = !this.hasNext();
@@ -2474,18 +2467,19 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
      * @param toAttach the elements to attach
      * @param filterDoubles filter out possible double elements (aka same markup)
      */
-    concat(toAttach: DomQuery, filterDoubles = true): any {
-        const ret = this.lazyStream.concat(toAttach.lazyStream).collect(new DomQueryCollector());
+    concat(toAttach: DomQuery, filterDoubles = true): DomQuery {
+        let domQueries = this.asArray;
+        const ret = new DomQuery(...domQueries.concat(toAttach.asArray));
         // we now filter the doubles out
         if (!filterDoubles) {
             return ret;
         }
         let idx = {}; // ie11 does not support sets, we have to fake it
-        return ret.lazyStream.filter(node => {
+        return new DomQuery(...ret.asArray.filter(node => {
             const notFound = !(idx?.[node.value.value.outerHTML as any]);
             idx[node.value.value.outerHTML as any] = true;
             return notFound;
-        }).collect(new DomQueryCollector());
+        }));
     }
 
     append(elem: DomQuery): DomQuery {
@@ -2523,7 +2517,7 @@ export class DomQuery implements IDomQuery, IStreamDataSource<DomQuery>, Iterabl
                 continue;
             }
             let res = this.rootNode[cnt].querySelectorAll(selector);
-            nodes = nodes.concat(objToArray(res));
+            nodes = nodes.concat(...objToArray(res));
         }
 
         return new DomQuery(...nodes);
diff --git a/api/src/client/typescript/mona_dish/Es2019Array.ts b/api/src/client/typescript/mona_dish/Es2019Array.ts
new file mode 100644
index 000000000..b0be4e420
--- /dev/null
+++ b/api/src/client/typescript/mona_dish/Es2019Array.ts
@@ -0,0 +1,135 @@
+/**
+ * Extended array
+ */
+
+/**
+ * Extended array which adds various es 2019 shim functions to the normal array
+ * We must remap all array producing functions in order to keep
+ * the delegation active, once we are in!
+ */
+class Es2019Array_<T>  extends Array<T>{
+
+    _another: T[];
+
+    constructor(...another: T[]) {
+        super(...another);
+        if((another as any)._another)  {
+            this._another = (another as any)._another;
+        } else {
+            this._another = another;
+        }
+
+        //for testing it definitely runs into this branch because we are on es5 level
+        //if (!(<any>Array.prototype).flatMap) {
+            this.flatMap = (flatMapFun) => this._flatMap(flatMapFun) as any;
+        //}
+        //if (!(<any>Array.prototype).flat) {
+            this.flat = (flatLevel: number = 1) => this._flat(flatLevel);
+        //}
+    }
+
+    map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] {
+        const ret = Array.prototype.map.call(this._another, callbackfn, thisArg);
+        return new (_Es2019Array as any) (... ret);
+    }
+
+    concat(...items): T[] {
+        const ret = Array.prototype.concat.call(this._another, ...items);
+        return new (_Es2019Array as any)(... ret);
+    }
+
+    reverse(): T[] {
+        const ret = Array.prototype.reverse.call(this._another);
+        return new (_Es2019Array as any)(... ret);
+    }
+
+    slice(start?: number, end?: number): T[] {
+        const ret = Array.prototype.slice.call(this._another, start, end);
+        return new (_Es2019Array as any)(...ret);
+    }
+
+    splice(start: number, deleteCount?: number): T[] {
+        const ret = Array.prototype.splice.call(this._another, start, deleteCount);
+        return new (_Es2019Array as any)(...ret);
+    }
+
+    filter<S extends T>(predicate: (value: T, index: number, array: T[]) => any, thisArg?: any): S[] {
+        const ret = Array.prototype.filter.call(this._another, predicate, thisArg);
+        return new (_Es2019Array as any)(...ret);
+    }
+
+
+    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T {
+        const ret = Array.prototype.reduce.call(this._another, callbackfn, initialValue);
+        return ret;
+    }
+
+    /*reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T {
+        const ret = Array.prototype.reduceRight.call(callbackfn, initialValue);
+        return ret;
+    }*/
+
+    private _flat(flatDepth = 1) {
+        return this._flatResolve(this._another, flatDepth);
+    }
+
+    private _flatResolve(arr, flatDepth = 1) {
+        //recursion break
+        if (flatDepth == 0) {
+            return arr;
+        }
+        let res = [];
+
+        let reFlat = item => {
+            item = Array.isArray(item) ? item : [item];
+            let mapped = this._flatResolve(item, flatDepth - 1);
+            res = res.concat(mapped);
+        };
+        arr.forEach(reFlat)
+
+        return new Es2019Array(...res);
+    }
+
+    private _flatMap(mapperFunction: Function): any {
+        let res = this.map(item => mapperFunction(item));
+        return this._flatResolve(res);
+    }
+}
+
+//let _Es2019Array = function<T>(...data: T[]) {};
+
+//let oldProto = Es2019Array.prototype;
+
+export function _Es2019Array<T>(...data: T[]): Es2019Array_<T> {
+    let ret = new Es2019Array_<T>(...data);
+    let proxied = new Proxy<Es2019Array_<T>>(ret, {
+        get(target: Es2019Array_<unknown>, p: string | symbol, receiver: any): any {
+            if("symbol" == typeof p) {
+
+                return target._another[p];
+            }
+            if(!isNaN(parseInt(p as string))) {
+                return target._another[p];
+            } else {
+                return target[p];
+            }
+        },
+
+        set(target, property, value): boolean {
+            target[property] = value;
+            target._another[property] = value;
+            return true;
+        }
+
+    });
+    return proxied;
+};
+
+/**
+ * this is the switch between normal array and our shim
+ * the shim is only provided in case the native browser
+ * does not yet have flatMap support on arrays
+ */
+export var Es2019Array: any = (Array.prototype.flatMap) ? function<T>(...data: T[]): T[] {
+    return data;
+} : _Es2019Array;
\ No newline at end of file
diff --git a/api/src/client/typescript/mona_dish/ExtendedArray.ts b/api/src/client/typescript/mona_dish/ExtendedArray.ts
deleted file mode 100644
index 82ea34cd5..000000000
--- a/api/src/client/typescript/mona_dish/ExtendedArray.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*!
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * Array with a set of shim functions for older browsers
- * we do not extend prototype (rule #1)
- *
- * This is a helper which for now adds the missing flatMap, without prototype pollution
- *
- * that way we can avoid streams wherever we just want to go pure JS
- * This class is self isolated, so it suffices to just dump it into a project one way or the other
- * without anything else
- */
-export class ExtendedArray<T> extends Array<T> {
-
-    constructor(...items: T[]) {
-        super(...items);
-        //es5 base class see //fix for es5 deficit from https://github.com/Microsoft/TypeScript/issues/13720
-
-        //for testing it definitely runs into this branch because we are on es5 level
-        if(!(<any>Array.prototype).flatMap) {
-            let flatmapFun = (<any>ExtendedArray).prototype.flatMap;
-            //unfortunately in es5 the flaptmap function is lost due to inheritance of a primitive
-            //es  class, we have to remap it back in
-            this.flatMap = flatmapFun;
-        }
-    }
-
-    flatMap(mapperFunction: Function, noFallback: boolean = false): ExtendedArray<T> {
-
-        let res = [];
-
-        let remap = item => {
-            let opRes = mapperFunction(item);
-            if(Array.isArray(opRes)) {
-                if(opRes.length == 1) {
-                    res.push(opRes[1])
-                    return;
-                }
-                if(opRes.length > 1) {
-                    opRes.forEach(newItem => remap(newItem))
-                }
-            } else {
-                res.push(item);
-            }
-        };
-        this.forEach( item => remap(item) )
-
-        return new ExtendedArray(...res);
-    }
-}
\ No newline at end of file
diff --git a/api/src/client/typescript/mona_dish/Lang.ts b/api/src/client/typescript/mona_dish/Lang.ts
index 40293c563..a4d846da2 100644
--- a/api/src/client/typescript/mona_dish/Lang.ts
+++ b/api/src/client/typescript/mona_dish/Lang.ts
@@ -16,6 +16,7 @@
  */
 
 import {Optional} from "./Monad";
+import {Es2019Array} from "./Es2019Array";
 
 /**
  * Lang helpers crossported from the apache myfaces project
@@ -25,7 +26,7 @@ export module Lang {
 
     //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those
     /**
-     * helper function to savely resolve anything
+     * helper function to safely resolve anything
      * this is not an elvis operator, it resolves
      * a value without exception in a tree and if
      * it is not resolvable then an optional of
@@ -50,6 +51,12 @@ export module Lang {
         }
     }
 
+    /**
+     * lazy resolve... aka the function is called on resolve and a default value also
+     * is a producing function (called only if the original producer does not produce any result)
+     * @param resolverProducer the producer for the resolve
+     * @param defaultValue the default value producer function
+     */
     export function saveResolveLazy<T>(resolverProducer: () => T, defaultValue: () => T = null): Optional<T> {
         try {
             let result = resolverProducer();
@@ -105,11 +112,11 @@ export module Lang {
         //special condition array delivered no offset no pack
         if ((<any>obj) instanceof Array && !offset && !pack) return obj;
 
-        return pack.concat(Array.prototype.slice.call(obj, offset));
+        return new Es2019Array(...pack.concat(Array.prototype.slice.call(obj, offset)));
     }
 
     /**
-     * equalsIgnoreCase, case insensitive comparison of two strings
+     * equalsIgnoreCase, case-insensitive comparison of two strings
      *
      * @param source
      * @param destination
@@ -134,7 +141,7 @@ export module Lang {
     }
 
     /**
-     * Backported from dojo
+     * Back ported from Dojo
      * a failsafe string determination method
      * (since in javascript String != "" typeof alone fails!)
      * @param it {|Object|} the object to be checked for being a string
@@ -146,6 +153,10 @@ export module Lang {
         return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
     }
 
+    /**
+     * Back-ported, a failsafe determination code for checking whether an object is a function
+     * @param it the object to check for being a function
+     */
     export function isFunc(it: any): boolean {
         return it instanceof Function || typeof it === "function";
     }
diff --git a/api/src/client/typescript/mona_dish/Messaging.ts b/api/src/client/typescript/mona_dish/Messaging.ts
index 96aca50c7..4371e9401 100644
--- a/api/src/client/typescript/mona_dish/Messaging.ts
+++ b/api/src/client/typescript/mona_dish/Messaging.ts
@@ -109,7 +109,10 @@ class MessageWrapper implements CustomEventInit<Message> {
     }
 }
 
-
+/**
+ * abstract broker class
+ * (The broker is the central distribution unit of messages)
+ */
 abstract class BaseBroker {
 
     static readonly EVENT_TYPE = "brokerEvent";
@@ -346,8 +349,12 @@ let broadCastChannelBrokerGenerator = (name) => {
 const DEFAULT_CHANNEL_GROUP = "brokr";
 
 /**
- * a broker which hooks into the Broadcast Channel broker
+ * a broker which hooks into the Broadcast Channel
  * either via shim or substitute lib
+ *
+ * The broadcast channels are a standardized messaging library
+ * The broker mechanism sets a layer on top to make it more manageable!
+ *
  */
 export class BroadcastChannelBroker extends BaseBroker {
     private openChannels: [{ key: string }, BroadcastChannel] = <any>{};
diff --git a/api/src/client/typescript/mona_dish/Monad.ts b/api/src/client/typescript/mona_dish/Monad.ts
index 6a574bf39..8b385e9a1 100644
--- a/api/src/client/typescript/mona_dish/Monad.ts
+++ b/api/src/client/typescript/mona_dish/Monad.ts
@@ -16,16 +16,14 @@
  */
 
 /**
- * A module which keeps  basic monadish like definitions in place without any sidedependencies to other modules.
+ * A module which keeps  basic monad like definitions in place
  * Useful if you need the functions in another library to keep its dependencies down
  */
 
 /*IMonad definitions*/
 
 import {Lang} from "./Lang";
-import {ArrayCollector, AssocArrayCollector} from "./SourcesCollectors";
-import {Stream} from "./Stream";
-import objAssign = Lang.objAssign;
+import {Es2019Array} from "./Es2019Array";
 
 
 /**
@@ -38,7 +36,7 @@ export interface IFunctor<T> {
 }
 
 /**
- * IMonad definition, basically a functor with a flaptmap implementation (flatmap reduces all nested monads after a
+ * IMonad definition, basically a functor with a flatMap implementation, flatMap reduces all nested monads after a
  * function call f into a monad with the nesting level of 1
  *
  * flatmap flats nested Monads into a IMonad of the deepest nested implementation
@@ -57,10 +55,11 @@ export interface IIdentity<T> extends IFunctor<T> {
     readonly value: T;
 }
 
+
 /**
  *  custom value holder definition, since we are not pure functional
  *  but iterative we have structures which allow the assignment of a value
- *  also not all structures are sideffect free
+ *  also not all structures are side - effect free
  */
 export interface IValueHolder<T> {
     value: T | Array<T>;
@@ -68,7 +67,7 @@ export interface IValueHolder<T> {
 
 /**
  * Implementation of a monad
- * (Sideffect free), no write allowed directly on the monads
+ * (Side - effect free), no write allowed directly on the monads
  * value state
  */
 export class Monad<T> implements IMonad<T, Monad<any>>, IValueHolder<T> {
@@ -84,7 +83,7 @@ export class Monad<T> implements IMonad<T, Monad<any>>, IValueHolder<T> {
 
     map<R>(fn?: (data: T) => R): Monad<R> {
         if (!fn) {
-            fn = (inval: any) => <R>inval;
+            fn = (inVal: any) => <R>inVal;
         }
         let result: R = fn(this.value);
         return new Monad(result);
@@ -103,7 +102,7 @@ export class Monad<T> implements IMonad<T, Monad<any>>, IValueHolder<T> {
 /**
  * optional implementation, an optional is basically an implementation of a Monad with additional syntactic
  * sugar on top
- * (Sideeffect free, since value assignment is not allowed)
+ * (Side - effect free, since value assignment is not allowed)
  * */
 export class Optional<T> extends Monad<T> {
 
@@ -173,8 +172,8 @@ export class Optional<T> extends Monad<T> {
     }
 
     /*
-     * we need to implement it to fullfill the contract, although it is used only internally
-     * all values are flattened when accessed anyway, so there is no need to call this methiod
+     * we need to implement it to fulfill the contract, although it is used only internally
+     * all values are flattened when accessed anyway, so there is no need to call this method
      */
     flatMap<R>(fn?: (data: T) => R): Optional<any> {
         let val = super.flatMap(fn);
@@ -187,7 +186,7 @@ export class Optional<T> extends Monad<T> {
 
     /*
      * elvis operation, take care, if you use this you lose typesafety and refactoring
-     * capabilites, unfortunately typesceript does not allow to have its own elvis operator
+     * capabilities, unfortunately typescript does not allow to have its own elvis operator
      * this is some syntactic sugar however which is quite useful*/
     getIf<R>(...key: string[]): Optional<R> {
 
@@ -223,9 +222,7 @@ export class Optional<T> extends Monad<T> {
                 currentPos = this.getClass().fromNullable(currentPos.value[arrPos]);
             }
         }
-        let retVal = currentPos;
-
-        return retVal;
+        return currentPos;
     }
 
     /**
@@ -266,7 +263,7 @@ export class Optional<T> extends Monad<T> {
      * by having a getClass operation we can avoid direct calls into the constructor or
      * static methods and do not have to implement several methods which rely on the type
      * of "this"
-     * @returns {Monadish.Optional}
+     * @returns the type of Optional
      */
     protected getClass(): any {
         return Optional;
@@ -331,9 +328,9 @@ export class Optional<T> extends Monad<T> {
 
 
     protected preprocessKeys(...keys): string[] {
-        return Stream.of(...keys)
+        return new Es2019Array(...keys)
             .flatMap(item => {
-                return Stream.of(...item.split(/\]\s*\[/gi))
+                return new Es2019Array(...item.split(/]\s*\[/gi))
                     .map(item => {
                         item = item.replace(/^\s+|\s+$/g, "");
                         if(item.indexOf("[") == -1 && item.indexOf("]") != -1) {
@@ -344,17 +341,16 @@ export class Optional<T> extends Monad<T> {
                         }
                         return item;
                     })
-            })
-
-            .collect(new ArrayCollector());
+            });
     }
 }
 
-// --------------------- From here onwards we break out the sideffects free limits ------------
+
+// --------------------- From here onwards we break out the side effect free limits ------------
 
 /**
  * ValueEmbedder is the writeable version
- * of optional, it basically is a wrappber
+ * of optional, it basically is a wrapper
  * around a construct which has a state
  * and can be written to.
  *
@@ -405,7 +401,7 @@ export class ValueEmbedder<T> extends Optional<T> implements IValueHolder<T> {
      * by having a getClass operation we can avoid direct calls into the constructor or
      * static methods and do not have to implement several methods which rely on the type
      * of "this"
-     * @returns {Monadish.Optional}
+     * @returns ValueEmbedder
      */
     protected getClass(): any {
         return ValueEmbedder;
@@ -417,392 +413,5 @@ export class ValueEmbedder<T> extends Optional<T> implements IValueHolder<T> {
 
 }
 
-/**
- * specialized value embedder
- * for our Configuration
- */
-class ConfigEntry<T> extends ValueEmbedder<T> {
-
-    /*default value for absent*/
-    static absent = ConfigEntry.fromNullable(null);
-
-    /**
-     * arrayed value positions
-     */
-    arrPos: number;
-
-    constructor(rootElem: any, key: any, arrPos?: number) {
-        super(rootElem, key);
-
-        this.arrPos = arrPos ?? -1;
-    }
-
-    get value() {
-        if (this.key == "" && this.arrPos >= 0) {
-            return this._value[this.arrPos];
-        } else if (this.key && this.arrPos >= 0) {
-            return this._value[this.key][this.arrPos];
-        }
-        return this._value[this.key];
-    }
-
-    set value(val: T) {
-        if (this.key == "" && this.arrPos >= 0) {
-            this._value[this.arrPos] = val;
-            return;
-        } else if (this.key && this.arrPos >= 0) {
-            this._value[this.key][this.arrPos] = val;
-            return;
-        }
-        this._value[this.key] = val;
-    }
-}
-
-
-export const CONFIG_VALUE = "__END_POINT__";
-export const CONFIG_ANY = "__ANY_POINT__";
-const ALL_VALUES = "*";
-
-
-
-export type ConfigDef = {[key: string]: any};
-
-
-/**
- * Config, basically an optional wrapper for a json structure
- * (not sideeffect free, since we can alter the internal config state
- * without generating a new config), not sure if we should make it sideffect free
- * since this would swallow a lot of performane and ram
- */
-export class Config extends Optional<any> {
-    constructor(root: any, private configDef ?: ConfigDef) {
-        super(root);
-    }
-
-    /**
-     * shallow copy getter, copies only the first level, references the deeper nodes
-     * in a shared manner
-     */
-    get shallowCopy(): Config {
-        return this.shallowCopy$();
-    }
-
-    protected shallowCopy$(): Config {
-        return new Config(Stream.ofAssoc(this.value).collect(new AssocArrayCollector()));
-    }
-
-    /**
-     * deep copy, copies all config nodes
-     */
-    get deepCopy(): Config {
-        return this.deepCopy$();
-    }
-
-    protected deepCopy$(): Config {
-        return new Config(objAssign({}, this.value));
-    }
-
-    /**
-     * creates a config from an initial value or null
-     * @param value
-     */
-    static fromNullable<T>(value?: T | null): Config {
-        return new Config(value);
-    }
-
-    /**
-     * simple merge for the root configs
-     */
-    shallowMerge(other: Config, overwrite = true, withAppend = false) {
-        for (let key in other.value) {
-            if('undefined' == typeof key || null == key) {
-                continue;
-            }
-            if (overwrite || !(key in this.value)) {
-                if (!withAppend) {
-                    this.assign(key).value = other.getIf(key).value;
-                } else {
-                    if (Array.isArray(other.getIf(key).value)) {
-                        Stream.of(...other.getIf(key).value).each(item => this.append(key).value = item);
-                    } else {
-                        this.append(key).value = other.getIf(key).value;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * assigns a single value as array, or appends it
-     * to an existing value mapping a single value to array
-     *
-     *
-     * usage myConfig.append("foobaz").value = "newValue"
-     *       myConfig.append("foobaz").value = "newValue2"
-     *
-     * resulting in myConfig.foobaz == ["newValue, newValue2"]
-     *
-     * @param {string[]} accessPath
-     */
-    append(...accessPath: string[]): IValueHolder<any> {
-        let noKeys = accessPath.length < 1;
-        if (noKeys) {
-            return;
-        }
-        this.assertAccessPath(...accessPath);
-
-        let lastKey = accessPath[accessPath.length - 1];
-        let currKey, finalKey = this.keyVal(lastKey);
-
-        let pathExists = this.getIf(...accessPath).isPresent();
-        this.buildPath(...accessPath);
-
-        let finalKeyArrPos = this.arrayIndex(lastKey);
-        if (finalKeyArrPos > -1) {
-            throw Error("Append only possible on non array properties, use assign on indexed data");
-        }
-        let value = <any>this.getIf(...accessPath).value;
-        if (!Array.isArray(value)) {
-            value = this.assign(...accessPath).value = [value];
-        }
-        if (pathExists) {
-            value.push({});
-        }
-        finalKeyArrPos = value.length - 1;
-
-        let retVal = new ConfigEntry(accessPath.length == 1 ? this.value : this.getIf.apply(this, accessPath.slice(0, accessPath.length - 1)).value,
-            lastKey, finalKeyArrPos
-        );
-
-        return retVal;
-    }
-
-    /**
-     * appends to an existing entry (or extends into an array and appends)
-     * if the condition is met
-     * @param {boolean} condition
-     * @param {string[]} accessPath
-     */
-    appendIf(condition: boolean, ...accessPath: string[]): IValueHolder<any> {
-        if (!condition) {
-            return {value: null};
-        }
-        return this.append(...accessPath);
-    }
-
-    /**
-     * assings an new value on the given access path
-     * @param accessPath
-     */
-    assign(...accessPath): IValueHolder<any> {
-        if (accessPath.length < 1) {
-            return;
-        }
-        this.assertAccessPath(...accessPath);
-
-        this.buildPath(...accessPath);
-
-        let currKey = this.keyVal(accessPath[accessPath.length - 1]);
-        let arrPos = this.arrayIndex(accessPath[accessPath.length - 1]);
-        let retVal = new ConfigEntry(accessPath.length == 1 ? this.value : this.getIf.apply(this, accessPath.slice(0, accessPath.length - 1)).value,
-            currKey, arrPos
-        );
-
-        return retVal;
-    }
-
-
-    /**
-     * assign a value if the condition is set to true, otherwise skip it
-     *
-     * @param condition the condition, the access accessPath into the config
-     * @param accessPath
-     */
-    assignIf(condition: boolean, ...accessPath: Array<any>): IValueHolder<any> {
-        return condition ? this.assign(...accessPath) : {value: null};
-    }
-
-    /**
-     * get if the access path is present (get is reserved as getter with a default, on the current path)
-     * TODO will be renamed to something more meaningful and deprecated, the name is ambigous
-     * @param accessPath the access path
-     */
-    getIf(...accessPath: Array<string>): Config {
-        this.assertAccessPath(...accessPath);
-        return this.getClass().fromNullable(super.getIf.apply(this, accessPath).value);
-    }
-
-
-
-    /**
-     * gets the current node and if none is present returns a config with a default value
-     * @param defaultVal
-     */
-    get(defaultVal: any): Config {
-        return this.getClass().fromNullable(super.get(defaultVal).value);
-    }
-
-    //empties the current config entry
-    delete(key: string): Config {
-        if (key in this.value) {
-            delete this.value[key];
-        }
-        return this;
-    }
-
-    /**
-     * converts the entire config into a json object
-     */
-    toJson(): any {
-        return JSON.stringify(this.value);
-    }
-
-    /**
-     * returns the first config level as streeam
-     */
-    get stream(): Stream<[string, any]> {
-        return Stream.of(... Object.keys(this.value)).map(key => [key, this.value[key]]);
-    }
-    
-    protected getClass(): any {
-        return Config;
-    }
-
-    private setVal(val: any) {
-        this._value = val;
-    }
-
-
-    /**
-     * asserts the access path for a semy typed access
-      * @param accessPath
-     * @private
-     */
-    private assertAccessPath(...accessPath: Array<string>) {
-        accessPath = this.preprocessKeys(...accessPath);
-        if(!this.configDef) {
-            //untyped
-            return;
-        }
-
-        let currAccessPos = null;
-
-        const ERR_ACCESS_PATH = "Access Path to config invalid";
-        const ABSENT = "__ABSENT__";
-        currAccessPos = this.configDef;
-
-
-
-        for (let cnt = 0; cnt < accessPath.length; cnt++) {
-            let currKey = this.keyVal(accessPath[cnt]);
-            let arrPos = this.arrayIndex(accessPath[cnt]);
-
-            //key index
-            if(this.isArray(arrPos)) {
-                if(currKey != "") {
-                    currAccessPos = (Array.isArray(currAccessPos)) ?
-                        Stream.of(...currAccessPos)
-                            .filter(item => !!(item?.[currKey] ?? false))
-                            .map(item => item?.[currKey]).first() :
-                        Optional.fromNullable(currAccessPos?.[currKey] ?? null);
-                } else {
-                    currAccessPos = (Array.isArray(currAccessPos)) ?
-                        Stream.of(...currAccessPos)
-                            .filter(item => Array.isArray(item))
-                            .flatMap(item => Stream.of(...item)).first() : Optional.absent;
-                }
-                //we noe store either the current array or the filtered look ahead to go further
-            } else {
-                //we now have an array and go further with a singular key
-                currAccessPos = (Array.isArray(currAccessPos)) ? Stream.of(...currAccessPos)
-                        .filter(item => !! (item?.[currKey] ?? false))
-                        .map(item => item?.[currKey])
-                        .first():
-                Optional.fromNullable(currAccessPos?.[currKey] ?? null);
-            }
-            if(!currAccessPos.isPresent()) {
-                throw Error(ERR_ACCESS_PATH)
-            }
-            currAccessPos = currAccessPos.value;
-
-            //no further testing needed, from this point onwards we are on our own
-            if(currAccessPos == CONFIG_ANY) {
-                return;
-            }
-        }
-
-    }
-
-
-    /**
-     * builds the config path
-     *
-     * @param accessPath a sequential array of accessPath containing either a key name or an array reference name[<index>]
-     */
-    private buildPath(...accessPath: string[]): Config {
-        accessPath = this.preprocessKeys(...accessPath);
-        let val = this;
-        let parentVal = this.getClass().fromNullable(null);
-        let parentPos = -1;
-        let alloc = function (arr: Array<any>, length: number) {
-            let length1 = arr.length;
-            let length2 = length1 + length;
-            for (let cnt = length1; cnt < length2; cnt++) {
-                arr.push({});
-            }
-        };
-
-        for (let cnt = 0; cnt < accessPath.length; cnt++) {
-            let currKey = this.keyVal(accessPath[cnt]);
-            let arrPos = this.arrayIndex(accessPath[cnt]);
-
-            if (this.isArrayPos(currKey, arrPos)) {
-
-                val.setVal((val.value instanceof Array) ? val.value : []);
-                alloc(val.value, arrPos + 1);
-                if (parentPos >= 0) {
-                    parentVal.value[parentPos] = val.value;
-                }
-                parentVal = val;
-                parentPos = arrPos;
-                val = this.getClass().fromNullable(val.value[arrPos]);
-                continue;
-            }
-
-            let tempVal = <Config>val.getIf(currKey);
-            if (this.isNoArray(arrPos)) {
-                if (tempVal.isAbsent()) {
-                    tempVal = <Config>this.getClass().fromNullable(val.value[currKey] = {});
-                } else {
-                    val = <any>tempVal;
-                }
-            } else {
-                let arr = (tempVal.value instanceof Array) ? tempVal.value : [];
-                alloc(arr, arrPos + 1);
-                val.value[currKey] = arr;
-                tempVal = this.getClass().fromNullable(arr[arrPos]);
-            }
-            parentVal = val;
-            parentPos = arrPos;
-            val = <any>tempVal;
-        }
-
-        return this;
-    }
-
-    private isNoArray(arrPos: number) {
-        return arrPos == -1;
-    }
-
-    private isArray(arrPos: number) {
-        return !this.isNoArray(arrPos);
-    }
-
-    private isArrayPos(currKey: string, arrPos: number) {
-            return currKey === "" && arrPos >= 0;
-    }
-
-}
-
 
 
diff --git a/api/src/client/typescript/mona_dish/PromiseShim.ts b/api/src/client/typescript/mona_dish/PromiseShim.ts
index 5af5f0640..0d420d9cc 100644
--- a/api/src/client/typescript/mona_dish/PromiseShim.ts
+++ b/api/src/client/typescript/mona_dish/PromiseShim.ts
@@ -21,7 +21,6 @@
  */
 
 import {Promise as _Promise} from "./Promise";
-import type = Mocha.utils.type;
 import {_global$} from "./Global";
 
 
diff --git a/api/src/client/typescript/mona_dish/SourcesCollectors.ts b/api/src/client/typescript/mona_dish/SourcesCollectors.ts
index 01734753c..687bfcd27 100644
--- a/api/src/client/typescript/mona_dish/SourcesCollectors.ts
+++ b/api/src/client/typescript/mona_dish/SourcesCollectors.ts
@@ -15,19 +15,18 @@
  * limitations under the License.
  */
 
-import {Stream, StreamMapper} from "./Stream";
 import {DomQuery} from "./DomQuery";
-
-import {Config} from "./Monad";
+import {Es2019Array} from "./Es2019Array";
+import {Config} from "./Config";
 
 /**
  * special status of the datasource location pointer
- * if an access, outside of the possible data boundaries is happening
+ * if an access, outside - of the possible data boundaries is happening
  * (example for instance current without a first next call, or next
  * which goes over the last possible dataset), an iteration status return
  * value is returned marking this boundary instead of a classical element
  *
- * Note this is only internally used but must be implemented to fullfill
+ * Note this is only internally used but must be implemented to fulfill
  * internal contracts, the end user will never see those values if he uses
  * streams!
  */
@@ -36,6 +35,14 @@ export enum ITERATION_STATUS {
     BEF_STRM = '___BEF_STRM__',
 }
 
+export function calculateSkips(next_strm: IStreamDataSource<any>) {
+    let pos = 1;
+    while (next_strm.lookAhead(pos) != ITERATION_STATUS.EO_STRM) {
+        pos++;
+    }
+    return --pos;
+}
+
 /**
  * Every data source wich feeds data into the lazy stream
  * or stream generally must implement this interface
@@ -55,12 +62,14 @@ export interface IStreamDataSource<T> {
     next(): T | ITERATION_STATUS;
 
     /**
-     * returns the next element in the stream
-     * difference to next is, that the internal data position
-     * is not changed, so next still will deliver the next item from the current
-     * data position. Look ahead is mostly needed internally
-     * by possible endless data constructs which have no fixed data boundary, or index
-     * positions. (aka infinite sets, or flatmapped constructs)
+     * looks ahead cnt without changing the internal data "pointers" of the data source
+     * (this is mostly needed by possibly infinite constructs like lazy streams,
+     * because they do not know by definition their
+     * boundaries)
+     *
+     * @param cnt the elements to look ahead
+     * @return either the element or ITERATION_STATUS.EO_STRM if we hit the end of the stream before
+     * finding the "cnt" element
      */
     lookAhead(cnt ?: number): T | ITERATION_STATUS;
 
@@ -95,14 +104,11 @@ export interface ICollector<T, S> {
     finalValue: S;
 }
 
-function calculateSkips(next_strm: IStreamDataSource<any>) {
-    let pos = 1;
-    while (next_strm.lookAhead(pos) != ITERATION_STATUS.EO_STRM) {
-        pos++;
-    }
-    return --pos;
-}
 
+/**
+ * A data source which combines multiple streams sequentially into one
+ * (this is used internally by  flatmap, but also can be used externally)
+ */
 export class MultiStreamDatasource<T> implements IStreamDataSource<T> {
 
     private  activeStrm;
@@ -229,7 +235,7 @@ export class SequenceDataSource implements IStreamDataSource<number> {
 
 
 /**
- * implementation of iteratable on top of array
+ * implementation of a datasource on top of a standard array
  */
 export class ArrayStreamDataSource<T> implements IStreamDataSource<T> {
     value: Array<T>;
@@ -329,6 +335,15 @@ export class FilteredStreamDatasource<T> implements IStreamDataSource<T> {
         return found;
     }
 
+    /**
+     * looks ahead cnt without changing the internal data "pointers" of the data source
+     * (this is mostly needed by LazyStreams, because they do not know by definition their
+     * boundaries)
+     *
+     * @param cnt the elements to look ahead
+     * @return either the element or ITERATION_STATUS.EO_STRM if we hit the end of the stream before
+     * finding the "cnt" element
+     */
     lookAhead(cnt = 1): ITERATION_STATUS | T {
         let lookupVal: T | ITERATION_STATUS;
 
@@ -390,129 +405,13 @@ export class MappedStreamDataSource<T, S> implements IStreamDataSource<S> {
     }
 }
 
-/**
- * Same for flatmap to deal with element -> stream mappings
- */
-export class FlatMapStreamDataSource<T, S> implements IStreamDataSource<S> {
-
-    mapFunc: StreamMapper<T>;
-
-    inputDataSource: IStreamDataSource<T>;
-
-    /**
-     * the currently active stream
-     * coming from an incoming element
-     * once the end of this one is reached
-     * it is swapped out by another one
-     * from the next element
-     */
-    activeDataSource: IStreamDataSource<S>;
-    walkedDataSources = [];
-    _currPos = 0;
-
-    constructor(func: StreamMapper<T>, parent: IStreamDataSource<T>) {
-        this.mapFunc = func;
-        this.inputDataSource = parent;
-    }
-
-    hasNext(): boolean {
-        return this.resolveActiveHasNext() || this.resolveNextHasNext();
-    }
-
-    private resolveActiveHasNext() {
-        let next = false;
-        if (this.activeDataSource) {
-            next = this.activeDataSource.hasNext();
-        }
-        return next;
-    }
-
-    lookAhead(cnt = 1): ITERATION_STATUS | S {
-
-        let lookAhead = this?.activeDataSource?.lookAhead(cnt);
-        if (this?.activeDataSource && lookAhead != ITERATION_STATUS.EO_STRM) {
-            //this should cover 95% of all cases
-            return lookAhead;
-        }
-
-        if (this.activeDataSource) {
-            cnt -= calculateSkips(this.activeDataSource)
-        }
-
-        //the idea is basically to look into the streams sub-sequentially for a match
-        //after each stream we have to take into consideration that the skipCnt is
-        //reduced by the number of datasets we already have looked into in the previous stream/datasource
-        //unfortunately for now we have to loop into them, so we introduce a small o2 here
-        for (let dsLoop = 1; true; dsLoop++) {
-            let datasourceData = this.inputDataSource.lookAhead(dsLoop);
-            //we have looped out
-            //no embedded data anymore? we are done, data
-            //can either be a scalar an array or another datasource
-            if (datasourceData === ITERATION_STATUS.EO_STRM) {
-                return ITERATION_STATUS.EO_STRM;
-            }
-            let mappedData = this.mapFunc(datasourceData as T);
-
-            //it either comes in as datasource or as array
-            //both cases must be unified into a datasource
-            let currentDataSource = this.toDatasource(mappedData);
-            //we now run again  a lookahead
-            let ret = currentDataSource.lookAhead(cnt);
-            //if the value is found then we are set
-            if (ret != ITERATION_STATUS.EO_STRM) {
-                return ret;
-            }
-            //reduce the next lookahead by the number of elements
-            //we are now skipping in the current data source
-            cnt -= calculateSkips(currentDataSource);
-        }
-    }
-
-    private toDatasource(mapped: Array<S> | IStreamDataSource<S>) {
-        let ds = Array.isArray(mapped) ? new ArrayStreamDataSource(...mapped) : mapped;
-        this.walkedDataSources.push(ds)
-        return ds;
-    }
-
-    private resolveNextHasNext() {
-        let next = false;
-        while (!next && this.inputDataSource.hasNext()) {
-            let mapped = this.mapFunc(this.inputDataSource.next() as T);
-            this.activeDataSource = this.toDatasource(mapped);
-            next = this.activeDataSource.hasNext();
-        }
-        return next;
-    }
-
-    next(): S | ITERATION_STATUS {
-        if (this.hasNext()) {
-            this._currPos++;
-            return this.activeDataSource.next();
-        }
-    }
-
-    reset(): void {
-        this.inputDataSource.reset();
-        this.walkedDataSources.forEach(ds => ds.reset());
-        this.walkedDataSources = [];
-        this._currPos = 0;
-        this.activeDataSource = null;
-    }
-
-    current(): S | ITERATION_STATUS {
-        if (!this.activeDataSource) {
-            this.hasNext();
-        }
-        return this.activeDataSource.current();
-    }
-}
 
 /**
  * For the time being we only need one collector
  * a collector which collects a stream back into arrays
  */
-export class ArrayCollector<S> implements ICollector<S, Array<S>> {
-    private data: Array<S> = [];
+export class ShimArrayCollector<S> implements ICollector<S, Array<S>> {
+    private data: Array<S> = new Es2019Array(...[]);
 
     collect(element: S) {
         this.data.push(element);
@@ -632,9 +531,24 @@ export class QueryFormStringCollector implements ICollector<DomQuery, string> {
     }
 
     get finalValue(): string {
-        return Stream.of(...this.formData)
-            .map<string>(keyVal => keyVal.join("="))
-            .reduce((item1, item2) => [item1, item2].join("&"))
-            .orElse("").value;
+        return new Es2019Array(...this.formData)
+            .map(keyVal => keyVal.join("="))
+            .reduce((item1, item2) => [item1, item2].join("&"));
     }
-}
\ No newline at end of file
+}
+
+/**
+ * For the time being we only need one collector
+ * a collector which collects a stream back into arrays
+ */
+export class ArrayCollector<S> implements ICollector<S, Array<S>> {
+    private data: Array<S> = [];
+
+    collect(element: S) {
+        this.data.push(element);
+    }
+
+    get finalValue(): Array<S> {
+        return this.data;
+    }
+}
diff --git a/api/src/client/typescript/mona_dish/Stream.ts b/api/src/client/typescript/mona_dish/Stream.ts
index 7fd24d126..548e4d60a 100644
--- a/api/src/client/typescript/mona_dish/Stream.ts
+++ b/api/src/client/typescript/mona_dish/Stream.ts
@@ -21,14 +21,15 @@
 import {IMonad, IValueHolder, Optional} from "./Monad";
 import {
     ArrayCollector,
-    ArrayStreamDataSource,
+    ArrayStreamDataSource, calculateSkips,
     FilteredStreamDatasource,
-    FlatMapStreamDataSource,
     ICollector,
     IStreamDataSource,
     ITERATION_STATUS,
     MappedStreamDataSource, MultiStreamDatasource
 } from "./SourcesCollectors";
+import {DomQuery} from "./DomQuery";
+import {Config} from "./Config";
 //import {from, Observable} from "rxjs";
 
 
@@ -43,6 +44,124 @@ export type Matchable<T> = (data: T) => boolean;
 export type Mappable<T, R> = (data: T) => R;
 export type Comparator<T> = (el1: T, el2: T) => number;
 
+
+/**
+ * Same for flatmap to deal with element -> stream mappings
+ */
+export class FlatMapStreamDataSource<T, S> implements IStreamDataSource<S> {
+
+    mapFunc: StreamMapper<T>;
+
+    inputDataSource: IStreamDataSource<T>;
+
+    /**
+     * the currently active stream
+     * coming from an incoming element
+     * once the end of this one is reached
+     * it is swapped out by another one
+     * from the next element
+     */
+    activeDataSource: IStreamDataSource<S>;
+    walkedDataSources = [];
+    _currPos = 0;
+
+    constructor(func: StreamMapper<T>, parent: IStreamDataSource<T>) {
+        this.mapFunc = func;
+        this.inputDataSource = parent;
+    }
+
+    hasNext(): boolean {
+        return this.resolveActiveHasNext() || this.resolveNextHasNext();
+    }
+
+    private resolveActiveHasNext() {
+        let next = false;
+        if (this.activeDataSource) {
+            next = this.activeDataSource.hasNext();
+        }
+        return next;
+    }
+
+    lookAhead(cnt = 1): ITERATION_STATUS | S {
+
+        let lookAhead = this?.activeDataSource?.lookAhead(cnt);
+        if (this?.activeDataSource && lookAhead != ITERATION_STATUS.EO_STRM) {
+            //this should cover 95% of all cases
+            return lookAhead;
+        }
+
+        if (this.activeDataSource) {
+            cnt -= calculateSkips(this.activeDataSource)
+        }
+
+        //the idea is basically to look into the streams sub-sequentially for a match
+        //after each stream we have to take into consideration that the skipCnt is
+        //reduced by the number of datasets we already have looked into in the previous stream/datasource
+        //unfortunately for now we have to loop into them, so we introduce a small o2 here
+        for (let dsLoop = 1; true; dsLoop++) {
+            let datasourceData = this.inputDataSource.lookAhead(dsLoop);
+            //we have looped out
+            //no embedded data anymore? we are done, data
+            //can either be a scalar an array or another datasource
+            if (datasourceData === ITERATION_STATUS.EO_STRM) {
+                return ITERATION_STATUS.EO_STRM;
+            }
+            let mappedData = this.mapFunc(datasourceData as T);
+
+            //it either comes in as datasource or as array
+            //both cases must be unified into a datasource
+            let currentDataSource = this.toDatasource(mappedData);
+            //we now run again  a lookahead
+            let ret = currentDataSource.lookAhead(cnt);
+            //if the value is found then we are set
+            if (ret != ITERATION_STATUS.EO_STRM) {
+                return ret;
+            }
+            //reduce the next lookahead by the number of elements
+            //we are now skipping in the current data source
+            cnt -= calculateSkips(currentDataSource);
+        }
+    }
+
+    private toDatasource(mapped: Array<S> | IStreamDataSource<S>) {
+        let ds = Array.isArray(mapped) ? new ArrayStreamDataSource(...mapped) : mapped;
+        this.walkedDataSources.push(ds)
+        return ds;
+    }
+
+    private resolveNextHasNext() {
+        let next = false;
+        while (!next && this.inputDataSource.hasNext()) {
+            let mapped = this.mapFunc(this.inputDataSource.next() as T);
+            this.activeDataSource = this.toDatasource(mapped);
+            next = this.activeDataSource.hasNext();
+        }
+        return next;
+    }
+
+    next(): S | ITERATION_STATUS {
+        if (this.hasNext()) {
+            this._currPos++;
+            return this.activeDataSource.next();
+        }
+    }
+
+    reset(): void {
+        this.inputDataSource.reset();
+        this.walkedDataSources.forEach(ds => ds.reset());
+        this.walkedDataSources = [];
+        this._currPos = 0;
+        this.activeDataSource = null;
+    }
+
+    current(): S | ITERATION_STATUS {
+        if (!this.activeDataSource) {
+            this.hasNext();
+        }
+        return this.activeDataSource.current();
+    }
+}
+
 /**
  * Generic interface defining a stream
  */
@@ -216,6 +335,14 @@ export class Stream<T> implements IMonad<T, Stream<any>>, IValueHolder<Array<T>>
         return new Stream(...value);
     }
 
+    static ofDomQuery(value: DomQuery): Stream<DomQuery> {
+        return Stream.of(...value.asArray);
+    }
+
+    static ofConfig(value: Config): Stream<[string, any]> {
+        return Stream.of(... Object.keys(value.value)).map(key => [key, value.value[key]])
+    }
+
     current(): T | ITERATION_STATUS {
         if(this.pos == -1) {
             return ITERATION_STATUS.BEF_STRM;
@@ -459,6 +586,14 @@ export class LazyStream<T> implements IStreamDataSource<T>, IStream<T>, IMonad<T
         return new LazyStream(value);
     }
 
+    static ofDomQuery(value: DomQuery): LazyStream<DomQuery> {
+        return LazyStream.of(...value.asArray);
+    }
+
+    static ofConfig(value: Config): LazyStream<[string, any]> {
+        return LazyStream.of(... Object.keys(value.value)).map(key => [key, value.value[key]])
+    }
+
     constructor(parent: IStreamDataSource<T>) {
         this.dataSource = parent;
 
@@ -669,3 +804,23 @@ export class LazyStream<T> implements IStreamDataSource<T>, IStream<T>, IMonad<T
 }
 
 
+/**
+ * 1.0 backwards compatibility functions
+ *
+ * this restores the stream and lazy stream
+ * property on DomQuery on prototype level
+ *
+ */
+
+Object.defineProperty(DomQuery.prototype, "stream", {
+    get: function stream(){
+        return Stream.ofDomQuery(this);
+    }
+})
+
+
+Object.defineProperty(DomQuery.prototype, "lazyStream", {
+    get: function lazyStream(){
+        return LazyStream.ofDomQuery(this);
+    }
+})
\ No newline at end of file
diff --git a/api/src/client/typescript/mona_dish/index.ts b/api/src/client/typescript/mona_dish/index.ts
index a8961a973..fc71978e6 100644
--- a/api/src/client/typescript/mona_dish/index.ts
+++ b/api/src/client/typescript/mona_dish/index.ts
@@ -18,15 +18,14 @@
  */
 export {DomQuery, ElementAttribute, DomQueryCollector, DQ, DQ$} from "./DomQuery";
 export {Lang} from "./Lang";
-export {Config, CONFIG_VALUE, CONFIG_ANY, ConfigDef, Monad, IValueHolder, IFunctor, IMonad, IIdentity, Optional, ValueEmbedder} from "./Monad";
+export {Monad, IValueHolder, IFunctor, IMonad, IIdentity, Optional, ValueEmbedder} from "./Monad";
 export {CancellablePromise, IPromise, PromiseStatus} from "./Promise";
 export {XMLQuery, XQ} from "./XmlQuery";
-export {Stream, LazyStream, IteratableConsumer, IStream} from "./Stream";
+export {Stream, LazyStream, IteratableConsumer, FlatMapStreamDataSource, IStream} from "./Stream";
 export {
     ArrayStreamDataSource,
     MappedStreamDataSource,
     FilteredStreamDatasource,
-    FlatMapStreamDataSource,
     MultiStreamDatasource,
     SequenceDataSource,
     QueryFormStringCollector,
@@ -44,5 +43,10 @@ export {TagBuilder} from "./TagBuilder";
 
 export {Message, Broker, BroadcastChannelBroker, Crypto, NoCrypto, Hash} from "./Messaging";
 export {JSONCrypto, ExpiringCrypto} from "./CryptoExtensions";
-
+export {assign, assignIf, simpleShallowMerge, shallowMerge} from "./AssocArray"
+export {Config} from "./Config";
+export {ConfigDef} from "./Config";
+export {CONFIG_ANY} from "./Config";
+export {CONFIG_VALUE} from "./Config";
+export {Es2019Array, _Es2019Array} from "./Es2019Array";
 
diff --git a/api/src/client/typescript/mona_dish/index_core.ts b/api/src/client/typescript/mona_dish/index_core.ts
index f1a911664..aaf734e64 100644
--- a/api/src/client/typescript/mona_dish/index_core.ts
+++ b/api/src/client/typescript/mona_dish/index_core.ts
@@ -18,24 +18,15 @@
  */
 export {DomQuery, ElementAttribute, DomQueryCollector, DQ, DQ$} from "./DomQuery";
 export {Lang} from "./Lang";
-export {Config, CONFIG_VALUE, CONFIG_ANY, ConfigDef, Monad, IValueHolder, IFunctor, IMonad, IIdentity, Optional, ValueEmbedder} from "./Monad";
+export {Monad, IValueHolder, IFunctor, IMonad, IIdentity, Optional, ValueEmbedder} from "./Monad";
 export {XMLQuery, XQ} from "./XmlQuery";
-export {Stream, LazyStream, IteratableConsumer, IStream} from "./Stream";
-export {
-    ArrayStreamDataSource,
-    MappedStreamDataSource,
-    FilteredStreamDatasource,
-    FlatMapStreamDataSource,
-    SequenceDataSource,
-    QueryFormStringCollector,
-    IStreamDataSource,
-    ICollector,
-    ArrayCollector,
-    AssocArrayCollector,
-    FormDataCollector,
-    QueryFormDataCollector
-} from "./SourcesCollectors";
-
+export {assign, assignIf, append, simpleShallowMerge, shallowMerge} from "./AssocArray"
+export {Config} from "./Config";
+export {ConfigDef} from "./Config";
+export {CONFIG_ANY} from "./Config";
+export {CONFIG_VALUE} from "./Config";
+export * as Assoc from "./AssocArray";
+export {Es2019Array, _Es2019Array} from "./Es2019Array";