diff --git a/source/components/form/form.mjs b/source/components/form/form.mjs
index a807bfd4c9aaf3b38e6fd18c193e7d3f8c19ab41..c75adad72ef47e3a3d84fbdd6967502d86d6e18d 100644
--- a/source/components/form/form.mjs
+++ b/source/components/form/form.mjs
@@ -12,576 +12,224 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import { instanceSymbol } from "../../constants.mjs";
-import { internalSymbol } from "../../constants.mjs";
-import { Datasource } from "../../data/datasource.mjs";
-import { RestAPI } from "../../data/datasource/server/restapi.mjs";
-import { WebConnect } from "../../data/datasource/server/webconnect.mjs";
-import { WriteError } from "../../data/datasource/server/restapi/writeerror.mjs";
-import { LocalStorage } from "../../data/datasource/storage/localstorage.mjs";
-import { SessionStorage } from "../../data/datasource/storage/sessionstorage.mjs";
+import {instanceSymbol} from "../../constants.mjs";
+import {internalSymbol} from "../../constants.mjs";
+import {TokenList} from "../../types/tokenlist.mjs";
+import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
+import {DataSet} from "../datatable/dataset.mjs";
+//import { Datasource } from "../../data/datasource.mjs";
+import {RestAPI} from "../../data/datasource/server/restapi.mjs";
+import {WebConnect} from "../../data/datasource/server/webconnect.mjs";
+import {WriteError} from "../../data/datasource/server/restapi/writeerror.mjs";
+import {LocalStorage} from "../../data/datasource/storage/localstorage.mjs";
+import {SessionStorage} from "../../data/datasource/storage/sessionstorage.mjs";
 import {
-	ATTRIBUTE_DISABLED,
-	ATTRIBUTE_ERRORMESSAGE,
-	ATTRIBUTE_PREFIX,
-	ATTRIBUTE_UPDATER_ATTRIBUTES,
-	ATTRIBUTE_UPDATER_INSERT,
-	ATTRIBUTE_UPDATER_REMOVE,
-	ATTRIBUTE_UPDATER_REPLACE,
+    ATTRIBUTE_DISABLED,
+    ATTRIBUTE_ERRORMESSAGE,
+    ATTRIBUTE_PREFIX,
+    ATTRIBUTE_UPDATER_ATTRIBUTES,
+    ATTRIBUTE_UPDATER_INSERT,
+    ATTRIBUTE_UPDATER_REMOVE,
+    ATTRIBUTE_UPDATER_REPLACE,
 } from "../../dom/constants.mjs";
 import {
-	assembleMethodSymbol,
-	CustomElement,
-	registerCustomElement,
-	getSlottedElements,
+    assembleMethodSymbol,
+    CustomElement,
+    registerCustomElement,
+    getSlottedElements,
 } from "../../dom/customelement.mjs";
-import { addObjectWithUpdaterToElement } from "../../dom/updater.mjs";
-import { isFunction, isString } from "../../types/is.mjs";
-import { Observer } from "../../types/observer.mjs";
-import { ProxyObserver } from "../../types/proxyobserver.mjs";
-import { Processing } from "../../util/processing.mjs";
-import { MessageStateButton } from "./message-state-button.mjs";
+import {addObjectWithUpdaterToElement} from "../../dom/updater.mjs";
+import {findElementWithSelectorUpwards} from "../../dom/util.mjs";
+import {isFunction, isString} from "../../types/is.mjs";
+import {Observer} from "../../types/observer.mjs";
+import {ProxyObserver} from "../../types/proxyobserver.mjs";
+import {Processing} from "../../util/processing.mjs";
+import {datasourceLinkedElementSymbol, handleDataSourceChanges} from "../datatable/util.mjs";
+import {MessageStateButton} from "./message-state-button.mjs";
 import {
-	ATTRIBUTE_FORM_DATASOURCE,
-	ATTRIBUTE_FORM_DATASOURCE_ARGUMENTS,
+    ATTRIBUTE_FORM_DATASOURCE,
+    ATTRIBUTE_FORM_DATASOURCE_ARGUMENTS,
 } from "./constants.mjs";
-import { StateButton } from "./state-button.mjs";
-import { FormStyleSheet } from "./stylesheet/form.mjs";
+import {StateButton} from "./state-button.mjs";
+import {FormStyleSheet} from "./stylesheet/form.mjs";
 
-export { Form };
+export {Form};
 
-/**
- * @private
- * @since 3.1.0
- * @type {string}
- */
-const ATTRIBUTE_FORM_DATASOURCE_ACTION = `${ATTRIBUTE_PREFIX}datasource-action`;
-
-/**
- * Form data is the internal representation of the form data
- *
- * @private
- * @type {symbol}
- * @since 1.7.0
- */
-const formDataSymbol = Symbol.for(
-	"@schukai/monster/components/form/form@@formdata",
-);
-
-/**
- * @private
- * @type {symbol}
- * @since 2.8.0
- */
-const formDataUpdaterSymbol = Symbol.for(
-	"@schukai/component-form/form@@formdata-updater-link",
-);
 
 /**
  * @private
  * @type {symbol}
- * @since 1.7.0
- */
-const formElementSymbol = Symbol.for(
-	"@schukai/component-form/form@@form-element",
-);
-
-/**
- * @private
- * @type {symbol}
- * @since 2.5.0
- */
-const registeredDatasourcesSymbol = Symbol.for(
-	"@schukai/component-form/form@@registered-datasources",
-);
-
-/**
- * @private
- * @since 1.7.0
- * @type {string}
- */
-const PROPERTY_VALIDATION_KEY = "__validation";
-
-/**
- * This CustomControl creates a form element with a variety of options.
- *
- * <img src="./images/form.png">
- *
- * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library.
- *
- * You can create this control either by specifying the HTML tag `<monster-form />` directly in the HTML or using
- * Javascript via the `document.createElement('monster-form');` method.
- *
- * ```html
- * <monster-form></monster-form>
- * ```
- *
- * Or you can create this CustomControl directly in Javascript:
- *
- * ```js
- * import {Form} from '@schukai/component-form/source/form.js';
- * document.createElement('monster-form');
- * ```
- *
- * @startuml form.png
- * skinparam monochrome true
- * skinparam shadowing false
- * HTMLElement <|-- CustomElement
- * CustomElement <|-- Form
- * @enduml
- *
- * @since 1.6.0
- * @copyright schukai GmbH
- * @memberOf Monster.Components.Form
- * @summary A configurable form control
  */
-class Form extends CustomElement {
-	/**
-	 * @throws {Error} the options attribute does not contain a valid json definition.
-	 * @since 1.7.0
-	 */
-	constructor() {
-		super();
-		this[formDataSymbol] = new ProxyObserver({});
-	}
-
-	/**
-	 * This method is called by the `instanceof` operator.
-	 * @returns {symbol}
-	 * @since 2.1.0
-	 */
-	static get [instanceSymbol]() {
-		return Symbol.for("@schukai/monster/components/form/form");
-	}
-
-	/**
-	 * To set the options via the html tag the attribute `data-monster-options` must be used.
-	 * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
-	 *
-	 * The individual configuration values can be found in the table.
-	 *
-	 * @property {Object} templates Template definitions
-	 * @property {string} templates.main Main template
-	 * @property {Datasource} datasource data source
-	 * @property {Object} reportValidity
-	 * @property {string} reportValidity.selector which element should be used to report the validity
-	 * @property {function} reportValidity.errorHandler function to handle the error
-	 * @property {Object} classes
-	 * @property {string} classes.button class for the form
-	 */
-	get defaults() {
-		return Object.assign(
-			{},
-			super.defaults,
-			{
-				templates: {
-					main: getTemplate(),
-				},
-				datasource: undefined,
-				reportValidity: {
-					selector: "input,select,textarea",
-					errorHandler: undefined,
-				},
-				classes: {
-					form: "",
-				},
-			},
-			initOptionsFromArguments.call(this),
-		);
-	}
-
-	/**
-	 * Called every time the element is inserted into the DOM. Useful for running setup code, such as
-	 * fetching resources or rendering. Generally, you should try to delay work until this time.
-	 *
-	 * @return {void}
-	 */
-	connectedCallback() {
-		super["connectedCallback"]();
-	}
-
-	/**
-	 * The refresh method is called to update the control after a change with fresh data.
-	 *
-	 * Therefore, the data source is called again and the data is updated.
-	 *
-	 * If you have updated the data source with `setOption('datasource',datasource), you must call this method.
-	 *
-	 * @return {Form}
-	 * @throws {Error} undefined datasource
-	 */
-	refresh() {
-		try {
-			this.setAttribute(ATTRIBUTE_DISABLED, "");
-			const datasource = this.getOption("datasource");
-
-			if (!(datasource instanceof Datasource)) {
-				throw new Error("undefined datasource");
-			}
-
-			return datasource
-				.read()
-				.then(() => {
-					this[formDataSymbol].setSubject(datasource.get());
-				})
-				.then(() => {
-					new Processing(() => {
-						this.removeAttribute(ATTRIBUTE_DISABLED);
-					}).run();
-				})
-				.catch((e) => {
-					this.removeAttribute(ATTRIBUTE_DISABLED);
-					this.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
-				});
-		} catch (e) {
-			this.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
-			this.removeAttribute(ATTRIBUTE_DISABLED);
-			throw e;
-		}
-	}
-
-	/**
-	 *
-	 * @return {Monster.Components.Form.Form}
-	 */
-	[assembleMethodSymbol]() {
-		super[assembleMethodSymbol]();
-
-		initControlReferences.call(this);
-		initDatasource.call(this);
-		initUpdater.call(this);
-		initObserver.call(this);
-		return this;
-	}
-
-	/**
-	 *
-	 * @return {*}
-	 */
-	getValues() {
-		return this[formDataSymbol].getSubject();
-	}
-
-	/**
-	 *
-	 * @return {string}
-	 */
-	static getTag() {
-		return "monster-form";
-	}
-
-	/**
-	 *
-	 * @return {CSSStyleSheet}
-	 */
-	static getCSSStyleSheet() {
-		return [FormStyleSheet];
-	}
-
-	static [registeredDatasourcesSymbol] = new Map([
-		["restapi", RestAPI],
-		["localstorage", LocalStorage],
-		["sessionstorage", SessionStorage],
-		["webconnect", WebConnect],
-	]);
-
-	/**
-	 * Register a new datasource
-	 *
-	 * @param {string} name
-	 * @param {Monster.Data.Datasource} datasource
-	 */
-	static registerDatasource(name, datasource) {
-		Form[registeredDatasourcesSymbol].set(name, datasource);
-	}
-
-	/**
-	 * Unregister a registered datasource
-	 *
-	 * @param {string} name
-	 */
-	static unregisterDatasource(name) {
-		Form[registeredDatasourcesSymbol].delete(name);
-	}
-
-	/**
-	 * Get registered data sources
-	 *
-	 * @return {Map}
-	 */
-	static getDatasources() {
-		return Form[registeredDatasourcesSymbol];
-	}
-
-	/**
-	 * Run reportValidation on all child html form controls.
-	 *
-	 * @since 2.10.0
-	 * @returns {boolean}
-	 */
-	reportValidity() {
-		let valid = true;
-
-		const selector = this.getOption("reportValidity.selector");
-		const nodes = getSlottedElements.call(this, selector);
-		nodes.forEach((node) => {
-			if (typeof node.reportValidity === "function") {
-				if (node.reportValidity() === false) {
-					valid = false;
-				}
-			}
-		});
-
-		return valid;
-	}
-}
+const debounceCallbackSymbol = Symbol("timerCallback");
+
+class Form extends DataSet {
+
+    /**
+     *
+     * @returns {{shadowMode: string, templates: {main: *}, display: string, disabled: boolean, delegatesFocus: boolean, templateMapping: {}} & {templates: {main: string}, classes: {form: string}}}
+     */
+    get defaults() {
+        const obj = Object.assign(
+            {},
+            super.defaults,
+            {
+                templates: {
+                    main: getTemplate(),
+                },
+
+                classes: {
+                    form: "",
+                },
+
+                writeBack: {
+                    events: ["change", "input", "keyup"]
+                },
+
+                reportValidity: {
+                    selector: "input,select,textarea",
+                }
+
+            }
+        );
+
+        obj['features']['mutationObserver'] = false;
+        obj['features']['writeBack'] = true;
+
+        return obj;
+
+    }
+
+
+    /**
+     *
+     * @return {string}
+     */
+    static getTag() {
+        return "monster-form";
+    }
+
+    /**
+     * @return {CSSStyleSheet[]}
+     */
+    static getCSSStyleSheet() {
+        return [FormStyleSheet];
+    }
+
+    /**
+     *
+     */
+    [assembleMethodSymbol]() {
+        super[assembleMethodSymbol]();
+
+        initControlReferences.call(this);
+        initEventHandler.call(this);
+        initDataSourceHandler.call(this);
+
+    }
+
+    /**
+     * This method is called when the component is created.
+     * @since 3.70.0
+     * @returns {DataSet}
+     */
+    refresh() {
+        this.write();
+        super.refresh();
+        return this;
+    }
+
+    /**
+     * Run reportValidation on all child html form controls.
+     *
+     * @since 2.10.0
+     * @returns {boolean}
+     */
+    reportValidity() {
+        let valid = true;
+
+        const selector = this.getOption("reportValidity.selector");
+        const nodes = getSlottedElements.call(this, selector);
+
+        nodes.forEach((node) => {
+            if (typeof node.reportValidity === "function") {
+                if (node.reportValidity() === false) {
+                    valid = false;
+                }
+            }
+        });
+
+        return valid;
+    }
 
-/**
- * @private
- */
-function initUpdater() {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	const slots = this.shadowRoot.querySelectorAll("slot");
-	for (const [, slot] of Object.entries(slots)) {
-		for (const [, node] of Object.entries(slot.assignedNodes())) {
-			if (!(node instanceof HTMLElement)) {
-				continue;
-			}
-
-			const query = `[${ATTRIBUTE_UPDATER_ATTRIBUTES}],[${ATTRIBUTE_UPDATER_REPLACE}],[${ATTRIBUTE_UPDATER_REMOVE}],[${ATTRIBUTE_UPDATER_INSERT}]`;
-			const controls = node.querySelectorAll(query);
-
-			const list = new Set([...controls]);
-
-			if (node.matches(query)) {
-				list.add(node);
-			}
-
-			if (list.size === 0) {
-				continue;
-			}
-
-			addObjectWithUpdaterToElement.call(
-				node,
-				list,
-				formDataUpdaterSymbol,
-				this[formDataSymbol],
-			);
-		}
-	}
 }
 
-/**
- * @private
- */
-function initDatasource() {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	const slots = this.shadowRoot.querySelectorAll("slot");
-	for (const [, slot] of Object.entries(slots)) {
-		for (const [, node] of Object.entries(slot.assignedNodes())) {
-			if (!(node instanceof HTMLElement)) {
-				continue;
-			}
-
-			const query = `[${ATTRIBUTE_FORM_DATASOURCE_ACTION}=write]`;
-			const controls = node.querySelectorAll(query);
-
-			const list = new Set([...controls]);
-
-			if (node.matches(query)) {
-				list.add(node);
-			}
-
-			if (list.size === 0) {
-				continue;
-			}
-
-			initWriteActions.call(this, list);
-		}
-	}
-}
+function initDataSourceHandler() {
+    if (!this[datasourceLinkedElementSymbol]) {
+        return;
+    }
+console.log(this[datasourceLinkedElementSymbol]);
+    this[datasourceLinkedElementSymbol].setOption("write.responseCallback", (response) => {
+        console.log("response!!!", response);
+    })
 
-/**
- * @private
- * @param elements
- */
-function initWriteActions(elements) {
-	elements.forEach((element) => {
-		if (element instanceof HTMLElement) {
-			element.addEventListener("click", () => {
-				runWriteCallback.call(this, element);
-			});
-
-			const g = element?.getOption;
-			if (!isFunction(g)) {
-				return;
-			}
-
-			const s = element?.setOption;
-			if (!isFunction(s)) {
-				return;
-			}
-
-			const fn = element.getOption("actions.click");
-
-			if (!isFunction(fn)) {
-				return;
-			}
-
-			// disable console.log of standard click event
-			element.setOption("actions.click", function () {
-				// do nothing!
-			});
-		}
-	});
-}
-
-function runWriteCallback(button) {
-	if (typeof this.reportValidity === "function") {
-		if (this.reportValidity() === false) {
-			if (
-				button instanceof StateButton ||
-				button instanceof MessageStateButton
-			) {
-				button.setState("failed");
-			}
-			return;
-		}
-	}
-
-	const datasource = this.getOption("datasource");
-	if (!(datasource instanceof Datasource)) {
-		return;
-	}
-
-	if (button instanceof StateButton || button instanceof MessageStateButton) {
-		button.setState("activity");
-	}
-
-	//const data = form?.[formDataSymbol]?.getRealSubject();
-	const writePromise = datasource
-		.set(this[formDataSymbol].getRealSubject())
-		.write();
-	if (!(writePromise instanceof Promise)) {
-		throw new Error("datasource.write() must return a promise");
-	}
-
-	writePromise
-		.then((r) => {
-			if (
-				button instanceof StateButton ||
-				button instanceof MessageStateButton
-			) {
-				button.setState("successful");
-			}
-			this[formDataSymbol].getSubject()[PROPERTY_VALIDATION_KEY] = {};
-		})
-		.catch((e) => {
-			if (e instanceof WriteError) {
-				this[formDataSymbol].getSubject()[PROPERTY_VALIDATION_KEY] =
-					e.getValidation();
-			}
-
-			if (
-				button instanceof StateButton ||
-				button instanceof MessageStateButton
-			) {
-				button.setState("failed");
-			}
-
-			if (button instanceof MessageStateButton) {
-				button.setMessage(e.message);
-				button.showMessage();
-			}
-		});
-}
-
-/**
- * This attribute can be used to pass a URL to this select.
- *
- * ```
- * <monster-form data-monster-datasource="restapi:....."></monster-form>
- * ```
- *
- * @private
- * @return {object}
- */
-function initOptionsFromArguments() {
-	const options = {};
-
-	const datasource = this.getAttribute(ATTRIBUTE_FORM_DATASOURCE);
-	if (isString(datasource)) {
-		for (const [key, classObject] of Form.getDatasources()) {
-			if (datasource === key) {
-				let args = this.getAttribute(ATTRIBUTE_FORM_DATASOURCE_ARGUMENTS);
-
-				try {
-					args = JSON.parse(args);
-				} catch (e) {
-					this.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
-					continue;
-				}
-
-				try {
-					options["datasource"] = new classObject(args);
-				} catch (e) {
-					this.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
-					continue;
-				}
-
-				break;
-			}
-
-			if (options["datasource"] instanceof Datasource) {
-				break;
-			}
-		}
-	}
-
-	return options;
 }
 
 /**
  * @private
- * @this Form
+ * @returns {initEventHandler}
  */
-function initObserver() {
-	const self = this;
-
-	let lastDatasource = null;
-	self[internalSymbol].attachObserver(
-		new Observer(function () {
-			const datasource = self.getOption("datasource");
-			if (datasource !== lastDatasource) {
-				new Processing(100, function () {
-					self.refresh();
-				}).run();
-			}
-
-			lastDatasource = datasource;
-		}),
-	);
+function initEventHandler() {
+
+    if (this.getOption("features.writeBack") === true) {
+        const events = this.getOption("writeBack.events");
+        for (const event of events) {
+
+            this.addEventListener(event, (e) => {
+
+                if (!this.reportValidity()) {
+
+                    this.classList.add("invalid");
+                    setTimeout(() => {
+                        this.classList.remove("invalid");
+                    }, 1000)
+
+                    return;
+                }
+
+                if (this[debounceCallbackSymbol] instanceof DeadMansSwitch) {
+                    try {
+                        this[debounceCallbackSymbol].touch();
+                        return;
+                    } catch (e) {
+                        if (e.message !== "has already run") {
+                            throw e;
+                        }
+                        delete this[debounceCallbackSymbol];
+                    }
+                }
+
+                this[debounceCallbackSymbol] = new DeadMansSwitch(200, () => {
+                    setTimeout(() => {
+                        this.write();
+                    }, 0);
+                });
+
+            });
+        }
+    }
+
+    return this;
 }
 
 /**
  * @private
- * @return {Monster.Components.Form.Form}
+ * @return {FilterButton}
  */
 function initControlReferences() {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	this[formElementSymbol] = this.shadowRoot.querySelector(
-		"[data-monster-role=form]",
-	);
-	return this;
+    if (!this.shadowRoot) {
+        throw new Error("no shadow-root is defined");
+    }
+    return this;
 }
 
 /**
@@ -589,8 +237,8 @@ function initControlReferences() {
  * @return {string}
  */
 function getTemplate() {
-	// language=HTML
-	return `
+    // language=HTML
+    return `
         <div data-monster-role="control" part="control">
             <form data-monster-attributes="disabled path:disabled | if:true, class path:classes.form"
                   data-monster-role="form"